在VBA Excel 2007中传递Variant ByRef

时间:2016-02-04 21:07:43

标签: excel vba parameters arguments variant

我在UserForm中声明了一个名为MainForm

的公共Variant变量
Public increaseArray As Variant
Public countryArray As Variant

然后在sub on按钮上单击MainForm:

Sub testButton_Click()

    Dim country As Variant

    Set countryArray = Module1.callSomeFunctionThatReturnsVariant(1)
    Set increaseArray = Module1.callSomeFunctionThatReturnsVariant(2)
    For Each country In countryArray
        Call Module1.createPage(country)
    Next country
End Sub

在Module1中我有:

Function callSomeFunctionThatReturnsVariant(ByVal testInt As Integer) As Variant
   .... do something when testInt = 1
   .... do something when testInt = 2
   callSomeFunctionThatReturnsVariant = someVariant
End Function

Public Sub createPage(ByVal country As String)

     Dim testInt As Integer

     ... do something
     testInt=insertSection(country, MainForm.increaseArray)
End Sub

Function insertSection(ByVal country As String, arr as Variant) As Integer
     Dim arrCountry As Variant

     For Each arrCountry In arr
         If country = "France" Then
             ...do something
             insertSection = 1
             Exit Function
         End If
     Next arrCountry

     insertSection = 2

End Function

MainForm.increaseArray传递给insertSection()函数时,我得到ByRef参数类型不匹配错误。我尝试使用Function insertSection(ByVal country As String, ByVal arr as Variant) As Integer,但我得到了同样的错误。

如果我尝试在createPage sub Dim testArray As Variant中定义Variant变量并从其getter函数Set testArray = MainForm.getterForIncreaseArray获取increaseArray,则会出现类型不匹配错误... 如果我直接将getter函数传递给insertSection函数的调用者,我得到ByRef参数类型不匹配...

请帮助:)

2 个答案:

答案 0 :(得分:1)

这个简单的代码工作正常。

不允许在userform中声明公共数组(因此使用变量作为伪装是个好主意。)

然而,函数不想接受将它作为一个合法的数组作为参数传递,所以我使用了一个临时的“合法的”#39;阵列。

用户窗体1上的

Option Explicit

Public a As Variant 'i would usually declare it like this : Public a() as variant, but public arrays not allowed in userforms (throws error)
'Private a() as variant ,  would not throw error (inside userform)

Private Sub UserForm_Initialize()
Dim i&
ReDim a(1 To 2) 'absolutely needed, it shows a is actually an array type
a(1) = 1
a(2) = 2
End Sub

Private Sub UserForm_Terminate()
Erase a
End Sub

在一个模块中:     选项明确

Sub test()
Load UserForm1
Dim b&
Call get_value(1, UserForm1.a, b)
Unload UserForm1
MsgBox b
End Sub

Sub get_value(ByVal i&, ByRef arr As Variant, ByRef answer As Long) ' function won't let it through, i used a sub with aditionnal variable as Byref.
answer = arr(i)
End Sub

通过致电TEST启动它。

注意:我没有成功传递函数中的参数,所以在SUB中添加了一个名为Answer的参数,它是Byref。

注意2:我回头查看了我的旧代码,看起来你可以在一个函数中传递一个byref数组(伪装成变体),但也许是因为这个被声明不是用()或者其他什么,它不是&# 39; t想要通过一个函数。

注3:在进一步挖掘之后,我找到了一个使用函数的解决方案,正如我所想,数组声明是麻烦制造者:

'in a module (use the same userform as before)
Sub test()
Load UserForm1
Dim b&
Dim i& 'counter
Dim Temp_Array() As Long 'as variant works too, but i filled it with numbers so as long is ok too
ReDim Temp_Array(LBound(UserForm1.a) To UBound(UserForm1.a))
'Temp_Array = UserForm1.a 'damn, i first thought this would work, in the same way you can fill a listbox in one simple line (wich would be a 3rd solution passing an array from the userform to a module)
For i = LBound(UserForm1.a) To UBound(UserForm1.a)
    Temp_Array(i) = UserForm1.a(i)
Next i
b = get_value(1, Temp_Array)
Erase Temp_Array
Unload UserForm1
MsgBox b
End Sub

Function get_value(ByVal i&, ByRef arr As Variant) As Long
get_value = arr(i)
End Function

答案 1 :(得分:0)

根据findwindow的评论。您无法在表单中使用模块1中的内容,因为它超出了其范围。相反,尝试将module1中的所有代码放入一个新的类模块中。从表单中实例化该实例,它应该可以正常工作。