【入門編】 初心者向け EXCEL VBA (3/10) – EXCEL VBAのFor Nextループをマスターする

この記事は約25分で読めます。
スポンサーリンク

現在のところ、以下の7つのEXCEL VBA講座がある。

第一回目 【入門編】 初心者向け EXCEL VBA (1/10) – 今年こそ使えるようになりたい人
第二回目 【入門編】 初心者向け EXCEL VBA (2/10) –実際にVBAを開発する手順はこれだ
第三回目  【入門編】 初心者向け EXCEL VBA (3/10) – EXCEL VBAのFor Nextループをマスターする
第四回目 【入門編】 初心者向け EXCEL VBA (4/10) – EXCEL VBAのFor Nextループで文字列を置換する
第五回目 【入門編】 初心者向け EXCEL VBA (5/10) – VBAユーザーフォームは男のロマン【これで完璧】
第六回目 【入門編】 初心者向け EXCEL VBA (6/10) – 現在のシートを加工して新シートを作成する【前半】
第七回目 【入門編】 初心者向け EXCEL VBA (7/10) – 現在のシートを加工して新シートを作成する【後半】

 

それと、読者の皆さんの疑問に答えるシリーズも開始した。

  タイトル

質問者さん(敬称略)

第一回目 【ワレコEXCEL講座】エクセルファイル①をエクセルファイル②に読み込む しがない事務員

当記事はそのEXCEL VBA講座の第三回目(2017/5/11 大幅改訂した)。

 

2018年12月22日追記

読者の方から当記事の最初に登場するVBAコードを実行するとエラーが出ると言う報告があったので、詳細な解説記事を書いた。

「初心者向け EXCEL VBA (3/10) – EXCEL VBAのFor Nextループをマスターする」の解説
さて、このところ更新を怠っていたワレコのサイトであるが、熱烈な読者の方からEXCEL VBAプログラミング記事に関して質問を頂いた。 この記事だ。 その質問内容は以下の通り。 康村 より: 2018年12月22日 11:...

もし下のコードでエラーが出る場合にはこの解説記事も参考にして下さい。

サンプルVBAダウンロード

本ページで使用したEXCELファイルをダウンロードしたい人はここからどうぞ。

EXCEL VBAのFor Nextループをマスターする用のVBAサンプルプログラム

 

スポンサーリンク
ワテ推薦のプログラミングスクールで学ぶ
スポンサーリンク
スポンサーリンク

ループ処理を覚える

どんなプログラミング言語でも、プログラミングの基本は二つだけだ。

つまり、

  • For Nextによるループ処理
  • IF文による条件分岐

の二つ。

要するに大量のデータをループ処理で順番に加工して目的のデータを得る。

その過程で、何らかの条件判断を入れたい場合にはIF文による条件分岐を使い、特定の条件を満たすデータのみ加工するなどが可能だ。

EXCEL VBAでは行と列の二次元のループ処理が基本

EXCEL VBAでプログラミングをする場合には、EXCELシート自身が2次元のデータ領域を持つので、その中にあるデータも必然的に2次元(あるいは1次元)となる。

それ故に、ループ処理でEXCELのデータを処理する場合には、以下のVBAプログラムに示すようにFor Nextが行(row)と列(column)の二重になる形式のループ処理が至る所に登場する。

Sub test1_二次元領域をループする()
 Dim r As Long           ' 行(row)ループカウンター
 Dim c As Long           ' 列(col)ループカウンター
 Const rsta As Long = 5  ' 行(row)開始番号
 Const csta As Long = 5  ' 列(col)開始番号
 Const rend As Long = 25 ' 行(row)終了番号
 Const cend As Long = 15 ' 列(col)終了番号

 For r = rsta To rend
 For c = csta To cend
  ActiveSheet.Cells(r, c) = "R" + CStr(r) + ":C" + CStr(c) ' 文字列連結は + か &
 'ActiveSheet.Cells(r, c) = "R" & CStr(r) & ":C" & CStr(c) ' なのでこれでも良い
 'ActiveSheet.Cells(r, c).FormulaR1C1 = "=RC[-2]+RC[-1]" '計算式も入れられる
 Next c
 Next r
