0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VBAで進捗状況を可視化! ステータスバーで処理の進み具合を表示する方法【コピペで使える】

Posted at

目次

  1. はじめに
  2. ステータスバーを使った進捗表示の基本
  3. プログレスバーを実装する
  4. 実際の使用例
  5. コード全体の解説
  6. 動作を確認する際の注意点
  7. まとめ

はじめに

大量のデータを処理するマクロを実行していると、「今どのくらい進んでいるのか」が分からず不安になることがあります。この記事では、Excelのステータスバーに進捗率とプログレスバー(視覚的なバー表示)を表示する方法を紹介します。

ステータスバーを使った進捗表示の基本

Excelの画面下部にあるステータスバーには、Application.StatusBarプロパティを使って任意のメッセージを表示できます。処理中に進捗状況を表示すれば、ユーザーに安心感を与えられます。

Application.StatusBar = "処理中です..."
' 何か処理を実行
Application.StatusBar = False  ' 元に戻す

Application.StatusBar = Falseとすると、ステータスバーが通常の状態に戻ります。マクロ終了時には必ずこの処理を入れるのがおすすめです。

プログレスバーを実装する

進捗率だけでなく、視覚的なバー表示があるとより分かりやすくなります。ここでは「□」と「■」の文字を組み合わせて、簡易的なプログレスバーを作成します。

【プログレスバー生成の仕組み】

プログレスバーは、進捗率に応じて「■」(塗りつぶし部分)と「□」(未完了部分)の数を計算して文字列を作ります。

Function GetProgressBar(ByVal percent As Long) As String
    Dim barLength As Long: barLength = 10  ' バーの長さ
    Dim filledCount As Long: filledCount = percent \ 10  ' 塗りつぶす数
    
    GetProgressBar = String(filledCount, "■") _
        & String(barLength - filledCount, "□")
End Function

String関数を使うと、指定した文字を指定回数繰り返した文字列を作れます。例えば、進捗率が30%なら、30 \ 10で3となり、「■■■□□□□□□□」という表示になります。

【進捗表示のプロシージャ】

進捗情報をステータスバーに表示する専用のプロシージャを作成すると、メインの処理から呼び出しやすくなります。

Sub ShowProgress(ByVal percent As Long)
    Application.StatusBar = "チェック中" _
                            & "(" & percent & "%)" _
                            & GetProgressBar(percent)
End Sub

シンプルな構成にすることで、処理速度への影響を最小限に抑えています。

実際の使用例

データチェックなど繰り返し処理を行う際に、この進捗表示を組み込んでみます。ここでは、ダミーデータを自動生成してチェックするサンプルを用意しました。

Const START_ROW As Long = 2  ' データ開始行

Sub CheckData()
    Dim lastRow As Long
    Dim totalCount As Long
    Dim currentCount As Long: currentCount = 0
    Dim percent As Long
    Dim prevPercent As Long: prevPercent = -1
    Dim i As Long
    
    Application.ScreenUpdating = False
    
    ' 初期化処理
    Call InitializeVariables(lastRow, totalCount, START_ROW)
    
    ' 繰り返し処理
    For i = START_ROW To lastRow
        ' メイン処理を呼び出し
        Call ExecuteMainProcess(i)
        
        ' 進捗更新
        currentCount = currentCount + 1
        percent = (((currentCount * 100) / totalCount) \ 10) * 10
        If percent <> prevPercent Then
            Call ShowProgress(percent)
            prevPercent = percent
        End If
    Next i
    
    MsgBox "チェックが完了しました。", vbInformation, "完了"
    
    Application.StatusBar = False
    Application.ScreenUpdating = True
End Sub

このコードは、InitializeVariablesで変数を初期化し、ExecuteMainProcessでメイン処理を実行する構造になっています。実際の業務で使う際は、これらのプロシージャの中身を書き換えるだけで対応できます。

【変数初期化プロシージャ】

変数の初期化を専用のプロシージャにまとめることで、データ範囲の取得方法を変更したい場合でも、ここだけを修正すれば済みます。

Sub InitializeVariables(ByRef lastRow As Long, ByRef totalCount As Long, _
                        ByVal startRow As Long)
    ' ダミーデータを作成(実際の業務では不要)
    Call CreateDummyData
    
    ' 最終行を取得
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row
    
    ' 総件数を計算
    totalCount = lastRow - startRow + 1
End Sub

ByRefを使うことで、呼び出し元の変数に値を返せます。実際の業務で使う場合は、CreateDummyDataの行を削除するだけで、既存のデータに対して処理を実行できます。

【メイン処理プロシージャ】

実際のチェック処理を行う部分です。ここでは、デモ用に簡単な処理を入れていますが、実務では書き換えてご使用ください。

Sub ExecuteMainProcess(ByVal rowNumber As Long)

    Dim value As Long: value = Cells(rowNumber, 1).Value
    
    If value Mod 2 = 0 Then
        Cells(rowNumber, 2).Value = "偶数"
    Else
        Cells(rowNumber, 2).Value = "奇数"
    End If
    
    ' 処理時間をシミュレート(実際の業務では不要)
    Application.Wait Now + TimeValue("00:00:01")
End Sub

