VBAでプログレスバーを使う

Visual Basic for Applications (VBA)

処理がどれぐらい進んでいるかを、使っているユーザーに伝える「プログロレスバー」コントロール。なにも表示がない画面だとフリーズしたかも?っていうの心配でてきますが、画面が動くことで心理的な安心感も与えてくれます。ただこの「プログレスバー」コントールはVBAの標準コントロールでは提供されていません。

使えるようにするには、手動で「プログレスバー」コントロールを追加する必要があります。手動で追加するのが手間な場合や標準コントロール以外は使いたくない時などは、「フレーム」コントロールと「ラベル」コントロールで比較的簡単に「プログレスバー」コントロールもどきを自作できます。

ここでは、手動で「プログレスバー」コントロールを追加する方法と、「フレーム」コントロールと「ラベル」コントロールで作成する方法を説明します。

手動でプログレスバーコントロールを追加する

プログレスバーコントロールは、MSCOMCTL.OCXを利用することになります。これを利用するには下記の操作を行うことで簡単に追加することができます。

一般的なWindowsではMSCOMCTL.OCXは入っていますが、macOSなどWindowsではないOSではこのMSCOMCTL.OCXは存在しません。

もしこのMSCOMCTL.OCXが入っていないWindowsや、macOSでこの「プログレスバー」コントロールを使ってるVBAを実行しようとするとエラーとなって実行することができませんのでご注意下さい。

  1. VBAのフォームエディタ上に表示される「ツールボックス」上で右クリックして、表示されるポップアップメニューからその他のコントロール(A)…をクリックします。
    ツールボックス上で右クリックして、「その他のコントロール」をクリックする

  2. 表示される「コントロールの追加」ダイアログの、利用可能なコントロールリストを下にスクロールした中程にあるMicrosoft ProgressBar Control, version 6.0にチェックを入れます。チェックを入れたら、OKボタンをクリックします。
    「Microsoft PgoressBar Control, version6.0」にチェックを入れる

  3. すると「ツールボックス」にプログレスバーコントロールが追加され、標準のコントロールと同じように使うことができるようになります。
    プログレスバーコントロールが追加された

フレームとラベルを使って作成する

「プログレスバー」コントロールはMSCOMCTL.OCXというOCXに依存するため、このMSCOMCTL.OCXが入っていないWindowsやmaOSでは利用できません。

だけど「プログレスバー」コントロールのように進捗を表示したい場合に、標準のコントロールである「フレーム」コントロールと「ラベル」コントロールで、同等な表示が可能なコントロールを作ることができます。ここではその作り方を説明します。

  1. VBAでユーザーフォームを作成し、その中に「フレーム」コントロールを配置します。
    フレームコントロールをフォームに配置する

  2. この「フレームコントロール」が「プログレスバー」の枠になります。枠にはテキストは不要なのでCaptionプロパティの文字列を削除しておきます。また高さHeightの値は後ほど使うので覚えておきます。
    フレームコントロールの設定

  3. 次に、「ラベル」コントロールを「フレーム」コントロールの中に配置します。
    ラベルをフレームコントロール上に配置する

  4. この「ラベル」コントロールが進捗状況を表すことになります。Captionプロパティの文字列を空にしておき、ラベルの位置を指定するLeftプロパティ、Topプロパティも0にしておきます。
    ラベルコントロールの設定

  5. 「ラベル」コントロールの高さであるHeightプロパティに、「フレーム」コントロールと同じ値を入力します。
    ラベルコントロールの高さを指定する

  6. 進捗表示のバーの色を、「ラベル」コントロールのBackColorプロパティで設定します。
    進捗表示の色を指定する

  7. 「フレーム」コントロールと「ラベル」コントロールの自作「プログレスバー」の進捗は、「ラベル」の幅で実現します。計算式はLabel1.Width = (Frame1.Width / [進捗最大値]) * [進捗値]のようになります。
    フレームとラベルのプログレスバー詳細

  8. 簡単なサンプルコードを載せておきます。動きとしては進捗を最大200として、1秒間待って5%(10)ずつ進めていき、最大の200まで進むとメッセージを表示しています。

    Private Sub Progress()
    
    Const MAX_VALUE As Long = 200   ' 進捗の最大値
    Me.Label1.Caption = ""
    me.Label1.Width = 0
    
    Dim i As Long
    For i = 0 To MAX_VALUE Step 10
        Application.Wait Now() + TimeValue("00:00:01")  ’ 1秒間待機する
        Me.Label1.Width = (Me.Frame1.Width / MAX_VALUE) * i ' バーを進める
        DoEvents    ' 再描画
    Next i
    Me.Label1.Caption = "完了"  ' 完了表示
    
    End Sub