2017-08-30 149 views
2

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

这是我到目前为止有:

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变为<ObjectRequired>,所以脚本的其余部分失败。有关如何将rng.Address永久设置到指定单元格区域的任何想法?

+0

你在关闭“更多的东西在这里”的wb? – exSnake

回答

7

很难说具体是什么问题,没有看到更多的代码,但我会提出一个更简洁的逻辑,喜欢的而不是这样的:

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 

NB:如果你的' 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) 
+1

这太棒了 - 更简洁,立即解决问题。附:你是对的,我正在关闭工作簿,所以谢谢你的附录! – alex1stef2

-3

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

+4

错误。虽然在其他语言(c#,python等)中这是真的,但VBA并不是这样。此外,OP的问题涉及迭代(因此无论如何它都在'While'循环的范围内)。 –

4

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

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

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 
+0

David在你面前有一点点但是是的,这也是解决问题的可行方法! – alex1stef2

+2

“以某种方式连接” - “rng”是工作表的属性(它是工作簿的属性)。这不是魔术:)另外,它不是“打开下一个工作簿”,它会导致'rng'超出范围,它会关闭导致rng丢失的初始工作簿。干杯.. –

+0

正确的解决方案,但我做了小的编辑,以您的答案澄清以上几点。 –