2013
6
07

プログラム初心者さんへ贈る、エラーが起きたら試してみて欲しいこと(ExcelVBA編)

チャレンジしてみたけど、エラーが…。どこをどうしていいのかも全然わからない! という方へ。どの言語でも共通項はあると思うのですが、このブログで扱っている手前、ExcelVBAを例にしてご紹介させて頂きます。


全角が混ざっていないか

日本語の文字列、若しくはコメントアウト以外は基本的に半角英数でなければいけない場合が多いです。シングルクォーテーション「’」、ダブルクォーテーション「”」、括弧「()」などが、どこからかコピーしてきたときに全角になったりしていませんか? 特に全角スペースあたりは曲者なので、Ctrl+Fで検索してみるのも手です。

コピペミス

正常にコピーできても、インデントが適正にペースト出来ない場合が多々あります。

また、全部コピーしたつもりが1行目や最終行、最後の1文字が抜けてしまっていたり、そういうことはありませんか? コピー元とよく見比べて、チェックしてみてください。

変数宣言を強制しちゃおう

デフォルトでは、変数宣言をしなくても、変数は使えます。親切なような気もしますが、逆に記述ミスなどを見つけにくくなってしまうので、各コード画面の一番上にこれを書いておきましょう。

こうしておくことで、宣言のない変数はエラーで拾ってくれるようになります。

エラーメッセージを読んで、調べる

初心者さんにとってのエラーは、全然意味の分からない、対処のしようのないものに感じられると思います。わたしも最初はそうでした。でも、エラー時に出てくるメッセージを読み解く努力をしてみないと、前に進むことはできません。まずは、「どこで」エラーが起きるかを突き止めることが大切です。

コンパイルエラー

130607-1

こういう表示が出たとき。これは、構文が間違っているなど、コードを実行する以前に問題があるということです。日本語で言うなら…「私 は リンゴ を 買います」が、「私 は を 買います」みたいに、必要な記述が抜けていたり、文章として成り立ってないですよ、というようなニュアンスです。

図の例なら、IfがあるのにEnd Ifがないですよー、って言ってるんですね。図のコードは短すぎるのでEnd Subにハイライトしてしまっていますが、だいたい問題の部分にハイライトしてくれるので、どこが悪いのか見当がつきます。

コンパイルエラーの例は、こちらのサイトに、とても詳しく載っています。

この中からわたしが独断と偏見で「あるある」というものをいくつか。

修正候補: 区切り記号 または)

カッコやカンマが足りなかったり多かったり、数が合ってませんよ、という感じ。

たとえば、左からi文字抜き出すのを書きたくて、Left("文字列", i)と書くとします。そのiRange("A1")にしたくて、Left("文字列", Range("A1"))みたいに入れ子にしたとき、右カッコが重なりますよね。こういうのを、うっかり少なく書いちゃったりすると言われます。

変数が定義されていません。

その名のとおりですね。前述したOption Explicitを設定しているのでよく怒られます。この場合、定義されてない変数にハイライトしてくれるので原因はすぐに分かりますけどね。

If ブロックに対応する End If がありません。

先ほど図解したやつですね。入れ子(IF~End Ifの中に更にIF~End If)を入れたりするといっこ忘れちゃったり。逆バージョンの「End If に対応する If ブロックがありません。」っていうのもあります。

End With が必要です。

With~End Withの閉じ忘れ。これも逆バージョン、「End With に対応する With がありません。」というのがあります。

引数は省略できません。

これは良く言われますねー! 指定しなければいけないものが抜けている場合です。

実行時エラー

130607-2

こういう表示が出た場合は、実行時エラーです。コンパイル(構文チェック)はOKなんだけど、実行してる途中で何かおかしなことが起こったよ、ということです。ここは迷わず、「デバッグ」を押してください。

130607-3

すると、一体どの行でエラーが起こっているのか黄色で示してくれます。超親切です。

この図の例を考えてみましょう。「オーバーフロー」って? そこで、分からないならば検索してみるんです。

130607-4

Googleでは「○○とは」と検索すると教えてくれます

桁あふれ…、変数iが「桁あふれ」を起こしているそうです。iIntegerで宣言していますよね。では、Integerがどんなものかを調べてみましょう。

130607-5

今度はこんな感じで検索してみます。言語名と合わせて、単語をスペースで区切って検索すると、より細かな情報を得やすいです。