End Sub

まあ、この関数を実行してもセルに文字を書くだけであるが、EXCEL VBAの基本形なので覚えておくと良いだろう。

なお、変数のネーミング方法は好き好きなので、ご自身で改良を加えて下さい。

ワテの場合、その時の気分でヘンテコな変数名を付けると言う悪癖が身に付いているので、皆さんにはお勧めしない。

Sub test1_二次元領域をループする() の実行結果

上の関数を実際に実行すると以下のようになる。

まあ、指定した長方形領域に文字列を書くだけの単純な処理だ。

なお、セルに値を代入する方式は以下のように各種ある。

' 値を入れる場合
ActiveSheet.Cells(r, c) = 777 
ActiveSheet.Cells(r, c).Value = 777
' 計算式を入れる場合
ActiveSheet.Cells(r, c).Formula = "=SUM(A1:A10)"
ActiveSheet.Cells(r, c).FormulaR1C1 = "=RC[-2]+RC[-1]"

最初の例のように .Valueを省略するとデフォルトのプロパティである .Value が仮定されてそこに値が入る。

計算式の場合には、最後の例のように .FormulaR1C1プロパティを使うと R1C1形式で扱えるので行と列を r や c と言う整数で扱う場合にはやり易い。

なお、どの代入文を使うべきなのかは、右辺に何が来るかに依存するので必要に応じて使い分けると良い。具体的には数値、文字列、計算式、その他(何があるかな?)

でも、どれを選んだら良いのか分からない場合には、第二回目の講習で習得したマクロの記録を実行してみると良い。

数値を足し算したい場合なら、その数式を入力する作業をマクロの記録してみる。

同じく、文字列の処理ならその計算式をマクロの記録する。

書式設定なども一緒にやりたい場合にも、マクロの記録をする。

それで得られたマクロから必要な部分を取り出して、上記の代入文の辺りを改造すれば良いのだ。

EXCELで扱える最大範囲は?

EXCEL 2007以上では、扱える範囲は以下の通り。

1,048,576 行 x 16,384 列

EXCEL 2003や、それ以前は

65,536 行 x 256 列

だった。

現在では、EXCEL2013やEXCEL2016を使っている人が多いので、約100万行x1万6千列もの広大な領域を扱う事が可能だ。

ちなみに、1,048,576 こんな数字は覚えられないと言う人も多いだろう。ワテもそうだ。

そう言う場合には、

Sub test2_EXCELで扱える最大の行数と列数を表示する()
 Dim rowMax As Long
 Dim colMax As Long
 rowMax = ActiveSheet.Rows.Count
 colMax = ActiveSheet.Columns.Count

 Debug.Print "rowMax=", rowMax
 Debug.Print "colMax=", colMax
 ActiveSheet.Cells(1, 1) = rowMax
 ActiveSheet.Cells(2, 1) = colMax
End Sub

を実行すると、イミディエイトウィンドウに今使っているエクセルで扱える最大の行数と列数が表示出来る。

実行結果

 rMax= 1048576 
 cMax= 16384 

処理対象の領域を決める

さて、実際にエクセルVBAを使って何らかのデータ処理をする場合に、先ず必要になるのが処理対象のデータが入っている領域を取得する処理だ。

その場合には、いろんな状況が考えられる。

  • 特定の領域のデータを処理する 例 ”A3:E20″ のように定数で指定
  • アクティブシート上のデータが入っている領域を自動取得する
  • ユーザーがマウスで選択した領域を取得する(複数領域の場合も有り)

一番目のように、処理対象の領域が ”A3:E20″ のように決まっているなら、その領域をVBAの定数で指定してやれば良い。

以下では、二番目と三番目の手法を説明したい。

アクティブシート上のデータが入っている領域を自動取得

例えば、先ほど上でtest1_二次元領域をループする()を実行したら、長方形領域にデータが書き込まれた。

