Excelを教えて25年以上が過ぎました。四半世紀です。私も歳を取るはずです。その間、数万人を超える「VBAって何ですか?まったく分かりません」というレベルの超初心者に教えてきましたが、正直言って「えぇ?そこ?」って感じる質問もたくさん受けました。まぁ、この「今さら聞けないVBA」では、そういう質問を多く取り上げているのですが。そんな「えぇ?そこ?」って感じる質問の中で、長い間「質問者が、本当は何で悩んでいるのか」という本質を、私が理解できなかったものがあります。それが、この質問です。たとえば、オブジェクト式を理解する上で、最も基本的な書き方である
Sheets("Sheet2").Name = "test"
というコードを示して「何か質問はありますか?」と聞くと、かなり多くの方から次のように聞かれます。
Sheet2ってダブルコーテーション("")で囲むんですか?
あるいは、セルに値を代入するという、これまたVBAでは基本中の基本である
Range("A1").Value = 100
を説明すると、こちらも同じような質問が多いです。
A1ってダブルコーテーション("")で囲むんですか?
私は最初、この質問を「文字列はダブルコーテーション("")で囲む」という、いわばプログラミング言語の大原則に関する内容だと思いました。だから、そのための解説をしました。たとえば、セル内に関数を入力するとき「=COUNTIF(A1:A5,"田中")」の田中は単なる文字ですよね。単なる文字はダブルコーテーション("")で囲みますよね。VBAも、それと同じなんですよ~みたいに。VBAは分からなくても、いつも使い慣れているワークシート関数で説明すれば理解してくれるだろうと。こうした回答を何度かしたのですが、どうも質問者は納得しないようでした。「・・・は、はぁ」みたいなw こちらも、今ひとつ手応えを感じていません。もちろん、コンピュータがメモリ内で行っている仕組み的な説明をしてもいいですが、おそらくそれだと、さらに混乱するでしょう。この手の質問、メチャクチャ多いんですけど、いったいどう説明すれば理解してくれるのだろうと、けっこう悩んでいました。それが、5~6年前になって、ようやく分かりました!この質問の真意を理解できました。Excelを教える者として、ほんの少しレベルアップできた感があり、その晩は祝杯をあげました。まぁ、それとは関係なく、いつも飲んでますけど。ちなみに「なぜ文字列はダブルコーテーション("")で囲まなければいけないのか」という、VBAの"仕組み"的な話は、下の動画で詳し~く解説しています。ああ、あと、ダブルコーテーション("")を「""」だったり「"""」だったり「""""」みたいに記述されているのを見たことはありませんか?その仕組みも解説していますので、ぜひご覧ください。
Excelは「機能」「関数」「VBA」の3要素で構成されています。「機能」というのは、ユーザーがマウスやキーボードでExcelに指示を与えて、Excelが何らかの動作をするという仕組みです。「関数」はSUM関数やVLOOKUP関数などのワークシート関数を駆使して、セル内で計算する仕組みです。そして「VBA」、これはマクロを使ってExcelを自動実行させる仕組みです。Excelは、この3要素で構成されているのですが、一般のユーザーは「機能」→「関数」→「VBA」の順番で学習することが多いです。つまり、これからVBAを学習しようという初学者は、すでに「関数」つまり、"セル内に入力する数式"の使い方に慣れているんです。Excelというアプリケーションに関しての学習で「機能」→「関数」まで来ました。となれば当然、これから学習する「VBA」も「機能や関数で学習してきた常識がVBAでも通用する。だって同じExcelなのだから」と考えて当然です。まずは、そこです。それは誤解です。「機能」「関数」と「VBA」は違います。つまり、「機能」「関数」で慣れ親しんできた"Excelの常識"と、"VBAの常識"は違います。違うんです。違うんだと思ってください。これを一緒だと感じている方がとても多いです。すると先のような疑問が生じます。
なぜ、「機能」「関数」という"Excelの常識"と、"VBAの常識"が異なるかというと、両者は別々に開発されたソフトウェアだからです。Excelは表計算ソフトです。データを並べ替えたり印刷したり、セル内に関数を入力して計算できます。Excelはそのように作られました。一方のVBAは、もともとあった「Visual Basic(通称VB)」というプログラミング言語を、Excelのセルやシートを操作できるように改良したものです。
ですから、「機能」や「関数」で当たり前だったことが、「VBA」では異なるということが起きます。両者の違いをいくつかご紹介しましょう。以下はどれも、VBAのセミナーで"超あるある"の質問ばかりです。
冒頭の質問です。なぜ多くのビギナーがこれを勘違いするのかというと、セルの中で使う数式はダブルコーテーション("")で囲まないからです。
Sheets("Sheet2").Range("A1").Value = 100
上記の「ダブルコーテーション("")で囲むんですか?」という質問は「(セルの中に入力する数式では囲まないのに、VBAでは)ダブルコーテーション("")で囲むんですか?」という意味だったんですね。お答えは「はい、そうです、囲みます」です。さらに「セルの中に入力する数式では囲まないのに、なぜVBAでは囲むんですか?」という疑問に対しては「ワークシート上のルールと、VBAのルールは違うから」が答えです。もし、これでも納得できないようでしたら、VBAは無理ですから諦めてください。
この件に関する質問も超多いです。たとえばセルに次のような数式を入力したとします。
A列全体を選択して、列を挿入します。それまでセルA1だったセルは、1列右に移動してセルB1になります。
すると、セルに入力した参照式のアドレスも、自動的に変化します。
あるいは、別シート上のセルを参照していたとします。
ここで、参照先のシート名を手動操作で変更します。
すると、参照式で指定していたシート名も自動的に変化します。
ワークシート上では、行や列の挿入または削除によって、参照しているセルのアドレスが変化すると、そのセルを参照していた数式内のアドレスも自動的に変わります。別シートを参照しているときのシート名も同様です。このようにワークシート上では「ユーザーが手動操作でExcelに何かをすると、数式内に記述したことが自動的に変化」します。しかしVBAでは、Excel上で何かが起きたからといって、マクロのコードが自動的に変わるということは一切ありません。マクロのコードは、ただ記述されているだけで、Excelの"状況"とはリンクしていません。ですから、マクロを記述したあとで、たとえばセルの位置が移動してアドレスが変わったり、シートの名称が変わったときなどは、自分でマクロのコードを書き換えなければなりません。
Range("A1").Value = 100 ''アドレスは変化しない Sheets("Sheet2").Select ''シート名は変化しない
これも過去に何度か質問されました。今になって思えばこれも、VBAを"Excelの常識"で考えてしまったのが原因です。たとえば、セルに次のような数式を入力したとします。
セルC1に「=IF(A1="田中",B1*2,"")」という数式を入力して、セルC9までコピーしました。この結果、Excelは「A列が"田中"であるとき、C列に、B列の数値を2倍した値を表示する」という状態になります。これと、同じようなことをマクロでやる場合、たとえば標準モジュールに、次のようなコードを記述します。
Sub Macro1() Dim i As Long For i = 1 To 9 If Cells(i, 1) = "田中" Then Cells(i, 3) = Cells(i, 2) * 2 End If Next i End Sub
このコードも「A列が"田中"であるとき、C列に、B列の数値を2倍した値を代入する」という、Excelに対する指示・命令です。結果だけを考えれば、先の数式と同じですが、両者はまったく異なります。数式は、セルにそれを記述するだけで、ただちに結果が現れます。しかしマクロは、このコードを"書いただけ"では何も起きませんし、セルには何も表示されません。「マクロって、実行しないといけないんですか?」という質問は、マクロとして記述したコードと、セル内に記述した数式の、どちらも同じ「Excelに対する指示・命令」だと考え(そこまでは合っています)、「機能」「関数」で培った"Excelの常識"と同じように「(マクロも)指示・命令は記述するだけで、ただちにExcelの状態が変わる」という誤解から生じたものでしょう。
また、似たような質問で、次のようなこともありました。マクロのコードを書いて、それを実行し、セルに値が代入されたあとで「手動でC列のセルをクリアしてください」と言ったところ「(モジュールにマクロを書いてあるのに)消えるんですか?」みたいな。これも、"Excelの常識"と混同した誤解です。
数式はセルの中に記述されている間はずっと、同じ計算結果を表示し続けます。マクロも同じ指示・命令ですが、セルとコードをリンクさせたわけではありません。人間が手動操作でセルに数値を代入するという行為を、マクロで代行しただけです。
最後の「違い3」みたいな質問は、それほど多くありませんが、それでも誤解する根本は同じです。対して「違い1」と「違い2」は、毎週のように実施しているVBAセミナーで、ほぼ毎回まったく同じ質問をされます。超定番の"あるある質問"です。正直に言いますが、マクロができるようになった人って、このへんは誰に教わるでもなく、自ら理解して進んできました。だから、そういう人が教える側になると、このへんの「自分にとっては当たり前」のことを軽視します。しかし、初学者というのは、こういうところで悩むんですよね。ビギナーからの「えぇ?そこ?」という質問をたくさん受けてきた私には、よく分かります。もし、この部分でモヤモヤしている人は、"Excelの常識"と"VBAの常識"は違うんだという認識からスタートしてください。