セルを一つずつクリックする。次いで、選択した順序で選択した値を取得したい。そのような要件があった。
例えば、このようなケースだ。
- 1から5まで一つずつ選択
- 20から16まで一つずつ選択
- 21から25まで一つずつ選択
まずは安易に、配列に格納してみる。
Sub test() Dim seq As Variant seq = Selection Dim s As Variant For Each s In seq Debug.Print s Next End Sub
結果、エラーが出た。
確認したところ、単独セルの値をVariant型の変数に入れると、配列ではなく値になるためのようだ。また、複数セルが選択されていたとしても、これでは次の選択範囲が処理対象とならない。
そこで、次のように変更してみた。
Sub test2() Dim seq() As Variant ReDim seq(0) Dim Area As Range Dim r As Range For Each Area In Selection.Areas For Each r In Area seq(UBound(seq)) = r.Value ReDim Preserve seq(UBound(seq) + 1) Next Next ReDim Preserve seq(UBound(seq) - 1) Dim s As Variant For Each s In seq Debug.Print s Next End Sub
Areasコレクションで、各選択範囲の各セルの値を一つずつ配列に格納していく。これはこれで上手くいったが、ちょっと大掛かりな感じがする。
そこで、選択範囲をRangeオブジェクトのまま変数に入れてみた。
Sub test3() Dim myRng As Range Set myRng = Selection Dim r As Range For Each r In myRng Debug.Print r Next End Sub
これも上手くいったが、myRngにはセルの番地やフォント名など、不要な情報もたくさん引き連れている。ちょっと無駄が多い気がする。
最後に、選択範囲の値をコレクションに入れてみた。
Sub test4() Dim col As Collection Set col = New Collection Dim r As Range For Each r In Selection col.Add r.Value Next Dim c As Variant For Each c In col Debug.Print c Next End Sub
これも上手くいった。単なる好みの問題なので上手く説明できないが、この方法が一番しっくりくる。
手法の良し悪しはさておき、ある目的を達成する手段を複数知っているというのは、多分良いことに違いない。と思う。
参考まで。