- 締切済み
エクセルVBA セル選択範囲を調べるメソッドについ
こんにちは 今回エクセルでセル選択範囲を調べる方法について探していたのですが”Selection.Address”が 見つかりました。 これは、結果を文字型で返す仕様となっていて、文字型では、応用処理がややこしそうになります。 離れた範囲で選択した場合"例 R1C1:R2:C2,R4C4:R5C5" のように返ってきます" そこで、これを数値に変換したり、選択範囲が離れてていた場合は離れた範囲ごとに配列として返 してくれる関数やメソッドのようなものは、VBAに用意されていないでしょうか? または、直接 希望する型で返ってくればそれでよいのですが、見つけることが出来ませんでした。 なお、エクセルのバージョンは2003です。 もしなければ作成する予定です。
- tubasa000
- お礼率50% (10/20)
- Visual Basic
- 回答数5
- ありがとう数1
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- cj_mover
- ベストアンサー率76% (292/381)
こんにちは。#1~4、cjです。 フラグ配列を使った例をあげることにしました。 応用できる機会が比較的多いと思います。 また、この方法だと、元々の行位置の順に格納できますから、 ソートする必要がありません。 また、重複の処理も簡単です。 一応、これは、元々の質問に対する答えに近いようにも思います。 Range オブジェクトのプロパティからフラグ配列を作って、 テーブル全体の値を格納した配列から フラグ配列のインデックスに対応したレコードを バッファに流し込みます。 (レコードの先頭が1行目から始まらない場合を考慮して書いていますので、その分少し長いです。) (一般的なエラー処理も加えました。) ' ' ============================================================ Sub Re7761791c5() Dim buf() ' 抽出レコードを流し込む配列 Dim mtxV() ' テーブル全体の値を格納する配列 Dim Target As Range ' Selectionを元に、テーブルからはみ出た範囲を削いだセル範囲 Dim a As Range ' Area ループ用 Dim nRowOffset As Long ' 『テーブル上の行番地』と『配列インデックス』との相対補正 Dim nYSize As Long ' テーブルの行サイズ Dim nXSize As Long ' テーブルの列サイズ Dim nTop As Long ' Area 先頭行の相対番地 Dim nBottom As Long ' Area 最下行の相対番地 Dim arFlg() As Boolean ' 抽出レコードをマークするフラグ配列 Dim cnt As Long ' 抽出レコード数カウンタ Dim i As Long, j As Long ' ループ用カウンタ ' Range("G13:G14,B2:B3,E10:G13,C6:D7,F7:G7").Select ' ダミー ' ' セル範囲以外を選択中なら、抜ける If TypeName(Selection) <> "Range" Then Exit Sub With Sheets("リスト") nRowOffset = 0 ' 先頭.Row - 1 ' ' 最下行位置を取得して、行サイズを求める nYSize = .Cells(Rows.Count, "A").End(xlUp).Row - nRowOffset nXSize = 11 ' 列サイズ ' ' テーブル全体を捉える With .Cells.Resize(nYSize, nXSize).Offset(nRowOffset) ' ' Selection について、テーブルから、はみ出た部分を削いでおく Set Target = Application.Intersect(.Cells, Selection) ' ' Selection がテーブル内にない場合、抜ける If Target Is Nothing Then Exit Sub ' ' テーブル全体の値を配列として格納しておく mtxV() = .Value End With End With ' ' フラグ配列を行サイズで定義 ReDim arFlg(1 To nYSize) As Boolean ' ' Target 各Areaをループ For Each a In Target.Areas ' ' Area の先頭行位置を相対位置で求める nTop = a.Row - nRowOffset ' ' Area の行数を取得して、最下行位置を相対位置で求める nBottom = nTop + a.Rows.Count - 1 ' ' Area の先頭行から最下行に対応したフラグをTrueに設定する For i = nTop To nBottom ' ' (他のAreaと重複している場合)既にTrueに設定してある場合は何もしない If Not arFlg(i) Then arFlg(i) = True ' ' 抽出するレコード数をカウント cnt = cnt + 1 End If Next i Next a ' ' 抽出レコードを流し込む配列をレコード数と列サイズで定義 ReDim buf(1 To cnt, 1 To nXSize) cnt = 0 ' ' フラグ配列を総なめして、Trueならbufに流し込む For i = 1 To nYSize If arFlg(i) Then cnt = cnt + 1 For j = 1 To nXSize buf(cnt, j) = mtxV(i, j) Next j End If Next i ' Range("M1").Resize(cnt, nXSize).Value = buf ' ダミー ' ' オブジェクト変数の解放 Set Target = Nothing ' ' 配列変数の初期化 ' Erase mtxV, arFlg, buf End Sub ' ' ============================================================ 応用できる場面が見つかるといいのですけれど。 以上です。
- cj_mover
- ベストアンサー率76% (292/381)
こんにちは。#1、2、3、cjです。#3補足欄へのレスです。 ご自分で研究しながら着実に進んでいることが、こちらにも伝わってきます。 非常にいい印象ですし、こちらもやりがいがあります。 さておき、 複数のセルブロックを指定して、 最終的に必要なレコードだけを、 ひとつの2次元配列に、(できればSortして)格納したい という【テーマ】に限って考えてみます。 まずは、#3でご提示のコードについて。 Select して Selection を追いかけるのは何かと紛れの元になりますから、 Range型の変数に一旦格納してみます。 Set Target = Application.Intersect(Sheets("リスト").Range("A:k"), Selection.EntireRow) If Target Is Nothing Then Exit Sub ' ↑(Dim Target As Range) これ↑で、 (テーブルの外を選択していたり、他のシートで実行してたり)エラーを回避できる意味もありますし、 後に続く処理が Target に対するものであることが明示的になり、より確実なものになります。 オブジェクト型の変数はプロシージャの最後で Set Target = Nothing のように解放してあげるようにしましょう。 '配列サイズ設定 の > ReDim buf(i, 11) 正しくは ReDim buf(1 To i, 1 To 11) ですね。 配列変数を扱う時は、最小の添え字(LBound)が 1 なのか 0 なのか (或いはそれ以外なのか)恒に、注意を払うようにしましょう。 ご提示のコードでは、buf(0, any)、buf(any, 0)がすべてEmpty値になっていて 不必要なことをしていることになります。 もう一点、.Intersectメソッドを使う利点として重複は既に除かれていることを利用すると、 i = Application.Intersect(Sheets("リスト").Range("A:A"), Target).Count ReDim buf(1 To i, 1 To 11) という纏め方も可能ではあります。 (簡単に書けるという意味です。処理が速くなる訳ではありません) (同じ.Intersectメソッドを使うのにも、こちらは、 エラーになる要因が既にクリアになっているので省略して書けます) '選択範囲を配列buf(行,列)へ設定 は、差し当たってダメ出しするほどの問題ではないのですけれど、 一貫性を通した書き方をすると、こんな感じでしょうか。 i = 0 For Each a In Target.Areas For Each rw In a.Rows i = i + 1 j = 0 For Each r In rw.Cells j = j + 1 buf(i, j) = r.Value Next r Next rw Next a ' ↑(Dim r As Range) > For Each rw In a.Rows < これは#3で私が書いたことの実践なのでしょうけれど、 レコード毎に切り分ける必要がないのならば .Rows プロパティを使う必要もなくて、 今回の【テーマ】では .Areas プロパティすら省略できて、うんと簡単に i = 1 j = 1 For Each r In Target buf(i, j) = r.Value If j = 11 Then j = 1 i = i + 1 Else j = j + 1 End If Next r ' ↑(Dim r As Range) ↑こんな風に纏めることも可能です。 一旦、整理します。今回の【テーマ】では .Areas プロパティ無しでも出来るということで。 Sub Re7761791r3() Dim buf() Dim Target As Range, r As Range Dim i As Long, j As Long ' Range("G13:G14,B2:B3,E10:G13,C6:D7,F7:G7").Select ' ダミー Set Target = Application.Intersect(Sheets("リスト").Range("A:k"), Selection.EntireRow) If Target Is Nothing Then Exit Sub '配列サイズ設定 i = Application.Intersect(Sheets("リスト").Range("A:A"), Target).Count ReDim buf(1 To i, 1 To 11) '選択範囲を配列buf(行,列)へ設定 i = 1 j = 1 For Each r In Target buf(i, j) = r.Value If j = 11 Then j = 1 i = i + 1 Else j = j + 1 End If Next r Set Target = Nothing End Sub .Intersectメソッドを使う利点を最大限活かす手法にも触れておきます。 .Intersectメソッドで得られるTargetのすべて.Areasが、共通の列幅をもっているならば、 そのまま.Copyして貼りつけてしまうことで、 ・重複は削除され・連結した配列として・Sortされた配列を シート上に作成できます。 Sub Re7761791_40() Dim buf() Dim Target As Range ' Range("G13:G14,B2:B3,E10:G13,C6:D7,F7:G7").Select ' ダミー Set Target = Application.Intersect(Sheets("リスト").Range("A:K"), Selection.EntireRow) If Target Is Nothing Then Exit Sub Target.Copy Destination:=Range("M2") '選択範囲を配列bufへ格納 buf = Range("M1").CurrentRegion.Value Set Target = Nothing End Sub 作業セル(作業シート)を(一時的にでも)設けることが許されるならば、 上記のような手法も場合によって(目的によって)は有効です。 案外、配列変数を使わなくとも、目的が果たせるケースも少なからずあることでしょう。 (上例の "M2" は、上の行が空行、左の列が空列、以下空セル、という条件で適宜指定してください) /// 私、今、余裕がないので、このレスは一旦、ここまでにしてあらためて続きを書きます。 次に、今回の【テーマ】に即した形で、Sortも併せ、配列への格納方法を探ってみます。 外部オブジェクトは使わずに純粋にVBAだけを用いるレベルで、 なるべく難しい関数などは使わない形で書いてみようと思います。 ある程度処理の速度を速める意図で、 配列変数を使うメリット(VBA独特のメリット)を出せるように考えてみます。 ポイントはRangeオブジェクトへのアクセスを最小限にして、 メモリ上の配列変数での処理を優先させること、になります。 ただ、色々な方法があるので、どんなものを紹介したらいいか迷っています。 文字数制限に掛かってしまうので、どのみち、もう1レスすることにはなりますが、 ちょっと体力的な問題を抱えてたりもするので、少し、時間をくださいませ。 それでは、また。
- cj_mover
- ベストアンサー率76% (292/381)
こんにちは。#1、2、cjです。 #2補足欄へのレスです。 > リスト形式のデーターテーブル(シート)がある。 > ユーザーは処理対象としたいレコード(セル)を任意に選択する(複数可)。 > プログラムは、選択されたレコード(セル)を対象に処理(他のシートにコピーや印刷 > など。差込印刷)をする。 > これらのことをするのにプログラムはユーザーの選択セル情報を知る必要があるのでそ > の方法を探していたところでした。 そういう目的ならば、行番地の数値を追いかけずとも、 Rangeオブジェクトで取得した方が何かと便利です。 次の例では、例えば、ユーザー操作で重複して選択されたセル範囲があった場合でも 自動的に重複を除いてくれます。 例えばコピーなら、そのままコピペ(VBAでも手作業でも)すれば 有用なレコードだけを整列して貼り付けできますし、、、。 割とお得な近道だと思いますが、どうでしょうか。 Sub Re7761791ja() Range("B2,D4,B4:B5,B7:B9,B8,B11:B14").Select ' ダミー MsgBox "Prep." Application.Intersect(ActiveCell.CurrentRegion.EntireColumn, Selection.EntireRow).Select MsgBox "Got" & vbLf & Selection.Address(0, 0) End Sub もしレコードごとのデータをレコードごとに切り分けて処理する必要がある場合は For Each a In Selection.Areas For Each rw In a.Rows のようにも切り分け可能ですし、 配列に格納したデータを行番地を参照して取得するような方法にも応用できます。 また、レコードそのものではなく、キーとなるIDなどをポイントする目的でも 基本的には同じように処理するのが簡単です。 > いずれにしろ構想の段階ですが、文字型では、処理が難しくなるのではないのかなぁと > 思い、数値型でのアドレス情報での処理をしようと思った次第です。 確かに、クエリやコマンドや正規表現が苦手という方は沢山いらっしゃいますから、 苦手意識がある人にはrange.Address でさえも難しいのかも知れませんね。 一般論としては文字列で処理するよりは数値で処理する方が優る、という場面が多いのも事実で 仰ることはよく解ります。 ただ、数値配列の取得も、数値配列を参照してRange オブジェクトを取得する方法も Excelには用意されてませんので、その代わりになる機能を他に求めるのが普通のやり方だと思います。 そういう意味では#1で紹介した手法もどこかで役に立つことがあればいいですけどね。 注).Select、Selectionは概念提示の為便宜的に使っているもので実践には使いません。 一応。質問者さんがここでメソッドと呼んでいるのはプロパティですので確認してみてください。 とりあえず、以上です。
- cj_mover
- ベストアンサー率76% (292/381)
なんか、ちょっとわかった気がしたので重ねてレスしてみます。 Range("A1:C5,D6:E10,G3:G12,B15:E16") を例えにすると matrix = [{1,1,5,3;6,4,10,5;3,7,12,7;15,2,16,5}] で、得られるような {top,left,bottom,right} 矩形範囲毎に絶対座標を配列にしたものを さらに二次元配列や二段階配列にする、みたいなことでしょうかね? そういうことでしたら > そこで、これを数値に変換したり、選択範囲が離れてていた場合は離れた範囲ごとに配列として返 > してくれる関数やメソッドのようなものは、VBAに用意されていないでしょうか? 残念ながら用意されていないです。なので、ご自分で工夫するしかないですね。 少し気になるのは最終的にそれらの座標を元に何をしたいか、ということです。 そこまでの見通しがあれば、また違うアドバイスもできるかも知れませんけれど。 "...でなければ出来ない"事例、というのは 私の経験では、相当に特殊で、例えば、 Excel2003までは 8192Areas より多い範囲を返してくれない.SpecialCells メソッドを拡張して自作した時 ぐらいで、通常は .Address プロパティ、.Row プロパティ .Column プロパティ、 Application.ConvertFormula メソッド、などを組み合わせ、 文字列処理して、セル範囲の参照文字列で工夫した方が まだ、扱い易いように思います。 (私の想像力が乏しいだけで、必然的なニーズがあるのかも知れませんが。) それから、 > もしなければ作成する予定です。 ということなので、一応、説明しておきますが、 Excel2003 で選択できるセルブロック(=矩形範囲、Area)の数は8192 までです。 ところが、.Address プロパティは 255文字までしか返しません。 255文字を超えた部分についてはバッサリ無視して、 不完全な結果だということを知ることさえ出来ません。 この点を理解した上で取り組まれた方がよいかと思います。 確実にやるなら、 .Address を採るにしても、Areaごとにするとか、 あらかじめ、Areas数を限定しておくとか、 対策が必要です。 なので、Areasごとに、.Row .Column を採っていった方が (#1下から2番目の例)結局能率的な場合もあると思います。 あとは、二次元配列なのか、ユーザー定義型(Type)を配列にするか、とか、 何にせよ、目的次第ですけれども。 とりあえず、以上です。
補足
cj_moverさん こんにちは アドバイスありがとうございます。 御回答の通りで、このような配列で返ってくることを求めていました。 次のような場合に使用出来ることを考えています。 エクセルでよく利用する使い方のではと自分自身で勝手に思っているのですが。 リスト形式のデーターテーブル(シート)がある。 ユーザーは処理対象としたいレコード(セル)を任意に選択する(複数可)。 プログラムは、選択されたレコード(セル)を対象に処理(他のシートにコピーや印刷 など。差込印刷)をする。 これらのことをするのにプログラムはユーザーの選択セル情報を知る必要があるのでそ の方法を探していたところでした。 いずれにしろ構想の段階ですが、文字型では、処理が難しくなるのではないのかなぁと 思い、数値型でのアドレス情報での処理をしようと思った次第です。 あと、.Areasは今まで知らなかったメゾッドですが、この処理に利用できるのではない のかなぁと感じました。 データ数の制限は、元データがそんなに大きくないのでとりあえずは大丈夫です。
- cj_mover
- ベストアンサー率76% (292/381)
こんにちは。 > そこで、これを数値に変換したり、選択範囲が離れてていた場合は離れた範囲ごとに配列として返 > してくれる関数やメソッドのようなものは、VBAに用意されていないでしょうか? > または、直接 希望する型で返ってくればそれでよいのですが、見つけることが出来ませんでした。 ご希望、に対する私の理解が不十分なようなので、思い当たる限りの解釈で、 応用し易そうな手法だけ、列挙したコードを掲げます。 VBEで、Ctrl+Gキーを押すとアクティブになる[イミディエイトウィンドウ] に表示される結果と、それに対応したコードとを照らし合わせれば、 大体のことは理解してもらえるように書いたつもりです。 Sub Re7761791a() Dim matrix, arr, v Dim rArea As Range Dim r As Range Range("A1:C5,D6:E10,G3:G12,B15:E16").Select ' ←テスト用のダミーです If TypeName(Selection) <> "Range" Then Exit Sub Debug.? "◆いわゆる普通のA1形式で .Address()を取得" _ & vbLf & " ? Selection.Address(0, 0)" _ & vbLf & " ⇒ " & Selection.Address(0, 0) & vbLf Debug.? "◆R1C1形式で .Address()を取得" _ & vbLf & " ? Selection.Address(ReferenceStyle:=xlR1C1)" _ & vbLf & " ⇒ " & Selection.Address(ReferenceStyle:=xlR1C1) & vbLf Debug.? "◆各Area毎 .Address()をA1形式で取得" For Each rArea In Selection.Areas Debug.? , rArea.Address(0, 0) Next rArea Debug.? Debug.? "◆.Address()を"",""区切りで配列変数に格納したものを出力" arr = Split(Selection.Address(0, 0), ",") For Each v In arr Debug.? , v Next v Debug.? Debug.? "◆各Area毎 左上の .Row .Column 右下の .Row .Column" For Each rArea In Selection.Areas With rArea Debug.? .Row, .Column; With .Cells(.Count) Debug.? , .Row, .Column End With End With Next rArea Debug.? Debug.? "◆各Areaの値を配列変数に格納して配列のサイズを確認" For Each rArea In Selection.Areas Debug.? , rArea.Address(0, 0) matrix = rArea.Value Debug.? , "1 to "; UBound(matrix, 1), "1 to "; UBound(matrix, 2) Next rArea Debug.? End Sub
お礼
cj_moverさん こんにちは 質問をしたものです。 早速ありがとうございます。 確認いたしますのですぐに返事が出来ませんが、一報としてお礼申し上げます。
関連するQ&A
- VBA、セルの選択範囲について
下記のような表を用意し、 A B C D E 1 1月 2月 3月 合計 2 Aさん 1 2 3 6 3 Bさん 1 2 3 6 4 Cさん 1 2 3 6 5 合 計 3 6 9 18 セルの範囲選択を指定し別シートの任意のセルへコピーをVBAで行いたいのですが、 Aさん、Bさん、Cさんという範囲を選択する為に、合計という文字は含みたくないので、 Range("A2").Select Range(Selection, Selection.End(xlDown).Offset(-1)).Select と記載し、これは出来ました。 同様に、 1月、2月、3月という範囲も同様にxlToRightを使用し選択出来ました。 Range("B1").Select Range(Selection.End(xlToRight).Offset(, -1), Selection).Select しかし、B2:D4の範囲の指定の仕方がわかりませんでした。 データのレコード数は一定ではないのでB2:D4というように範囲を指定する事は出来ません。 そのときに応じてDさん、Eさんと増えたり、4月、5月と増えたりするので。 何か方法があればご指導お願いします。
- ベストアンサー
- オフィス系ソフト
- VBA_選択セル範囲の最小値を求めるプロシージャ。教えてください。
EXCELVBAの参考書を読んでいて分からないところがあります。 以下は参考書に書いてある内容。 『 1:Sub Position() 2: '選択セル範囲の位置を代入するための変数を宣言する 3: Dim R1 As Long, R2 As Long, C1 As Long, C2 As Long 4: '選択セル範囲の左上の行番号/列番号を求める 5: R1 = Selection.Row 6: C1 = Selection.Column 7: '選択セル範囲の右下の行番号/列番号を求める 8: R2 = Selection.Row + Selection.Row.Count - 1 9: C2 = Selecton.Columns + Selecton.Columns.Count - 1 10: '選択セル範囲の1行下に、各列の最小値を求めるMIN関数の式を代入する 11: Range(Cells(R2 + 1, C1),Cells(R2 + 1,C2)).FormulaR1C1 = "MIN(R" & R1 & "C:R" & R2 "C)" 』 と書いてあり 11行目の説明は、 『"MIN(R" & R1 & "C:R" & R2 "C)" は、「MIN(R」 & R1 & 「C:R」 & R2 「C)」になり、最終的にセルに置きたい式は次のような式です。式の中の「□」と「○」は、変数R1とR2の値、つまり選択セル範囲の上端/下端の行番号です。 =MIN(R□:CR○C) 』とあります。 なぜ=MIN(R□:CR○C)になるのでしょうか?? CRとは行の先頭という意味ですか?? 初心者ですので分かりやすく教えてください。
- ベストアンサー
- その他(ソフトウェア)
- エクセルVBAでの範囲選択について
はじめまして。 VBAを勉強し始めたばかりなのですが、 sub test() Range("A1:M10").Select Selection.WrapText=True End Sub とあるものを、 『InputBox』を使わずに自由に範囲選択をするように するにはどういう方法があるのですか?
- ベストアンサー
- オフィス系ソフト
- ExcelのVBAで特定のセルのみ選択
Excel VBAの初心者です。 数式など入ったセルの選択は Selection.SpecialCells(xlFormulas).Select で、出来ましたが単純にセルの値が「1」などの時に選択するには どうすれば良いでしょうか。
- ベストアンサー
- オフィス系ソフト
- Excel VBAで選択範囲を一括編集
Excelで選択された範囲に入力された数値を、例えば2倍するにはどのようにすればいいのでしょうか。 Selection.Value = Selection.Value * 2 のようなやり方が知りたいです。
- ベストアンサー
- オフィス系ソフト
- Excel VBA のセル内の選択テキストの読み書きは?
Excel VBAで、選択されたセルではなくセル内の選択された部分のテキストの読み書きはできるのでしょうか? つまり、選択されたセルのテキストは Selection.Value を使って OldText = Selection.Value Selection.Value = "NewText" と読み書きができますが、セル内で選択されたテキストについてのインターフェイスはあるんでしょうか?
- 締切済み
- その他(プログラミング・開発)
- エクセルVBAでセル選択
エクセル2000でリストを作成し、VBAで編集しようとしています。 A列に入力されているコードの先頭に「’」をつけて文字列とするための関数をB2のセルからA列のデータが入力されている最後のセルの隣までコピーしたいと思っています。 A列の最終セルを取得するVBAは分かったのですが、その値をB列の選択範囲として使用する方法がわかりません。 エクセルVBAは全くの初心者です。 どなたか教えてください!
- ベストアンサー
- オフィス系ソフト
- エクセルVBAで、選択セルを常にC行にする。
エクセルVBAで、選択セルを常にC行にする。 例:ボタンをクリックすれば、選択しているセルがN25ならC25になり、N7ならC7にしたいのです。 選択セル範囲がB2:N12ならば、一番上を有効として、C2のみを選択範囲としてほしいのです。 VBAで記述するならどのようになるか。ご教示ください。
- ベストアンサー
- オフィス系ソフト
- EXCEL VBA 空白行を含んだ範囲選択
EXCEL VBA超初心者です。 EXCELのVBAについての質問です。 以下のような、日ごとのお金の貸付、返済の一覧データがあります。 例 A B C D E 1 年 月 日 貸付 返済 2 2008 5 10 10000 3 2008 6 10 8000 4 2008 7 10 20000 5 2008 8 20 7000 ・データの行数は決まっていません。 ・最後の行が「貸付」で終わることもありますし 例のように「入金」で終わることもあります。 ・各データには必ず「年」「月」「日」が入力してあります。 VBAで、A2セルからE5セルを範囲選択するには どのように記述したらいいですか? ちなみに自分で色々と調べてみて Selection.SpecialCells(xlCellTypeConstants, 23).Select としたのですが それだと空白セル(例でいうとE2やD3セル)が選択されず とびとびになってしまいました。 ご教授お願いいたします!
- ベストアンサー
- オフィス系ソフト
- セルの範囲選択
エクセルVBAの質問です。 セルの範囲選択をしたくて色々と試してみたのですが、どうも上手くいかないので教えてください。 「Range("F25:F36")」とした時の「F36」が可変の場合はどうすれば良いのでしょうか? よろしくお願いします。
- 締切済み
- Visual Basic
補足
cj_moverさん こんにちは たびたびありがとうございます。 ご回答をいただいてからそれをヒントに何とか自分で解決しようとして、さらに調べたり テストプログラムを走らせたりしてたら報告が遅くなってしまいました。 出来上がったコードが以下の通りです。 Dim buf(), a, rw Dim i As Integer, j As Integer Application.Intersect(Sheets("リスト").Range("A:k"), _ Selection.EntireRow).Select '配列サイズ設定 i = 0 For Each a In Selection.Areas i = i + a.Rows.Count Next ReDim buf(i, 11) '選択範囲を配列buf(行,列)へ設定 i = 0 For Each a In Selection.Areas For Each rw In a.Rows i = i + 1 For j = 1 To 11 buf(i, j) = Cells(rw.Row, j) Next Next Next これの結果は、配列buf(行 ,列)にセルのデータが代入されます。 選択範囲が何個もあるときなど、配列の行側の順番が上から順にならないことがあります。 この辺は、改善したかったのですが、難しくなりそうなので諦めました。 この配列データを元に自分がしたい処理が出来ると思います。 ただ、このコードは、いまのスキルで書いた為、多少無駄があるのかもしれません。 関数等を利用して数行で出来る方法があれば、ヒントを頂けたら有り難く思います。 (実は、これを探していて時間がかかりました。 元々ないから見つからなかったのかも しれません。)