---topics:rangeプロパティ、withステートメント---

VBA編其ノ4 まとめて料理してやるゼ!

前回(→其ノ3)、いくつかマクロを書いてもらいました。 ちょっと思い出してみてほしいのですが、例えばこのマクロ※1

連続してるのだから、まとめてできないものか
※1 連続してるのだから、まとめてできないものか

セル(3,2)から(5,2)までを1コずつ、「塗りつぶし:なし」にしました。 だけど、セル(3,2)から(5,2)までは連続したひとつの範囲なのだから、何も1コずつやらなくても良いのではないだろうか。 それに、全部同じ命令(「塗りつぶし:なしにする」)だしね。
もう1コ、見てください※2

同じセル(3,3)に対する命令
※2 同じセル(3,3)に対する命令

こちらの、1行目と2行目を見てください。 1行目と2行目で命令は違います(「値を入れる」と「文字色をつける」)が、どちらも対象は同じセル(3,3)です。 だったらこのマクロ、cells(3,3)」を2回書く必要があるんだろうか…
今回のテーマは「もうちょっとだけステキに書く」です。 題材は前回(其ノ3)と同じなので、マクロを動かした結果は前回と同じになっちゃうのですが、よりスタイリッシュなマクロ記述になると思うので、お付き合いください。

おっとすみません、この話に進む前に。

VBAの文法

ここで、VBAの文の構造について。
下↓の文、思い出してください※3

cells(5,3).select
※3 cells(5,3).select

VBAの文は、基本的に、

目的語動詞

から成っています。 つまり、「~~を○○する」というかたちになっていて、「~~を」の部分が目的語、「○○する」が動詞に該当します。
さきほどの文にあてはめてみましょう※4

cells(5,3).selectの文法構造
※4 cells(5,3).selectの文法構造

コレ↑が基本の型になります。 各単語の区切り、目的語と動詞の区切りは「.(ピリオド)」です。

なので、例えばマクロ「worksheets(2).select」を書いてみてください。 「worksheets」と複数形でお願いします。 これの意味は…、何となくお分かりですね※5 ※6

worksheets(2).selectで…
※5 worksheets(2).selectで…
2枚目のシートが選択される
※6 2枚目のシートが選択される

コイツの構造は…、こう↓なりますね※7

worksheets(2).selectの文法構造
※7 worksheets(2).selectの文法構造

目的語が「ワークシート(2)」、動詞が「選択する」なので、全体として「ワークシート(2)を選択する」となります。

目的語と動詞は、基本的にはいつもワンセットです。 目的語ナシの動詞、例えば「select」だけでは、機能しません。 当然ですよね、「何を」セレクトして良いかわからないですもんね。 もちろんその逆の、目的語だけ、というのも機能しません。 セル(5,3)を「どう」して良いのかわからないからです。 「じゃあ、最初にやったmsgboxはどうなるの?」という疑問もあるでしょうが、これは…、ちょっとした例外だと思ってください。 たしかにmsgboxには目的語はありません、が、特殊な動詞と言うか、目的語が省略されていると言うか…、とにかくコレは特別であって、基本的には「目的語+動詞」となります。

もう1コ書いてみましょうか。 さっきのマクロのせいでsheet2が選択されていると思いますので、sheet1に戻ってください※8

sheet1に戻ってきた
※8 sheet1に戻ってきた

で、新たにマクロ「columns(2).insert」を書いてください※9

columns(2).insert
※9 columns(2).insert

コレ↑、意味わかります?
「columns」も「insert」も初登場のワードですもんね。 「column」は「列」って意味です。 「columns(2)」だと、「(左から)2番目の列」という意味になります。 あ、そうそう。 コレも「columns」と複数形ね。
「insert」は…、「挿入」という意味です。 なので、「columns(2).insert」で「第2列を挿入する」という意味になります。 試しにこのマクロを動かしてみましょう※10

2列目に新しく列が挿入された
※10 2列目に新しく列が挿入された

こうなります。
このマクロの文法構造も、すでにお分かりのとおり「目的語+動詞」です※11

columns(2).insertの文法構造
※11 columns(2).insertの文法構造

ここまでご理解いただけましたでしょうか。
ではではここで。値を入力するマクロ「Cells(4, 7).Value = 123」 のことも考えてみましょう※12

cells(4,7).value=123
※12 cells(4,7).value=123

この文↑も実は、「目的語+動詞」から成っています。 ただ、今回の場合は、「目的語」の部分が「Cells(4, 7).Value」、「動詞」は「= 123」となります※13

cells(4,7).value=123の目的語と動詞
※13 cells(4,7).value=123の目的語と動詞

ちょっと解説しますね。 まず「動詞」から。
この文の動詞は「= 123」です。 意味は、「「123」とイコールにする」です※14

cells(4,7).value=123の動詞
※14 cells(4,7).value=123の動詞

