VBA編其ノ4 まとめて料理してやるゼ!
前回(→其ノ3)、いくつかマクロを書いてもらいました。 ちょっと思い出してみてほしいのですが、例えばこのマクロ※1。
セル(3,2)から(5,2)までを1コずつ、「塗りつぶし:なし」にしました。
だけど、セル(3,2)から(5,2)までは連続したひとつの範囲なのだから、何も1コずつやらなくても良いのではないだろうか。
それに、全部同じ命令(「塗りつぶし:なしにする」)だしね。
もう1コ、見てください※2。
こちらの、1行目と2行目を見てください。
1行目と2行目で命令は違います(「値を入れる」と「文字色をつける」)が、どちらも対象は同じセル(3,3)です。
だったらこのマクロ、「cells(3,3)」を2回書く必要があるんだろうか…。
今回のテーマは「もうちょっとだけステキに書く」です。
題材は前回(其ノ3)と同じなので、マクロを動かした結果は前回と同じになっちゃうのですが、よりスタイリッシュなマクロ記述になると思うので、お付き合いください。
おっとすみません、この話に進む前に。
VBAの文法
ここで、VBAの文の構造について。
下↓の文、思い出してください※3。
VBAの文は、基本的に、
目的語+動詞
から成っています。
つまり、「~~を○○する」というかたちになっていて、「~~を」の部分が目的語、「○○する」が動詞に該当します。
さきほどの文にあてはめてみましょう※4。
コレ↑が基本の型になります。 各単語の区切り、目的語と動詞の区切りは「.(ピリオド)」です。
なので、例えばマクロ「worksheets(2).select」を書いてみてください。 「worksheets」と複数形でお願いします。 これの意味は…、何となくお分かりですね※5 ※6。
コイツの構造は…、こう↓なりますね※7。
目的語が「ワークシート(2)」、動詞が「選択する」なので、全体として「ワークシート(2)を選択する」となります。
目的語と動詞は、基本的にはいつもワンセットです。 目的語ナシの動詞、例えば「select」だけでは、機能しません。 当然ですよね、「何を」セレクトして良いかわからないですもんね。 もちろんその逆の、目的語だけ、というのも機能しません。 セル(5,3)を「どう」して良いのかわからないからです。 「じゃあ、最初にやったmsgboxはどうなるの?」という疑問もあるでしょうが、これは…、ちょっとした例外だと思ってください。 たしかにmsgboxには目的語はありません、が、特殊な動詞と言うか、目的語が省略されていると言うか…、とにかくコレは特別であって、基本的には「目的語+動詞」となります。
もう1コ書いてみましょうか。 さっきのマクロのせいでsheet2が選択されていると思いますので、sheet1に戻ってください※8。
で、新たにマクロ「columns(2).insert」を書いてください※9。
コレ↑、意味わかります?
「columns」も「insert」も初登場のワードですもんね。
「column」は「列」って意味です。
「columns(2)」だと、「(左から)2番目の列」という意味になります。
あ、そうそう。
コレも「columns」と複数形ね。
「insert」は…、「挿入」という意味です。
なので、「columns(2).insert」で「第2列を挿入する」という意味になります。
試しにこのマクロを動かしてみましょう※10。
こうなります。
このマクロの文法構造も、すでにお分かりのとおり「目的語+動詞」です※11。
ここまでご理解いただけましたでしょうか。
ではではここで。値を入力するマクロ「Cells(4, 7).Value = 123」
のことも考えてみましょう※12。
この文↑も実は、「目的語+動詞」から成っています。 ただ、今回の場合は、「目的語」の部分が「Cells(4, 7).Value」、「動詞」は「= 123」となります※13。
ちょっと解説しますね。
まず「動詞」から。
この文の動詞は「= 123」です。
意味は、「「123」とイコールにする」です※14。
では「何を」「「123」とイコールにする」のでしょうか。
それは、「Cells(4,7).Valueを」です。
この文の目的語「Cells(4,7).Value」は、「Cells(4, 7)」と「Value」という2つのワードから成っています。
この場合、後ろにくる「Value」は、前にくるワードをより詳しく説明するための付加説明になります※15。
セル(4,7)って、いろんな要素から成り立っていますよね。
「幅」とか「高さ」とか「背景色」とか。
中に入力されている「値」もそうです。
「Cells(4,7).Value」は、「.Value」という付加説明をプラスすることによって、「セル(4,7)について、その中の特に「値」を」というかたちで、ターゲットを特定しているのです。
だから、全体として、「セル(4,7)の「値」を」という意味になるのです。
そして、こうして成立した目的語「セル(4,7)の「値」」を、「「123」とイコールにする」のです※16。
このようにして、「Cells(4,7).Value = 123」は、「セル(4,7)の値を「123」にする」という意味になるワケです。 オケイ?
背景色を塗るマクロ「Cells(1, 2).Interior.ColorIndex = 3」も同様です。 付加説明が増えた、すなわち目的語の部分が長くなっただけです※17。
目的語のベースになるのは「Cells(1,2)」です。
それを、直後の付加説明「.Interior」で、「(その)内部を」とより詳細に規定してやってるのです。
今回はそこにさらに付加説明「.ColorIndex」が従います。
こうして、全体として「セル(1,2)の内部の色番号を」という意味になるワケです。
以上、文法解説終わり。
オブジェクト?プロパティ?メソッド?
…実はね、申し訳ないんですが、「目的語+動詞」というVBA文法説明の仕方は、わたしが勝手にそう呼んでるだけなんですよ。 本来は、
オブジェクト(.プロパティ).メソッド
というのが「正しい」文法解説です。
本屋に行くとたくさん並んでいるVBAテキストには、たいていこのかたちで載っているハズです。
私流の解説と並列すると、「メソッド」は「動詞」のことです。
「オブジェクト」は「目的語」、「プロパティ」は「付加説明」とニアリーイコールかな?
ちょっと意味する範囲が違うので、単純な比較はムリがあるんですけど※18。
だから、他所で「目的語が~」とか「動詞が~」とか言っても、通じません。
それに対して、「オブジェクト」「プロパティ」「メソッド」というのは、プログラムの歴史の中で錬成された伝統ある概念です。
ではなぜ、わたしは「オブジェクト」「プロパティ」「メソッド」を避けたのか。
…うーん、結論から言うと、初学者にやさしくないからです。
「オブジェクト」「プロパティ」「メソッド」の解説は、たいていVBAテキストの最初の方のページに出てくるんですけど、なんかね、ぼんやりしてるんですよ。
特に、経験値の少ない人にとっては。
実は、わたしの経験上、「オブジェクト」「プロパティ」「メソッド」というのは、やっていくうちになんとなくわかっていく性質のものなんですよ。
だから、「そのうち理解できるサ」という力の抜けた態度で臨むのが良いと思うんだけど、
初学者ってマジメだから、「コレを理解するまでは一歩も前に進まないぞ!」なんて思春期の受験生みたいになっちゃったり。
そんなところに、「セルはオブジェクトだけど、cellsはプロパティ」みたいな、よくわかんない議論に首をつっこむハメになっても…、良いことはひとつもないと思います。
だからみなさんも、VBAテキストのなかでこれらの用語が出てきて「よくわかんねぇな…」となったとしても、「そのうちわかるようになるだろう」と未来志向で進んじゃうのが良いように思います。
…ああ、でも一応、ことばの一般的な意味ぐらいはまとめておきましょうか。こんな↓カンジです。
オブジェクト (object) |
対象、目的物。
もともとは「目標となるもの」ぐらいの意味です。
英文法の「目的語」も、「object」と綴ります。 VBAでは、セルやワークシートなどが、オブジェクトの例として挙げられます。 |
プロパティ (property) |
性質、属性。 元来は「(何か対象に)固有のもの」という意味で、例えばあるモノの、匂いとか、肌触りとか、大きさとか。 そういうものが「プロパティ」。 |
メソッド (method) |
方法。 由来はギリシア語の「メタ ホドス」で、「メタ」は「~の上に」(「メタ言語」とか言うよね)、「ホドス」は「道」の意。 なので「メタ ホドス」だと「道に沿って」ぐらいの意味になります…、ていう話、ハイデガーに影響を受けた人はこの話好きだよねーホント。 |
なので、VBA本のなかで「○○オブジェクト」とか「△△プロパティ」といった表現が出てきたら、「ああ、対象は○○なのね」「属性は△△なのね」ぐらいの理解でさらっと進みましょう。 さらっと。
範囲を指定する
で、何の話だったっけ?
…そうそう、マクロ記述をもちょっとステキに、という話だったよね。
ではまず、さっきマクロで1列挿入しちゃったので、それを元に戻してください、お手数ですが※19。
それでね、前回やった「セルの背景色を塗りつぶし:なしにする」マクロのことを、再度思い出しましょう※20。
すでにお分かりのとおり、セル(3,2)、セル(4,2)、セル(5,2)というのは、ひとつの範囲です※21。
なので、この範囲をまとめて相手してやりましょう。
範囲をターゲットとするには、「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。
では、マクロを書いて、動かしてみましょう※23 ※24。
では、2列目の、20行目までを全部、色ナシにするには? …そうです、前回カラーインデックス表で塗ったところ、全部です※25 ※26。
こんなこともできます。1行で※27 ※28。
「range」で指定する、「始まりのセル」「終わりのセル」の関係は、下↓のように※29なっています。 つまり、左上から右下に向かう、ってワケ。
以上、「range」の話終わり。
同じワードを1コにまとめる
さて、今度はこちらのマクロのこの部分※30です。
「cells(3,3)」を2回書いてます。
まちがいではないんですが、なんとなくカッコ悪い。
それに、後で読み返したとき、わかりにくいような気がします。
こういうときは、「with」というワードを使って、まとめてあげましょう。
「with」を使うと、この部分は、
With Cells(3, 3)
.Value = "ノゾミ"
.Font.ColorIndex = 3
End With
と書くことができます。
ためしに、改めてマクロを書きなおしてみましょう※31。
あ、そうそう、比較のために、となりの列(4列目)に入るよう修正しました。
元のマクロより長くなっちゃったけど(笑)、こっちの方がわかりやすい感じがしませんか?
なんとなく。
で、動かしてみると…※32。
もちろん同じ結果になります。
では、解説。
「with」は、複数回登場する同一ワードをまとめあげるときに使います。
イメージとしては、こんな↓カンジです※33。
元々の文だと、「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」は必ずワンセットで。