ExcelVBAでFormにプログレスバー(進行表示)と簡易ログを表示する
Excel等のVBAでマクロを実行中に進行を表示したい場合があります。
標準のプログレスバーは、64bit版で不具合があったりと、イマイチです。
左下のステータスバーに表示する方法が簡単ですが、フィルターを使用したりすると 表示が上書きされてしまって見にくい場合があります。
フォームを利用する事で いろいろと試せるので そちらを使うことにしました。
進行表示をバー表示するだけではなく、
手順とかの簡易ログ的なものも同時に表示できます。(イミディエイトウィンドウの様に)
こうする事で 進行を見ながら、簡易デバッグにも利用できます。
やっぱり、文字やメッセージも表示できると便利ですよね。
また、複数のファイルを作成するようなマクロの場合にも どんなファイルを作成したのか?も表示できます。
フォームを作成する
まず、フォームを作成します。
フォームの名称は変えなくてもOKですが、変えておいた方が 他のマクロに利用するときにも便利だと思います。
ラベルとテキストボックスを配置します。
(進捗バーのみの場合は ラベルのみでOKです。)
次に ラベルの名前やプロパティー設定を変更します。
ラベルの width 300 となるように注意してください。
次に、テキストボックスの名前やプロパティー設定を変更します。
標準モジュールに表示用の関数を作成する
下記のコードをコピペしてください。
'宣言セクションで パブリックな変数(グローバル変数)(どのモジュールからでも変数を参照できるようにしておく)を宣言しておく。
Public PBar_count As Long '他のモジュールでも共有する変数の宣言
Public PBar_str_all As String
Sub PBar_Form(PBar_input As Variant)
'プログレスバーをユーザーフォームで表示。下記の準備と宣言が必要。
'フォーム名PBarForm1 / ラベル名PBarLabel. ラベルWidth=300 ラベルBackColorを適当に着色 / テキストボックス名PBarBox フォントサイズは6程度
'◆宣言セクション
'Public PBar_count As Long '他のモジュールでも共有する変数の宣言(宣言セクションで宣言する必要がある)
'Public PBar_str_all As String
'◆Main関数の最初
'PBarForm1.Show vbModeless 'プログレスバーのフォーム表示
'PBar_count = 100
'◆Main関数の最後
'Unload PBarForm1 'プログレスバーを消す
'
'◆使用例
'Call PBar_Form('あ123いうえお')
'Call PBar_Form(Str(i))
'Call PBar_Form(i)
Dim maxWidth As Integer
Dim i As Integer
Dim j_str As String
maxWidth = 300 'フォームのラベルをwidth300で作成しておく
j_str = "進捗をBar表示しています。。。進捗%ではなく、繰り返し表示です。。。" '進捗バー(ラベル)にメッセージを表示したらおもしろいかな。。。と。不要なら消す。
PBarForm1.PBarLabel.Caption = j_str & vbCrLf & PBar_input 'ラベルに最新のログを追記する表示です。
PBarForm1.PBarLabel.Width = maxWidth * (PBar_count / 100) '進捗バーの巾を変えて進捗表示にしています。
PBar_str_all = PBar_str_all & vbCrLf & PBar_input 'テキストボックス内に表示する簡易ログの文字列を生成
PBarForm1.PBarBox.Text = PBar_str_all 'テキストボックスに 簡易ログを表示。
DoEvents '再作画
If PBar_count < 100 Then
PBar_count = PBar_count + 1
Else
PBar_count = 1
End If
End Sub
試してみる
上記のコードを試してみます。
Sub PBar_test()
PBarForm1.Show vbModeless 'プログレスバーのフォーム表示
PPbar_count = 100
For i = 1 To 250
DoEvents '再作画
'1ミリ秒待機する処理
Application.Wait [Now() + "0:00:00.1"]
Call PBar_Form("123")
Next i
MsgBox "終了!"
Unload PBarForm1 'プログレスバーを消す
End Sub
ちなみに、最後の
Unload PBarForm1 'プログレスバーを消す
を、コメントアウトして
'Unload PBarForm1 'プログレスバーを消す
の様にすると デバッグ時に便利です。
各部分の説明
最初に宣言セクションで Public で変数を宣言しています。
こうする事で 他のモジュールから呼び出しても進行バーや簡易ログの中身が継承されるので便利でした。
Public PBar_count As Long '他のモジュールでも共有する変数の宣言
Public PBar_str_all As String
Sub PBar_Form(PBar_input As Variant)
とする事で Long型やString型とか気にしなくても表示できるようになります。
DoEvents '再作画
これを入れないと 再作画されないので、進捗バーが動かないです。
ただ、テキストボックスにユーザが入力できてしまいます。
簡易ログ的な利用なら問題ないでしょう。
テキストボックスにする事で まとまって、コピペする事も可能になります。
使い方
下記の様に使う事ができます。
中に入れる変数は 文字型でも数値型でもどちらでも大丈夫でした。
Call PBar_Form('あ123いうえお')
Call PBar_Form(Str(i))
Call PBar_Form(i)
最後に
私は 日曜プログラマーです。
色々なコマンドや設定を 覚えていて、がりがりとプログラムをかけるわけでもない為、
注釈をいっぱい入れています。
後で 見直したときに、何やっていた?と分かり易いようにです。
なので、こんなに注釈の多いプログラムは 汚いと、怒られる方もおられるでしょう。
ご容赦ください。
また、
部品として繰り返し利用するような関数には、利用方法等も記載するようにしておくと
後々、忘れてしまってから再利用するときにも便利です。
毎日VBAを触るような方には、不要な注釈ですので 消していただいてもOKです。
全体のコード
最後に、一式コピペするだけにまとめたコードを添付しておきます。
'宣言セクションで パブリックな変数(グローバル変数)(どのモジュールからでも変数を参照できるようにしておく)を宣言しておく。
Public PBar_count As Long '他のモジュールでも共有する変数の宣言
Public PBar_str_all As String
Sub PBar_Form(PBar_input As Variant)
'プログレスバーをユーザーフォームで表示。下記の準備と宣言が必要。
'フォーム名PBarForm1 / ラベル名PBarLabel. ラベルWidth=300 ラベルBackColorを適当に着色 / テキストボックス名PBarBox フォントサイズは6程度
'◆宣言セクション
'Public PBar_count As Long '他のモジュールでも共有する変数の宣言(宣言セクションで宣言する必要がある)
'Public PBar_str_all As String
'◆Main関数の最初
'PBarForm1.Show vbModeless 'プログレスバーのフォーム表示
'PBar_count = 100
'◆Main関数の最後
'Unload PBarForm1 'プログレスバーを消す
'
'◆使用例
'Call PBar_Form('あ123いうえお')
'Call PBar_Form(Str(i))
'Call PBar_Form(i)
Dim maxWidth As Integer
Dim i As Integer
Dim j_str As String
maxWidth = 300 'フォームのラベルをwidth300で作成しておく
j_str = "進捗をBar表示しています。。。進捗%ではなく、繰り返し表示です。。。" '進捗バー(ラベル)にメッセージを表示したらおもしろいかな。。。と。不要なら消す。
PBarForm1.PBarLabel.Caption = j_str & vbCrLf & PBar_input 'ラベルに最新のログを追記する表示です。
PBarForm1.PBarLabel.Width = maxWidth * (PBar_count / 100) '進捗バーの巾を変えて進捗表示にしています。
PBar_str_all = PBar_str_all & vbCrLf & PBar_input 'テキストボックス内に表示する簡易ログの文字列を生成
PBarForm1.PBarBox.Text = PBar_str_all 'テキストボックスに 簡易ログを表示。
DoEvents '再作画
If PBar_count < 100 Then
PBar_count = PBar_count + 1
Else
PBar_count = 1
End If
End Sub
Sub PBar_test()
PBarForm1.Show vbModeless 'プログレスバーのフォーム表示
PPbar_count = 100
For i = 1 To 100
DoEvents '再作画
'1ミリ秒待機する処理
Application.Wait [Now() + "0:00:00.1"]
Call PBar_Form("123")
Next i
MsgBox "終了!"
Unload PBarForm1 'プログレスバーを消す
End Sub