VBA技術解説
Rangeの使い方:最終行まで選択を例に

ExcelマクロVBAの問題点と解決策、VBAの技術的解説
最終更新日:2019-06-16

Rangeの使い方:最終行まで選択を例に


Rangeの使い方・書き方について、データ最終行まで選択する場合を例に説明します、
Rangeの書き方なので、RangeオブジェクトではなくRangeプロパティの解説という事になります。


最近続けざまに、以下のようなコードを見かけました。
Range("A2", Range("A2").End(xlDown)).Select
Range("A2", Cells(Rows.Count, 1).End(xlUp)).Select

Selectの部分は、Copyだったりでしたが、基本的な書き方としては同じです。

しかも、これらが、VBA逆引き辞典からの引用だったり、ネットから探したとの事。
ちょっと信じられない感じです。
指定方法が分からずに、試行錯誤でこの記述にたどり着いたのなら、それはその人をむしろ誉めたいくらいですが、
書籍や、ネットで情報発信する人が書くべきコードではないと思います。
以下、順に説明しますが、
基本的なRangeの指定方法については、
ExcelマクロVBA入門
・VBA入門の大目次 ・1. VBAの基礎・基本:VBA入門 ・2. VBA入門に必要なVBEの基本的使い方 ・3. VBAプログラミングの基礎・基本 ・4. Excel各種機能とオブジェクトの理解:VBA入門 ・5. VBA初級からVBA中級を目指して ・6. VBA入門の後日追加記事 ・7. VBA入門その後の学習について
第9回.Rangeでのセルの指定方法
・複数のセル(矩形のセル範囲) ・列全体 ・行全体 ・名前定義のセル範囲 ・特殊な指定方法 ・マクロVBAで良く使う書き方
こちらを参照してください。

A1セルに見出しがあり、A2からA10にデータが入っているとします。
そこで、A2~A10を選択するVBAでのRangeの書き方のいろいろです。
ここでは動作確認しやすいようにSelectで説明しますが、
実際には、Copyメソッド等になることが多いと思います。

まずは、固定位置として書くと、
Range("A2:A10").Select
これは極一般的な書き方なので問題ないでしょう。

少し違う指定方法として
Range("A2", "A10").Select
これでも同じ指定となります。

固定位置としてではなく、データの最終行を取得して指定する場合ですと、
Range("A2", Range("A1").End(xlDown)).Select
これが最初に書いたもので、どうしてこんな書き方になってしまうのか・・・
これは悪い例です。

そもそも途中にブランクのセルがあると、最終行が正しく取得できません。

まあ、それで相談をうけたのですけど。
それでは、これもたまに見かける書き方ですが、
Range("A2", Range("A65536").End(xlUp)).Select
これ、2003までなら良いですけど、2007が出てから久しいですし、今や2013ですから、
固定の65536ってわけにはいきません。
では、1048576とするかって事ですが、これだと互換モード(.xls)では使えません。

最終行は正しく取得しましょう。
Range("A2", Cells(Rows.Count, 1).End(xlUp)).Select
こういう事になりますね。

しかし、この指定、見ていてなんとなく違和感というか、変な感じがしませんか、私だけかなw
これは、
Range(セル番地文字, Rangeオブジェクト)
このような指定になっているのです。

Rangeプロパティのヘルプを見てみましょう。
WorksheetのRangeプロパティのヘルプより。
セルまたはセル範囲を表す Range オブジェクトを返します。
構文
式.Range(Cell1, Cell2)
式 Worksheet オブジェクトを表す変数。
パラメーター


名前 必須/オプション データ型 説明
Cell1 必須 バリアント型 (Variant) セル範囲の名前を指定します。これは、コード記述時の言語の A1 形式での範囲である必要があります。
範囲名には、範囲を表す演算子 (:)、共通部分を表す演算子 (スペース) または複数の範囲を表す演算子 (,) を含めることができます。また、ドル記号 ($) は含めることはできますが、無視されます。
範囲の一部にローカルに定義した名前を使用できます。名前を使用する場合、その名前はコード記述時の言語と見なされます。
Cell2 オプション バリアント型 (Variant) セル範囲の左上隅と右下隅のセルを指定します。
各引数には、単一のセル、列全体、または行全体を含む Range オブジェクト、あるいはコード記述時の言語で単一のセルの名前を示す文字列を指定できます。

