Excelマクロ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入門
ExcelVBAとはエクセルの操作を自動化するマクロ機能で使われているプログラミング言語です。VBAは「MicrosoftVisualBasicApplications」の略になります。このVBA入門シリーズでは実務で必要とされるVBAの入門として基本から応用までのVBA全般を解説していきます。
第9回.Rangeでのセルの指定方法
前回までに出てきたRangeの使い方はRange("A1") このように書きくことで1つのセルを指定する場合でした。複数のセル範囲を指定する場合矩形のセル範囲行全体列全体特殊なセル範囲 これらの指定方法を見ていきましょう。複数のセル(矩形のセル範囲) 複数のセル(矩形のセル範囲)を指定する場合の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の使い方
VBAではセルを指定する方法としてRangeとCellsがありますRangeもCellsもどちらもRangeオブジェクトでセルを指定するものです。どちらを使ったらよいのでしょうかどう使い分けたらよいのでしょうか実際のVBA記述ではRangeとCellsを使い分ける必要がありますRangeとCellsの使い方について解説をします。
RangeとCellsの深遠
RangeとCells特集にします。今さら…と、あなどるなかれ、結構奥が深いのです。すでに説明した内容もありますが、知っておいた方が良い事、知らなくても困らない事(笑) これらを、まとめてみました。まずは基本 A1セルに"エクセル"と入れる場合。
だまされるな!RangeとCellsの使い分け!
ネットを見ているとRange("A"&i) と言う記述を良く見かけます。初心者の方がマクロの自動記録を見て記録されたマクロを自分で工夫して行数を変数にしたというのなら素晴らしい事です。しかしマクロについてかなり手慣れた人や時にはExcelマクロの指導的立場にいる人が
Range以外の指定方法(Cells,Rows,Columns)
Rangeの指定で、あらゆるセルおよびセル範囲は指定できるのですが、マクロで使う場合は、ちょっと使いづらい場合があります。"A1"や"B5"と言うような文字で指定するのでは何かと不便です、もっと、プログラムっぽい(笑)指定方法があります。




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

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


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

VBAクラスのAttributeについて(既定メンバーとFor Each)|VBA技術解説(10月19日)
VBAの用語について:ステートメントとは|VBA技術解説(10月16日)
VBAのマルチステートメント(複数のステートメントを同じ行に)|VBA技術解説(10月14日)
VBAコードの全プロシージャー・プロパィ一覧を取得|VBAサンプル集(10月12日)
VBAでエラー行位置(行番号)を取得できるErl関数|VBA技術解説(10月11日)
手動計算時の注意点と再計算方法|ExcelマクロVBA技術解説(10月9日)
引数の数を可変にできるパラメーター配列(ParamArray)|VBA入門(10月7日)
VBEの使い方:デバッグ|ExcelマクロVBA入門(10月6日)
VBAにおける配列やコレクションの起点について|VBA技術解説(10月5日)
VBEの使い方:オブジェクト ブラウザー|VBA入門(10月5日)


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

1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.RangeとCellsの使い方|ExcelマクロVBA入門
4.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
5.変数とデータ型(Dim)|ExcelマクロVBA入門
6.繰り返し処理(For Next)|ExcelマクロVBA入門
7.マクロって何?VBAって何?|ExcelマクロVBA入門
8.ひらがな⇔カタカナの変換|エクセル基本操作
9.空白セルを正しく判定する方法(IsEmpty,IsError,HasFormula)|VBA技術解説
10.セルに文字を入れるとは(Range,Value)|VBA入門



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

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


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




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