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

変数って宣言しなくちゃいけないの?



いや、別にいいですよ、宣言しなくても。

もし、あなたが、辛いことや苦しいことが大好きでたまらないドMな性格だったり、とにかく自分に厳しく、苦行や荒行に目がない修行僧のような生き方を好むのなら、どうぞ変数の宣言をしないでマクロを作成してください。ただし、その苦しさは少しも気持ちよくありませんし、その修行はあなたの肉体や精神を何も鍛えてはくれませんけどね。

百聞は一見にしかずです。変数を宣言しないとどうなるか、実例をお見せしましょう。



上図のようなデータを用意してください。A列に2種類のデータが入っています。「東京都××区」と「○○市××区」です。ここでは、仮に6件としました。ここから「××区」部分を抜き出してB列に入力します。ついでに「○○市」が何件あったかをカウントして、最後に表示します。変数の宣言を強制しないモジュールで、下記のマクロを実行してみてください。もし、モジュールの先頭に Option Explicit と記述されていたら、これをコメントアウトしてから実行してください。

'Option Explicit    ''←これがあったら、コメントにする

Sub Sample1()
    For i = 1 To 6
        Address = Cells(i, 1).Value                         ''セルの値を変数に格納
        POS = InStr(Addres, "都")                           ''都の位置を調べる
        If POS > 0 Then
            ''都があったら
            Cells(i, 2).Value = Mid(Address, POS + 1)       ''都から後ろを抜き出す
        Else
            ''都がなかったら
            POS = InStr(Address, "市")                      ''市の位置を調べる
            If P0S > 0 Then
                ''市があったら
                Cells(i, 2).Value = Mid(Adress, P0S + 1)    ''市から後ろを抜き出す
                cnt = cnt + l                               ''市の件数をカウントする
            Else
                ''市がなかったら
                Cells(i, 2).Value = "不明データ"
            End If
        End If
    Next i
    MsgBox "市は " & cnt & " 件ありました"
End Sub

実行結果は下図のとおりです。



まぁ、まずは上のコードをじっくり見てください。それで間違っている部分に気がついたら修正してください。わずかこれだけのコードでも、なかなか間違いに気づきにくいでしょう。お手上げの方は、次のように変数の宣言を強制して、変数宣言を追加してから実行してください。

Option Explicit    ''←変数の宣言を強制する

Sub Sample1()
    Dim i As Long, POS As Long, Address As String, cnt As Long    ''←変数の宣言
    For i = 1 To 6
        Address = Cells(i, 1).Value                         ''セルの値を変数に格納
        POS = InStr(Addres, "都")                           ''都の位置を調べる
        If POS > 0 Then
            ''都があったら
            Cells(i, 2).Value = Mid(Address, POS + 1)       ''都から後ろを抜き出す
        Else
            ''都がなかったら
            POS = InStr(Address, "市")                      ''市の位置を調べる
            If P0S > 0 Then
                ''市があったら
                Cells(i, 2).Value = Mid(Adress, P0S + 1)    ''市から後ろを抜き出す
                cnt = cnt + l                               ''市の件数をカウントする
            Else
                ''市がなかったら
                Cells(i, 2).Value = "不明データ"
            End If
        End If
    Next i
    MsgBox "市は " & cnt & " 件ありました"
End Sub

上のようにすれば、どこが間違えているか一目瞭然です。いくら何でも、こんな間違いはしないでしょう・・・という話ではありません。重要なことは、最初の変数の宣言を強制しない環境では、あのマクロがエラーにならないということです。エラーにならないということは、マクロ的には"正常終了"するということです。今回のように、明らかに結果がおかしければ、結果を見て「マクロが間違えているかも」と気づくかもしれません。しかしこれが、もっと複雑なマクロで、一見しただけでは結果の間違いに気づかなかったら・・・ああ、恐ろしくて、夜も眠れません。そして、もし、マクロの間違いに気づいて、コードを修正するのなら、コードを1行ずつ目で見てチェックしていかなければなりません。なにしろ、エラーにならないのですから、VBEのデバッグ機能を有効活用することもできません。これが数100行におよぶ長いコードだったら・・・ああ、恐ろしくて、食事も喉を通りません。

上のマクロ、要するに変数の名前を打ち間違えているのですが、もし、変数の宣言を強制するようにしていたら、そんなもの一瞬でわかります。



丁寧にも、間違えている箇所が選択されるのですから、嫌でも直したくなりますね。

なぜ変数を宣言しないのか 〜人の造りしもの〜


VBAは、

  • 変数を宣言しなくても使える設定
  • 変数を宣言しなくては使えない設定

の2種類があります。その設定は、VBEの[ツール]-[オプション]で切り替えられます。



[編集]タブの[変数の宣言を強制する]チェックボックスをオンにすると、各モジュールでコードペインの先頭にOption Explicitが自動的に入力されます。これは「Option Explicitステートメント」で、モジュールの中で使用すると、そのモジュールでは、変数を宣言しないと使用できなくなります。[オプション]ダイアログボックスの[変数の宣言を強制する]は、各モジュールに、このステートメント自動入力するという設定に過ぎません。