では「何を」「「123」とイコールにする」のでしょうか。 それは、「Cells(4,7).Valueを」です。
この文の目的語「Cells(4,7).Value」は、「Cells(4, 7)」と「Value」という2つのワードから成っています。 この場合、後ろにくる「Value」は、前にくるワードをより詳しく説明するための付加説明になります※15

cells(4,7).value=123の目的語
※15 cells(4,7).value=123の目的語

セル(4,7)って、いろんな要素から成り立っていますよね。 「幅」とか「高さ」とか「背景色」とか。 中に入力されている「値」もそうです。 「Cells(4,7).Value」は、「.Value」という付加説明をプラスすることによって、「セル(4,7)について、その中の特に「値」を」というかたちで、ターゲットを特定しているのです。
だから、全体として、「セル(4,7)の「値」を」という意味になるのです。

そして、こうして成立した目的語「セル(4,7)の「値」」を、「「123」とイコールにする」のです※16

cells(4,7).value=123の文法構造
※16 cells(4,7).value=123の文法構造

このようにして、「Cells(4,7).Value = 123」は、「セル(4,7)の値を「123」にする」という意味になるワケです。 オケイ?

背景色を塗るマクロ「Cells(1, 2).Interior.ColorIndex = 3」も同様です。 付加説明が増えた、すなわち目的語の部分が長くなっただけです※17

cells(1,2).interior.colorindex=3の文法構造
※17 cells(1,2).interior.colorindex=3の文法構造

目的語のベースになるのは「Cells(1,2)」です。 それを、直後の付加説明「.Interior」で、「(その)内部を」とより詳細に規定してやってるのです。
今回はそこにさらに付加説明「.ColorIndex」が従います。 こうして、全体として「セル(1,2)の内部の色番号を」という意味になるワケです。

以上、文法解説終わり。

オブジェクト?プロパティ?メソッド?

…実はね、申し訳ないんですが、「目的語+動詞」というVBA文法説明の仕方は、わたしが勝手にそう呼んでるだけなんですよ。 本来は、

オブジェクト(.プロパティ).メソッド

というのが「正しい」文法解説です。 本屋に行くとたくさん並んでいるVBAテキストには、たいていこのかたちで載っているハズです。
私流の解説と並列すると、「メソッド」は「動詞」のことです。 「オブジェクト」は「目的語」、「プロパティ」は「付加説明」とニアリーイコールかな? ちょっと意味する範囲が違うので、単純な比較はムリがあるんですけど※18

オブジェクト、プロパティ、メソッド
※18 オブジェクト、プロパティ、メソッド

だから、他所で「目的語が~」とか「動詞が~」とか言っても、通じません。 それに対して、「オブジェクト」「プロパティ」「メソッド」というのは、プログラムの歴史の中で錬成された伝統ある概念です。 ではなぜ、わたしは「オブジェクト」「プロパティ」「メソッド」を避けたのか。
…うーん、結論から言うと、初学者にやさしくないからです。 「オブジェクト」「プロパティ」「メソッド」の解説は、たいていVBAテキストの最初の方のページに出てくるんですけど、なんかね、ぼんやりしてるんですよ。 特に、経験値の少ない人にとっては。
実は、わたしの経験上、「オブジェクト」「プロパティ」「メソッド」というのは、やっていくうちになんとなくわかっていく性質のものなんですよ。 だから、「そのうち理解できるサ」という力の抜けた態度で臨むのが良いと思うんだけど、 初学者ってマジメだから、「コレを理解するまでは一歩も前に進まないぞ!」なんて思春期の受験生みたいになっちゃったり。 そんなところに、「セルはオブジェクトだけど、cellsはプロパティ」みたいな、よくわかんない議論に首をつっこむハメになっても…、良いことはひとつもないと思います。
だからみなさんも、VBAテキストのなかでこれらの用語が出てきて「よくわかんねぇな…」となったとしても、「そのうちわかるようになるだろう」と未来志向で進んじゃうのが良いように思います。

…ああ、でも一応、ことばの一般的な意味ぐらいはまとめておきましょうか。こんな↓カンジです。

オブジェクト
(object)
対象、目的物。 もともとは「目標となるもの」ぐらいの意味です。 英文法の「目的語」も、「object」と綴ります。
VBAでは、セルやワークシートなどが、オブジェクトの例として挙げられます。
プロパティ
(property)
性質、属性。 元来は「(何か対象に)固有のもの」という意味で、例えばあるモノの、匂いとか、肌触りとか、大きさとか。 そういうものが「プロパティ」。
メソッド
(method)
方法。 由来はギリシア語の「メタ ホドス」で、「メタ」は「~の上に」(「メタ言語」とか言うよね)、「ホドス」は「道」の意。 なので「メタ ホドス」だと「道に沿って」ぐらいの意味になります…、ていう話、ハイデガーに影響を受けた人はこの話好きだよねーホント。

なので、VBA本のなかで「○○オブジェクト」とか「△△プロパティ」といった表現が出てきたら、「ああ、対象は○○なのね」「属性は△△なのね」ぐらいの理解でさらっと進みましょう。 さらっと。

