エクセルVBAのRangeの基本!Cellsとの違いは?

初心者

エクセルVBARangeとCellsの違いが分からない!
どっちを使えばいいの?

Dr.オフィス

RangeCellsはどちらもセル操作に使われるから迷ってしまうよね。

エクセルVBAでセルを操作する際、最も基本となるのがRangeCellsです。

この記事ではRangeの基本的な使い方と、Cellsとの使い分けについて、マクロ初心者がつまずきがちなポイントを中心に解説しています。

RangeCells使い分けポイント
  1. 固定範囲はRangeを使う
  2. 繰り返し処理はCellsを使う
  3. RangeCellsの組み合わせで柔軟なコードが書ける
Dr.オフィス

エクセルVBAで60万件以上のデータを扱った私が、Rangeの使い方を解説するよ!

この記事を読むことで、RangeCellsの使い分けに迷わなくなります。

コードを試して、より柔軟性が高く無駄の少ないマクロを書くヒントを手に入れましょう!

この記事のほか、エクセルVBAの基本を学びたい方はこちらの記事もご覧ください。

エクセルマクロの基礎をゼロから学ぶ!有効化やボタン設置!

※本記事は『OS:Windows11』画像は『Excelのバージョン:Microsoft365』を用いて解説をしています。

\ Officeドクター読者限定・無料Q&A /

この記事の内容でわからないことや、今すぐ解決したいOfficeのお悩みはありませんか?
Officeドクターの中の人が、公式LINEで直接ご質問にお答えします!
下のボタンをタップして、表示された入力欄からそのまま送信してくださいね。

目次

エクセルVBAのRangeの基本

エクセルVBAでセルを操作する際、最も基本となるオブジェクトがRangeです。

Rangeはセルやセル範囲を直接指定し、値の取得やコピー、削除などのセル操作に使われます。

特に初心者がRangeでつまづく場面は、次の2つを混同してしまうことです。

  • セルに値を入れる
  • セルの値を取得して変数に代入する

Rangeの基本を理解することで、Cellsなど他のセル操作のコードをスムーズに使えるようになります。

Rangeの基本を確実に押さえていきましょう。

Rangeでセルを指定する構文

まずはRangeでセルを指定してみましょう。

基本の書き方から、段階を追って説明します。

Rangeの基本構文

Rangeの最も基本的な書き方は次のとおりです。

Range("A1")

これは、セル番地「A1」を意味しています。

ここでのポイントは2点あります。

  • セル番地をダブルクォーテーション""で囲む
  • シートを指定しない場合はアクティブシートが対象になる
Dr.オフィス

アクティブシートとは、現在、作業しているシートのことだよ!

複数セルを指定

複数セルを指定する場合は、「:」コロンで範囲指定をします。

以下は、A1からB5までの長方形の範囲を指定するコードです。

Range("A1:B5")

離れた複数範囲を指定する場合は、「,」カンマで区切りましょう。

以下のコードは、A1~A5、C1~C5の二つの範囲を同時に指定しています。

Range("A1:A5,C1:C5")

シートを指定する書き方

実務でRangeを使用する際は、必ずシートを指定しましょう。

次のコードは、「Sheet1」というシート名にある「A1セル」を指定しています。

Worksheets("Sheet1").Range("A1")

シートを指定しない場合、次のような事故が起こる可能性があります。

  • 想定外のシートのセルを指定
  • 別のエクセルファイルが意図せず前面に出てきてエラーになる

VBAでエラーが少ないコードを書くために、セルを指定する際はシートも必ず指定するようにしましょう。

Rangeでセルに値を入れる2種類の方法

セルに値を入れる方法は、大きく分けて2種類あります。

Valueは特によく使いますので、必ず覚えましょう。

Valueで値を入れる

Valueは、セルに文字列や数値そのものを入れるときに使います。

例えば、次のコードはセル番地「A1」に「テスト」という文字、「A2」に100という数字を入れるコードです。

Public Sub 文字入力()

Worksheets("Sheet1").Range("A1").Value = "テスト"
Worksheets("Sheet1").Range("A2").Value = 100

End Sub

新しいエクセルファイルを作成し、実際にコードを試してみましょう。

STEP
VBAエディターを開く
「開発」タブより挿入
「開発」タブより挿入
  • 「開発」タブを押す
  • 「Visual Basic」をクリック