で、問題は、VBAの初期状態は、このオプションがオフになっているということです。普通にExcelをインストールすると、このオプションはオフです。そもそも、このオプションの存在を知らないユーザーも少なくありません。標準の設定とは、いわばMicrosoftが「こう使ってはいかがですか?」と推奨しているようなものですから、[変数の宣言を強制する]が初期状態でオフになっていることから「変数は宣言しないで使う方がいいのかな」と、信じるユーザーもいます。実際に、そういう意見を聞いたこともあります。

VBAの初期設定がどうであれ、上の例で見たように、変数を宣言しないで使うことは百害あって一利なしです。VBAを使えるようになりたいと思ったら、まず最初にやるべきことは、[変数の宣言を強制する]のオプションをオンにすることです。

なぜ変数を宣言しないのか 〜嘘と沈黙〜


VBAを学習するとき、パソコン雑誌は頼りになる教材です。多くのパソコン雑誌で、多くのVBA入門記事が書かれています。
VBAなんて難しくありませんよ、マクロ記録すれば誰にでも作れますよ、さぁ本誌で初めてみましょう。
誰にでもできますよ、すぐできますよ、3日でできますよ、3行でできますよ、犬でも猿でもできますよ、
さぁ、いらっしゃい!いらっしゃい!社長、カワイイ子いますよ!1000円ポッキリですよ!
と、まるで夜の歌舞伎町かと思わんばかりの謳い文句を信じてページをめくるのですが、それでVBAをマスターできたという話は、なかなか耳に入ってきません。パソコン雑誌の「VBA入門」では、変数を宣言しなくても使える設定で解説をする記事が少なくありません。変数を宣言することは、ミスを減らす第一歩であり、VBAのビギナーは最初にしっかり学習しなければならない大事なところです。なぜ、パソコン雑誌は、ビギナーのためにならない「変数は宣言しなくてもいい」的に教えるのでしょう。

理由はいくつか考えられます。たとえば、私が経験したケースでは次のようなことがありました。

  • 編集者がマクロを作ったことがなく変数宣言の重要性を理解していない
    雑誌を作っている者が、すべてその内容に精通しているとは限りません。たとえば、Excelに関する記事を掲載する雑誌で、担当者はあまりExcelを使ったことがなく、その原稿をチェックする編集長までもが、Excelをどう使うべきかを理解していないという雑誌がありました。もちろん、編集部として、読者に役立つような記事を掲載しようと真面目に企画を考えています。しかし、実際にExcelを使ったことがない者に、Excelユーザーが本当は何を知りたいのかなんて、分かるはずもありません。「読者はきっと、これを望んでいるのだろう」という、方向性を見誤っていました。そうした編集部では、いつも同じような言い訳を聞きます。「自分(編集者)もExcelビギナーだから、Excelビギナーの気持ちが分かる。自分(編集者)が知りたいことは、読者も知りたいに違いない」と。何を思い上がっているのでしょう。そんなの、単なる詭弁です。すべての読者が、あなたと同じですか?まるで、小学校の先生を小学生が務めるようなものです。ちなみに、その雑誌は廃刊になりました。

  • ページ数や誌面構成の都合で解説を割愛した
    雑誌にはページ構成があります。たとえば、最も目立つ特集は何ページ、毎号掲載している「Excel講座」は何ページという具合です。その中で原稿を書き、画像を配置していくわけです。もし、VBAの記事で、編集者が変数宣言の重要性を認識していたとしても、その解説をするのには、そのために数ページを使わなければなりません。しかも、やっかいなことに、変数宣言の重要性をビギナーに正しく理解させるのは、決して簡単ではありません。そこで、やむを得ず「今回は、変数を宣言しないということでいきましょう」と・・・こうしたケースは少なくありません。これは、変数宣言に関することだけではありません。何でもかんでも「個人用マクロブックにマクロ記録しましょう」というスタンスも同じです。VBAの解説を書いてみれば分かりますが、個人用マクロブックにマクロ記録させるという解説の方が、書くのは簡単なんです。それがユーザー(読者)にとって"ためになる"からではありません。単なる、書き手や作り手の事情です。

  • 編集者が「変数は宣言しなくてもいい」と誤解している
    最初のケースに似ていますが、さらに悪質です。変数宣言の重要性を認識していないのではなく「いや、変数は宣言しなくてもいいだろう、その方がいい」と誤解しているケースです。某有名パソコン雑誌の副編集長さんがそうでした。こうした方は、ご自身でマクロを作成されていることが多いです。そして「変数は宣言しなくてもいいんだ」という信念をお持ちです。何事もそうですが、誤った信念を改めさせるのは大変です。さらに悪いのは「変数の宣言は上級者がやるもの」とか「変数の宣言は大規模なマクロでやるもの」という誤解です。上級者になるために必要なら、ビギナーのうちから変数宣言の習慣と技術をしっかりと身につけるべきです。大規模なマクロと小規模なマクロの違いは何でしょう。冒頭の例でお見せしたように、変数宣言をしなかったばかりに誤動作を起こしたあのコードは、大規模なマクロなのでしょうか。

