今回は、Accessのフォームに、時間の掛かる処理の進捗状況を表示させるのに役立つ「プログレスバー」を自作して設置する方法を紹介します。
ActiveXコントロールのプログレスバーは使わない方がよい
AccessやExcelでは、フォーム内に設置するテキストボックスやラベルなどの標準的なコントロール以外に「ActiveXコントロール」と呼ばれる特殊なコントロールが有ります。
AccessやExcelなどで「プログレスバー」を使いたい場合に、標準的なコントロールにはその機能は存在しておらず、ActiveXコントロールに含まれている、「Microsoft ProgressBar Control」を使います。
ただ、ActiveXコントロールでは、例えば、インストールされたAccessのバージョンが異なる端末間で、ActiveXコントロールが使用されたフォームを動かそうとした場合、ActiveXコントロールのバージョンの違いなどに起因してエラーが出たり、正常に動作しなくなるケースがあります。
その為、異なるAccessやExcelのバージョン間の互換性を意識した場合は、ActiveXコントロールの使用は控えた方が良いとされています。
よって、今回の記事では、Accessの標準的なコントロールである「ラベルコントロール」を使用して、プログレスバーを自作する方法を紹介します。
プログレスバーをラベルで実装する概要説明
ラベルをプログレスバーに見立てて実装する際に、プログレスバーの背景用のラベルと、プログレスバーのメーター用のラベルをフォームに設置します。
プログレスバーでは、例えば処理対象のデータ件数の全行数といった、進捗状態が100パーセントの場合の値が必要になります。
VBAで背景用のラベルの幅を取得して、メーター用ラベルでは、背景用ラベルの幅に対して、100パーセント時の値を割り、その値をメーター用ラベルの最小単位の幅として指定します。
後は、ループ処理内で進捗状態を表す値をメーター用ラベルの最小単位の幅に掛け算して、進捗状態を加味したメーター用ラベルの幅を逐次広げていくという仕組みです。
文章ではわかり難いですが、実装は非常に簡単なので、実際に作ってみましょう。
自作プログレスバーの作り方
当項では、実際にフォームにプログレスバー用のラベルを設置して、VBAで処理を実装する一連の方法を紹介していきます。
フォームを作成してラベルを設置
まずは以下の様なフォームを作ります。
サンプル用のフォームなので、実行用のボタンとプログレスバー用のラベルを二つ設置しただけの簡単なものです。
サンプルフォームで指定した各コントロールのプロパティは以下です。
このプロパティ内のコントロール名と同じ名前で指定してもらえれば後述するVBAのコードもコピペで動作します。
コントロール名:lbl_ProgressBar_Back
背景スタイル:普通※背景色を使う場合は指定
境界線スタイル:実践※枠線が必要なら指定
立体表示:くぼみ※好みで指定
②プログレスバーメーター用ラベル
コントロール名:lbl_ProgressBar_Front
背景スタイル:普通※用途上背景色は必要
境界線スタイル:実践※枠線が必要なら指定
立体表示:なし※好みで指定
③処理実行ボタン
コントロール名:btn_実行
尚、ラベルは文字が入力されていないと保存できないので、仮で半角スペースを一文字入れてください。
後、①の背景用ラベルの前面に、②のメーター用ラベルを重ねて配置し、左端の位置は①と合わせてください。
また、①のラベルの幅はお好みで設定し、②のラベルはVBAで動的に幅を変えるので、適当で結構です
VBAのサンプルコード
VBエディタ画面にて、新しく「標準モジュール」を作成します。
モジュールの名称は何でも結構ですが、仮で「ProgressBar」としてください。
作成した「標準モジュール」に以下のプログラムを貼り付けて保存してください。
尚、今回作成したサンプルコードでは、エラー処理などの作り込みは省略しております。
もし当記事のコードを参考にされる場合は、必要によってエラー処理も実装して頂くことをおススメします。
Option Compare Database Option Explicit Private prgBar_back As Label Private prgBar_front As Label Private prgMaxValue As Long Public Sub Init_ProgressBar(backLabel As Label, frontLabel As Label) '引数で渡されたラベルコントロールをプログレスバーの背景とメーターとして指定します。 Set prgBar_front = frontLabel Set prgBar_back = backLabel 'メーター用ラベルの長さを0にします。 prgBar_front.Width = 0 End Sub Public Sub Set_MaxValue(maxValue As Long) 'プログレスバーの最大値をセットします。 prgMaxValue = maxValue End Sub Public Sub Set_ProgressValue(currentValue As Long) Dim minWidth As Currency 'メーター用ラベルの最小単位幅を取得します。 minWidth = prgBar_back.Width / prgMaxValue 'メーター用ラベルがはみ出ないようにチェックします。 If prgBar_back.Width >= minWidth * currentValue Then 'メーター用ラベルの幅を引数の値で指定します。 prgBar_front.Width = minWidth * currentValue End If End Sub
Set_ProgressValue内の変数「minWidth」のデータ型はCurrency(通貨型)を指定しています。
これは、小数が扱えて、且つ大きな数値まで対応できるようにする場合、VBAだと通貨型が最適だからです。
また、同プロシージャ内でメーター用ラベルのはみ出しチェックをしていますが、このチェックはしてもしなくても良いです。
次に、フォーム内のボタン(btn_実行)のクリック時イベントに以下のプログラムを貼り付けてください。
Private Sub btn_実行_Click() Dim sampleMaxValue As Long Dim i As Long sampleMaxValue = 10000 'プログレスバーを初期化します。 Call Init_ProgressBar(Me.lbl_ProgressBar_Back, Me.lbl_ProgressBar_Front) 'プログレスバーに最大値をセットします。 Call Set_MaxValue(sampleMaxValue) 'プログレスバーを動かす為にループします。 For i = 1 To sampleMaxValue 'プログレスバーの進捗を表示するために画面描写します。 DoEvents 'プログレスバーの進捗状態を指定します。 Call Set_ProgressValue(i) Next MsgBox "処理が完了しました。" End Sub
当プロシージャ内では変数「sampleMaxValue」に固定値を指定していますが、実際に業務アプリケーションで使用する場合は、レコードセットで取得した行をカウントした値などを入れるイメージです。
また、For文でループさせていますが、ここもFor文やDo文などでレコードセットを行数文ループさせて、何らかの処理をループ内で実行するイメージです。
ループ内で「DoEvents」を呼んでおり、これを呼ばないと画面描写されず、メーター用のラベルが処理状況に合わせて動いてくれません。
ただ、「DoEvents」は処理が遅くなることで有名なので、もしあまりに処理が遅くなる場合はWindowsAPIのGetInputState関数などを組み合わせて実装することをお勧めします。
次にフォームの読み込み時イベントに以下のプログラムを貼り付けてください。
Private Sub Form_Load() 'プログレスバーを初期化します。 Call Init_ProgressBar(Me.lbl_ProgressBar_Back, Me.lbl_ProgressBar_Front) End Sub
当フォームを読み込む際に、プログレスバーの初期化のみ行います。
この処理を呼ばないと、メーター用ラベルがデザイナー画面の表示状態のままで読み込まれてしまいます。
作成した処理を実行
ここまで作成すれば、通常はフォーム内の「実行」ボタンを押下することで、プログレスバーの動作を確認することができるはずです。
最後に
今回は、Accessのラベルコントロールを利用してプログレスバーを作成する方法を紹介させて頂きました。
プログレスバーは時間の掛かる処理の進捗状況をユーザーに伝えるために使用されますが、プログレスバーが無いフォームで重い処理を行う場合、ユーザーからすると、実行している処理が今動いているのか、何らかのトラブルで固まってしまっているのかの判別が出来ずに、非常に不安になります。
アプリケーションを使用するユーザーを不安にさせる実装では、使い勝手の良いシステムとは言えません。
今回紹介した、「ラベルコントロールを利用したプログレスバー」は手軽に実装できる為、上手く活用して頂けると嬉しいです。
それでは今回も読んで頂きましてありがとうございました。