我需要声明一堆变量,并且想知道是否有任何方法可以缩短执行此操作所需的行数。这是代码:
Sub test()
dim comps as New Collection
dim noOfCompanies as Integer: noOfCompanies = 25
dim c1 as New Names 'Names is a class I have made
dim c2 as New Names
... ' in this gap is c3 to c29
dim c30 as New Names
End Sub
我不知道您可以创建变量并执行以下操作,是吗? (注:Psuedocode)
dim i as Integer
for i = 1 to 30
Dim "c" & i as New Names
next i
编辑: @rene提到使用数组 - 我怎么会这样做,如果以后我要设置类属性的部分(对不起,我学习课程并且不知道正确的术语):
c1.companyCode = 10: c1.companyCountry = "USA": c1.companyName = "Batman LTD"
c2.companyCode = 13: c2.companyCountry = "Krypton": c2.companyName = "Superman LLC"
... 'etc until c30.
这是我到目前为止所尝试的内容,但无济于事: Dim tempC As String,tempN As String
For i = 1 To noOfCompanies
c(i) = "c" & i
tempC = c(i)
Debug.Print tempC 'This will correctly print "c1", "c2", "c3", etc.
Dim c(i) As New Names 'This is where I can't figure out how to declare the different array parts as an individual "new Names" class part.
Debug.Print tempN
Next i
EDIT2: 这就是为什么我要尝试创建30个变量的原因。我每周都会收到一个包含一列代码的电子表格(代码是我在上面初始化的companyCode)。如果我找到一行我想要声明的30个代码中的任何一个,那么我需要将companyName和companyCountry放在该行的其他一些单元格中。我的想法是能够做这样的事情(伪代码):
dim rng as Range
rng = Range("A1:A30") 'this has the codes in it, i.e. 13, 10, 11, 20...
for each cel in Rng
'here would be code where I just check for IF the cel.Value is anywhere in companyCode,
'return its equivalent companyCountry and companyName
next cel
那么,字典最好吗?我可以这样做
if dict.exists(cel.value)
但是我如何将companyCountry和companyName存储在同一个词典条目中,AFAIK我每条目只能存储一个密钥?
...当然,如果只是将这些信息保存在excel表格中某个地方(xlsx或csv)并且只是打开/使用那么那么关闭将是最好的做法,请告诉我!
答案 0 :(得分:2)
Dim arrNames(1 to 30) as Names, n
for n=1 to 30
Set arrNames(n)=new Names
next n
arrNames(5).companyCountry = "USA"
编辑:我认为将您的代码信息存储在工作表上并直接访问它是最好的"除非你需要高容量/高性能的查询(即使那样它也不会坏......)
例如,这里有一个非常简单的功能,你可以从VBA调用:
Function CompanyInfo(companyCode, infoType As String)
Dim rng As Range, colNum As Long, rv
Select Case infoType
Case "Country": colNum = 2
Case "Name": colNum = 3
Case Else
CompanyInfo = "InfoType?"
Exit Function
End Select
rv = Application.VLookup(companyCode, _
ThisWorkbook.Sheets("Codes").Range("A2:C100"), _
colNum, False)
CompanyInfo = IIf(IsError(rv), "???", rv)
End Function
用法:
Dim v, v2
v = CompanyInfo(10,"Country")
v2 = CompanyInfo(10,"Name")
答案 1 :(得分:1)
为什么不将c1,... c30对象属性存储在表,xml文件,csv文件或任何其他多种类型的文件中?这可以存储数据并通过VBA读取。
因此,在需要时,您可以打开表格,并使用表格中的值填充对象属性的数组?如果您的表/文件包含30行,则将创建一个包含30个对象的数组。
通过这样做,您还将separate your code from your data,这通常被视为最佳做法。
答案 2 :(得分:1)
我不确定我是否喜欢使用" Names"作为一个类名,因为"姓名"已经有了Excel VBA的含义,但如果这就是你想要的。
正如其他人所指出的那样,阵列可能是要走的路。但是如果你真的想拥有30个变量并且你不想做很多打字,你可以这样做:
Sub DeclareVars()
Dim i As Long, v As Variant
ReDim v(1 To 30)
For i = 1 To 30
v(i) = "c" & i & " As New Names"
Next i
Debug.Print "Dim " & Join(v, ", ")
End Sub
运行一次并将结果从即时窗口复制到您的代码中。如果你了解Python,你可以在Python shell中使用1-liner并输入更少的内容。只评估:
"Dim " + ", ".join('c' + str(i) + " As New Names" for i in range(1,31))
答案 3 :(得分:1)
使用集合创建包含名称的类的30个实例的示例。
如果必须使用"c1-c30"
检索它们,那么您可以将其用作类中的变量(如Name)或集合索引/键。
例如:
名称类:
Private pName As String
Private pOther As Integer
Public Property Get Name() As String
Name = pName
End Property
Public Property Let Name(Value As String)
pName = Value
End Property
分配和打印我们的30个名称:
Sub Test()
Dim MyNames As Collection
Set MyNames = New Collection
Dim x
For x = 1 To 30
Dim t As Names
Set t = New Names
t.Name = "c" & x
MyNames.Add t
Next x
Dim y
For Each y In MyNames
MsgBox (y.Name)
Next y
End Sub
最后,我认为您的问题是您希望能够在分配代码之后通过名称在代码中引用这30个cnames。这不会起作用,这是一个糟糕的编码习惯。你不应该这样做:
Dim c1
Set c1 = new Names
c1.Name = "Bob"
Dim c2 '...
人们通常会使用增量数字声明30个变量。原因是因为有更好的方法。这种方式通常使用变量类型的集合或可以使用索引或循环引用的变量类型数组。
如果您要创建30个特定数据类型的实例,并且想要为它们提供每个唯一值,请创建一个表甚至静态数组来保存它们的值并将它们分配到循环中。
要进行跟进,如果您想使用c & x
引用它们,请在您的类中添加一个名为ID的变量并分配给它。
如果您希望能够快速检索ID而无需循环检查ID,则可能需要考虑使用dictionary。
修改强>
我很高兴你解释了你的最终比赛。你绝对会使这种情况过于复杂。
一个简单的VLOOKUP公式和一个查找表将使您不必在VBA中编写任何代码。
示例:
创建一个名为LookupTable的命名区域,其中包含最左侧的公司ID:
然后,使用这些公式在表格中搜索ID,并为您提供名称/位置。
参数1是Lookup的值
参数2是我们的LookupTable
参数3是我们表中要返回的列
(1 = ID,2 =公司名称,3 =城市)
参数4表示我们只想要完全匹配。
=VLOOKUP(A1,LookupTable,2,FALSE)