【问题标题】:Variable value being forgotten after loop VBA循环VBA后变量值被遗忘
【发布时间】:2017-08-30 13:05:15
【问题描述】:

我目前正在尝试设置一个Do While 循环,其中循环的一部分只执行一次。我正在有效地尝试为一张工作表定义一个单元格范围,然后让我的循环将此相同的单元格范围应用于所有工作表/工作簿,而无需重新指定范围。

这是我目前所拥有的:

isExecuted = False
Do While FileName <> ""
    ' Open a workbook in the folder
    Set WorkBk = Workbooks.Open(Folder & "\" & FileName)

        ' Conditional to select range only once
        If Not isExecuted Then

            Dim rng As Range
            Set rng = Application.InputBox("Select a Range", "Obtain Range Object", Type:=8)
            Debug.Print (rng.Address)
            MsgBox "The cells selected were " & rng.Address
            isExecuted = True

        End If


    Set SourceRange = WorkBk.Worksheets(1).Range(rng.Address)

' more stuff goes here

处于调试模式。这个循环第一次执行时,一切都按预期工作,我可以看到我的 rng.Address 是指定的单元格范围。但是,在第二个循环中,rng.Address 变为&lt;ObjectRequired&gt;,因此脚本的其余部分将失败。关于如何将 rng.Address 永久设置为指定单元格范围的任何想法?

【问题讨论】:

  • 您是否正在关闭“这里有更多内容”中的 wb?

标签: vba excel


【解决方案1】:

如果没有看到更多代码,很难说具体问题是什么,但我建议使用更简洁的逻辑,例如:

    If Not isExecuted Then

        Dim rng As Range
        Set rng = Application.InputBox("Select a Range", "Obtain Range Object", Type:=8)
        Debug.Print (rng.Address)
        MsgBox "The cells selected were " & rng.Address
        isExecuted = True

    End If

这样做:

If rng is Nothing Then
    Set rng = Application.InputBox("Select a Range", "Obtain Range Object", Type:=8)
End If

注意:如果您在 ' more stuff goes here 部分期间关闭工作簿,那可能会杀死对该范围的对象引用

关于如何将rng.Address 永久设置为指定单元格范围的任何想法?

是的,只保留Address 而不是对象。由于Address 是字符串文字,即使对象引用超出范围,您也可以将其保留在String 变量中:

Dim addr As String
If addr = vbNullString
    addr = Application.InputBox("Select a Range", "Obtain Range Object", Type:=8).Address
End If
Set SourceRange = WorkBk.Worksheets(1).Range(addr)

【讨论】:

  • 这太棒了 - 更简洁并立即解决了问题。附:你是对的,我正在关闭工作簿,所以谢谢你的附录!
【解决方案2】:

问题是,范围对象连接到第一个工作簿。因此,当您关闭该工作簿时,范围对象将丢失。

您需要将地址保存在字符串变量中,这样您就可以在每个循环中访问它。

    Dim strAddress as String
    isExecuted = False
    Do While FileName <> ""
        ' Open a workbook in the folder
        Set WorkBk = Workbooks.Open(Folder & "\" & FileName)

            ' Conditional to select range only once
            If Not isExecuted Then

                Dim rng As Range
                Set rng = Application.InputBox("Select a Range", "Obtain Range Object", Type:=8)
                Debug.Print (rng.Address)
                MsgBox "The cells selected were " & rng.Address
                strAddress = rng.Address
                isExecuted = True

            End If


        Set SourceRange = WorkBk.Worksheets(1).Range(strAddress )

    ' more stuff goes here

【讨论】:

  • 大卫比你早一点到达那里,但是这也是解决问题的可行方法!
  • “以某种方式连接” -- rng 是工作表的属性(它是工作簿的属性)。这不是魔法 :) 此外,它不是“打开下一个工作簿”导致 rng 超出范围,而是 关闭 导致 rng 丢失的初始工作簿。干杯..
  • 正确的解决方案,不过,我对您的回答做了一些小修改,以澄清上述几点。
  • @DavidZemens 感谢您的解释。和编辑
【解决方案3】:

您需要在 if 语句之外声明变量,最好在循环之外声明。否则你不能在 if/loop 语句之外访问它。

【讨论】:

  • 错了。虽然这在其他语言(c#、python 等)中是正确的,但对于 VBA 则不是这样。此外,OP 的问题与迭代有关(因此无论如何它都在 While 循环的范围内)。
猜你喜欢
  • 1970-01-01
  • 2014-06-22
  • 2018-07-31
  • 2019-04-30
  • 1970-01-01
  • 1970-01-01
  • 2014-02-25
  • 2019-02-11
  • 1970-01-01
相关资源
最近更新 更多