機能と数式 | VBA | セミナー | オンラインソフト | お問い合わせ | その他
Top > Excel > 今さら聞けないVBA

括弧はどんなときに使うの?



たとえば、次のようなマクロがあったとします。

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は、特殊な使い方と言えます。なので、普通は関数の引数を括弧で囲まなければなりません。メソッドも、実行結果のオブジェクトを返すものがあります。そうしたメソッドの返り値を何かに利用するときは、引数を括弧で囲みます。ただし、すべてのメソッドがオブジェクトを返すわけではありません。では、オブジェクトを返すメソッドと、オブジェクトを返さないメソッドの違いは、どうやって知ればいいのでしょう。その方法はひとつしかありません。ヘルプを見ることです。



このエントリーをはてなブックマークに追加