範囲を指定する

で、何の話だったっけ? …そうそう、マクロ記述をもちょっとステキに、という話だったよね。
ではまず、さっきマクロで1列挿入しちゃったので、それを元に戻してください、お手数ですが※19

さっき挿入した列を削除した
※19 さっき挿入した列を削除した

それでね、前回やった「セルの背景色を塗りつぶし:なしにする」マクロのことを、再度思い出しましょう※20

セルの色をなくすマクロ
※20 セルの色をなくすマクロ

すでにお分かりのとおり、セル(3,2)、セル(4,2)、セル(5,2)というのは、ひとつの範囲です※21

セル(3,2)からセル(5,2)の範囲
※21 セル(3,2)からセル(5,2)の範囲

なので、この範囲をまとめて相手してやりましょう。
範囲をターゲットとするには、「range」というワードを使います。 「range」は「範囲」って意味ね。 VBAのワード「range」の使い方は、

range(始まりのセル , 終わりのセル)

なので、「Range(Cells(3, 2), Cells(5, 2))」とすれば、上の範囲を対象としたことになります。
したがって、前回3行にわたって書いていたマクロ、

Cells(3, 2).Interior.ColorIndex = 0
Cells(4, 2).Interior.ColorIndex = 0
Cells(5, 2).Interior.ColorIndex = 0

は、

Range(Cells(3, 2), Cells(5, 2)).Interior.ColorIndex = 0

と書けば、1行で済みます。 ためしにこのマクロを書いて、動かしてみましょう…、とその前に、前回すでにこの範囲は一度「塗りつぶし:なし」にしてたんでしたね。 この状態で動かしても何も起こらないです。 それではおもしろくない。 なのでもう一度、色、塗ってあげてください、お手数ですが※22

色を復活させました
※22 色を復活させました

では、マクロを書いて、動かしてみましょう※23 ※24

rangeを使ったバージョン
※23 rangeを使ったバージョン
結果は同じ だけど1行で書ける
※24 結果は同じ だけど1行で書ける

では、2列目の、20行目までを全部、色ナシにするには? …そうです、前回カラーインデックス表で塗ったところ、全部です※25 ※26

セル(1,1)からセル(20,1)まで
※25 セル(1,1)からセル(20,1)まで
キレイさっぱり
※26 キレイさっぱり

こんなこともできます。1行で※27 ※28

範囲に一括で値を入れた
※27 範囲に一括で値を入れた
マクロはこちら
※28 マクロはこちら

range」で指定する、「始まりのセル」「終わりのセル」の関係は、下↓のように※29なっています。 つまり、左上から右下に向かう、ってワケ。

rangeの指定の仕方
※29 rangeの指定の仕方

以上、「range」の話終わり。

同じワードを1コにまとめる

さて、今度はこちらのマクロのこの部分※30です。

cells(3,3)が2回
※30 cells(3,3)が2回

「cells(3,3)」を2回書いてます。 まちがいではないんですが、なんとなくカッコ悪い。 それに、後で読み返したとき、わかりにくいような気がします。
こういうときは、「with」というワードを使って、まとめてあげましょう。 「with」を使うと、この部分は、

With Cells(3, 3)
.Value = "ノゾミ"
.Font.ColorIndex = 3
End With

と書くことができます。 ためしに、改めてマクロを書きなおしてみましょう※31

withを使って書いてみた
※31 withを使って書いてみた

あ、そうそう、比較のために、となりの列(4列目)に入るよう修正しました。 元のマクロより長くなっちゃったけど(笑)、こっちの方がわかりやすい感じがしませんか? なんとなく。
で、動かしてみると…※32

前回と同じ結果になる
※32 前回と同じ結果になる

もちろん同じ結果になります。

では、解説。
with」は、複数回登場する同一ワードをまとめあげるときに使います。 イメージとしては、こんな↓カンジです※33

withの使い方まとめ
※33 withの使い方まとめ

元々の文だと、「Cells(3,4)」が2回出てきちゃうんですよね。 それを、先頭にwith文をもってきて代表させてやる。 それによって、以下「Cells(3,4)」の記述を省略できる、というワケです。 だから、2行目3行目の文は、「Cells(3,4)」が省略された「.Value~」「.Font.ColorIndex~」となります。
英語だと「with」って「~~と一緒に」って意味ですよね。 だから、「With Cells(3,4)」は、 「以下の文をCells(3,4)と一緒に読んでください、Cells(3,4)があると思って読んでください」 ぐらいの意味になります。

あ、そうそう、1点注意。 with文の終わりには必ず「end with」を書いてあげてください。 そうじゃないと、「With Cells(3,4)」の有効範囲がどこまでなのかわからないので、VBAはCells(3,4)がずーっとあるつもりで進んじゃうことになっちゃいます。 なので、「with ~~」と「end with」は必ずワンセットで。

Copyright(C)森田表計算