その領域をプログラム的に取得するには、以下のVBAを実行すれば良い。

Sub test3_UsedRangeを取得し単一領域として選択する()
 Dim objUsedRng As Object 'オブジェクト型の変数と言うのを使うのでここで宣言
 Set objUsedRng = ActiveSheet.UsedRange 'オブジェクトを代入する場合はSetが必要

 Dim rowSta As Long ' (rowSta, colSta)┏━━━━━┓
 Dim rowEnd As Long '             ┃データ域 ┃
 Dim colSta As Long '              ┃     ┃
 Dim colEnd As Long '             ┗━━━━━┛(rowEnd, colEnd)

 rowSta = objUsedRng.Rows.Row
 rowEnd = rowSta + objUsedRng.Rows.Count - 1
 colSta = objUsedRng.Columns.Column
 colEnd = colSta + objUsedRng.Columns.Count - 1

 Debug.Print "rowSta=", rowSta
 Debug.Print "rowEnd=", rowEnd
 Debug.Print "colSta=", colSta
 Debug.Print "colEnd=", colEnd

 ActiveSheet.Range(Cells(rowSta, colSta), Cells(rowEnd, colEnd)).Select
End Sub

ここでは、

ActiveSheet.UsedRange

と言うオブジェクトを利用している。

文字通り、使用されている領域と言う感じのニュアンスだ。

その実行結果

イミディエイトウィンドウに以下のように出力される。

rowSta= 5 
rowEnd= 25 
colSta= 5 
colEnd= 15 

かつ、下図に示すように、データが入っている領域を自動で選択する事が出来た。

ちなみに、データが長方形領域ではなくて、適当に削除していびつな形状の場合に実行すると以下のようになる。

この場合には、データ領域をピッタリと囲む領域が自動で得られる。

ただし、図で分るように空白域も含んでいる。

 

注意事項

全くデータの無いシートに対してこの関数Sub test3_UsedRangeを取得し単一領域として選択する()を実行すると、左上隅 (1, 1) のセルが選択されてしまう問題がある。

本来はデータが入っているセルを選択するのが目的なので、この動作正しくない。

従って、この関数の末尾に以下のようなコードを追加して、UsedRangeの判定結果が (1, 1) セルになった場合にのみ、さらにそこにデータが有るのか無いのか判定すると良いかも。

Dim val As Variant
If rowSta = 1 And rowEnd = 1 And colSta = 1 And colEnd = 1 Then
 val = Cells(1, 1).Value
 If IsEmpty(val) Then
  MsgBox "このシートにはデータは無い"
 End If
End If

こんなヘンテコな小細工的手法よりもスマートな方法が有りましたらお教えください。

 

 

UsedRangeオブジェクトの詳細な情報を調べる

さて、EXCEL VBAでプログラミングをしていると、

  • ActiveSheet
  • ActiveWorkbook
  • ThisWorkbook
  • UsedRange
  • ActiveCell
  • ActiveWindow
  • その他多数

こんなのが沢山出て来る。

それらは全てオブジェクトと言う奴だが、例えば今回利用した UsedRange と言うのはどんな奴なのか調べたい場合は、ネットを検索しても良いがEXCELを使ってその情報を知る事が可能だ。

関数 sub test3_UsedRangeを取得し単一領域として選択する() の中にブレークポイントを置いて実行する。ブレークポイントの使い方などは第一回目の記事で詳しく説明しているので参考にして頂きたい。

そうして、下図のように、

Set objUsedRng = ActiveSheet.UsedRange 

を実行した直後でブレーク(停止)させると良い。

その状態で、[ローカルウインドウ]を見る。もしそのウインドウが出ていない場合には、

[上部メニュー]

  [表示]

    [ローカルウインドウ]

で開ける。

[ローカルウインドウ]の中の objUsedRng を見ると確かに右端に

 objUsedRng   型 Object/Range

と書いてあるので、このobjUsedRngはRange型の Objectである事が分る。

その中味は沢山のプロパティが入っているが、例えば上図に示すように、

 Column     5     Long