STEP
標準モジュールを挿入
「挿入」タブより操作
「挿入」タブより操作
  • 「挿入」タブをクリック
  • 「標準モジュール」を選択
STEP
プロシージャを挿入
続けて「挿入」タブより実行
続けて「挿入」タブより実行
  • 「挿入」タブを押す
  • 「プロシージャ」をクリック
STEP
マクロ名を入力
マクロ名は日本語でOK
マクロ名は日本語でOK
  • 「マクロ名」に内容が分かりやすいタイトルを入力
  • 「OK」ボタンを押す
STEP
コードを入力
入力する内容により””を付ける
入力する内容により””を付ける

Public Sub 文字入力()End Subの間に以下のコードをコピペします。

Worksheets("Sheet1").Range("A1").Value = "テスト"
Worksheets("Sheet1").Range("A2").Value = 100

文字列には前後に「””」ダブルクォーテーションを付けましょう。

STEP
マクロを実行する
マクロの動きを確認する
マクロの動きを確認する
  • 実行ボタンを押す
  • マクロ名はSTEP4と同じものを選択
  • 「実行」ボタンを押す
STEP
文字が入力されたことを確認
Sheet1に文字が入力された
Sheet1に文字が入力された

セル番地A1・A2に文字列が入力されたことを確認しましょう。

数式を入れるときはFormulaがお勧め

マクロを使っているとあまり活用する機会はありませんが、セルに数式を入れるケースがあります。

その場合、Valueを使っても構いませんが、Formulaを使えば、数式であることが明確に分かるのでお勧めです。

試しに、以下のコードを実行してみましょう。

Public Sub 数式入力()

Worksheets("Sheet1").Range("A3").Formula = "=50+50"
Worksheets("Sheet1").Range("A4").Formula = "=SUM(A2:A3)"

'ValueとFormula比較用
Worksheets("Sheet1").Range("A5").Value = "=SUM(A2:A3)"

End Sub

前節で作ったValueのマクロの後にコピー貼り付けしてください。

続けてコピー貼り付けする
続けてコピー貼り付けする

このマクロを実行した結果は以下のとおりです。

A4とA5の結果は変わらない
A4とA5の結果は変わらない

セル番地「A4」と「A5」の結果が変わらないこと、セルが数式であることを確認しましょう。

実務ではValue2を使うことも

大量データ処理をする場合、Valueの代わりに使われるのがValue2です。

ValueValue2の違いは、日付や通貨を扱う際、Valueの場合は数値の書式が適用された「yyyy/mm/dd」などに変換されますが、Value2は内部値をそのまま扱います。

Dr.オフィス

「内部値」とは、日付などの表示形式を反映する前の生の数値のことだよ!

その分だけ処理が速くなるため、パフォーマンス改善につながることがあります。

通常はValueで問題ありませんが、大量処理をしたり他の方のマクロを使う機会があったりする場合は、覚えておきましょう。

セルの値を取得して変数に代入しよう

Rangeを使って値を入れるだけではなく、セルに入力された値を取得することができます。

次のコードは、セル番地「A1」に入力された値を変数vに格納し、それをメッセージボックスで表示するマクロです。

Public Sub 値を取得()

Dim v As Variant

v = Worksheets("Sheet1").Range("A1").Value

MsgBox v

End Sub
コードをコピー貼り付けする
コードをコピー貼り付けする

前節で作ったFormulaのマクロの後にコピー貼り付けし、実行してみましょう。

メッセージボックスが表示された
メッセージボックスが表示された

セル番地「A1」の値がメッセージボックスに表示されることを確認してください。

なお、Dim v As Variantで変数vに格納されるデータはVariant型であることを宣言しています。

Dr.オフィス

Variantは「バリアント」と読むよ!

A1に入っている値が数値なのか文字列なのか、空白なのか分からないため、あらゆる種類のデータを格納できるVariant型を使っています。

他にもデータの型はありますが、迷ったらVariantを使いましょう。

RangeCellsとの違いを理解しよう

エクセルVBAを学び始めると、最初に混乱するのがRangeCellsの違いです。

どちらもセルを指定するコードですが、指定方法と得意分野がまったく異なります。

まずはCellsの基本構文を理解した上で、Rangeとの違いを整理しましょう。

Cellsの基本とRangeとの違い

Cellsの基本的な書き方は次のとおりです。

Cells(行番号, 列番号)

