如果将变量传递给for循环中的另一个sub

时间:2018-02-18 10:01:23

标签: vba global-variables parameter-passing

我的代码中出现以下错误,

  

编译错误

     

错误的参数数量或无效的属性赋值

Public Sub ListBox1_Click()

    Dim ShNameRow As Integer
    For i = 0 To ListBox1.ListCount - 1

        If ListBox1.Selected(i) = True Then

            Set T1 = Range("A" & i + 13).Resize(26 - i, 1)
            Set T2 = Range("E" & i + 13).Resize(26 - i, 2)
            Set T3 = Range("K" & i + 13).Resize(26 - i, 1)
            Set y = Application.Union(T1, T2, T3)
            y.Select
            Selection.Copy


            ShNameRow = 13 + i
            'Error with passing this variable
            CopyData_Click (ShNameRow)

        End If
    Next i

End Sub

Private Sub CopyData_Click()
    'Testing variable
    MsgBox (ShNameRow)
End Sub

-

更新

我尝试了将变量从一个sub传递到另一个sub的示例,因为我觉得我的代码更适用。

Public Sub ListBox1_Click()

Dim ShNameRow As Integer
For i = 0 To ListBox1.ListCount - 1

    If ListBox1.Selected(i) = True Then

        Set T1 = Range("A" & i + 13).Resize(26 - i, 1)
        Set T2 = Range("E" & i + 13).Resize(26 - i, 2)
        Set T3 = Range("K" & i + 13).Resize(26 - i, 1)
        Set y = Application.Union(T1, T2, T3)
        y.Select
        Selection.Copy


        ShNameRow = 13 + i
        'Error with passing this variable
        CopyData_Click (ShNameRow)

    End If
Next i

End Sub

Private Sub CopyData_Click(ListboxShNameRow As Integer)
MsgBox (ListboxShNameRow)
End Sub

这会带来另一个编译错误,由下面的块引用显示

Private Sub CopyData_Click(ListboxShNameRow As Integer)
  

程序声明与具有相同名称的事件或程序的描述不匹配

2 个答案:

答案 0 :(得分:1)

在OP问题编辑和澄清之后

编辑

所以CopyData_Click是按钮事件处理程序...

然后您必须在ListBox1_Click()内设置变量并在CopyData_Click()

中使用它

1)使用模块作用域变量

ShNameRow声明为模块作用域变量,即"看到的变量"在同一模块内的任何子/函数内部(在您的情况下是您的用户表单代码模块

这样做只需将Dim ShNameRow As Integer放在模块的最顶层

然后只调用没有参数的CopyData_Click传递(因为签名需要)

    Option Explicit

    Dim ShNameRow As Integer

    Public Sub ListBox1_Click()

        Dim i As Integer
        Dim T1 As Range, T2 As Range, T3 As Range, y As Range
        For i = 0 To ListBox1.ListCount - 1

            If ListBox1.Selected(i) = True Then

                Set T1 = Range("A" & i + 13).Resize(26 - i, 1)
                Set T2 = Range("E" & i + 13).Resize(26 - i, 2)
                Set T3 = Range("K" & i + 13).Resize(26 - i, 1)
                Set y = Application.Union(T1, T2, T3)
                y.Select
                Selection.Copy

                ShNameRow = 13 + i

                CopyData_Click ' call 'CopyData' button 'Click' event handler

            End If
        Next i

    End Sub


    Private Sub CopyData_Click()
        MsgBox ShNameRow ' 'ShNameRow ' variable can be used inside this sub because it's a module scoped variable. i.e. it's "seen" throughout every sub or function inside the module on top of which it's declared 

        ... rest of your code (I guess you are "pasting" the already copied range)
    End Sub

2)使用Tag对象的UserForm属性来存储想要的信息

    Option Explicit


    Public Sub ListBox1_Click()

        Dim i As Integer
        Dim T1 As Range, T2 As Range, T3 As Range, y As Range
        For i = 0 To ListBox1.ListCount - 1

            If ListBox1.Selected(i) = True Then

                Set T1 = Range("A" & i + 13).Resize(26 - i, 1)
                Set T2 = Range("E" & i + 13).Resize(26 - i, 2)
                Set T3 = Range("K" & i + 13).Resize(26 - i, 1)
                Set y = Application.Union(T1, T2, T3)
                y.Select
                Selection.Copy

                Me.Tag = 13 + i
                'Error with passing this variable
                CopyData_Click

            End If
        Next i

    End Sub

    Private Sub CopyData_Click()
        Dim ShNameRow As Integer ' declare 'ShNameRow' as a local variable, i.e. it's "seen" only inside the sub/function it's declared in
        ShNameRow = Me.Tag ''Me' is the keyword referring to the User Form object whose module code you're inside
        MsgBox ShNameRow

        ... rest of your code (I guess you are "pasting" the already copied range) 
    End Sub

答案 1 :(得分:1)

从一个子到另一个子的数据可以通过几种方式完成,但这里有两个你正在混淆:

全局变量

Public myGlobalVariable As String

Sub myMainSub()
    myGlobalVariable = InputBox("Enter a word:")
    myOtherSub
End Sub


Sub myOtherSub()
    MsgBox "Any sub can see 'Public' variables : " & myGlobalVariable
End Sub

将变量作为参数传递

Sub myMainSub2()
    Dim myVariableWithinSub As String
     myVariableWithinSub = InputBox("Enter a word:")
     myOtherSub2 (myVariableWithinSub)
End Sub


Sub myOtherSub2(variableIgotFromOtherSub As String)
    MsgBox "Variables can be passed as 'Parameters' like this." & _
        vbLf & "See? : " & variableIgotFromOtherSub
End Sub

这个问题可能会被关闭,因为这是一个非常基本的东西,你应该用Google搜索并想出来,但我知道当你不知道要搜索什么时很难开始。

在您的模块和实验中尝试我的示例(单独),以便您可以看到差异。 Google使用“全局变量Excel VBA”和“传递参数Excel VBA”这些术语来了解有关这两者的更多信息。

另外,我强烈建议您将Option Explicit作为每个模块的第一行。这似乎会导致错误,但它会通过强迫您正确声明和放弃来防止将来对您自己感到沮丧。处理所有变量,对象,属性等。

请注意示例中的代码:

  • 我修复了你的缩进。缩进不会改变代码运行的方式,但它使您(和其他人)更容易阅读和排除故障。

  • 此外,我将您的Dim语句从循环中移到了开头。你不希望循环中任何你不想反复运行的东西(比如声明一个变量)。 ...从技术上讲,我不应该在你的问题中更改你的代码(在缩进等美容事物之外),但它是习惯的力量(你很容易犯错!)

祝你好运!