2017-08-30 1 views
2

現在ループの一部が一度だけ実行されるDo Whileループを設定しようとしています。私は効果的に1つのシートのセル範囲を定義しようとしているし、私のループは、範囲を再指定することなく、すべてのシート/ワークブックにこの同じセル範囲を適用します。ループの後に変数値を忘れてしまいました

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が指定されたセル範囲であることがわかります。しかし、2番目のループでrng.Addressは<ObjectRequired>になり、残りのスクリプトは失敗します。 rng.Addressを指定されたセル範囲に永久に設定する方法に関するアイデアはありますか?

+0

「more stuff goes here」でwbをクローズしていますか? – exSnake

答えて

7

特定の問題は、多くのコードを見ずですが、私はこれに代えて同様に、より簡潔なロジックを示唆しているものを言うのは難しい:

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

NB:

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 

はこれを行います。 ' 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

これは非常に簡潔で、はるかに簡潔で、すぐに問題を解決しました。 P.S.あなたは正しい、私はワークブックを閉じていたので、その付属書に感謝します! – alex1stef2

-3

変数をif文の外側で宣言する必要があります。そうでなければ、if/loop文の外ではアクセスできません。

+4

間違っています。これは他の言語(c#、pythonなど)でも当てはまりますが、VBAでは当てはまりません。さらに、OPの質問は反復に関するものです(したがって、Whileループの範囲内にあります)。 –

4

問題は、Rangeオブジェクトが最初にワークブックに接続されていること、です。したがって、そのブックを閉じると、Rangeオブジェクトが失われます。

必要がありますアドレスを文字列変数に保存すると、すべてのループでアクセスできます。

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

ダビデはあなたの前に少し居ましたが、はい、これも問題を回避するための実行可能な方法です! – alex1stef2

+2

"何らかの形で接続されています" - rngはワークシート(ブックのプロパティ)のプロパティです。マジックではありません:)また、「rng」がスコープから外れる「次のワークブックを開く」ではなく、「rng」を失う最初のワークブックを閉じる*です。乾杯。 –

+0

右の解決策ですが、上記の点を明確にするためにあなたの答えに小さな編集を加えました。 –

関連する問題