行は1行・2行・3行…と上から下に向かって増えていき、列はA列・B列・C列…と左から右に向かって増えていきます。

行と列
行と列

以下のコードはB3セルを意味します。

Cells(3,2)

CellsRangeとの違いをまとめると次のとおりです。

項目RangeCells
指定方法文字で指定数字で指定
記載例Range("B3")Cells(3,2)
向いている処理決まった範囲を指定繰り返し処理

Rangeは決まった範囲の指定、Cellsは繰り返し処理に向いています。

Cellsの実用例として、次のコードを試してみましょう。

Public Sub 繰り返し入力()

Dim i As Integer

    For i = 1 To 10
        Worksheets("Sheet1").Cells(i, 1).Value = i
    Next i

End Sub

このマクロは、Sheet1のA列に、1から10までの数字を順番に入力する処理です。

マクロの実行結果
マクロの実行結果

変数iに1から10までの数字を順に格納しながら同じ処理を繰り返す仕組みです。

Cellsは行・列番号に変数を使用でき、Cells(i, 1)iの部分が変化することで、行番号が自動で変わっていきます。

例えば変数iに5を格納した場合、Cells(i, 1).Value = iCells(5, 1).Value = 5となり、Cells(5, 1)であるセル番地A5に5が入力されます。

このように、繰り返し処理をする際はCellsが必須です。

VBAでRangeCellsを組み合わせよう

実務でよく使われるのがRangeCellsの組み合わせです。

基本構文はこのように書きます。

Range(Cells(1,1), Cells(5,2))

Cells(1,1)はA1、Cells(5,2)はB5であり、Rangeで囲むことでA1からB5までの範囲を指定できます。

セル番地を文字列で指定する際はRange("A1:B5")のように「""」ダブルクォーテーションで囲んでいましたが、Cellsで指定する場合は囲みません。

また、開始セルと終了セルの間は「,」カンマで区切ります。

この書き方を応用して、データ件数が変わっても範囲指定を自動で変更するコードが作れます。

以下は、A列の最終行を調べて、「A1~最終行のB列」を黄色に塗るマクロです。

Public Sub 範囲を自動取得して黄色に塗る()

    Dim lastRow As Long

    lastRow = Cells(Rows.Count, 1).End(xlUp).Row

    Range(Cells(1, 1), Cells(lastRow, 2)).Interior.Color = vbYellow

End Sub

マクロを実行すると次のようになります。

最終行を自動取得
最終行を自動取得

コードのポイントは以下のとおりです。

lastRow = Cells(Rows.Count, 1).End(xlUp).Row

最終行の数を調べて変数lastRowに格納しています。

Range(Cells(1, 1), Cells(lastRow, 2)).Interior.Color = vbYellow

Rangeで次の範囲を指定しています。

  • Cells(1, 1):A1
  • Cells(lastRow, 2):最終行のB列

また、.Interior.Color = vbYellowでセルの色を黄色に指定しています。

RangeCellsは単体でも使用できますが、より柔軟なマクロを作るには2つを組み合わせることが必須です。

Rangeを使ってVBAでセルのコピーと削除をしよう

エクセルVBAを使うと、セルのコピーや削除を自動で行えます。

実務では集計表にデータを転記したり、不要なデータを削除したりする作業はほぼ毎日行います。

そのため、正しい書き方と併せて「速い書き方」も知っておきましょう。

コピーと貼り付けの基本と高速コピー

コピー貼り付けの方法を3つご紹介します。

通常のコピー
Range("A1").Copy Range("B1")

セル番地「A1」をコピーし、「B1」へ貼り付けます。

Range("B1")は改行せず、半角スペースのあとに続けて書くのがポイントです。

値のみコピー
Range("A1").Copy
Range("B2").PasteSpecial xlPasteValues

セル番地「A1」をコピーし、「B2」へ値のみ貼り付けます。

書式や数式はコピーされません。

高速コピー
Range("B3").Value = Range("A1").Value

セル番地「A1」の値を取得し、「B3」へ直接代入しています。

コピー操作をしていないため、クリップボードを使わず処理が速いです。

3種類のコピーの実行結果を比較してみましょう。

A1に数式を入力
A1に数式を入力

数式を入力し、文字とセルの色を変えたA1セルについて、次のマクロでコピーしてみましょう。

Public Sub コピー結果の比較()

'通常のコピー
Range("A1").Copy Range("B1")

