DTPのためのExcel VBA基礎 (2) For文
VBAのFor文の使い方です.
構文
For文は処理を反復するのに用いられます.
A列の1行目〜10行目に入力する例は次の通りです.
Sub For文の一例 |
i
はカウンタで,いま何回目の処理を行っているかを数えています.
この増えていく数字を利用して,処理したいセルの位置を自動的にずらしていくというのが最も多い使われ方です.
この例では初期値の1に始まり,10までカウンタが1ずつ増加していきます.
- 1回目の処理なら,
Cells(i, 1)
はCells(1, 1)
のセルを表します. - 2回目の処理なら,
Cells(i, 1)
はCells(2, 1)
のセルを表します. - 10回目の処理なら,
Cells(i, 1)
はCells(10, 1)
のセルを表します.
問題
- 1行目〜50行目を処理したいとき,どのように書けばよいでしょうか?
- 2行目〜10行目を処理したいとき,どのように書けばよいでしょうか?
- 1列目〜10列目を処理したいとき,どのように書けばよいでしょうか?
応用(一定範囲のレコードの処理)
作業集約時にある作業者のレコードを201行目〜250行目に差し込みましたが,C列の数値(金額)が千円単位であるのを忘れて1円単位で入力してしまったと報告を受けました.
For文を使って修正するには,どのように記述すればよいですか?
切り上げ・切り捨ては無視して構いません.
応用(リスト項目)
A2セルからA10セルに入力されている文言を<li>
と</li>
で囲んでください.(HTMLで箇条書き等のリスト項目を意味します.リスト項目群をさらに<ol>
と</ol>
で囲めば連番のついた箇条書き—オーダード・リスト—になり,<ul>
と</ul>
で囲めば連番のない箇条書き—アンオーダード・リスト—になります.)
ステップ
上述の例ではStep
が省略されています.
本来は
Sub For文の一例 |
という形です.
Step 1
はカウンタを1つ刻みで増加させることを意味しています.
しかしながら,多くのVBAマクロは1行ずつ何かを処理するので1
がデフォルトの値として設定されており,Step 1
であれば省略しても構いません.
問題
1行飛ばしで処理したい場合,どこを変えればよさそうでしょうか?
応用(2行ペアのスプレッドシート)
1, 2行目,3, 4行目…というように2行ごとでペアになった,100行のスプレッドシートがあります.
全データがA列のみに入っているのですが,偶数行目のデータを奇数行目のB列にコピーできますか?
(こうした後で偶数行目を削除すれば,1行1レコードへときれいに纏められます.)
置換
置換にはReplace
関数を用います.
Excelで行う置換をVBAで書くと,次のようになります.
入力セル = Replace(加工する文章, "置換前文言", "置換後文言") |
例えば,A1セルにフットサル
と入力されているなら,
Sub 置換の例() |
とすることでA2セルに置換後のおサル
という文言を入力します.
問題
A1セルのフットサル
を直接A1セルでおサル
へと置き換えるには,どのようにしたらよいでしょうか?
応用(範囲置換)
A列1〜100行目に「QRコード」と入っている場合,商標に抵触する可能性があるので全て「二次元コード」にするようにとの指示が出ました.
処理できますか?
応用(相対パス)
相対パス(./xxx.html
等)で記述されたWebサイトのファイル群が,あるxlsxファイルのA列に整理されています.
これまでカレントディレクトリ直下に置かれていた画像のファイル群(120行目〜200行目)は数が多かったため,カレントディレクトリと同じ階層にimgという名前でディレクトリを作ってまとめました.
xlsxファイル中に記載された相対パスも書き換えたいと思いますが,どのように処理すればよいですか?
不要文言の除去
ある文言を空白に置換することで,不要な文言を除去することができます.
例えば,
Sub 置換を利用した不要文言の除去 |
とすると,A1セルから「トル」という文言を消し去ったテキストをA2セルに入力することができます.
問題
たぬき&こけし&くない&おとり暗号があるので,置換してください.
たたこおそおおこおくろたたこおたくおくそくたおこたたこたたろたたおくここおおくたくたひたここたるこおおくおくたおこここくおくおくねたおたくのおくくこじこたくくかくたくおんたおたたくくたこ |
セル内改行
セル内での改行はvbLf
で表します.
これはVisual Basicで改行コードがLFのものという意味の定数です.Windowsの改行コードは通常CRLFであり,セル内改行は特殊な改行となっています.
Sub セル内改行のある入力例() |
vbLf
はダブルクオートで囲みません.
文字列ではなく,セル内改行が格納された変数のようなものだと考えてください.
応用(改行タグ)
D列2行目〜20行目の各行に,あるブログの各ページ記事が入っており,それゆえセル内には改行があります.
各記事を再利用したいので,セル内改行を<br>
に置換してください.(<br>
はHTMLファイルで改行を意味します.)
挿入と削除
セルの挿入
For文のページの一番最初のマクロを実行したところから説明を始めます.
マクロを再掲しましょう.
Sub For文の一例 |
A1セルから下へセルを挿入するには次のように書きます.
Sub 下へのセル挿入() |
Shift:=xlDown
をShift:=xlToRight
とすると右側にシフトします.
このShift
オプションを設定しない場合には勝手にセルの挿入方向を決める仕組みなので,思わぬ方向にシフトしてしまうかもしれません.
バグの原因となるので,必ず設定するようにしましょう.
なお,英語の一般動詞のように「〜する」という処理を施すものをVBAではメソッドといいます.ここではA1セルを主語として,動詞にあたるInsert
メソッドで,挿入するという動作を表現しています.動作に対して副詞句を作るのがオプションです.VBAでは各オプションをオプション名:=設定値
の形式で指定します.ここでは「挿入する」という動作に対し,「下へ向かって」という副詞句を与えています.
セルの削除
For文のページの一番最初のマクロを実行したところに戻りましょう.
セルを削除したい場合には,次のようにします.
Sub 上へのセル削除() |
Shift:=xlUp
をShift:=xlToLeft
とすると左側にシフトします.
For文との組み合わせ
セルを次々に挿入もしくは削除するという手作業は大変面倒なので,For文と組み合わせて処理するのは効果的です.
しかし,この処理は,知らないとハマるポイントがあります.
問題
- 上から下に連続で5行削除しようとする次のコードで,1〜5行目が削除できないことを確認してください.
Sub 上から下に削除する誤った例() |
- 1行ずつ処理しては停止するVBEのコマ送り機能ステップインを使い,Excelの動きを確認しましょう.
VBEはデバッグ(=バグの除去)を行うための機能をいくつか提供しており,ステップインはそのうちの一つです.マクロを進めて特定のポイント(ブレークポイント)で停止する機能や,進行中のマクロの変数を書き換えたりする機能が存在します.
対策
カウンタで指定しながら行や列の挿入/削除を行うときには,Step -1
で外側から(行なら下から上,列なら右から左に向かって)処理せねばなりません.
問題
次のコードで1〜5行目が削除できることを確認してください.
Sub 下から上に削除する正しい例() |
For文での各行の処理
For文を2つ組み合わせることで,一定の範囲の各セルに処理を施すことができます.
A1〜B3セルに同じ文言を入れてみましょう.
A1〜A3セルに同じ文言を入れる,B1〜B3セルに同じ文言を入れると考えれば,2つFor文を作ればいいことが分かります.
Sub 愚直に書いた範囲処理() |
i
は使い回すので、Dim i As Long
は1回しか書かなくて構いません(し、2回書いても「もう宣言されてるよ」と、2回目はエラーになってしまいます)。
2列の処理をまとめるには
同じ処理をまとめるのがFor文です。
上の2つのFor文を、For文でまとめてしまいましょう。
違うのは列のところだけですから、For文
Dim j As Long |
を使って列をまとめます.
すると,
Sub ネストで範囲処理をコンパクトにまとめる() |
となります。
このように構文の中に構文が入った形を、ネスト(入れ子)と言います。
For文に限らず、コードが読みにくくなるためネストは深くしすぎないようにしてください。
なお、i
とj
は両方とも整数なので、変数の宣言はDim i, j As Long
とまとめても構いません。もし個別に変数の型を宣言したいなら、Dim i As Long, str As String
といった具合に書くことができます。
問題
A1〜D5セルに文言を入れるネストを作ってみてください。
次回
「〜のときにだけ」繰り返すということができたら一層便利ですね。
次回は条件を設定するためにIf文を扱います。