Excel VBA でプログラミングした際に、思ったように動作しないことがあります。
構文エラーは出ておらず、動作はするけど意図したのとは違う結果が出るような場合。
こんなときにはデバッグ(プログラミングコードの間違い探し)をしなければなりません。
プログラミング1つ作り上げる作業全体の半分以上の時間はデバッグに費やすイメージです。
さて、今日はデバッグ方法の1つとして「MsgBox 関数を使う方法」を紹介します。
1、MsgBox 関数
まず、MsgBox 関数について説明します。
MsgBox = メッセージボックス
ということで、この関数を使えばメッセージボックスに文字列を表示させることができます。
適当に Excel ファイルを作り、VBE(エディタ)を開いて(Alt + F11)コードを記述しましょう。
以下のように記述します。
MsgBox 関数は「MsgBox 文字列」のように記述します。
文字列は” “で囲わなければなりません。また、この文字列の部分に変数を持ってくることも OK です。
上記のコードを実行すると「テスト」という文字列がメッセージボクスに表示されます。
このように MsgBox 関数自体の使い方は至って簡単です。
そして、この関数をデバッグ(プログラミングコードの間違い探し)にも使うことができるので、そのあたりのことについてお話ししますね。
2、MsgBox 関数をデバッグに使う
実例をあげながら MsgBox 関数でデバッグを行う方法について説明します。
税抜金額を税込金額に変換するシート
ある日付における売上高について、税抜金額を税込金額に変換するシートを例にあげます。
次のように「日付」と「税抜金額」を入力してから、「実行ボタン」をクリックすればマクロが動作して「税込金額」が計算されるというものです。
日付は「2014/2/21」のように入力します。
なお消費税率は
・2014年4月1日以降は8%
・2014年3月31日以前は5%
ですので、その点を考慮に入れて日付によって消費税率を分けて計算するコードを考えているものとします。
コード(一部間違いあり)
次のようなコード入れ込みました。
*予め言いますと以下のコードは敢えて一部間違えています。デバッグの方法を説明するわけですからね(^^);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
Sub MsgBox_Debug() '変数の定義' Dim Syouhi_Zeiritsu '消費税率' Dim Hiduke '日付' Dim Nen '年' Dim Tsuki '月' Dim Zeinuki_Kingaku '税抜金額' '日付と税抜金額の読込み' Hiduke = Cells(3, "A") Zeinuki_Kingaku = Cells(3, "B") '年の抽出(左端から4文字分)' Nen = Left(Hiduke, 4) '月の抽出(左端から6文字目を起点に2文字)' Tsuki = Mid(Hiduke, 6, 1) '年・月による消費税率の区分' If Nen >= 2015 Then '2015年以降の場合' Syouhi_Zeiritsu = 8 / 100 '消費税率 8%' ElseIf Nen = 2014 And Tsuki >= 4 Then '2014年4月以降の場合' Syouhi_Zeiritsu = 8 / 100 '消費税率 8%' Else Syouhi_Zeiritsu = 5 / 100 '消費税率 5%' End If '税込金額の表示' Cells(3, "C") = Zeinuki_Kingaku * (1 + Syouhi_Zeiritsu) End Sub |
コードの説明
変数の定義
まずは変数の定義です。
私の場合は型は特定していません。
「Hiduke」と「Zeinuki_Kingaku」は Excel シートに入力した値を読み込むことになります。
1 2 3 4 5 6 |
'変数の定義' Dim Syouhi_Zeiritsu '消費税率' Dim Hiduke '日付' Dim Nen '年' Dim Tsuki '月' Dim Zeinuki_Kingaku '税抜金額' |
日付と税抜金額の読込み
ここでは「Hiduke」をセルA3から、「Zeinuki_Kingaku」をセルB3から読み込んでいます。
1 2 3 |
'日付と税抜金額の読込み' Hiduke = Cells(3, "A") Zeinuki_Kingaku = Cells(3, "B") |
日付から「年」と「月」の抽出
Left 関数と Mid 関数を用いて日付(変数 Hiduke)から「年」と「月」を抽出しています。
1 2 3 4 5 6 |
'年の抽出(左端から4文字分)' Nen = Left(Hiduke, 4) '月の抽出(左端から6文字目を起点に2文字)' Tsuki = Mid(Hiduke, 6, 1) |
年・月による消費税率の区分
ここでは消費税率が8%か5%かを日付から判断しています。
具体的には、
・まず「年」で見て 2015 年以降であれば 消費税率8%
・「年」が 2014年の場合において、「月」が4月以降であれば 消費税率8%
・上記以外の場合 消費税率5%
というような判断を If ~ Else 構文を使って行っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
'年・月による消費税率の区分' If Nen >= 2015 Then '2015年以降の場合' Syouhi_Zeiritsu = 8 / 100 '消費税率 8%' ElseIf Nen = 2014 And Tsuki >= 4 Then '2014年4月以降の場合' Syouhi_Zeiritsu = 8 / 100 '消費税率 8%' Else Syouhi_Zeiritsu = 5 / 100 '消費税率 5%' End If |
税込金額の表示
最後に「税抜金額」と「消費税率」を掛け算して「税込金額」を計算し、セルC3に表示しています。
単純な掛け算です。
1 2 |
'税込金額の表示' Cells(3, "C") = Zeinuki_Kingaku * (1 + Syouhi_Zeiritsu) |
コードの実行
さて、「日付」と「税抜金額」を入力して実行してみます。
まず消費税率が5%となる条件である
●日付:2014年3月1日
●税抜金額:100,000
の場合に実行すると税込金額(セルC3)は次のようになります。
税込金額が 105,000 になっているのでちゃんと消費税率が5%で計算されていることが分かりますね。
次に消費税率が8%となる条件である
●日付:2014年12月1日
●税抜金額:100,000
の場合に実行すると税込金額(セルC3)は次のようになります。
税込金額が 105,000 になっているので、消費税率は5%で計算されてしまっています。
8%のはずなのに。。。
デバッグ
さて、ここで何が原因なのかデバッグを行わなければならないわけですね。
デバッグの際のポイントはまずあるべき結果は何か?を把握することです。
今回の場合は、「日付:2014年12月1日 では消費税率が8%になるはず」という点があげられます。
ではなぜ5%で計算されてしまったのか?
今からどこがおかしいのか、MsgBox 関数を使って調べていきますね!
まず、消費税率の区分を If 文で分ける箇所で5%の区分のところに入ってきてしまうことを確認しておきます。
If文の Else の後(8%に該当しない期間の場合)に「MsgBox “チェック”」と入力してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
'年・月による消費税率の区分' If Nen >= 2015 Then '2015年以降の場合' Syouhi_Zeiritsu = 8 / 100 '消費税率 8%' ElseIf Nen = 2014 And Tsuki >= 4 Then '2014年4月以降の場合' Syouhi_Zeiritsu = 8 / 100 '消費税率 8%' Else Syouhi_Zeiritsu = 5 / 100 '消費税率 5%' MsgBox "チェック" End If |
実行するとメッセージボックスで「チェック」の文字が出てくるので、間違いなく5%の区分で計算されてしまっていることが分かりました。
では、消費税率が5%と判断されてしまう理由は日付が2014年3月31日以前と認識されてしまっていることになるでしょう。
まず、日付が正しく読み込めてるか確認します。
日付を変数「Hiduke」に読み込んだ直後に MsgBox 関数を入れ込んで確認してみます。
1 2 3 4 5 |
'日付と税抜金額の読込み' Hiduke = Cells(3, "A") Zeinuki_Kingaku = Cells(3, "B") MsgBox Hiduke |
実行するとメッセージボックスで「2014/12/01」の文字が出てくるので、日付自体は問題なく読み込めていることが確認できました。
次に、日付の中の「年」が正しくなっているか確認します。仮に2010 などと認識されているとその時点で消費税率5%と判断されてしまうので。
年を抽出して変数「Nen」に読み込んだ直後に MsgBox 関数を入れ込んで確認してみます。
1 2 3 4 |
'年の抽出(左端から4文字分)' Nen = Left(Hiduke, 4) MsgBox Nen |
実行するとメッセージボックスで「2014」の文字が出てくるので、年も問題なく読み込めていることが確認できました。
次に日付の中の「月」が正しくなっているか確認します。
月を抽出して変数「Tsuki」に読み込んだ直後に MsgBox 関数を入れ込んで確認してみます。
1 2 3 4 |
'月の抽出(左端から6文字目を起点に2文字)' Tsuki = Mid(Hiduke, 6, 1) MsgBox Tsuki |
実行するとメッセージボックスで「1」の文字が出てきます。12月なのに「1」はおかしいですね。
さて、もう少し調べてみましょう。
試しに他の日付がどのように認識されているか見てみます。
「2014/4/1」の場合を確認するためセル「A2」にその日付を入力して、先と同じ位置に MsgBox 関数を入れ込んで「月」を確認します。
1 2 3 4 |
'月の抽出(左端から6文字目を起点に2文字)' Tsuki = Mid(Hiduke, 6, 1) MsgBox Tsuki |
すると、今度は「0」と表示されました。
4月のはずなのに「0」とこれまたおかしいですね。。
日付は「2014/04/01」のように常に10文字で認識されます。
月は4月の場合「04」、12月の場合「12」
日付で「月」として抽出したい箇所は、以下の赤で囲った2文字の部分です。
しかし、現実には「12」を「1」、「04」を「0」として認識してしまっているわけですね。
このことから、月を表す2文字のうちの最初の1文字分しか認識していないことが分かりますね。
では抽出している文字の数が間違っているのではないかということで、その部分を確認してみます。
Mid 関数は
Mid(文字列,開始位置,文字数)
のように使います。
今回のコードでは
Tsuki = Mid(Hiduke, 6, 1)
としているので、
・文字列が Hiduke
・開始位置が 6文字目
・文字数が 1文字
となっています。
文字数は1文字ではなく2文字抽出しなければなりませんね。。
間違いはここだ!! と気付くわけです。
正しくは
Tsuki = Mid(Hiduke, 6, 2)
ですね。
ここを訂正して、もう一度日付を「2014/12/1」として実行してみましょう。
ちゃんと消費税率8%で計算してくれますね!
3、まとめ
一応正しいコードを載せておきます(1箇所しか訂正はありませんが)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
Sub MsgBox_Debug() '変数の定義' Dim Syouhi_Zeiritsu '消費税率' Dim Hiduke '日付' Dim Nen '年' Dim Tsuki '月' Dim Zeinuki_Kingaku '税抜金額' '日付と税抜金額の読込み' Hiduke = Cells(3, "A") Zeinuki_Kingaku = Cells(3, "B") '年の抽出(左端から4文字分)' Nen = Left(Hiduke, 4) '月の抽出(左端から6文字目を起点に2文字)' Tsuki = Mid(Hiduke, 6, 2) '年・月による消費税率の区分' If Nen >= 2015 Then '2015年以降の場合' Syouhi_Zeiritsu = 8 / 100 '消費税率 8%' ElseIf Nen = 2014 And Tsuki >= 4 Then '2014年4月以降の場合' Syouhi_Zeiritsu = 8 / 100 '消費税率 8%' Else Syouhi_Zeiritsu = 5 / 100 '消費税率 5%' End If '税込金額の表示' Cells(3, "C") = Zeinuki_Kingaku * (1 + Syouhi_Zeiritsu) End Sub |
今回のケースはごく初歩的なコードを実例にあげていますが、もっと複雑になるとデバッグもかなり大変になります。
For文やDo文が出てくると特に苦労は大きいです。。
様々なデバッグの方法がありますが、MsgBox を使う方法は簡単で分かりやすいと思います。
是非活用してみて下さい。