セルに対して操作を行うと、たいていRangeというキーワードが出てきます。
Rangeは、セルが複数集まったものだと思えばいいでしょう。
Range | A1形式の指定方法(1セル) | [/2002-07-19] |
Cells | 座標形式の指定方法 | |
Offset | 位置をずらす方法 | |
Range | 複数セルの指定方法 | |
Columns , Rows | 行のみ、列のみの指定方法 | [/2008-08-17] |
Union , Areas | 複数領域の使用方法 | [/2002-07-19] |
Count | セル数の取得方法 | [2002-07-19] |
Range.Name | 名前を付けたセルの指定方法 | |
Column , Row | Rangeの位置や行数・列数の取得方法 | [2002-07-19] |
シート | シートを明示する方法 | [/2002-07-19] |
Range | Rangeに対してRangeを使う方法 | [2002-07-19] |
[範囲] | 角括弧を使って指定する方法 | [2006-06-17] |
UsedRange | 使われている範囲を取得する | [2008-08-17] |
参照元・参照先 | セルの参照先・参照元を取得する | [2008-08-17] |
1つのセルに値を入れるなら、
Range("A2").Value = "a"
セルA2に値を代入します。 なお、キーワード「Value」は省略できるので、省略して書く人も多いようですが… 詳しくはFormulaとValueの関係を参照のこと。
しかし プログラム内でループして使いたいような場合は この表記方法は不便です。その場合はCellsを使えます。
Dim Y As Integer
For Y = 1 To 5
Cells(Y, 1).Value = "a"
Next
Cellsというキーワードを使っていますが、内容的にはRangeと同じです。 Cells(行,列)という形式で、いわばCells(Y座標,X座標)という指定です。 (X,Y)という順序と逆なので混乱しやすい(苦笑)…まぁExcelは表なので(行,列)なんだけど
ある範囲を移動していって処理するような場合は、Rangeだけでも出来ますけどね。
Dim Rng As Range
Set Rng = Range("A1")
Dim Y As Integer
For Y = 1 To 5
Rng.Value = "a"
Set Rng = Rng.Offset(1, 0)
Next
Offsetは、現在のRangeから、位置を(行,列)にずらしたRangeを返します。
複数セルの内容を消すような場合、
Range("B2:E3").ClearContents
セルB2からセルE3の範囲の、複数セルの内容を消去します。
複数セルを座標で指定したい場合は、ちょっとくどいですが
Range(Cells(r1,c1), Cells(r2,c2)).ClearContents
と書けば、(r1,c1)から(r2,c2)の範囲を指定したことになります。
なお、行=ROW,列=COLUMNということで、r,cという記号(変数)を使っています。
縦の列あるいは横の行を扱いたい場合には、さらに他の表現があります。
Columns(2).ClearContents '2列目を消去 Rows(3).ClearContents '3行目を消去 Columns("A").ClearContents 'Aの列を消去 Rows("4").ClearContents '4行目を消去 Columns("C:E").ClearContents 'C〜Eの列を消去 Rows("5:6").ClearContents '5〜6行目を消去
実際のところ、Columns("A")はRange("A:A")と、Rows("4")はRange("4:4")と同等です。
ただし、Countの結果は違う。
複数列・複数行を扱う為にColumns(3,5)とかRows(5,6)といった表現ができれば便利だと思うんですが、
そういう書き方は出来ないようです。
行から行までを指定(例:Rows(3,5))するより、
各行を指定(例:Rows(3,4,5))する方が応用が効くか…とか考えると
単純には出来ないけど。
対象Rangeを含む列全体・行全体を扱うには、以下のような方法もあります。[2008-08-17]
Cells(2, 3).EntireColumn.Select 'Columns(3).Selectと同じ Cells(2, 3).EntireRow.Select 'Rows(2).Selectと同じ Dim r As Range Set r = Range(Cells(2, 1), Cells(4, 1)) r.EntireRow.Select 'Rows("2:4").Selectと同じ
複数Rangeを結合して、とりまとめて一つの範囲として扱うこともできます。 シート上で、Ctrlキーを押しながらセルを選択した状態と同等。
Dim R1 As Range, R2 As Range, R3 As Range
Set R1 = Range("A1:C1")
Set R2 = Range("A3:C3")
Set R3 = Range("A5:C5")
Dim Rng As Range
Set Rng = Union(R1, R2, R3)
Rng.Value = "a"
Unionを使ってR1〜R3をまとめてRngにセットし、複数Rangeを1つのRangeのように扱っています。
RangeがいくつのRangeから成っているかを知るには、以下のようにします。 [2002-07-19]
Dim n As Integer
n = Rng.Areas.Count
ちなみに、Rangeがいくつのセルから成っているかを知るには、以下のようにします。 ただし、下の例で言えばRngが Columnsから代入された場合は列数、Rowsの場合は行数になってしまう。
Dim n As Long
n = Rng.Count
行全体や列全体のRangeに対してこれを使うと 65536以上の値が返ってくる可能性があります。 その場合、Integerの変数に入れようとすると実行時エラー(オーバーフロー)になります。
複数Rangeを1つずつの領域にして使いたい場合は、以下のようにします。
Dim I As Integer
For I = 1 To Rng.Areas.Count
Rng.Areas(I).Value = I
Next I
セルや範囲に名前を付けている場合、
Range("ほげほげ").Value = "a"
という様に、「ほげほげ」という名前を付けられた領域に値を入れることが出来ます。
Rangeの位置(範囲の場合は、最も左上のセルの位置らしい)を取り出すには、以下のようにします。 [2002-07-19]
Dim x As Integer, y As Integer x = Range("ほげほげ").Column y = Range("ほげほげ").Row
Dim Rng As Range Set Rng = Range("A1:B3") Dim cx As Long, cy As Long cx = Rng.Columns.Count cy = Rng.Rows.Count
範囲でないRange(要するに単独のセル)は行数も列数も1です。
「Columnsで指定した範囲」に対する行数と
「Rowsで指定した範囲」に対する列数は
65536以上の値が返ってくる可能性があります。
その場合、Integerの変数に入れようとすると実行時エラー(オーバーフロー)になります。
範囲が単純な四角形でない場合(複数RangeをUnionで繋げたもの)は、
最初のRangeが対象になるようです。全てを網羅したい場合は、Areasを使うしかありません。
今まで直接Rangeから書き始めていましたが、実は「どのシートの範囲か」という情報を省略していました。 省略した場合、アクティブなシート(表示されているシート)を指定したことになります。
Range("A1").Value = "A"↓
ActiveSheet.Range("A1").Value = "A"
これを明示的に記すことにより、アクティブでないシートも扱うことが出来ます。
Dim Src As Worksheet, Dst As Worksheet Set Src = Sheets("Sheet2") Set Dst = Sheets("Sheet3") Dst.Range(Dst.Cells(1, 1), Dst.Cells(2, 2)).Value = Src.Cells(1, 1).Value
Sheet2のセルA1の値を、Sheet3のA1〜B2の範囲に代入しています。
ただし、Range型の変数を使用する場合にはシートの指定は不要です。 [2002-07-19]
Dim DR As Range, SR As Range
Set SR = Src.Cells(1, 1)
Set DR = Dst.Range(Dst.Cells(1, 1), Dst.Cells(2, 2))
DR.Value = SR.Value
さらに、Rangeに対してRange(やCells)を使うことが出来ます。 その場合、最初のRangeの範囲の最も左上のセルを基準(A1・(1,1))にした座標系を使うことになります。 Offsetと同じようなもんですかねぇ。
Dim Rng As Range Set Rng = Range("B2:C5") Rng.Cells(1, 1).Value = "s" Rng.Range("B2:C3").Value = "r"
上記の例だと、シートのB2に「s」が入り、C3〜D4の範囲に「r」が入ります。
シートの中で使われている(値が入っている)範囲はUsedRangeによって取得できます。[2008-08-17]
Dim r As Range Set r = ActiveSheet.UsedRange Debug.Print r.Column, r.Columns.Count Debug.Print r.Row, r.Rows.Count
UsedRangeは、シートの中で値の入っている最も左上のセルと 最も右下にあるセルによる四角形が返ります。
自セルが参照している先や、自セルが他セルから参照されている場合の参照元を取得することが出来ます。[2008-08-17]
(「=A1」という式が設定されている場合、自分はA1を参照している。A1は(自セルから)参照されている。)
Dim r1 As Range, r2 As Range, r3 As Range, r4 As Range set r1 = Range("A1").DirectPrecedents '参照元 set r2 = Range("A1").Precedents set r3 = Range("A1").DirectDependents '参照先 set r4 = Range("A1").Dependents r4.Select
Directが付いているものは、直接自分を使っている・使われているセルが対象。
Directが付いていないものは、間接的に自分が使っている・使われているセル全てが対象。
A1の式が「=B2」でB2の式が「=C3」の場合、A1セルに対するPrecedentsはB2とC3が返され、DirectPrecedentsはB2のみが返されます。