Excel VBA でを使用することの当然の嫌悪感についてはよく耳にします.Select
が、 の使用を避ける方法がわかりません。 関数の代わりに変数を使用できれば、コードの再利用性が高まると思います。 ただし、を使用しない場合、 などのSelect
ものを参照する方法がよくわかりません。ActiveCell
Select
見つけた範囲に関するこの記事そして選択を使用しないことの利点に関するこの例ですが、その方法については何も見つかりません。
ベストアンサー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
変数にはメソッド (やなど) も適用する必要がありますFind
。Copy
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
これは、可能性のほんの一例です。