は、上図で選択した領域の開始カラムが5列目つまりE列である事を示している。

こんな風にデバッガーを使って、興味あるオブジェクトのプロパティを確認すれば、どう言うプロパティが利用出来るのかが分る。

さて、殆どの場合はこのUsedRangeを使えば良いと思うが、もう少し便利な選択手法も覚えておくと何かの役に立つかも知れない。

それを次の章で説明してみた。

空白域は除外し実際にデータが入っている領域のみを選択

一般にVBAで選択域のデータを取得して処理する場合には、For Next文が行と列の2重のループ処理になる事は冒頭で述べた。

その領域の面積が小さい場合には問題は無いが、例えば 数万行x数千列 のような広大な領域をFor Nextの2重ループ処理すると何十秒も掛る場合がある。

なので、場合によっては空白域を除外して、実際にデータが入っている領域のみを取り出して、それらの領域を順番に処理するほうが速い場合もある。

EXCELではそう言う選択も可能だ。

そのVBAコードを書いてみた。

Sub test4_データが入っている領域のみを選択する()
On Error GoTo LABEL_Error

 Selection.SpecialCells(xlCellTypeConstants, 23).Select 'この部分はマクロの記録で生成した
 Exit Sub

LABEL_Error:
 Beep
 Debug.Print "データが無いので選択出来なかった。"
End Sub

この関数を作成する時には、実は、マクロの記録を利用したのだが、後で説明する。

その実行結果

八個の長方形領域に自動で分割されて、全部のデータが選択出来ている。

色付きの枠線は、分かり易くする為にワテが塗ったので、実際には出ない。

ちなみに、この関数Sub test4_データが入っている領域のみを選択する()はマクロの記録で作成した。

その手順を紹介しょう。

マクロの記録を使う

データを選択したいシートを表示する。

[開発タブ]を開いて[マクロの記録]を実行する。

[ホーム]

  [検索と置換]

    [条件を選択してジャンプ]

を開く。

下図の[選択オプション]ウインドウが出るので、定数を選択して[OK]をクリックする。

そうすると、下図のように、全ての飛び地を選択する事が出来た。

実行する場合は、単一のセルを選んでおく事

重要な注意事項としては、この関数

Sub test4_データが入っている領域のみを選択する()

あるいは、

 [条件を選択してジャンプ]

を実行する場合には、シート上のどこでも良いので単一のセルを選んでおく必要がある。

もし “A1:F10” のような長方形領域が選択されていると、その選択した領域の中で実質のデータ域を選択する動作となる。

興味ある人は試してみると良いだろう。

23の意味

ここで、23の意味が気になる。

Selection.SpecialCells(xlCellTypeConstants, 23).Select

こんなふうに数字が割り当てられている。

数値 1
文字 2
論理値 4
エラー値 16

23 = 1 + 2 + 4 + 16

なので、四つのデータを全て選択すると言う意味になる。

と言う事で、広大な領域の中から、実際にデータが入っている領域のみを選択する事が出来た。

ユーザーが選択した領域を取得する

EXCELでマウスを使って長方形領域を選択する場合に、CTRLキーを押した状態で選択すると、複数の領域を選択する事が可能になる。

例えば、三つの長方形領域を選択してみた。

手順としては、最初の選択ではCTRLは押さずに、通常通りマウスドラッグだけで選択する。

二番目の領域以降は、CTRLキーを押した状態でマウスドラッグをすると良い。

この操作方法を使うと、一つ前の章で説明した

[条件を選択してジャンプ]

で八個の飛び地を自動選択したのと同じ状態を手作業で選択する事も可能だ。

ここまでの説明で、領域の選択方法の説明は終わり。

ここからは、その選択域のデータを取り出す処理をしてみよう。

選択している領域を順番にループ処理する

まずは、選択されている領域の範囲を順番にイミディエイトウィンドウに表示するだけの簡単なプログラム。

