Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 加快声明变量的速度?_Vba_Excel - Fatal编程技术网

Vba 加快声明变量的速度?

Vba 加快声明变量的速度?,vba,excel,Vba,Excel,我有一大堆变量需要声明,我想知道是否有任何方法可以缩短这样做所需的行数。代码如下: 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 Name

我有一大堆变量需要声明,我想知道是否有任何方法可以缩短这样做所需的行数。代码如下:

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)

编辑: @rene提到使用数组-如果稍后我要设置类属性的一部分(对不起,我正在学习类,不知道正确的术语),我将如何使用数组:

以下是我目前正在尝试的,但没有用: Dim tempC作为字符串,tempN作为字符串

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
编辑2: 这就是为什么我要创建30个变量。我每周都会收到一份电子表格,其中有一列代码(这些代码就是我在上面初始化的公司代码)。如果我发现一行包含我试图声明的30个代码中的任何一个,那么我需要将companyName和companyCountry放在该行的其他单元格中。我的想法是能够做这样的事情(psuedocode):

那么,字典是最好的吗?我可以喜欢

if dict.exists(cel.value) 
但是,如果每个条目只能存储一个键,那么如何将companyCountry和companyName存储在同一个词典条目中呢

…当然,如果只是将此信息保存在某个excel表格中(xlsx或csv),然后打开/使用它,那么关闭将是最佳做法,请告诉我

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")
编辑:我认为将代码信息存储在工作表上并直接访问它是“最好”的方法,除非您需要大量/高性能的查找(即使这样也不会很糟糕…)

例如,您可以从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")

你为什么不储存你的c1。。。c30对象表、xml文件、csv文件或任何其他多种类型的文件中的属性?可以存储数据并通过VBA读取

因此,在需要时,您可以打开表,用表中的值填充对象属性的数组?如果表/文件包含30行,则将创建一个包含30个对象的数组


通过这样做,您也将获得成功,这通常被认为是最佳实践。

为什么不存储c1。。。c30对象表、xml文件、csv文件或任何其他多种类型的文件中的属性?可以存储数据并通过VBA读取

因此,在需要时,您可以打开表,用表中的值填充对象属性的数组?如果表/文件包含30行,则将创建一个包含30个对象的数组


通过这样做,您还将看到,这通常被认为是最佳实践。

我不确定是否喜欢使用“名称”作为类名,因为“名称”已经具有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))

我不确定我是否喜欢使用“名称”作为类名,因为“名称”已经具有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))

使用集合创建包含名称的类的30个实例的示例

如果必须使用
“c1-c30”
检索它们,则可以将其用作类中的变量(如名称)或集合索引/键

例如:

名称类:

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
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个姓名:

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
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个CNAME。这是行不通的,这是一种糟糕的编码实践。你不应该这样做:

Dim c1
Set c1 = new Names
c1.Name = "Bob"
Dim c2 '...
人们通常不会用递增的数字声明30个变量,这是有原因的。原因是有更好的方法。这种方法通常使用变量类型集合或变量类型数组,您可以使用索引或循环引用这些变量类型

如果要创建30个特定数据类型的实例,并且希望为每个实例指定唯一的值,请创建一个表或甚至一个静态数组来保存它们的值并在循环中分配它们

接下来,如果您想使用
c&x
引用它们,请在类中添加一个名为ID的变量并分配给该变量

如果您希望能够在不循环检查ID的情况下快速检索ID,您可能需要研究使用

编辑:

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
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
我很高兴你解释了你的结局。你完全把这个场景复杂化了

一个简单的VLOOKUP公式和一个查找表将使您不必在VBA中编写任何代码

例如:

创建名为LookupTable的命名范围,该范围包含最左侧的公司ID:

然后,使用这些公式在表中搜索ID,并给出名称/位置

参数1是要查找的值

参数2是可查找的

参数3是表中要返回的列

(1=ID,2=公司名称,3=城市)

参数4表示我们需要一个e