お疲れ様です。
はざまです。
今回は、Excel VBAで作成したツールのデバッグ方法を共有します。
前回、ツール作成でエネルギー切れを起こしたので、その続きもかねて。。
では、まずおさらいから。
自動化する際の考え方
自動化をする際、自分はそんなに難しいことは考えていません。
基本4つのステップを踏めば簡単に自動化できます。
【自動化に向けた4ステップ】
【1.作業整理】
自動化したい作業を箇条書きで書き出す。
★ポイント:なるべく1クリック1作業として箇条書きすることを意識します。
【2.作業のグループ化】
自動化したい作業を、グループ化する。
★ポイント:作業開始前と終了後で状態が変わらないよう作業をグループ化します。
【3.ツール作成】
グループごとに、VBAを書く。
★ポイント:VBAを書く際、なるべくコメントを入れます。
【4.テスト・デバッグ】
ツールを実際に動かして想定通りに動くか確認する。
★ポイント:ループ、分岐にブレークポイントを設定します。
1~3までは前回やったので、今回は4からやりましょう。
【4.テスト・デバッグ】
テスト・デバッグですね。
ループ、分岐にブレークポイントを設定するのがポイントです。
設定する理由は以下です。
・ツールがうまく動かない際、ループ、分岐で意図しない処理が入っていることが多い。
⇒ツール修正を素早く行うために、アタリを付けるイメージですね。
・誤ってループ処理に入ってしまった時にすぐに処理を停止させられる。
⇒特にDO While文に多いのですが、ループが止まらず無限に処理し続けちゃうことがあります。
そんな時、ブレークポイントを事前に設定しておくと無限に処理が走る前に検知できます。
・ツールの動きがわかる
⇒ブレークポイントを設定することで、ツールの動きを視覚的にとらえることができます。
特にプログラムに不慣れな時期は視覚的にとらえることでより理解が深まります。
ちなみにブレークポイントとは、プログラムを任意の場所で停止させる際に指定する場所のことです。
VBEではモジュールのすぎ左の帯の任意の行をクリックしてあげることで指定できます。
※こんなイメージ
はい、先ほど作ったツールを標準モジュールに貼り付けた上でブレークポイントを設定しましょう。
※こんなイメージ
では設定できたのでツールを実行します。
実行すると以下のようにブレークポイントで処理が止まります。
止まったことを確認出来たら[F5]キーを押して次処理に行きます。
全処理網羅できるまで[F5]キーを押し続けましょう。
そうすると全ブレークポイントに入るはずです。
デバッグの目安として最低でも全処理3周、できれば処理が全て終わるまで[F5]キーを押し続けます。
そんな感じでデバッグしたところ、一つバグを見つけました。
これ、過去の集計した情報がそのまま蓄積されちゃっていますね。。
なので、一番最初の処理で過去の情報を削除する処理を入れてあげます。
※こんな感じ
Sub SelectFolder()
'■情報クリア
Range("B:E").Clear
'■変数宣言
Dim selectedFolder As String '選択されたフォルダ
'■ダイアログを表示してフォルダを選択
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "フォルダを選択してください"
.ButtonName = "選択"
'■マクロを実行しているワークブックのパスを初期値として設定
.InitialFileName = ThisWorkbook.Path
If .Show = -1 Then
'■選択されたフォルダを"selectedFolder"変数に格納
selectedFolder = .SelectedItems(1)
Else
'■キャンセルされた場合は処理を終了
Exit Sub
End If
End With
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
' ■FileSystemObjectを作成
Set objFSO = CreateObject("Scripting.FileSystemObject")
' ■フォルダオブジェクトを取得
Set objFolder = objFSO.GetFolder(selectedFolder)
' ■フォルダ内のファイルを順に取得
' ★作業をコピー対象ファイル分繰り返す。
For Each objFile In objFolder.Files
'■ファイルを開く
Set wb = Workbooks.Open(objFile)
'----------------------------------以下部品2----------------------------------
Dim C_SheetName As String '■コピー対象シート名
Dim C_CellName As String '■コピー対象セル名
Dim P_BookName As String '■貼り付け先エクセルファイル名
Dim P_SheetName As String '■貼り付け先シート名
Dim P_CellName As String '■貼り付け先セル名
'■パラメータ取得
C_SheetName = "作業実績"
C_CellName = "B2:E30"
P_BookName = "集約マクロ.xlsm"
P_SheetName = "転記先"
P_CellName = "B2" '
'■Workbook内の各Worksheetをループで開く
For Each ws In wb.Worksheets
'■シートをアクティブにする
ws.Activate
' ■シート名がコピー対象シート名、もしくはコピー対象シート名の文字列を含む場合、以下処理をする
If InStr(ws.Name, SheetName) > 0 Then
'■指定されたセルをコピー
ws.Range(C_CellName).Copy
'■貼り付け先シートをアクティブにする
Workbooks(P_BookName).Worksheets(P_SheetName).Activate
'■貼り付け先セルにすでに値が入っているかチェック、値が入っていたら値が入っていないセルを指定する処理を入れる
If Range(P_CellName).Value <> "" Then
'■貼り付け先セル上でCtl + ↓ を実行し、さらに1行下に移動したセルのアドレスを取得
P_CellName = Range(P_CellName).End(xlDown).Offset(1, 0).Address
End If
'■上記処理で指定されたセルに対して、値貼り付け
Range(P_CellName).PasteSpecial Paste:=xlPasteAll
End If
Next ws
'-----------------------------------------------------------------------------
'■ファイルを閉じる
wb.Close
Next objFile
' ■オブジェクトを解放
Set objFile = Nothing
Set objFolder = Nothing
Set objFSO = Nothing
End Sub
はい、これでデバッグ・テストは終わり。
見てくれてありがとうございました。
ではまた。
コメント