'値のみコピー
Range("A1").Copy
Range("B2").PasteSpecial xlPasteValues

'高速コピー
Range("B3").Value = Range("A1").Value

End Sub
通常のコピーでは数式・書式がコピーされる
通常のコピーでは数式・書式がコピーされる

通常のコピーを行った「B1」セルは数式・書式がコピーされますが、値のみコピー・高速コピーでは計算結果の値のみがコピーされます。

マクロを導入する場合、計算はVBAで行い、書式はフォーマット化されている場合がほとんどです。

そのため、高速コピーである「Value代入」を基本として覚えておくことをお勧めします。

セルをコピーするマクロを作る際、手作業でのエクセル操作を想像して次のようなコードを書いてしまいがちです。

Public Sub コピーでやりがち()

Range("A1:A5").Select
Selection.Copy
Range("B1").Select
ActiveSheet.Paste

End Sub

.Selectでセルを選択し、.Copyでコピーして.Pasteで貼り付けています。

これでも問題なくマクロは動きますが、Selectを挟むことでコードが長くなり、処理も遅いです。

手作業ではまずセルを選択してから操作を行いますが、VBAでは直接命令することができます。

Dr.オフィス

マクロに慣れてきたら「選択せずに直接操作できないか?」と考えるクセをつけてみよう!

セルの削除を使い分けよう

コピーと同様、削除にも種類があります。

値のみ削除
Range("A1").ClearContents

値のみ削除し、書式は残ります。

入力欄の初期化によく使われます。

すべて削除
Range("A2").Clear

値・書式とも削除します。

セルを完全にリセットする場合に使います。

書式のみ削除
Range("A3").ClearFormats

実務ではあまり使いませんが、色・フォント・罫線のみ削除し、値は残します。

3種類の削除の結果を比較してみましょう。

A1~A3は同じ内容
A1~A3は同じ内容

数式を入力し、文字とセルの色を変えたA1~A3セルについて、次のコードで削除してみましょう。

Public Sub 削除結果の比較()

'値のみ削除
Range("A1").ClearContents

'すべて削除
Range("A2").Clear

'書式のみ削除
Range("A3").ClearFormats

End Sub
マクロを実行した結果
マクロを実行した結果

A1の「値のみ削除」が使用頻度が最も高いので覚えておきましょう。

Dr.オフィス

コピー・削除で特に覚えておくべきなのはこの2つだよ!
Range("B1").Value = Range("A1").Value
Range("A1").ClearContents

Rangeの応用ワザを使いこなそう

ここからは実務に使えるRangeの応用テクニックをいくつかご紹介します。

どれもマクロの完成度を大きくアップさせるものですので、ぜひ、実務に取り入れてみてください。

エクセルの表全体を自動で取得するCurrentRegion

CurrentRegionは「指定したセルを含む表全体」を自動で取得します。

Public Sub 表の選択()

    Range("A1").CurrentRegion.Select

End Sub

このコードは、A1が表の中にあった場合、その表全体を選択します。

行数が確定していない表をコピーするときに便利です。

SelectCopyClearに変更すれば、表全体をコピー・削除できます。

CurrentRegionは表の途中に空白行や空白列があると、そこで分断されます。
データが連続している表向けのコードです。

途中に空白列があると分断される
途中に空白列があると分断される

UsedRangeで使用範囲を取得

UsedRangeはシート内で使われているセルの範囲を取得します。

Public Sub 使ったセルの選択()

    ActiveSheet.UsedRange.Select

End Sub

データがある最も左上のセルと最も右下のセルを範囲選択するコードです。

SelectClearContentsに変更すれば、まとめて値を削除することができます。

UsedRangeは値だけではなく、書式が設定されたセルも含まれます。
そのため、見た目は空白なのに範囲が広いことがあるので注意が必要です。

書式が残っている場合も範囲指定される
書式が残っている場合も範囲指定される

セルのアドレスを取得するAddress

Addressはセルの位置を文字として表示したいときに使います。

普通のデータ処理で使うことはあまりありません。

データ量が多いマクロの処理中に、どのセルを選択しているのかを確認したい場合などに使います。

Public Sub 今選択しているセル番地を表示()

    MsgBox ActiveCell.Address
    
End Sub

上記は、今選択しているセルの場所をメッセージボックスで表示するコードです。

メッセージボックスで表示
メッセージボックスで表示