このサンプルでは、A列の値が偶数か奇数かを判定してB列に出力しています。Application.Waitは処理を一時停止する命令で、進捗表示の動きを確認しやすくするために入れています。

【ダミーデータ作成プロシージャ】

デモをすぐに実行できるよう、ダミーデータを自動生成するプロシージャも用意しました。

Sub CreateDummyData()
    Const DATA_COUNT As Long = 50  ' 生成するデータ件数
    Dim i As Long
    
    ' シートをクリア
    Cells.Clear
    
    ' ヘッダー作成
    Cells(1, 1).Value = "データ"
    Cells(1, 2).Value = "判定結果"
    
    ' ダミーデータ生成
    For i = 2 To DATA_COUNT + 1
        Cells(i, 1).Value = Int(Rnd() * 100) + 1  ' 1~100の乱数
    Next i
End Sub

Rnd()関数は0以上1未満の乱数を生成します。それに100を掛けて整数化することで、1~100の範囲の数値を作成しています。

コード全体の解説

【プロシージャ分割のメリット】

コードを複数のプロシージャに分割することで、以下のようなメリットがあります。

  • 保守性の向上 - 修正箇所が明確になり、変更が容易になります
  • 再利用性 - 各プロシージャを他の処理でも使い回せます
  • テストのしやすさ - 個別のプロシージャ単位で動作確認ができます

特に、CheckDataというメインプロシージャは進捗管理の枠組みだけを提供し、実際の処理内容はExecuteMainProcessに委譲する設計になっているため、業務内容が変わってもCheckData自体を修正する必要がありません。

【進捗率の計算と更新タイミング】

進捗率を計算する部分には工夫が施されています。

percent = (((currentCount * 100) / totalCount) \ 10) * 10
If percent <> prevPercent Then
    Call ShowProgress(percent)
    prevPercent = percent
End If

まず、(((currentCount * 100) / totalCount) \ 10) * 10という計算で、パーセンテージを10%単位に切り捨てています。例えば、進捗が34%でも39%でも、30%として扱われます。

そして、prevPercentという変数で前回の進捗率を記憶しておき、値が変わったときだけステータスバーを更新する仕組みになっています。これにより、無駄な更新処理を省いて、処理速度を向上させています。

【ByRefとByValの使い分け】

プロシージャ間で値を受け渡す際、ByRefByValを使い分けることが重要です。

  • ByRef - 参照渡し。呼び出し元の変数自体を渡すため、値を変更できます
  • ByVal - 値渡し。値のコピーを渡すため、呼び出し元の変数は変わりません

InitializeVariablesでは、計算結果を呼び出し元に返したいのでByRefを使い、ExecuteMainProcessでは行番号を受け取るだけなのでByValを使っています。

【ScreenUpdatingの制御】

Application.ScreenUpdating = Falseを最初に設定することで、画面の更新を停止して処理速度を向上させています。ただし、ステータスバーは画面更新が停止していても表示されるため、進捗表示には影響しません。

処理が完了したら、必ずApplication.ScreenUpdating = Trueで画面更新を再開することを忘れないようにしてください。

【完了時の通知】

処理が完了したら、MsgBoxでメッセージを表示してユーザーに通知しています。ステータスバーだけでは気づかない場合もあるため、明示的な通知があると親切です。

MsgBox "チェックが完了しました。", vbInformation, "完了"

vbInformationを指定することで、情報アイコン付きのメッセージボックスが表示されます。

動作を確認する際の注意点

【すぐに試せる構成】

このサンプルコードは、そのままコピーして実行するだけで動作します。CreateDummyDataが自動的にA列にデータを生成し、ExecuteMainProcessがそれを処理してB列に結果を出力します。

実際の業務で使う場合は、以下の2箇所を修正するだけです。

  1. InitializeVariablesからCreateDummyDataの呼び出しを削除
  2. ExecuteMainProcessの中身を実際のチェック処理に書き換える

【処理速度の調整】

サンプルコードでは、進捗表示を確認しやすくするためにApplication.Waitで1秒の待機時間を入れています。

Application.Wait Now + TimeValue("00:00:01")

実際の業務では、この行は不要なので削除してください。また、DATA_COUNTの値を変更することで、生成されるダミーデータの件数を調整できます。件数を増やすと、より長時間の動作を確認できます。

【10%単位の更新について】

進捗率を10%単位で更新する設計になっているため、データ件数が少ない場合、進捗表示が飛び飛びに見えることがあります。例えば、データが5件しかない場合、0%→20%→40%→60%→80%→100%のように表示されます。

より細かい単位で表示したい場合は、計算式を調整してください。

' 5%単位にする場合
percent = (((currentCount * 100) / totalCount) \ 5) * 5

ただし、更新頻度を上げすぎると処理速度に影響が出る可能性があるため、バランスを考えて調整することが大切です。

定数の活用
START_ROWを定数として宣言することで、データの開始行が変わった場合でも、1箇所を修正するだけで対応できます。このように、変更される可能性のある値は定数化しておくと便利です。

まとめ

ステータスバーに進捗率とプログレスバーを表示することで、長時間かかる処理でもユーザーに安心感を与えられます。プロシージャを適切に分割し、進捗更新のタイミングを工夫することで、保守性が高く実用的なコードになります。

0
0
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?