Excel VBAでSelectを使用しないようにする方法 質問する

Excel VBAでSelectを使用しないようにする方法 質問する

Excel VBA でを使用することの当然の嫌悪感についてはよく耳にします.Selectが、 の使用を避ける方法がわかりません。 関数の代わりに変数を使用できれば、コードの再利用性が高まると思います。 ただし、を使用しない場合、 などのSelectものを参照する方法がよくわかりません。ActiveCellSelect

見つけた範囲に関するこの記事そして選択を使用しないことの利点に関するこの例ですが、その方法については何も見つかりません。

ベストアンサー1

選択を回避する方法の例

Dim'd変数を使用する

Dim rng as Range

Set変数を必要な範囲に参照します。単一セル範囲を参照する方法は多数あります。

Set rng = Range("A1")
Set rng = Cells(1, 1)
Set rng = Range("NamedRange")

または、複数のセルの範囲:

Set rng = Range("A1:B10")
Set rng = Range("A1", "B10")
Set rng = Range(Cells(1, 1), Cells(10, 2))
Set rng = Range("AnotherNamedRange")
Set rng = Range("A1").Resize(10, 2)

メソッドへのショートカットを使用することもできますEvaluateが、効率性が低いため、通常は実稼働コードでは避ける必要があります。

Set rng = [A1]
Set rng = [A1:B10]

上記の例はすべて、アクティブ シートWorksheetのセルを参照しています。アクティブ シートのみで作業したい場合を除き、変数もDim する方がよいでしょう。

Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
Set rng = ws.Cells(1, 1)
With ws
    Set rng = .Range(.Cells(1, 1), .Cells(2, 10))
End With

を操作したい場合ActiveSheet、明確にするために明示的に記述するのが最善です。ただし、一部のWorksheetメソッドはアクティブ シートを変更するので注意してください。

Set rng = ActiveSheet.Range("A1")

繰り返しますが、これはアクティブなワークブックを参照します。ActiveWorkbookまたはのみを具体的に操作する場合を除きThisWorkbook、変数も Dim する方が適切ですWorkbook

Dim wb As Workbook
Set wb = Application.Workbooks("Book1")
Set rng = wb.Worksheets("Sheet1").Range("A1")

を操作したい場合ActiveWorkbook、明確にするために明示的に記述するのが最善です。ただし、多くのWorkBookメソッドがアクティブなブックを変更するので注意してください。

Set rng = ActiveWorkbook.Worksheets("Sheet1").Range("A1")

ThisWorkbookオブジェクトを使用して、実行中のコードを含むブックを参照することもできます。

Set rng = ThisWorkbook.Worksheets("Sheet1").Range("A1")

よくある(悪い)コードは、本を開いてデータを取得してから再び閉じるというものです。

これは悪いです:

Sub foo()
    Dim v as Variant
    Workbooks("Book1.xlsx").Sheets(1).Range("A1").Clear
    Workbooks.Open("C:\Path\To\SomeClosedBook.xlsx")
    v = ActiveWorkbook.Sheets(1).Range("A1").Value
    Workbooks("SomeAlreadyOpenBook.xlsx").Activate
    ActiveWorkbook.Sheets("SomeSheet").Range("A1").Value = v
    Workbooks(2).Activate
    ActiveWorkbook.Close()
End Sub

そして、次のようにすると良いでしょう:

Sub foo()
    Dim v as Variant
    Dim wb1 as Workbook
    Dim  wb2 as Workbook
    Set wb1 = Workbooks("SomeAlreadyOpenBook.xlsx")
    Set wb2 = Workbooks.Open("C:\Path\To\SomeClosedBook.xlsx")
    v = wb2.Sheets("SomeSheet").Range("A1").Value
    wb1.Sheets("SomeOtherSheet").Range("A1").Value = v
    wb2.Close()
End Sub

範囲をRange 変数としてSubおよびに渡します。Function

Sub ClearRange(r as Range)
    r.ClearContents
    '....
End Sub

Sub MyMacro()
    Dim rng as Range
    Set rng = ThisWorkbook.Worksheets("SomeSheet").Range("A1:B10")
    ClearRange rng
End Sub

変数にはメソッド (やなど) も適用する必要がありますFindCopy

Dim rng1 As Range
Dim rng2 As Range
Set rng1 = ThisWorkbook.Worksheets("SomeSheet").Range("A1:A10")
Set rng2 = ThisWorkbook.Worksheets("SomeSheet").Range("B1:B10")
rng1.Copy rng2

セルの範囲をループする場合は、範囲の値を最初にバリアント配列にコピーし、それをループする方がよい (高速) ことがよくあります。

Dim dat As Variant
Dim rng As Range
Dim i As Long

Set rng = ThisWorkbook.Worksheets("SomeSheet").Range("A1:A10000")
dat = rng.Value  ' dat is now array (1 to 10000, 1 to 1)
for i = LBound(dat, 1) to UBound(dat, 1)
    dat(i,1) = dat(i, 1) * 10 ' Or whatever operation you need to perform
next
rng.Value = dat ' put new values back on sheet

これは、可能性のほんの一例です。

おすすめ記事