検索して上からいくつか見てみると、整数型Integerは-32,768から32,767の整数ということが書かれていませんか? 先程のコードでは、変数iに100,000を入れようとしていました。桁あふれですねー、まさに。この場合は、長整数型Long(-2,147,483,648から2,147,483,647の整数)で宣言してやるのが正しいのだということが分かりますね。

言語名と一緒に検索するのは、かなり有効です。今回の例なら「excel vba オーバーフロー」で検索すると一発で解決するので、他の調べ物のときもおすすめです。

先ほどと同じサイトですが、実行エラーの例も詳しく載っています。ここからもいくつかご紹介。

型が一致しません。

あるある。Integer(整数型)で宣言した変数に文字列を突っ込んで怒られたり。

オーバーフローしました。

図解でやったやつですね。私がよくやるのが、最終行を取得しようと思ってi = Range("A1").End(xlDown).Rowって書いたらそこにデータが何にも入ってなくて、行の最大値を取得しちゃってオーバーフローとか…。2003だと6万ちょいですけど2010だと100万とからしいですね。怖っ!

インデックスが有効範囲にありません。

存在しないものを指定しようとすると良く出てきます。sheet5が存在しないのにSheets("sheet5").Range("A1")って書いちゃったときとか。

0 で除算しました。

割り算の割る数をゼロにしちゃった場合ですね。○/iみたいに割る数を変数にしておいて、何かのタイミングでiがゼロになっちゃったりした時に怒られますねー。

「わからない」と決めつけない

エラーメッセージとは、「ここがこんなふうに間違ってるよ!」と教えてくれる、とっても親切なものなのです。「自分には分からないものだ」と頭から決めつけずに、読んで、調べてみましょう。

どこでエラーが起こってるか分からないとき

例えば、Do~Loopで、ちゃんとExitするきっかけを与えてあっても、何かのタイミングでそのExitへ入らずに無限ループに入ってしまうこともあります。フリーズしてしまってにっちもさっちも行かない状態です。Ctrl+Breakで止まってくれればいいのですが、最悪タスクマネージャからタスクの強制終了になることも…。(実行する前に必ず保存する癖をつけておきましょうね!!)

そんな時、私はこのように検証することが多いです。

130607-6

適当な数値で一時停止する、という形です。この場合なら、これで実行してブレイクポイントまで正常に走れば、少なくともiが10までは正常に動くということになりますし、フリーズするようなら1から10のどこかに原因があると推測できます。

ループの最大値が1000とか2000になるものを10ずつ試していくのも非効率なので、半分の数値から検証していくのがおすすめです。母数が1000ならまず500で止めてみて、次は250か750で…、という感じ。だいたい10以内に絞れてきたら、あとはF8キーで1行ずつ追いかければどこが原因か分かると思います。

ブレイクポイントなどの説明

誰かに質問する前に

有識者が近くにいるならば、まずはそちらへ

というのも、エラーというもののほとんどが、実際にそのPCで、そのコードを動かしながら見てみないと原因を突き止めるのが非常に困難だからです。

PCのOSが違ったり(WindowsXP, Vista, 7, 8, Macなんてこともあるのかな?)、Excelのバージョン(2000, 2003, 2007, 2010, 2013など…)の違いや、そのPCにインストールされている固有のソフトウェアによる影響なども考えられます。(これらを全てひっくるめて「環境」と呼んだりします。)環境の違うPCのことを、遠隔で理解するのは、ほぼ不可能なのです。

ですので、分かる方がいるのならば、実際にその人にそのPCで見てもらうことが一番現実的です。

ネット上でのアドバイスは難しい

初心者さんほど、「ちょっと見るだけなんだからいいじゃん!」と思うでしょうが、ネット上でそれを行う場合、全然「ちょっと」じゃないんです。

前述した「環境」が分からないと何も言えないですし、よく言われる「動かない」「エラーが出た」という質問では曖昧すぎて、原因を想像することすら難しいのです。そして、初心者さんほど、その問題を適切に説明できません。

例えば、離れて暮らしている高齢の親御さんが「パソコンがおかしい」と電話してきたら。「おかしい」とは、具体的になんなのか? 何をしたら、どのタイミングで、どうなるのか? なんていうメッセージが出るのか? 電話で聞いても、本人も分からないので曖昧な返答ばかり。これで、適切なアドバイスが出来るでしょうか?

