2017-08-30 148 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

正確的解決方案,但我做了小的編輯,以您的答案澄清以上幾點。 –