もりさんのプログラミング手帳

教えることは、二度学ぶこと

スポンサーリンク

【ExcelVBA】スキルアップに必要なことはすべてエラーが教えてくれた

VBAの基本的な文法を習得して、自分で一からコーディングするレベルの初級者が遭遇する「エラーあるある」を、自分への戒めも込めてまとめてみました。

f:id:excel-accounting:20180429143617p:plain:w200

※随時更新していきます。
※すべて筆者体験談です。


f:id:excel-accounting:20180414233757p:plain:w500

入門編(★)

Do~Loop文の条件指定

WhileUntilを間違えて一瞬でEnd Sub

f:id:excel-accounting:20180429192409p:plain:w150

【NGコード】

Sub sample()

    Dim cnt As Long
    'cntが10になるまで繰り返したい    
    Do While cnt = 10
        '~処理~
        cnt = cnt + 1
    Loop

End Sub

この場合はWhileではなくUntilですね。

これはVBA以前に英語力の問題・・・恥ずかしい。

For~Next文のカウンタ変数

カウンタ変数を i = i +1 したら処理が飛び飛びになる。

【NGコード】

For i = 1 To 10
    Cells(i, 1).Value = "hogehoge"
    i = i + 1 '不要!!
Next i

Do~Loop文と混同してますね。

For文では自動的にカウンタ変数が増えます。

オブジェクト変数への代入

変数への代入時にSetを付け忘れる。

【NGコード】

Dim sh As Worksheet
sh = Sheets(1)

そして謎のエラーが出現する。

f:id:excel-accounting:20180429142359p:plain:w400

えっ、オブジェクト変数設定してるよね・・・
Withブロック変数ってなに・・・

f:id:excel-accounting:20180426143057p:plain:w150

初級編(★★)

エラー処理(On Error)

・gotoラベルの挿入位置を間違えて無限ループにはまる

goto処理を書いたら(よほどの自信がない限り、)まずは慎重にステップ実行しましょう。

f:id:excel-accounting:20180426142925p:plain:w150

・Exit Subの書き忘れ

Exitし忘れて、正常パターン時に無限ループにはまる。
正常パターンの処理が終わったら速やかにExitしましょう。

行削除を上から処理しようとする

行を削除したらもちろん行番号が変わりますよね。

step -1で最終行から処理しましょう。
(列削除処理の場合は、右端の列からですね。)

【OKコード】

For r = maxrow To 1 Step -1
    If Cells(r, 1).Value = "hogehoge" Then
        Rows(r).Delete
    End If
Next r

論理エラーも構文エラーもないのに処理が空振る

エラーが出てくれればネットや本で調べられるのに・・・

コーディングには間違いがない(はず)なのに・・・

という謎の事象。


複数のブックやシートを操作する場合、RangeやCellsプロパティ等は、上位オブジェクトを指定しないと、その行が実行される時点のアクティブなシートを見にいきます。

Book1のsheet1をアクティブにして・・・
Book2のsheet1をアクティブにして・・・

なんて処理を繰り返していると、想定外のシートを見にいって空振ることがあります。

ブックやシートを複数操作する時は、オブジェクト変数にセットして明示的に扱いましょう

【サンプルコード】

[ファイルを開く]ダイアログボックスで開いたブックを変数wbに格納する

Dim OpenFileName As String
OpenFileName = Application.GetOpenFilename _
    (FileFilter:="Microsoft Excelブック,*.xls*", MultiSelect:=False)

If OpenFileName <> "False" Then 'ファイルが選択されたら
    Workbooks.Open FileName:=OpenFileName '開く
End If

Dim wb As Workbook
Set wb = ActiveWorkbook

カウンタ変数の宣言位置

変数は宣言位置によって下記のような違いがあります。
思わぬバグを引き起こすので、用途にあった適切な位置で宣言しましょう。

・プロシージャレベル変数
→マクロ実行が終了したら値はリセットされる

・モジュールレベル変数
→マクロ実行が終了しても値を保持し続ける
VBEの「リセット」ボタンを押すか、Excel再起動でリセットされる

【サンプルコード】

Option Explicit
'モジュールレベル変数
Dim cnt As Long
Dim a As Long

Sub sample()

    cnt = cnt + 1
    Debug.Print " ---マクロ実行:" & cnt & "回目--- "

    Dim i As Long
    
    For i = 1 To 3
        a = a + 1
        Debug.Print "a = " & a
    Next i

End Sub

【出力結果】5回連続実行
 ---マクロ実行:1回目--- 
a = 1
a = 2
a = 3
 ---マクロ実行:2回目--- 
a = 4
a = 5
a = 6
 ---マクロ実行:3回目--- 
a = 7
a = 8
a = 9
 ---マクロ実行:4回目--- 
a = 10
a = 11
a = 12
 ---マクロ実行:5回目--- 
a = 13
a = 14
a = 15

値が保持されて増加していくのがわかりますね。

まとめ

ネット上のソースを「コピペ」ばかりしていると、いざエラーが出たときに対処できなくなってしまいます。

自分で一から書き、

エラーに遭遇し、

エラーの原因を考える。

「エラーは最高の成長チャンス」ですよ。

f:id:excel-accounting:20180428154537p:plain:w150


ExcelVBAの記事をまとめたVBAのカテゴリもぜひご覧くださいね。

以上、「あるある」と思ってくれた方、スターをポチっとしていただけると励みになります。

スポンサーリンク