親御さんなら週末にでも見に行って、なんだこんなことだったのか、ということができますが、これを知らない相手と文章だけでやりとりするのは、とってもとーっても、大変です。せめて、

  • OSのバージョン
  • ソフトウェアのバージョン
  • どのコードを
  • どうしたら
  • どのタイミングで
  • どうなったのか
  • なんというエラーが出たのか

という情報は、最低限最初に欲しいところです。

とはいえ、提示していただいたとしても、大抵はコードが断片的なものであり、全体像がなければ同じエラーが起こる可能性は低いです…。こうなるともう想像上の回答しかできません。回答を出すのにあれこれと考える時間は長い上に、それが合ってるかはわからないのです。(しかもそれを、こちらの意図通りにやってもらえているかも、確認のしようがありません。)

出来るだけ質問には答えたい気持ちはありますが、経験上、初心者さんと文章だけのやりとりで問題解決まで至ったことは、非常に少ないです…。。ほとんどの方が途中でフェイドアウトされてしまうのが現実です。

曖昧なまま質問しない

「この記述はなんでこんな事を?」と聞くと「どこかからコピってきたからわかりません」と言う人がいます。これが一番困ります。そこは、自分で、調べないと…!

ゼロからさあ書け、って言われたら難しいかもしれませんが、コードが存在しているなら、それを1行ずつ検索してどんな動きをしているのか、何をしているのかは調べれば分かるはずです。自分の目的にそぐわない部分はコメントアウトしてみて動くか試してみるなど、ここでの試行錯誤こそがプログラミングに必要不可欠なものだと、私は思っています。

どういう動きをしているか分からないコードの意味を知りたいとき、1行まるまる検索して出てくれば良いですが、だいたいが固有の変数が含まれているので、そのままでは難しいです。そういう場合は、かっこの外側の単語に注目してください。
  • UserForm1.ComboBox1 = Year(the_date)
  • n = Day(DateAdd(“d”, -1, Date))
  • the_date = CDate(yy & “/” & mm & “/” & n)

このような部分です。これを「excel vba DateAdd」のようにひとつずつ検索すると、どういう動きをしているのかが分かります。

検索スキルを磨く

私の私見ですが、ExcelVBAはユーザーがとても多く情報が豊富なので、検索でほとんどのことは解決できるんじゃないかと思っています。同じようなことをしたいと思っている人は必ずどこかにいるし、同じことでつまずいている人も、必ずいます。

ただ、その情報を探し出すのに、慣れていないとちょっとコツが要るのかもしれません。

できるだけ細かい単語に分けて、スペースで区切って検索するのがお勧めです。エラー内容など文章で検索したい場合は、そのままだと自動で文節などが区切られた情報が出てきてしまうので、“エラー内容”のようにダブルクォーテーションで括ると、完全一致で検索してくれます。特に英語で文章検索したいときはダブルクォーテーションが必須です。

また、自分の考えた単語で検索した結果、それについて有効そうなキーワードが見つかったら、今度はそのキーワードで検索してみる、というのも手です。(自分が○○だと思っていたワードが、世間一般では△△と呼ばれていたということも結構ありますし)

検索スキルはプログラミング以外でも役に立ちますので、磨いておいて損はないですね!

置いておく

とはいえ、どーーーーしても解決できないときも、ありますよね。

そういうときは、一旦それは置いて、違うものを作ってみます。すると、それを作るうえで習得したスキルで前に躓いた部分の解決策がひらめくということが結構あるんです。

また、作れば作るほど、検索スキルも確実に上がってきます。日を置いてみると、違ったアプローチからの検索が出来るようになったりして、すんなりと解決策が見つかるということもあります。

諦めない!

ExcelVBAは比較的勉強のしやすい言語だと(個人的には)思っています。エラーを自分で処理できて、プログラムが思い通りに動いたときは、それはもう快感です。しかも自分の仕事が効率化されるとなれば、もう。

是非、がんばってみてくださいー!

  • このエントリーをはてなブックマークに追加
  • follow us in feedly 618
  • RSSを登録

公開日:2013/06/07
更新日:2013/12/06


コメントを残す




*印は必須項目です。コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にですがスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)


back to top