はじめに
業務の傍らで、VBAを使って作業効率化した時のことを投稿にまとめます。
対象者
- VBA(プログラミング)初学者
- Excel作業の効率化を考えている人
前提知識
マクロとは
- 処理を自動化するための機能です。主に作業記録や自動化に適しています
- Excelなどのアプリケーション内での操作を記録して再現することで、繰り返し行う作業を自動化し、作業効率を向上させることができます
VBAとは
- ExcelやAccessなどのOffice製品で使えるプログラミング言語です
- マクロ単体でも操作を記録・再生はできますが、VBAが使えるとより複雑な処理や制御が行えます
マクロとVBAの違い
マクロが機能であるのに対し、VBAはプログラミング言語です。
つまり、マクロを作成するための手段の1つとして、VBAがあります。
マクロを使用するときの注意点
1.業務が属人化しやすい
作成した社員しか修正や改善ができず、他の社員が業務を引き継ぐ際に大きな負担となる可能性があります。
コードが複雑になると、その仕組みが理解しづらくなり、どこでエラーが発生しているのか特定するのが難しくなります。
マクロの内容を詳細にドキュメント化しておかないと、後からトラブルが発生した場合に、対応が遅れてしまう可能性があります。
2. マクロウイルスへの感染リスク
インターネットからダウンロードしたマクロ付きのファイルを実行することで、ウイルスに感染するリスクがあります。
マクロの実行を許可する設定になっている場合、悪意のあるマクロが実行されてしまう可能性があります。
アンチウイルスソフトの導入や、OSのアップデートなど、定期的なセキュリティ対策を行うことが重要です。
3. 自動化できる範囲が限定的
複雑な判断や柔軟な対応が必要な作業は、RPAなど他のツールが適している場合もあります
人が判断して行う必要がある作業は、マクロだけでは自動化できません
他のシステムとの連携が必要な場合、マクロだけでは対応できないことがあります
使用するファイル
説明の関係上、ファイル1とファイル2と定義します。
- ファイル1:業務で実際に運用されているリスト(コピー元)
- ファイル2:入力漏れがないかをチェックするためのリスト(コピー先)
「前置きは良いから、早くコードを見せてくれ」という方は、こちらからスキップしてください。
共通点
- A列〜M列までが同じ値であること
目的
ファイル1の内容をファイル2にコピーする。
入力作業手順(手動で行う場合)
- ファイル1とファイル2を開く
- ファイル1で更新した行のA列〜M列セルの値をコピーする
- ファイル2で更新したい行のA列〜M列セルの値に貼り付けする
- ファイル2を上書き保存する
問題点
- 手動で入力する手間と工数がかかる
- コピペミスをしてしまう可能性がある
- 作業工程や範囲が毎回決まっている単純作業(であるにも関わらず手動作業)
解決方法
結論
- マクロでコピペ作業を自動化する
入力作業手順(マクロを実行した場合)
- マクロを登録したボタンを実行する
- ファイル1を選択するダイアログが開く
- コピー元のxlsxファイルを選択する
- ファイル2を選択するダイアログが開く
- コピー先のxlsxファイルを選択する
- コピーが成功したら、メッセージボックスが表示される
懸念点
- プログラムの不具合やエラーでコピーが失敗する
- プログラムを作成した手間よりも手動作業の効率が上回る
- ループ処理で時間がかかって、手動の方が結局早く終わる
期待できる効果
- 毎回数分〜数十分かけていた作業をほぼ1クリックで完了できる
代替案
- ファイル1のコピー対象の列(A列からM列)までを一括コピーする。そしてファイル2に貼り付ける
懸念点
- 手動であるのに変わりはない
- 入力ミスのリスクが無いわけではない(例えばフィルターをかけてたなどで、コピペする列がズレるなど)
- メタ的なことを言うと、これを採用したらこの記事はここで終わってしまう
実際のコード
以下のコードは正解ではなく、あくまで一例です。
Sub SyncColumns()
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim lastRow As Long
Dim i As Long
Dim j As Long
Dim filePath1 As String
Dim filePath2 As String
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
'ダイアログを開く
filePath1 = Application.GetOpenFilename("Excelファイル(*.xlsx", , "ファイル1の選択")
If filePath1 = "False" Then Exit Sub
filePath2 = Application.GetOpenFilename("Excelファイル(*.xlsx", , "ファイル2の選択")
If filePath2 = "False" Then Exit Sub
'ワークブックを開く
Set wb1 = WorkBooks.Open(filePath1)
Set wb2 = WorkBooks.Open(filePath2)
'ワークシートを指定する
Set ws1 = wb1.Sheets("Sheet1")
Set ws2 = wb2.Sheets("Sheet1")
'最終行の取得
lastRow = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row
For i=1 To lastRow
For j=1 To 13 'M列まで繰り返す
ws2.Cells(i, j).Value = ws1.Cells(i, j).Value 'ファイル1のワークシートのM列までのセルをファイル2のワークシートにコピーする
Next j
Next i
wb2.Save
wb1.Close SaveChanges:=False '保存せずにファイルを閉じる
wb2.Close SaveChanges:=True '保存したらファイルを閉じる
MsgBox "データのコピーが完了しました"
Exit Sub
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
ErrorHandler:
MsgBox "Error" & Err.number & ":" & Err.description
End Sub
補足
-
Sub, End Sub
: プロシージャー名(いわゆるマクロの名前)のことで、複数の処理を一つにまとめたものです。プロシージャー名に始まりEndを付けたSubで終わります -
Dim
: 変数宣言をします。As
を使うことでデータ型を指定することができます -
Application.Calculation
: 数式の計算モードを設定するプロパティです。xlCalculationManual
で手動計算、xlCalculationAutomatic
で自動計算に変更します -
Application.ScreenUpdating
: マクロ実行時に描画を停止・開始する機能です -
GetOpenFilename
: [ファイルを開く] ダイアログボックスを表示させます。引数にダイアログの名前、ファイルの種類(.xlsx)などを指定することができます -
Set
: オブジェクトへの参照を変数に代入します。オブジェクトの参照とは、あるオブジェクトのメモリ上の場所を示すような「住所」です -
With, End With
: 単一のオブジェクトに対して、一連の処理を実行することができます。Withステートメントを記述することにより、コードが簡潔になります -
For Next
: 繰り返し処理(ループ処理)を実行するVBA構文です。変数が開始数値から終了数値になるまで繰り返します
おまけ
VBAのデバッグ方法の例
-
イミディエイトウインドウに値を出力
-
ブレークポイント
おわりに
慣れないVBAの投稿だったため拙い文章になりましたが、最後まで読んで頂きありがとうございました。