備考
オブジェクト修飾子を指定せずにこのプロパティを使用すると、ActiveSheet.Range のショートカットとなります。つまり、アクティブ シートから範囲を取得します。アクティブ シートがワークシートでない場合、このプロパティは失敗します。
Range オブジェクトに対して使用すると、このプロパティは、その Range オブジェクトと相対的に動作します。たとえば、セル C3 を選択すると、Selection.Range("B1") は、Selection プロパティで取得される Range オブジェクトと相対的な範囲を取得するので、セル D3 が返されます。一方、コード ActiveSheet.Range("B1") は必ずセル B1 を取得します。

使用例
次の使用例は、シート 1 のセル A1 の値を 3.14159 に設定します。
Worksheets("Sheet1").Range("A1").Value = 3.14159

次の使用例は、シート 1 のセル A1 に数式を作成します。
Worksheets("Sheet1").Range("A1").Formula = "=10*RAND()"

次の使用例は、シート 1 のセル範囲 A1:D10 に対してループを行います。セルの値が 0.001 未満の場合は、値をゼロ (0) に置き換えます。
For Each c in Worksheets("Sheet1").Range("A1:D10")
  If c.Value < .001 Then
    c.Value = 0
  End If
Next c

次の使用例は、"TestRange" という名前の範囲に対してループを行い、範囲内の空のセル数を表示します。
numBlanks = 0
For Each c In Range("TestRange")
  If c.Value = "" Then
    numBlanks = numBlanks + 1
  End If
Next c
MsgBox "There are " & numBlanks & " empty cells in this range"

次の使用例は、シート 1 のセル範囲 A1:C5 のフォント スタイルを斜体に設定します。Range プロパティの構文 2 を使用します。
Worksheets("Sheet1").Range(Cells(1, 1), Cells(5, 3)).Font.Italic = True

※若干の編集を加えています。


先の使い方は、このヘルプが原因なのでしょう。
Range(Cell1, Cell2)
このCell1の説明が、「セル範囲の名前を指定します。」となっていますからね。
しかし、これはヘルプを書いた人の意図と少し違っているものと思われます。
最後の、「Range プロパティの構文 2 を使用」ここに注目してください。

つまり、構文1と構文2があり、
構文1は、
Range(Cell1)
Cell1は、セル範囲の名前を指定
構文2は、
Range(Cell1, Cell2)
Cell1とCell2は、「セル範囲の左上隅と右下隅のセルを指定
と考えるべきなのです。

理由として、
Range(Cells(1, 1))
このような記述が出来ないことにあります。
Range(Cells(1, 1), Cells(5, 3))、これができるのに、Range(Cells(1, 1))、こちらができないのです。
そして、そもそも、
Range(Cells(1, 1), Cells(5, 3))
この指定は、ヘルプのCell1の説明に反しています。
「セル範囲の名前を指定します。」と書いてあるのに、違う指定となっています。
この理由により、Rangeプロパティの作者の意図は、
構文1と構文2を明確に区分けしているという事です。

ただし、
構文2のCell指定は、バリアント型で、
「Range オブジェクト、あるいはコード記述時の言語で単一のセルの名前を示す文字列を指定」
となっていますので、先のような文字列とオブジェクトの混在も許されているということです。
ただし、構文2で文字列を指定するという事は、その文字列のRangeオブジェクトへの変換を、
Rangeプロパティにやってもらっているだけのことでしかありません。
ですから、先の書き方が絶対にダメだと言っているわけではなく、
あまり良い書き方ではないという事、初心者に伝えるべき書き方ではないということです。
このような書き方を見せられても、初心者は応用が効かなくなってしまいます。
そして、先のコードも、そのような問い合わせを受けたものです。

