VBAでは、どんなときに括弧を使うのか。さらに、巷でよく見かける"文法的に"間違った括弧の使い方なども動画で詳しく解説しています。ぜひ、ご覧ください。Youtubeでは、ほかにもたくさんの動画を公開しています。チャンネル登録をお忘れなく!
Office TANAKAチャンネル
たとえば、次のようなマクロがあったとします。
Sub Sample1() Dim Re As Long Re = MsgBox("OKですか?", vbYesNo) If Re = vbYes Then MsgBox "それはよかった", vbInformation End If End Sub
上のマクロでは、2つのMsgBoxが使われています。しかし、最初のMsgBoxは引数を括弧で囲っているのに、2番目のMsgBoxは括弧で囲っていません。試しに、最初のMsgBoxで括弧をはずすと、エラーになります。
逆に、2番目のMsgBoxの引数を括弧で囲むと、これまたエラーになります。
いったい、VBAの括弧は何なのでしょう。
たとえば、ワークシート関数のSUM関数を思い出してください。SUM関数は、引数に指定した数値を合計して、その結果を返す関数です。
SUM関数は、計算した結果を返しました。このように、ある命令が、その結果として返す値のことを返り値(または戻り値)と呼びます。
では、今度はVBAの関数を見てみましょう。ワークシート関数にも同じ名前の関数がある、Left関数を例にします。Left関数は、引数に指定した文字列のうち、指定した文字数だけ左から抜き出す関数です。
Left("tanaka", 2)
の返り値は"ta"ですね。VBAで括弧が必要かどうかは、この返り値を、使うかどうかで決まります。上のようなVBAの関数では、一般的に関数の返り値(ここでは"ta")を何かに使います。たとえば、セルに代入したり、変数に格納したり、別の命令の引数に指定したり。そのように、返り値を何かに使うときは、引数を括弧で囲まなければなりません。
Sub Sample2() Dim buf As String Range("A1") = Left("tanaka", 2) ''返り値をセルに代入します buf = Left("tanaka", 2) ''返り値を変数に格納します Sheets(Left("tanaka", 2)).Activate ''返り値をSheetsコレクションの引数に指定します End Sub
最後の行は、[ta]という名前のシートをアクティブにします。
関数は、その計算結果(返り値)を何かに使うのが一般的です。もし、Left関数の計算結果(返り値)を使わないのなら、次のように括弧で囲みません。
Sub Sample2() Dim buf As String Range("A1") = Left("tanaka", 2) ''返り値をセルに代入します buf = Left("tanaka", 2) ''返り値を変数に格納します Sheets(Left("tanaka", 2)).Activate ''返り値をSheetsコレクションの引数に指定します Left "tanaka", 2 ''返り値を使わない End Sub
意味がありませんよね。意味がありませんけど、VBAの文法的には間違っていません。なので、上のコードはエラーになりません。さて、冒頭でお見せしたMsgBoxですが、これも立派なVBAの関数です。関数であるからには、何かの結果を返します。MsgBox関数は、何を返す関数なのでしょう。実は、MsgBox関数は、ユーザーが「どのボタンを押したか」という結果を返します。最初の
Re = MsgBox("OKですか?", vbYesNo)
は、ユーザーがどのボタンを押したかという返り値を、変数Reに格納しています。これは、その後のIfステートメントで判定するためです。このように、MsgBoxの返り値を使っていますから、引数は括弧で囲まなければなりません。
次のMsgBox関数
MsgBox "それはよかった", vbInformation
は、ユーザーがどのボタンを押したかという返り値を使っていません。先の「Left "tanaka", 2」と同じです。てゆーか、そもそも[OK]ボタンしか表示していないのですから、どのボタンが押されたかを判定する必要はありませんね。押されたのは[OK]ボタンに決まっています。ここは、ただユーザーにメッセージを表示しただけです。つまり、返り値を使っていませんから、引数を括弧で囲ってはいけません。これが、VBAにおける括弧のルールです。
関数の返り値を何かに使うときは、引数を括弧で囲まなければなりません。それは、よろしいですか。ところがVBAには、関数以外にも、何かを返す命令があるのです。
たとえば、新しいワークシートを挿入するAddメソッドは、挿入したワークシート(Worksheetオブジェクト)を返します。「挿入したワークシートの名前」ではありません。「挿入したワークシートそのもの(オブジェクト)」です。Addメソッドのヘルプを見てみましょう。
「読みにくい」「日本語になってない」「意味が分からない」というご批判は、ひとまず置いておいて。ちゃんとヘルプにも(一応は)書いてあります。Addメソッドは、挿入したワークシート(Worksheetオブジェクト)を返します。そこで、その返り値を使うことができます。たとえば、次のコードは、挿入したワークシート(であるWorksheetオブジェクト)を、変数wsに格納しています。
Sub Sample3() Dim ws As Worksheet Set ws = Worksheets.Add(After:=Worksheets("Sheet3")) ws.Name = "Sample" End Sub
もし、Addメソッドの返り値を使わないのなら、引数を括弧で囲みません。
Sub Sample4() Worksheets.Add After:=Worksheets("Sheet3") End Sub
ちなみに、メソッドの返り値を使うというテクニックを応用すると、次のような書き方もできます。
Sub Sample5() Worksheets.Add(After:=Worksheets("Sheet3")).Name = "tanaka" End Sub
ほかにも、実行結果のオブジェクトを返すメソッドとしてよく使われるのは、ブックを開くOpenメソッドです。これは、開いたブック(Workbookオブジェクト)を返します。
では、VBAのメソッドはどれも、何らかのオブジェクトを返すのかというと、そうではありません。たとえば、セルを削除するDeleteメソッドは、実行結果として「削除が成功したらTrue」を返します。
Sub Sample6() Dim re re = Range("A1").Delete(Shift:=xlToLeft) MsgBox re End Sub
もっとも、何らかの理由でセルを削除できず、Deleteメソッドが失敗した場合は、そこでエラーになりますので、こうした判定をすることは希です。ちなみに、何らかの理由でDeleteメソッドがエラーになるときは、そもそもDeleteメソッドが正常終了しませんので、返り値は何も得られません。
VBAの関数は、一般的には何らかの返り値を返します。返り値を使わないMsgBoxは、特殊な使い方と言えます。なので、普通は関数の引数を括弧で囲まなければなりません。メソッドも、実行結果のオブジェクトを返すものがあります。そうしたメソッドの返り値を何かに利用するときは、引数を括弧で囲みます。ただし、すべてのメソッドがオブジェクトを返すわけではありません。では、オブジェクトを返すメソッドと、オブジェクトを返さないメソッドの違いは、どうやって知ればいいのでしょう。その方法はひとつしかありません。ヘルプを見ることです。