Sub test5_全ての選択域を順番にループしてその範囲を表示する()
 Dim objSelectedAreas As Object 'オブジェクト型の変数と言うのを使うのでここで宣言
 Set objSelectedAreas = Selection 'オブジェクトを代入する場合はSetが必要

 Dim i As Long '選択域Areaを順番にループする変数
 Dim iEndArea As Long 'そのAreaの数
 iEndArea = objSelectedAreas.Areas.Count

 Dim objAreasItem_i As Object
 Dim rowSta_i As Long ' (rowSta_i, colSta_i)┏━━━━━┓
 Dim rowEnd_i As Long '                 ┃データ域 ┃
 Dim colSta_i As Long '                  ┃     ┃
 Dim colEnd_i As Long '                 ┗━━━━━┛(rowEnd_i, colEnd_i)

 For i = 1 To iEndArea
  Set objAreasItem_i = objSelectedAreas.Areas.Item(i)
  rowSta_i = objAreasItem_i.Rows.Row
  rowEnd_i = rowSta_i + objAreasItem_i.Rows.Count - 1
  colSta_i = objAreasItem_i.Columns.Column
  colEnd_i = colSta_i + objAreasItem_i.Columns.Count - 1

  Debug.Print "i="; i, "rowSta_i="; rowSta_i
  Debug.Print "i="; i, "rowEnd_i="; rowEnd_i
  Debug.Print "i="; i, "colSta_i="; colSta_i
  Debug.Print "i="; i, "colEnd_i="; colEnd_i
 Next i
End Sub

ここで使ったオブジェクトは、

Set objSelectedAreas = Selection

の中の、

Set objAreasItem_i = objSelectedAreas.Areas.Item(i)

である。

Selectionの中には今選択されている領域の全情報が入っていて、個々の選択域がItem(i) の中に入ってる。それらを順番にループ処理で取り出している。

Selectionの中にどんなプロパティが有るのかを知りたい人は、デバッガーでブレークして変数objSelectedAreas の中身を見てみると良いだろう。

この関数を実行すると、以下のようになった。

i= 1 rowSta_i= 1 
i= 1 rowEnd_i= 2 
i= 1 colSta_i= 1 
i= 1 colEnd_i= 1 
i= 2 rowSta_i= 5 
i= 2 rowEnd_i= 25 
i= 2 colSta_i= 5 
i= 2 colEnd_i= 15 

この例では選択域が二個あり、それぞれの領域の

左上セル (rowSta, colSta)

右下セル (rowEnd, colEnd)

が表示されている。

実行結果は、現在のシート上でどの領域が選択されているかによって異なるので、各自、適当に領域を選択して実行してみると良い。必要ならCTRLキーを使って複数領域を選択すると良い。

全ての選択域を順番にループしてセルの値を出力する

上の例では領域の範囲を単純に表示するだけであったが、それだけだと詰まらないので、セルのデータを順番に取り出してみよう。

プログラムの前半部分は先ほどプログラムと全く同じ。

後半部分では、各選択域の

左上セル (rowSta, colSta)

右下セル (rowEnd, colEnd)

の値を利用して、その範囲のデータを各セルから取り出してイミディエイトウィンドウに出力している。

Sub test6_全ての選択域を順番にループしてセルの値を出力する()
 Dim objSelectedAreas As Object 'オブジェクト型の変数と言うのを使うのでここで宣言
 Set objSelectedAreas = Selection 'オブジェクトを代入する場合はSetが必要

 Dim i As Long '選択域Areaを順番にループする変数
 Dim iEndArea As Long 'そのAreaの数
 iEndArea = objSelectedAreas.Areas.Count

 Dim objAreasItem_i As Object
 Dim rowSta_i As Long ' (rowSta_i, colSta_i)┏━━━━━┓
 Dim rowEnd_i As Long '                 ┃データ域 ┃
 Dim colSta_i As Long '                  ┃     ┃
 Dim colEnd_i As Long '                 ┗━━━━━┛(rowEnd_i, colEnd_i)

 For i = 1 To iEndArea
  Set objAreasItem_i = objSelectedAreas.Areas.Item(i) 'i番目のAreaオグジェクトを取り出す

  rowSta_i = objAreasItem_i.Rows.Row
  rowEnd_i = rowSta_i + objAreasItem_i.Rows.Count - 1
  colSta_i = objAreasItem_i.Columns.Column
  colEnd_i = colSta_i + objAreasItem_i.Columns.Count - 1

  Dim r As Long ' row(行)をループする変数
  Dim c As Long ' col(列)をループする変数
  Dim val As Variant ' セルの値を入れるので何でも入れられるバリアント型にしておく
 
  For r = rowSta_i To rowEnd_i
   For c = colSta_i To colEnd_i
    val = Cells(r, c).Value ' r行c列のセルの値を取り出す
    Debug.Print "i="; i, "r="; r, "c="; c, "Value= ->"; val; "<-"
   Next c
  Next r

 Next i
