【VBA】DoEventsステートメント完全攻略!応答なし対策の5つの秘訣
VBAで大量データを処理していると「応答なし」でExcelが固まってしまった。。。長時間編集したのに強制終了しなければならない。。。マジ最悪。。。
こんな経験をしたことありませんか?
こんな問題はDoEventsステートメントの活用で解決することができます。
DoEventsはVBAの処理を中断させることができるコードです。
本記事では、DoEventsの正しい使い方から「応答なし」対策の実践テクニックまで徹底解説します。
「処理が重くて困っている」「ユーザーにキャンセル機能を提供したい」「パフォーマンスを落とさずに応答性を保ちたい」
こんな悩みを抱えている方は是非本記事を参考にしてみてください。
VBA DoEventsステートメントとは?基本概念を徹底解説
DoEventsステートメントは、VBAでアプリケーションの応答性を保つために欠かせない重要な機能です。
このステートメントを使うことで、
長時間の処理中もExcelが固まることなく、ユーザーの操作を受け付けることができる
ようになります。
特に大量のデータを扱う処理やループ処理では、必ずDoEventsを導入しましょう。
DoEventsの役割と動作原理
DoEventsの最大の役割は、
VBAの処理実行中にWindowsのメッセージキューを処理すること
です。
通常、VBAのコードが実行されている間は他の操作が一切受け付けられませんが、
DoEventsを呼び出すことで、一時的にVBAの処理を中断してWindowsに制御を渡し、マウスクリックやキーボード入力などのユーザー操作を処理できる
ようになります。
この仕組みにより、長時間の処理中でも画面が応答なしになることを防げるのです。
DoEventsを使った基本的なサンプルコードがこちら
Sub SampleDoEvents()
Dim i As Long
For i = 1 To 100000
DoEvents ' Windowsに制御を渡す
Cells(i, 1).Value = i
Next i
End Sub
上記のコードは
A1セルからA100000セルに繰り返し数値を入力する。繰り返し処理中でも他の処理ができる
という内容です。
For~Nextの中にDoEventsを記述することで繰り返し処理実行中でも、「処理を中断させる」「エクセルを閉じる」などの操作ができるようになります。
関連記事「For Eachの使い方」では、オブジェクトや配列を繰り返し処理する方法を紹介されています。
DoEventsが必要になる3つのケース
DoEventsが必要になる主なケースは3つあります。
- 大量のデータを処理する
- ファイル操作を繰り返す処理
- ユーザーフォームでキャンセル機能を実行する
何万行ものデータを扱うループ処理では、DoEventsがないとExcelが「応答なし」になる可能性があります。
次に、ファイル操作を繰り返す処理では、DoEventsを配置することで複数のExcelファイルを開いて処理する際に、他の作業も並行して行えます。
ユーザーフォームでキャンセル機能を実装する場合、処理中にユーザーがキャンセルボタンを押せるようにするためにDoEventsが必須となります。
ファイル操作VBAにDoEventsを導入したサンプルコードがこちら
Sub FileProcessing()
Dim i As Integer
For i = 1 To 50
DoEvents ' ユーザー操作を受け付ける
Workbooks.Open "C:\Data\File" & i & ".xlsx"
' ファイル処理
ActiveWorkbook.Close SaveChanges:=False
Next i
End Sub
上記のコードは、
ブックを開く→適当な処理をする→保存して閉じるを50回繰り返す
という内容です。
「ブックを開く」「保存して閉じる」操作には処理時間がかかります。
DoEventsがあれば処理中に他の操作ができるのでとても便利です。
関連記事「複数のエクセルファイルを操作するVBA」では、ファイルを開く・編集する・閉じる方法が紹介されています。
DoEventsを使わない場合の問題点
DoEventsを使わないと、Excelが「応答なし」になることです。
ユーザーは処理が終わるまで何もできず、場合によってはタスクマネージャーで強制終了せざるを得なくなります。
また、処理の進捗が分からないため、「どれくらい時間がかかるのだろう。。。」「もしかしてフリーズしてる?」と不安になりますよね。
さらに、処理を途中でキャンセルしたくても、DoEventsがないとキャンセルボタンが反応しません。
これらの問題を解決するために、DoEventsの適切な配置が重要なのです。
DoEventsステートメントの基本的な書き方と使い方
DoEventsステートメントの基本的な使い方は非常にシンプルで、処理の適切な箇所に「DoEvents」と記述するだけです。
どこに配置するか、どのような間隔で配置するかによって、応答性が大きく変わるので注意してください。
正しい使い方をマスターすることで、大量のデータを処理するマクロを安心して作成できるようになります。
基本構文とサンプルコード
DoEventsの基本構文は「DoEvents」の一言だけ。
引数も戻り値も特に意識する必要がない、最もシンプルなステートメントの一つです。
一般的には、ループ処理の中に配置して使用します。
ループ処理の中にDoEventsを配置したサンプルコードがこちら
Sub BasicDoEventsExample()
Dim i As Long
' 基本的なDoEventsの使用例
For i = 1 To 10000
DoEvents ' 基本構文
Cells(i, 1).Value = "データ" & i
Cells(i, 2).Value = i * 100
Next i
MsgBox "処理が完了しました"
End Sub
上記のコードは、
1から10000までの数値をセルに入力する
という内容です。
For文のすぐ下にDoEventsを記述しましょう。
ループ処理での正しい配置方法
ループ処理でDoEventsを配置する際は、パフォーマンスと応答性のバランスを考慮することが重要です。
毎回のループでDoEventsを呼び出すと処理が遅くなる可能性があるため、適切な間隔で配置する必要があります。
一般的には、100回から1000回に1回程度の頻度が推奨されます。
100回に1回DoEventsを実行するサンプルコードがこちら
Sub OptimizedDoEvents()
Dim i As Long
For i = 1 To 100000
' 100回に1回DoEventsを実行
If i Mod 100 = 0 Then
DoEvents
Application.StatusBar = "処理中..." & Format(i / 100000, "0%")
End If
Cells(i, 1).Value = i
Cells(i, 2).Value = i ^ 2
Next i
Application.StatusBar = False
End Sub
上記のコードは、
1から10000までの数値をセルに入力する。100回に1回の頻度でDoEventsを実行し進捗状況をステータスバーに表示する
という内容です。
この方法により、処理速度を保ちながら応答性も確保できます。
DoEventsの戻り値と活用法
DoEventsは戻り値として整数値を返しますが、通常のVBA開発では戻り値を使用することはほとんどありません。
戻り値は主にWindows APIとの連携で使用される高度な機能です。
一般的なExcel VBAの開発では、DoEventsを単独で使用し、戻り値は無視して構いません。
重要なのは、
DoEventsがWindowsのメッセージを処理して、アプリケーションの応答性を保つことを理解しておくこと
です。
以下のコードは、戻り値を取得する例ですが、実際の開発では単純に「DoEvents」と記述するだけで十分です。
Sub DoEventsReturnValue()
Dim i As Long
Dim result As Integer
For i = 1 To 5000
' 戻り値を取得(通常は使用しない)
result = DoEvents
Cells(i, 1).Value = "行" & i
' 一般的な使用方法(戻り値を無視)
DoEvents
Next i
End Sub
上記のコードを実際のエクセル業務に応用させることはないと思いますが、DoEventsの特徴を理解するためにコピペしてコードを動かしてみてください。
応答なし対策の5つの秘訣【実践編】
DoEventsを効果的に活用するには、単に配置するだけでなく、戦略的なアプローチが必要です。
ここからは、
DoEventsをより効果的に活用できる5つの秘訣
をご紹介します。
これらのテクニックを組み合わせることで、応答なしの問題を完全に解決し、安全なマクロの作成が可能です。
各秘訣には具体的なサンプルコードを掲載しているのでコピペして活用してください。
秘訣1:適切な配置間隔で処理速度を最適化
処理速度を最適化するには、DoEventsの配置間隔を慎重に決める必要があります。
頻繁すぎるとパフォーマンスが低下し、少なすぎると応答性が悪くなります。
最適な間隔は処理内容によって異なりますが、一般的には50回から200回に1回が効果的です。
条件によってDoEventsを実行するサンプルコードがこちら
Sub OptimalInterval()
Dim i As Long
Dim processType As String
processType = "heavy" ' "light" または "heavy"
For i = 1 To 50000
' 処理の重さに応じて間隔を調整
If processType = "light" And i Mod 200 = 0 Then
DoEvents
ElseIf processType = "heavy" And i Mod 50 = 0 Then
DoEvents
End If
' メイン処理
Cells(i, 1).Value = WorksheetFunction.Sum(Range("A1:A" & i))
Next i
End Sub
上記のコードは、
処理の重さに応じて間隔を調整する。軽い処理では200回に1回、重い処理では50回に1回DoEventsを実行する
という内容です。
秘訣2:GetInputState関数との組み合わせテクニック
GetInputState関数とDoEventsを組み合わせることで、必要な時だけWindowsに制御を渡すことができます。
この方法により、無駄なDoEvents呼び出しを避けて処理速度を向上させつつ、ユーザー操作があった時は確実に応答させることが可能です。
GetInputState関数は、マウスやキーボードの入力待ちがあるかどうかを判定するWindows API関数です。
入力待ちがある場合のみDoEventsを実行することで、効率的な処理を実現できます。
GetInputState関数とDoEventsを組み合わせたサンプルコードがこちら
Private Declare PtrSafe Function GetInputState Lib "user32" () As Long
Sub SmartDoEvents()
Dim i As Long
For i = 1 To 100000
' 入力待ちがある場合のみDoEventsを実行
If GetInputState() <> 0 Then
DoEvents
End If
' メイン処理
Cells(i, 1).Value = "処理" & i
Cells(i, 2).Value = Now()
Next i
End Sub
上記のコードは
繰り返し処理中に条件分岐で、GetInputStateが検知するとDoEventsを実行する
という内容です。
秘訣3:ユーザーフォームでのキャンセル機能実装
ユーザーフォームにキャンセルボタンを配置する場合、DoEventsの活用は必須です。
DoEventsとグローバル変数を組み合わせることで、処理の途中でも確実にキャンセル操作を受け付けることができます。
DoEventsとグローバル変数を組み合わせせたサンプルコードがこちら
Public cancelFlag As Boolean
Sub ProcessWithCancel()
Dim i As Long
cancelFlag = False
' ユーザーフォームを表示(キャンセルボタン付き)
UserForm1.Show vbModeless
For i = 1 To 50000
DoEvents ' キャンセルボタンのクリックを検知
If cancelFlag Then
MsgBox "処理がキャンセルされました"
Exit Sub
End If
Cells(i, 1).Value = "データ" & i
UserForm1.Label1.Caption = "進捗: " & Format(i / 50000, "0%")
Next i
Unload UserForm1
MsgBox "処理が完了しました"
End Sub
' ユーザーフォームのキャンセルボタンイベント
Private Sub CommandButton1_Click()
cancelFlag = True
Unload Me
End Sub
上記のコードは、
フラグ変数を使用してキャンセル状態を管理し、DoEventsによってキャンセルボタンのクリックイベントを処理する
という内容です。
秘訣4:ステータスバー更新による進捗表示
ステータスバーに処理の進捗を表示することで、ユーザーは処理の状況を把握でき、安心して待つことができます。
ステータスバーを使用するときはDoEventsと組み合わせて定期的に更新させることで、より正確な進捗状況の表示が可能です。
進捗表示は100回から500回に1回程度の頻度で更新するのが適切とされています。
ステータスバーとDoEventsを組み合わせたサンプルコードがこちら
Sub ProcessWithStatusBar()
Dim i As Long
Dim startTime As Double
Dim totalCount As Long
totalCount = 30000
startTime = Timer
For i = 1 To totalCount
If i Mod 100 = 0 Then
DoEvents
' ステータスバー更新
Dim progress As Double
Dim elapsedTime As Double
Dim estimatedTime As Double
progress = i / totalCount
elapsedTime = Timer - startTime
estimatedTime = elapsedTime / progress
Application.StatusBar = "処理中 " & Format(progress, "0%") & _
" (残り約" & Format((estimatedTime - elapsedTime) / 60, "0") & "分)"
End If
' メイン処理
Cells(i, 1).Value = "レコード" & i
Next i
Application.StatusBar = False
End Sub
上記のコードでは、
パーセンテージと残り時間の推定値をステータスバーに表示する
という内容です。
秘訣5:条件分岐による無駄なDoEvents実行回避
処理の内容や状況に応じて、DoEventsの実行を制御することで、パフォーマンスを最大化できます。
たとえば、
ユーザーが他のアプリケーションを使用している時は頻繁にDoEventsを実行し、Excelがアクティブな時は実行頻度を下げる
といった制御が可能です。
また、処理の重要度に応じてDoEventsの実行を判断するという活用方法もおすすめです。
条件によってDoEventsの実行を制御するサンプルコードがこちら
Sub ConditionalDoEvents()
Dim i As Long
Dim isExcelActive As Boolean
Dim lastDoEventsTime As Double
For i = 1 To 80000
' 複数の条件でDoEventsの実行を制御
isExcelActive = (Application.WindowState <> xlMinimized)
' 条件1: 時間間隔による制御
If Timer - lastDoEventsTime > 0.1 Then ' 0.1秒間隔
DoEvents
lastDoEventsTime = Timer
' 条件2: 処理回数による制御
ElseIf i Mod 500 = 0 And isExcelActive Then
DoEvents
' 条件3: 重要な処理の前後
ElseIf i Mod 1000 = 0 Then
DoEvents
End If
' メイン処理
Range("A" & i).Value = i
Range("B" & i).Formula = "=A" & i & "*2"
Next i
End Sub
上記のコードは、
時間間隔で制御する、処理回数で制御する、条件分岐で制御する、複数の条件を組み合わせて制御する
という内容です。
業務内容に合わせて最適なコードをコピペして活用してください。
DoEventsステートメント実装例とコードサンプル集
実際のビジネスシーンでDoEventsを活用する具体的な実装例をご紹介します。
大容量データの処理、ファイル操作、Web API通信など、あなたが処理している業務内容と照らし合わせながら参考にしてみてください。
実際のエクセル業務にそのまま使用できるよう、エラーハンドリングや最適化も考慮してサンプルコードを作成されています。
大容量データ処理での実装例
大容量データを処理する際は、メモリ使用量とパフォーマンスの両方を考慮してDoEventsを配置する必要があります。
10万行を超えるデータを扱う場合、適切な間隔でDoEventsを実行しないとExcelが「応答なし」になってしまいます。
処理速度が遅くならずにDoEventsを活用したサンプルコードがこちら
Sub ProcessLargeData()
Dim i As Long, j As Long
Dim dataArray As Variant
Dim resultArray As Variant
Dim totalRows As Long
Dim startTime As Double
totalRows = 100000
startTime = Timer
' 配列でデータを読み込み(高速化)
ReDim dataArray(1 To totalRows, 1 To 5)
ReDim resultArray(1 To totalRows, 1 To 3)
For i = 1 To totalRows
' 1000行ごとにDoEventsとメモリ管理
If i Mod 1000 = 0 Then
DoEvents
Application.StatusBar = "データ処理中: " & _
Format(i / totalRows, "0%") & " (" & i & "/" & totalRows & ")"
' 定期的にメモリを最適化
If i Mod 10000 = 0 Then
DoEvents
Application.CalculateFullRebuild
End If
End If
' データ処理のメインロジック
For j = 1 To 5
dataArray(i, j) = "データ" & i & "-" & j
Next j
' 計算処理
resultArray(i, 1) = i
resultArray(i, 2) = i * 1.1
resultArray(i, 3) = WorksheetFunction.Round(i * 0.95, 2)
Next i
' 結果を一括でワークシートに出力
Range("A1").Resize(totalRows, 3).Value = resultArray
Application.StatusBar = False
MsgBox "処理完了: " & Format(Timer - startTime, "0.0") & "秒"
End Sub
上記のコードは、
大量のデータを効率的に処理しながら、定期的にメモリを解放し、進捗状況をユーザーに知らせる。また、配列を使用して処理速度が遅くならないようにする
という内容です。
関連記事「配列の使い方」では、セルの値を配列に格納する、配列に格納した値をセルに出力する方法が紹介されています。
ファイル操作時のフリーズ防止コード
複数のExcelファイルを開いて処理する場合、ファイルの読み込みや保存に時間がかかるため、DoEventsによる応答性の確保が特に重要になります。
また、ファイルが見つからない場合やアクセス権限の問題など、エラーハンドリングも組み合わておきましょう。
ファイル操作VBAとDoEventsを組み合わせたサンプルコードがこちら
Sub ProcessMultipleFiles()
Dim folderPath As String
Dim fileName As String
Dim wb As Workbook
Dim processedCount As Integer
Dim errorCount As Integer
Dim startTime As Double
folderPath = "C:\Data\"
fileName = Dir(folderPath & "*.xlsx")
startTime = Timer
processedCount = 0
errorCount = 0
Do While fileName <> ""
DoEvents ' ファイル処理の前にユーザー操作を受付
On Error GoTo ErrorHandler
' ファイルを開く
Application.StatusBar = "処理中: " & fileName
Set wb = Workbooks.Open(folderPath & fileName, ReadOnly:=False)
DoEvents ' ファイルオープン後の操作を受付
' ファイル内のデータ処理
With wb.Worksheets(1)
Dim lastRow As Long
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
Dim i As Long
For i = 2 To lastRow
If i Mod 100 = 0 Then DoEvents ' 大量データでも応答性確保
' データ加工処理
.Cells(i, 5).Value = .Cells(i, 2).Value * 1.08 ' 税込価格計算
.Cells(i, 6).Value = Now() ' 処理日時
Next i
End With
DoEvents ' 保存前の操作を受付
' ファイルを保存して閉じる
wb.Save
wb.Close SaveChanges:=True
processedCount = processedCount + 1
GoTo NextFile
ErrorHandler:
errorCount = errorCount + 1
If Not wb Is Nothing Then
wb.Close SaveChanges:=False
Set wb = Nothing
End If
Resume NextFile
NextFile:
fileName = Dir() ' 次のファイルを取得
DoEvents ' 次のファイル処理前に操作を受付
Loop
Application.StatusBar = False
MsgBox "処理完了" & vbCrLf & _
"成功: " & processedCount & "ファイル" & vbCrLf & _
"エラー: " & errorCount & "ファイル" & vbCrLf & _
"処理時間: " & Format(Timer - startTime, "0.0") & "秒"
End Sub
上記のコードは、
ファイル操作でよく発生するエラーを防止しながら、指定フォルダ内の全Excelファイルを処理する。
という内容です。
関連記事「エラーを無視するVBAの注意点」では、Resume Nextを安全に使うテクニックが紹介されています。
Web API通信での応答待ち処理
Web APIとの通信では、ネットワークの状況によって応答時間が大きく変わるため、DoEventsを使用した適切な待機処理が必要です。
タイムアウト機能と組み合わせることで、安定したAPI通信を実現できます。
Web API通信VBAにDoEventsを導入したサンプルコードがこちら
Sub WebAPIProcessing()
Dim http As Object
Dim apiUrl As String
Dim response As String
Dim i As Long
Dim apiCount As Long
Dim timeoutSeconds As Long
Dim startTime As Double
Dim cancelRequested As Boolean
Set http = CreateObject("MSXML2.XMLHTTP")
apiCount = 50
timeoutSeconds = 30
cancelRequested = False
For i = 1 To apiCount
DoEvents ' API呼び出し前のユーザー操作受付
' キャンセルチェック(ユーザーフォームや変数で制御)
If cancelRequested Then
MsgBox "処理がキャンセルされました"
Exit Sub
End If
apiUrl = "https://api.example.com/data/" & i
startTime = Timer
' API呼び出し
http.Open "GET", apiUrl, False
http.setRequestHeader "Content-Type", "application/json"
Application.StatusBar = "API通信中... (" & i & "/" & apiCount & ")"
On Error GoTo APIError
http.send
' レスポンス待ち(タイムアウト付き)
Do While http.readyState <> 4
DoEvents ' 通信待ち中もユーザー操作を受付
If Timer - startTime > timeoutSeconds Then
MsgBox "API " & i & " がタイムアウトしました"
GoTo NextAPI
End If
Application.Wait Now + TimeValue("00:00:01") ' 1秒待機
Loop
' レスポンス処理
If http.Status = 200 Then
response = http.responseText
' JSONパース処理(省略)
Cells(i, 1).Value = "API " & i
Cells(i, 2).Value = "成功"
Cells(i, 3).Value = Now()
Else
Cells(i, 1).Value = "API " & i
Cells(i, 2).Value = "エラー: " & http.Status
Cells(i, 3).Value = Now()
End If
DoEvents ' API処理完了後の操作受付
GoTo NextAPI
APIError:
Cells(i, 1).Value = "API " & i
Cells(i, 2).Value = "通信エラー"
Cells(i, 3).Value = Now()
NextAPI:
' 次のAPI呼び出しまで少し待機
Application.Wait Now + TimeValue("00:00:02")
DoEvents
Next i
Application.StatusBar = False
MsgBox "Web API処理が完了しました"
End Sub
上記のコードは、
XMLHttpRequestを使用してWeb APIと通信しながら、DoEventsでユーザー操作を受け付ける
という内容です。
通信中もExcelが固まることなく、途中でキャンセルすることもできます。
VBA初心者が効率化マクロを導入する方法
VBAなんて扱ったことないけど、処理が途中で止まらない効率化マクロを導入したい!
こんな問題を解決する方法がこちら
- マクロの開発を外注に依頼する
- マクロが設定されたエクセルファイルをダウンロードする
- 参考書やネットでVBAスキルを身に付ける
VBAスキルを身に着ける前は、「マクロ開発の外注」で対応していましたが、
今では自分で効率化マクロをサクッと導入しちゃいます。
完成されたマクロを使ってエクセル業務を処理する
↓
作業効率が2倍以上アップ!!
↓
便利すぎて自分でもマクロを設定したいと考え始める
↓
参考書やネットの情報でVBAスキルを身に付ける
↓
マクロ開発を代行できる程のスキルを習得
VBAは
他のプログラミングに比べて参考書やネットで紹介されている情報量が多いので初心者でも導入しやすい
という特徴があります。
外注した方が楽だけど、費用がかかる。自分で導入すれば費用は0円だけど時間がかかる。。
いずれにせよ、効率化マクロを導入できれば作業効率が飛躍的にアップするのは間違いありません。
あなたに合った方法で導入しちゃいましょう。
マクロ開発を外注に依頼する
マクロ開発を外注に依頼する方法は
VBAを全く扱えない方でもエクセル作業を自動化できる最も簡単な方法
です。
「こんなデータ抽出作業を自動化したい」「作った資料を自動的にPDFで保存したい」「決まった様式に写真を自動で貼り付けたい」
こんな感じで実現したい内容を依頼するだけで業務内容に合ったマクロを開発してくれます。