パソコン雑誌は、VBAを学習する上で役に立つ教材です。真面目に取り組んで、読者のためになる記事を、毎号大変な思いをして作っている雑誌もたくさんあります。しかし、そうではない雑誌もあるということです。雑誌に書いてあるから正しい、と鵜呑みにするのは危険です。

なぜ変数を宣言しないのか 〜奇跡の価値は〜


VBAのビギナーは、VBAが分かりません。当たり前ですね。分からないけれど、業務で必要だから、何とかマクロを作成しようとします。その心意気は立派です。何とか応援したくなります。しかし、悲しいかな、VBAの適切な基礎を、正しく教えてくれるスクールや教材は、ほとんどありません。もちろん、職場の周りにも、親切に教えてくれる先輩や上司は見あたりません。そうしたビギナーが、マクロを作成するために行うアクションは、たいてい決まっています。インターネットの検索です。自分の知りたいことを検索してみて、ヒットしたページを開き、よく意味が分からないけど、見よう見まねでコードをコピペ(笑)したら動いたと。とりあえず、これでいいや、みたいな。

だけど、コピペして動いたからといって、VBAのスキルが向上した訳ではありません。自分のコードが、どんな意味かも分かっていないのですから、何かトラブルがあったときに、対応できるはずがありません。たとえば、次のようなケースをご覧ください。



A列の製品番号をE列から探して、該当する単価と数量をかけ算したいんです。実務では、こうした単価表が別シートや別ブックに存在することが多いですけど、ここではシンプルなレイアウトにしました。また、もちろん実際には、もっと膨大なデータだったとします。さて、やり方がわからないので、インターネットの掲示板で質問してみました。すると「これでできるよ」と下記のようなコードを教わりました。

Sub Sample2()
    Dim i As Long, j As Long, NO As Long
    For i = 3 To 10
        If Cells(i, 1) = "" Then Exit Sub
        NO = Cells(i, 1)
        For j = 3 To 10
            If Cells(j, 5) = NO Then
                Cells(i, 3) = Cells(i, 2) * Cells(j, 6)
                Exit For
            End If
        Next j
    Next i
End Sub



なるほど、確かに計算できました。
ところが後日、新しい製品が追加されました。今度の製品は2パターンあって、製品番号がそれぞれ「xxxxxA」と「xxxxxB」のように区別されています。さっそく、その通りに入力しました。



すると今度は、マクロがエラーになります。



訳が分かりません。何がいけないのでしょう。分からないまま試行錯誤の結果、次のように変数の宣言を削除したら、動くようになりました。もちろんこの人は変数の宣言を強制しない設定のまま使っていたのです。

Sub Sample2()
    For i = 3 To 10
        If Cells(i, 1) = "" Then Exit Sub
        NO = Cells(i, 1)
        For j = 3 To 10
            If Cells(j, 5) = NO Then
                Cells(i, 3) = Cells(i, 2) * Cells(j, 6)
                Exit For
            End If
        Next j
    Next i
End Sub



ああ、やっぱり変数は難しいなぁ。型とか意味分かんないし。宣言なんて面倒なことしないで済むなら、そっちの方がいいや。楽だし、何よりも、とりあえず動くし・・・

よろしいですか?その結果行き着くのは、本コンテンツ冒頭の、あのトラブルなんですよ。AddressをAddresと打ち間違えたばかりに、計算結果が違ってえらいことになったり、間違いを発見するために、目薬と睡眠打破を机に並べて、延々と徹夜作業を繰り返すハメになるんです。

ビギナーが変数で悩むのは、変数の宣言ではありません。変数のです。LongだとかIntegerだとか、単精度浮動小数型だとか倍精度浮動小数型だとか、かんべんしてくださいよ、って感じです。だから、型が分からないから宣言そのものをやめてしまうんです。これは乱暴です。変数の宣言と、型の指定は別の作業です。

変数の型が分からないのなら、全部バリアント型にすればいいんです。バリアント型は、どんな値でも格納できるオールマイティの型です。こんな便利な型があるのなら、使わない手はありません。しかも、バリアント型の指定は

Dim A As Variant

と書かなくても

Dim A

と、型指定を省略すればいいんです。これなら超簡単でしょ。

変数を宣言すると、変数のタイプミスによる重大なバグを回避できます。だから[変数の宣言を強制する]をオンにして、必ず宣言します。でも、変数の適切な型を指定するのは難しいです。それなら、型指定を省略して、全部バリアント型にします。そして、余裕ができたら、あらためて変数の型について学習すればいいです。

ちなみに、マクロで使われる変数の型は、ほとんどが

  • 長整数型(Long) → 整数を入れる
  • 文字列型(String) → 文字列を入れる

の2種類です。この2つを覚えておけば、たいていのマクロでは困りません。

変数の型が分からないうちは → 全部バリアント型でOK
ちょっと余裕ができたら → 整数はLong、文字列はStringと宣言する
さらに余裕ができたり、必要になったら → その他の型について学習する

と思っててください。


バリアント型のススメについては、下記のページでも解説しています。


似たようなことも書いていますが、バリアント型のデメリットなどに触れています。ぜひ、ご覧ください。



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