End Sub 

まあ、For Nextのループが i, r, c の三重になっているが、難しい所は無いと思う。

実行結果(沢山表示されるので一部のみ)

i= 2 r= 24 c= 15 Value= ->R24:C15<-
i= 2 r= 25 c= 5 Value= ->R25:C5<-
i= 2 r= 25 c= 6 Value= ->R25:C6<-
i= 2 r= 25 c= 7 Value= ->R25:C7<-
i= 2 r= 25 c= 8 Value= ->R25:C8<-
i= 2 r= 25 c= 9 Value= ->R25:C9<-
i= 2 r= 25 c= 10 Value= ->R25:C10<-
i= 2 r= 25 c= 11 Value= ->R25:C11<-
i= 2 r= 25 c= 12 Value= ->R25:C12<-
i= 2 r= 25 c= 13 Value= ->R25:C13<-
i= 2 r= 25 c= 14 Value= ->R25:C14<-
i= 2 r= 25 c= 15 Value= ->R25:C15<-

この例では、

val = Cells(r, c).Value ' r行c列のセルの値を取り出す

のように、セルの値を取り出しているだけであるが、

Cells(r, c).Value = "好きな値を代入しても良い"

のようにすれば、そのセルに何らかの値をセットする事も出来る。

 

ここまでの手順を使うと、シート上のデータを加工するループ処理の基本をマスターする事が出来たと思います。

大変長い説明が続きましたが、ここまでお付き合い頂きましてありがとうございました。

さて、最後にもう一つだけ説明して、EXCEL VBAループ処理の説明は終わりたい。

Cellを行・列の数字ではなくて英数字 “A1:F5” の形式で指定したい

今までの説明では、行と列のループ処理で Long型の r, c の二つの変数を使って、

val = Cells(r, c).Value ' r行c列のセルの値を取り出す

こう言う形式で値を取り出した。あるいは代入しても良い。

でも、場合によっては、英数字文字列 “A1:F5” の形式で処理したい場合もある。

その為には、二つの数字 r, c から 英数字文字列への相互変換が必要になる。

そのテクニックを覚えておくと何かと役に立つ。

ちなみに、EXCELでは

 Cells(10, 5) = "単一セル"
 Range(Cells(10, 20), Cells(20, 30)).Value = "長方形領域"

のように行と列を数字で表現する形式をR1C1形式と言い、

 Range("A1").Value = "単一セル"
 Range("a1:f5").Value = "長方形領域"
 Cells("a2").Value = "単一セル"   ' これは出来ない。

のように “A1″、あるいは “A1:F5” のような形式をA1形式と言う。

R1C1形式をA1形式に変換

この手の変換の方式は沢山あるが、例えばこう言う手法で変換可能だ。

Sub test8_アドレス形式_R1C1_to_A1()
 Dim A1 As String
 A1 = Range(Cells(1, 2), Cells(1, 2)).Address(RowAbsolute:=False, ColumnAbsolute:=False)
 Debug.Print A1
 
 A1 = Range(Cells(1, 2), Cells(10, 6)).Address(RowAbsolute:=False, ColumnAbsolute:=False)
 Debug.Print A1
End Sub

実行すると

B1
B1:F10

のように列位置がアルファベットの形式で表示される。