メッセージボックスは$マークのついた絶対参照で表示されます。

.Address(False, False)と書くことで、$マークを消して相対参照にできます。

Intersectで重なり部分を取得しよう

Intersectは、2つの範囲の重なっている部分を取得します。

Public Sub 重なっているセルを選択()

    Intersect(Range("A1:D8"), Range("C5:F11")).Select
    
End Sub

このコードを実行すると、2つの範囲が重なる「C5~D8」が選択されます。

重なった部分が選択された
重なった部分が選択された

実務では、入力チェックに使われることが多いです。

例えば以下の表でセル「C2~C10」に数字のみ入力して欲しい場合に、シートモジュールに入力チェックのコードを設定してみましょう。

エラーチェックに活用する
エラーチェックに活用する
STEP
シートモジュールを開く
入力チェックしたいシートをダブルクリック
入力チェックしたいシートをダブルクリック

プロジェクトエクスプローラーから、入力チェックをしたいシート名をダブルクリックします。

STEP
入力チェックのコードを貼る
シートモジュールに貼る
シートモジュールに貼る

シートに割り当てられたモジュールに、以下のコードを貼ります。

Private Sub Worksheet_Change(ByVal Target As Range) '①

    If Not Intersect(Target, Range("C2:C10")) Is Nothing Then '②
        
        If Not IsNumeric(Target.Value) Then '③
            MsgBox "数字を入力してください" '④
            Target.ClearContents '④
        End If
        
    End If

End Sub

コードの詳細の解説は省きますが、次のようなことが行われます。

  1. セルの内容が変更されるたびに自動でマクロが実行される
  2. 変更されたセルが「C2~C10」の中かどうかIntersectでチェックする
    範囲が重なっていなければ何もしない
  3. 入力された値が数字かどうか調べる
  4. 数字ではなかったらメッセージボックスを表示したのちに値を削除する
STEP
結果を確認
結果を確認する
結果を確認する

エクセルに戻り、マクロが正しく動くかどうか確認してみましょう。

セルの選択範囲を拡張するResize

Resizeは基準となるセルから選択範囲を拡張して取得します。

Public Sub セルのサイズを変更して選択()

    Range("A1").Resize(5, 2).Select
    
End Sub

このコードは、A1を始点に5行×2列の範囲を選択します。

A1~B5が選択される
A1~B5が選択される

実務で使う場合は、例えば以下のコードを実行すると、A1から最終行までの3列分を選択します。

Public Sub A1から最終行までの3列分を選択()

    Range("A1").Resize(Cells(Rows.Count, 1).End(xlUp).Row, 3).Select
    
End Sub
A列~C列を選択
A列~C列を選択

Resizeのカッコ内が少し複雑に見えますが、やっていることは難しくはありません。

Cells(Rows.Count, 1).End(xlUp).RowでA列の最後にデータが入っている行番号を取得しています。

3は列番号で、A1を基準にしているためC列が該当します。

まとめて値を削除したい場合は、SelectClearContentsに変更しましょう。

エクセルVBAのRangeに関するQ&A

VBAでCellsRangeの使い分けはどうすればいいですか?

あらかじめ範囲が決まっている場合はRange、繰り返し処理の場合はCellsを使います。

VBAでRangeのセルに値を入れる方法は?

以下のようにValueで代入しましょう。

Range("A1").Value = "サンプル"

文字列の場合は「"”」ダブルクォーテーションで囲みます。

CellsRangeの使い分けにもう迷わない!

この記事では、エクセルVBAでセルを操作するときに必ず登場するRangeCellsの違いについて解説しました。

大切なのは、どんな場面で使うのかを理解することです。

固定された範囲を扱うのか、それとも行や列が変わる可変処理なのかを基準に判断しましょう。

それではポイントのおさらいです。

おさらい
  1. 固定範囲はRangeを使う
  2. 繰り返し処理はCellsを使う
  3. RangeCellsの組み合わせで柔軟なコードが書ける

この基礎が理解できれば、VBAのセル操作はもう迷いません。

実際にコードを書いて、結果を確認しながら慣れていきましょう!

今回の記事以外にも、知っておきたいマクロの基本を以下にまとめましたので、ぜひご活用ください。

エクセルマクロの基礎をゼロから学ぶ!有効化やボタン設置!

よかったらシェアしてね!
  • URLをコピーしました!
目次