では、構文1と構文2での書き方になります。
構文1
Range("A2:A" & Cells(Rows.Count, 1).End(xlUp).Row).Select
こうなっちゃいますよね、これは構文1に忠実に書いてはいますが、このような書き方は止めましょう。
その為に、構文2が用意されているのですから。
構文2
Range(Range("A2"), Cells(Rows.Count, 1).End(xlUp)).Select
これが推奨の書き方になります。
もちろん、Range("A2")は、Cells(2, 1)のどちらでもよいです。

正直、分かっている人にとっては、そんなにこだわるほどの問題ではないのですが、
VBAを覚えようとしている人に見せるコードとしては、
やはり基本に忠実なコードを提示すべきだと思い、かなり気にかかったのでここに書きました。


RangeとCellsの関連記事
RangeとCellsの使い方
・RangeとCellsの基本的な使い分け方 ・固定セル(固定位置)の指定 ・Rangeに変数は使わないようにします ・1つの(VBAで位置を変化させる)セルを指定する場合 ・セル範囲(複数セル)を指定する場合 ・複数行全体、複数列全体の指定 ・RangeとCellsの使い分け方のまとめ ・RangeとCellsの基本の関連記事 ・RangeとCellsの応用の関連記事
RangeとCellsの深遠
RangeとCells特集にします。今さら…と、あなどるなかれ、結構奥が深いのです。すでに説明した内容もありますが、知っておいた方が良い事、知らなくても困らない事(笑) これらを、まとめてみました。まずは基本 A1セルに"エクセル"と入れる場合。
だまされるな!RangeとCellsの使い分け!
ネットを見ていると、Range("A"&i) と言う記述を良く見かけます。初心者の方が、マクロの自動記録を見て、記録されたマクロを自分で工夫して、行数を変数にしたというのなら素晴らしい事です。しかし、マクロについて、かなり手慣れた人や、時にはExcelマクロの指導的立場にいる人が、
Range以外の指定方法(Cells,Rows,Columns)
・Cells(行番号, 列番号) ・Rows(行番号) ・Columns(列番号) ・RangeとCellsの関連記事




同じテーマ「マクロVBA技術解説」の記事

オートフィルタ(AutoFilter)の使い方まとめ
複雑な条件(複数除外等)のオートフィルター(AutoFilter)
クリップボードを使わないセルのCopy
Rangeの使い方:最終行まで選択を例に
フルパスをディレクトリ、ファイル名、拡張子に分ける
Colorプロパティの設定値一覧(カラー定数、XlRgbColor列挙)
VBAを定型文で覚えよう
VBAこれだけは覚えておきたい必須基本例文10
エクセルVBAでのシート指定方法
文字列結合&でコンパイルエラーになる理由
手動計算時の注意点と再計算方法


新着記事NEW ・・・新着記事一覧を見る

TOROW関数(配列を横1行の配列にして返す)|エクセル入門(2022-10-31)
TOCOL関数(配列を縦1列の配列にして返す)|エクセル入門(2022-10-31)
CHOOSECOLS関数(配列から複数の指定された列を返す)|エクセル入門(2022-10-29)
CHOOSEROWS関数(配列から複数の指定された行を返す)|エクセル入門(2022-10-29)
WorksheetFunctionの効率的な使い方とスピル新関数の利用|VBA入門(2022-10-27)
VSTACK関数(配列を縦方向に順に追加・結合)|エクセル入門(2022-10-25)
HSTACK関数(配列を横方向に順に追加・結合)|エクセル入門(2022-10-25)
LAMBDA以降の新関数の問題と解説(配列操作関数編)|エクセル入門(2022-10-24)
LAMBDA以降の新関数の問題と解説(ヘルパー関数編)|エクセル入門(2022-10-24)
LAMBDA以降の新関数の問題集|エクセル入門(2022-10-24)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.Excelショートカットキー一覧|Excelリファレンス
7.並べ替え(Sort)|VBA入門
8.マクロって何?VBAって何?|VBA入門
9.エクセルVBAでのシート指定方法|VBA技術解説
10.ExcelマクロVBAの基礎を学習する方法|エクセルの神髄




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