【ExcelVBA】処理の経過をバーで表示するプログラム(プログレスバー)

How to create a progress bar with ExcelVBA
目次

【ExcelVBA】処理の経過をバーで表示するプログラム(プログレスバー)

処理時間が長い時に、ユーザーがフリーズしたのか処理が長いだけなのかをわかってもらうための処理状況を表示するバーを表示するプログラムを紹介します。

作成の流れ

まずは全体の作成の流れです。

STEP
処理状況を表示するフォームを作成
STEP
処理状況を表示するクラスを作成
STEP
クラスをインスタス化して使用する

使いまわしができるようにクラスで作成します。

フォームの作成

まずは、処理状況を表示するためのフォームを作成をしていきましょう!

STEP
フォームの作成
STEP
フォームのオブジェクト名を「ProgressTimerForm」に変更
STEP
フォームオブジェクトのCaptainを「処理状況」に変更
STEP
バック用のラベルを配置してプロパティを変更
 オブジェクト名:lblBackground
 BackColor:&H80000000&
STEP
処理状況を表示するラベルを同じ場所に追加
 オブジェクト名:lblProgress
 BackColor:&H8000000D&

最初は、後で追加したlblProgressの幅を0にして、処理が進むごとにwidth(幅)を1,2,3と増やしていくことで、青のラベルの幅が広くなり処理が進んでいるように見えます。

クラスの作成

クラスの作成です。

STEP
クラスの作成
STEP
クラスのオブジェクト名を「ProgressTimer」に変更
STEP
クラスにコードを記載する
Option Explicit
'#######################################
'目的:処理時間をバー形式で表示する
'引数:なし
'戻り値:なし
'エラー処理:
'メモ:
'作成日 作成者 2024/4/15 合同会社縁紡ぐ 稲垣
'#######################################

'インスタンス変数
Private frmProgressProgress As ProgressTimerForm
Private lblBackground As MSForms.Label
Private lblProgress As MSForms.Label
Private maxStep As Long

Public Sub Class_Initialize()
    '#######################################
    '目的:コンストラクタ
    '引数:なし
    '戻り値:なし
    'エラー処理:
    'メモ:ProgressTimerFormを利用
    '作成日 作成者 2024/4/15 合同会社縁紡ぐ 稲垣
    '#######################################

    Set frmProgressProgress = ProgressTimerForm
    Set lblBackground = frmProgressProgress.lblBackground
    Set lblProgress = frmProgressProgress.lblProgress
    frmProgressProgress.StartUpPosition = 1  'Windowsの既定値
    lblProgress.Width = 0 ' 初期状態で進捗バーを幅0にする

End Sub
Property Let setMaxStep(maxSteps As Long)
    '#######################################
    '目的:インスタンス変数maxStepに値を代入
    '引数:整数
    '戻り値:なし
    'エラー処理:
    'メモ:
    '作成日 作成者 2024/4/15 合同会社縁紡ぐ 稲垣
    '#######################################

    maxStep = maxSteps
    
End Property
Public Sub updateProgress(step As Long)
    
    '#######################################
    '目的:現在処理しているステップ数を引数に進捗状況バーを更新する
    '引数:現在のステップを整数で
    '戻り値:なし
    'エラー処理:
    'メモ:
    '作成日 作成者 2024/4/15 合同会社縁紡ぐ 稲垣
    '#######################################
    
    If Not frmProgressProgress Is Nothing And Not lblProgress Is Nothing And Not lblBackground Is Nothing Then
        If maxStep < 10000 Then
                lblProgress.Width = (step / maxStep) * lblBackground.Width
                frmProgressProgress.Repaint '再描画
        Else
            If step Mod 100 = 0 Then
                lblProgress.Width = (step / maxStep) * lblBackground.Width
                frmProgressProgress.Repaint '再描画
            End If
        End If
    End If
    
End Sub
Public Sub show()
    '#######################################
    '目的:処理状況を描画するProgresssTimerFormを表示する
    '引数:なし
    '戻り値:なし
    'エラー処理:
    'メモ:
    '作成日 作成者 2024/4/15 合同会社縁紡ぐ 稲垣
    '#######################################
    
    If Not frmProgressProgress Is Nothing Then
        frmProgressProgress.show vbModeless
    End If
    
End Sub
Public Sub hide()
    '#######################################
    '目的:処理状況を描画するProgresssTimerFormの表示を終了する
    '引数:なし
    '戻り値:なし
    'エラー処理:
    'メモ:
    '作成日 作成者 2024/4/15 合同会社縁紡ぐ 稲垣
    '#######################################
    
    If Not frmProgressProgress Is Nothing Then
        frmProgressProgress.hide
    End If
    
End Sub

クラスをインスタンス化して使う方法

それでは、早速つくったクラスで処理バーを表示してみましょう!

Option Explicit

Sub TestProgressBar()
    
    'ProgressTimerの変数宣言とインスタンス作成
    Dim progressTimer As progressTimer
    Set progressTimer = New progressTimer

    '変数宣言
    Dim i As Long
    Dim maxSteps As Long
    
    maxSteps = 100000 ' 進捗の最大ステップ数を設定
    progressTimer.setMaxStep = maxSteps 'インスタンス変数に代入
    progressTimer.show 'フォームを表示

    '繰り返し処理
    For i = 1 To maxSteps
        ' 進捗を更新
            progressTimer.updateProgress i
    Next i
    
   '後処理
    progressTimer.hide 'フォームを閉じる
    Set progresstime = Nothing

End Sub

処理状況を表示することで処理が遅くなる💦

今回は、ExcelのVBAで処理状況を表示する方法をご紹介しました。ただし、この処理状況を表示することによって、かなり処理速度が遅くなります💦

描画を何度もやり直しているのが原因です。

100000回描画を更新した場合

10回に1回描画を更新した場合

全然スピードが変わりますね。

変更点は、updateProgressメソッドに再描画する条件をつけます。

Public Sub updateProgress(step As Long)
    
    '#######################################
    '目的:現在処理しているステップ数を引数に進捗状況バーを更新する
    '引数:現在のステップを整数で
    '戻り値:なし
    'エラー処理:
    'メモ:
    '作成日 作成者 2024/4/15 合同会社縁紡ぐ 稲垣
    '#######################################
    
    If Not frmProgressProgress Is Nothing And Not lblProgress Is Nothing And Not lblBackground Is Nothing Then
            If step Mod 10 = 0 Then
                lblProgress.Width = (step / maxStep) * lblBackground.Width
                frmProgressProgress.Repaint '再描画
            End If
    End If
    
End Sub

処理の最大数によって、条件をわけるのもありだと思います。適宜修正してもらったらと思います。

まとめ

今回は、処理の進捗状況を表示するバーを作成しました。が、あまりにも描画の更新数が多いと、処理がかなり遅くなるという欠点もわかりましたね!

大切なのは、ユーザーがExcelが固まったのか、ちゃんと動いるけど処理に時間がかかっているからまだ待たないといけないのか。これが、わかってもらうことです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次