ちなみに、RowAbsolute:=True で実行すると $ が入る絶対アドレスの形式になるので、必要に応じて使い分けると良い。

また、単一セルの場合には、

A1 = Cells(1, 2).Address(RowAbsolute:=False, ColumnAbsolute:=False)

こんな風に単純化しても良い。

A1形式をR1C1形式に変換

先ほどとは逆の変換になる。

この場合も各種の方法があるが、Application.ConvertFormula() と言う関数を使うと変換出来る。

Sub test9_アドレス形式_A1_to_R1C1()
 Dim inputFormulaA1 As String
 Dim r1c1 As String
 
 inputFormulaA1 = "B1"
 r1c1 = Application.ConvertFormula( _
           Formula:=inputFormulaA1, _
           fromReferenceStyle:=xlA1, _
           toReferenceStyle:=xlR1C1, _
           ToAbsolute:=xlAbsolute _
         )
 Debug.Print r1c1
 
 inputFormulaA1 = "B1:F10"
 r1c1 = Application.ConvertFormula( _
           Formula:=inputFormulaA1, _
           fromReferenceStyle:=xlA1, _
           toReferenceStyle:=xlR1C1, _
           ToAbsolute:=xlAbsolute _
         )
 Debug.Print r1c1

End Sub

その実行結果

R1C2
R1C2:R10C6

のようにR1C1形式が得られた。

必要ならこの中からrowやcolumnの数字を取り出して使えば良いだろう。

なお、この Application.ConvertFormula() の手法を使えば、R1C1からA1への変換も出来るので、興味ある人は試してみると良いだろう。from と to の部分を入れ替えれば良い。

これらの手法以外にも、R1C1とA1の間の相互変換のやり方に関してはネット上に多数の手法があるので、検索してみると良いかも。

 

なお、列番号と列アルファベットの間で相互に変換する専用関数の記事を書いてみたので参考にして下さい。

【ワレコのVBA】列番号と列アルファベット文字列の相互変換 – 高速版

 

まとめ

当記事では、EXCELシート上にあるデータをVBAのFor Nextのループ処理で順番に取り出す手法を紹介した。

UsedRangeを使い、データ領域を囲む長方形領域を自動で選択する手法を覚えた。

[条件を選択してジャンプ]の方式で、データが入っているセルのみを選択する手法を紹介した。

それらの選択域に対して、ループで順番にセルのデータを取り出す手法を覚えた。

R1C1形式のアドレスをA1文字列の形式に変換する手法を紹介した。

逆に、A1文字列をR1C1形式のアドレスに変換する手法を紹介した。

なお、今回紹介した手法は、あくまでワテ流の手法ですので、ネット上にはより良いサンプルもあります。

色んなサンプルプログラムを見て、自分流のプログラミングスタイルを身に付けるのが良いでしょう。

EXCEL関連の本を読む

最強と言う事だ。気になったのでアマゾンで中身を少し読む事が出来るので早速見てみた。

ワテの第一印象は、目次がとっても見易い。目次には、この本を使って習得する項目が細かく書かれているが、それを順番にマスターして行けば、かなり上級者のレベルになれる感じ。。

ただし、この本はVBAの解説と言うよりはEXCEL本体の使い方の説明のようだ(ワテの推測)。

 

こちらの本もアマゾンランキングは高い。

VBAの解説本なので、これからVBAを学ぶ予定の人にはお勧めかも。

こちらの本もアマゾンで目次を見る事が出来る。

小型の本なので通勤電車で読むと良いだろう。

次の講座

【入門編】 初心者向け EXCEL VBA (4/10) – EXCEL VBAのFor Nextループで文字列を置換する

スポンサーリンク
ワテ推薦のプログラミングスクールで学ぶ
コメントを読む

この記事には読者の方からコメントが 4件あります。
興味ある人はこのページ下部にあるコメントを参照下さい。

ExcelVBA
スポンサーリンク
warekoをフォローする
スポンサーリンク
われこ われこ