ガッツポーズの人
デメリットは、費用がかかることだけ。
開発内容、依頼先によってかかる費用は大きく異なります。
私が会社員の頃利用していた業者さんは1マクロあたり2万円~3万円の費用がかかりました。

疑問がある人
ちなみに、マメBlogでもエクセルマクロ開発代行サービスを承っています。
開発内容の確認、VBAコードの設定、動作確認後の調整、など全ての工程を私(マメ父ちゃん)が行っているので、
費用が安い!スピード納期!!
でやらせてもらっています。
ほとんど独学で身に付けたVBAスキルなので、内容によっては開発できないこともあるのでご了承ください。
ご相談、見積もり依頼は完全無料ですので気になる方は下記のリンクよりお問合せ下さい。
マクロが設定されたエクセルファイルをダウンロードする
VBA初心者でも『マクロが設定されたエクセルファイルをダウンロード』することで、
すぐに使っているエクセルにマクロを導入することができます。
VBA初心者でも形になっているマクロをゲットできる、費用が安い、
というメリットがあります。
しかし、
想定するマクロを見つけることが難しい、業務内容に合わせるためのアレンジが必要
というデメリットもあります。

ガッツポーズの人
個人ブログやファイルを販売できるサイト「note」や「Tips」ではいろんなマクロの情報が掲載されているので是非参考にしてみてください。
今までマメBlogで受注した効率化マクロを下記のnoteで掲載していますので併せてチェックしてみてください。
参考書やネットでVBAスキルを身に付ける
先程も紹介しましたが、
VBAは他のプログラミングに比べて参考書やネットで紹介されている情報量が多いので初心者でも導入しやすい
プログラミングです。
言い換えると、
情報量が豊富なので自分で勉強できちゃう
ということです。
私のVBAスキルはほとんど独学で身に付けたもので、
考えた処理のほとんどをVBAで表現できるレベルにまで到達した!
と思っています。
私の作ったマクロをプロのプログラマーが見れば、
お前の書くコードはインチキだ!「変数の宣言」とか「引数」を正しく使えよ!!
と感じるはずです。
でも、
私からすればどうでもいい!!!想定した内容を正しく処理できればよくないですか!?
独学であっても『写真を貼り付けるマクロ』『全てのシートをPDF出力するマクロ』『連番を振るマクロ』など、
業務内容に合ったマクロを開発できるようになれます。
独学でVBAスキルを身に付けるコツは、
エラーが発生してもいいからひたすらコードを書く、なんでもいいからエクセル作業をマクロ化してみる
です。
とは言っても、全くの知識0の方は何をすればいいかわからないですよね。
VBA知識0の初心者の方は、参考書『たった1秒で仕事が片づくExcel自動化の教科書【増強完全版】』を読んでみてください。
VBAの知識0の方でもすいすい読み進められる内容になっています。
やさしい内容にも関わらず「え!!VBAを使えばこんなことできるの!?」と感動すると思います。
実際に私はこの参考書を読んでからVBAの勉強を始めました。

ひらめく人
VBAの魅力を発見した後は、
ひたすら自動化したい内容のコードを書くだけ
です。
【VBA 固まる】【VBA 無限ループ解除】でネット検索すれば知りたいコードをすぐにゲットできます。
実現したい処理に向かって、「調べる→書いてみる→エラーを改善する→調べる」を繰り返していると
自然といろんなマクロが作れるようになっているはずです。
VBAに興味が湧いてきたという方は今からVBA学習をスタートさせちゃいましょう。