【问题标题】:Passing variable to another sub in a for loop if如果在for循环中将变量传递给另一个子
【发布时间】:2018-02-18 10:01:22
【问题描述】:

在下面显示的代码中出现以下错误,

编译错误

参数数量错误或属性分配无效

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

-

更新

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

公共子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)

过程声明与同名事件或过程的描述不匹配

【问题讨论】:

  • 哪一行给出了错误?
  • @ashleedawg CopyData_Click (ShNameRow) 给出错误
  • 是的,我知道发生了什么事......你有一些潜在的问题,但我会在回答中专注于你的问题......
  • 下面有几个答案。不要忘记 ✓ 接受 一个可以帮助您解决问题的答案,并 ▲ Upvote 任何您认为写得好的答案。
  • @ashleedawg 刚从晚餐回来,给我一些时间来测试一下,没想到会有这么快的反应。谢谢

标签: vba global-variables parameter-passing


【解决方案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) 使用 UserForm 对象的 Tag 属性来存储想要的信息

    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

【讨论】:

  • 什么样的错误,哪一行抛出了那个错误?
  • 错误 = 过程声明与同名事件或过程的描述不匹配 代码 = Private Sub CopyData_Click(ShNameRow As Integer)
  • 还没有测试过,我知道用户表单属性下有标签功能,但是,里面有什么?不知道怎么用
【解决方案2】:

从一个潜艇获取数据到另一个潜艇可以通过几种方式完成,但这里是你混淆的两种方式:

全局变量

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 上搜索“全局变量 Excel VBA”和“传递参数 Excel VBA”以了解有关两者的更多信息。

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

关于您的示例中的代码需要注意的几点:

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

  • 我还将您的 Dim 语句从循环内部移到了开头。您不希望循环内有任何您不想一遍又一遍地运行的东西(比如声明一个变量)。 ...从技术上讲,我不应该在您的问题中更改您的代码(除了缩进之类的装饰性问题),但这是习惯的力量(而且您很容易犯错误!)

祝你好运!

【讨论】:

  • 我在测试完上面的代码后更新了它们。后一个子出现错误
  • 什么错误?你用了什么代码?您可能仍在某处使用不正确的语法,因为我发布的示例非常简单(并且它们自己可以正常运行。)您是否在 Google 上搜索了我在回答中建议的术语
  • (顺便说一句,"code" 总是单数。"Codes" 不是一个词,当在编程环境中使用(每次都让我畏缩!)。更多信息 here)。 ☺
猜你喜欢
  • 2017-04-01
  • 1970-01-01
  • 2021-06-21
  • 1970-01-01
  • 2014-10-05
  • 2022-10-15
  • 2019-11-29
  • 1970-01-01
  • 2021-05-31
相关资源
最近更新 更多