コメント

  1. 康村 より:

    こんにちは。今会社内でPC言語に強くならないといけなくなった一社員です。

    色々見てるうちにこちらのサイトにたどり着き、内容を見ながら自分でもやってみていたのですが躓いておりますのでご教示いただければ大変うれしゅうございます。

    1.1のところで全く式は同じだと思うのですが、マクロを実行すると「オブジェクトはこのプロパティまたはメソッドをサポートしていません。」と出ます。

    解決策はお分かりになりますでしょうか。
    ちなみにPCは今月購入したばかりのWin10の64bit、H&B2016です。
    関係ないかもしれませんが念のためお知らせしておきます。

  2. wareko より:

    康村様

    この度は小生のVBA解説記事に興味を持って頂きましてありがとうございます。
    さて

    マクロを実行すると「オブジェクトはこのプロパティまたはメソッドをサポートしていません。」と出ます。

    との事ですが、私の環境ではそのようなエラーは出ませんでした。
    マクロを実行する手順の詳細な解説記事を作成してみましたので、この記事の手順に従ってもう一度試して頂けないでしょうか?

    https://www.wareko.jp/blog/an-article-on-excel-vba-3-of-10-mastering-a-for-next-loop

    それで、もし同じエラーが出た場合には、そのエラーメッセージがどの部分に出たのかなど、参考となる情報を教えて頂きましたら、調査してみます。

  3. 康村 より:

    出来ました!なぜでしょう!

    前にエラーが出たときはSheet2で行っていたのですが
    これは関係あるのでしょうか?

    と思って新規シートでやってみたところできたのです。

    sheet2で行う場合、VBA画面のsheet2のところから
    挿入
    標準モジュール
    で作成してはダメなのでしょうか。

    また別の式になりますか??

    いずれにせよ、早速のご返信とページの追加、大変ありがたく存じます。

    このページはとりあえずクリアできましたので
    次のぺージに進ませていただきます。

    ありがとうございました。

  4. wareko より:

    康村様

    >前にエラーが出たときはSheet2で行っていたのですが
    >これは関係あるのでしょうか?

    計算式は、
    ActiveSheet.Cells(r, c) = “R” + CStr(r) + “:C” + CStr(c)
    のように現在アクティブ(Active)なシートに対して実行していますので、Sheet1やSheet2があっても、現在アクティブなシートつまり、現在選択されているシートに対して書き込まれます。
    ですので、Sheet2でやっても正常に出来るはずです。

    もしSheet1とSheet2がある場合に、Sheet1がアクティブだとしても、
    Sheet2.Cells(r, c) = “R” + CStr(r) + “:C” + CStr(c)
    のようにSheet2を明示的に指定してすれば、Sheet1の裏にSheet2が隠れていてもSheet2に書き込まれます。

    もしSheet2を削除してSheet1しか無い状態で、
    Sheet2.Cells(r, c) = “R” + CStr(r) + “:C” + CStr(c)
    を実行すると、
    「実行時エラー ’424′:オブジェクトが必要です。」
    と言うエラーが出ました。
    でも、康村さんご報告のエラー
    「オブジェクトはこのプロパティまたはメソッドをサポートしていません。」
    とはちょっと違いますね。
    康村さんのエラーメッセージがどのような操作で出たのか少し調べてみたのですが、こちらでは再現させることが出来ませんでした。

    >sheet2で行う場合、VBA画面のsheet2のところから
    >挿入
    標準モジュール
    >で作成してはダメなのでしょうか。

    それも問題ありません。
    標準モジュールは、どのシートで挿入しても同じです。
    標準モジュールに書き込んだSub関数はどのシートからでも呼び出せます。
    Sheet2で挿入しても、Sheet1で挿入しても、現在Sheet1がアクティブなら関数の実行結果はSheet1に反映されます。
    つまり標準モジュールの挿入はSheetに対して行うと言うよりは、今開いているExcelのブックに対して挿入すると言う意味です。

    >このページはとりあえずクリアできましたので
    >次のぺージに進ませていただきます。
    無事に実行出来たとの事で、安心しました。