プログレスバーで進捗状況をビジュアルで表示する記事を紹介しています。そこで使ったプログレスバーは「ActiveXコントロール」MSCOMCTL.OCX の「プログレスバーコントロール」でした。
「ActiveXコントロール」を使う方法の場合、MSCOMCTL.OCX が入っていない環境又はOCXのバージョンが違っていたりするとエラーで実行できないケースが存在していました。
また、今回これを変更しようと思ったのは、前回記事「動的にUserFormを作成する」の続編を検討中に、この「プログレスバーコントロール」を動的にうまく設置することができなかったからです。
それなら、以前から少し気になっていた MSCOMCTL.OCX の使用をやめて標準のコントロールで対応しようという結論に至ったわけです。
前置きが少し長くなりましたが、そんなわけで「プログレスバー」を標準コントロールで代用設置する方法を解説したいと思います(^^)
わかりました。よろしくお願いしますm(__)m
その「ActiveXコントロール」版 プログレスバーの記事がこちらです。
【この記事でわかることは】
・標準コントロール「ラベル」と「フレーム」の配置方法
・VBA で プログレスバー のように表示させる方法
代替版プログレスバーの部品を設置します
「プログレスバー」の動きと同じように表示できればOKということですね。
ユーザーフォームにコントロールを配置します
それでは「プログレスバー」用のユーザーフォームを用意します。
・VBE の [挿入]メニューからユーザフォームを挿入します。
サイズだけ次のように横長に設定しました。
プロパティーの設定は次のとおり
・Height: 138(高さ)
・Width : 370(横幅)
プログレスバーとして使用するコントロールは二つ
・メーター部分 = 「ラベルコントロール」
・メーターの枠部分 = 「フレームコントロール」
※枠は無くてもいいんですが、無いとバーの終点も見えないしカッコよくないので(^-^;
イメージとしては、窪んだフレーム内に配置した着色ラベルのWidthを進捗に応じ変化させていくようにして表現します。
【重要】先に「フレーム」を配置してから、その中に「ラベル」を配置します。
設定したプロパティは次のとおりです。
項目 | 「フレーム」 | 「ラベル」 |
---|---|---|
Caption | 空白 | 空白 |
Top | 18 | 0 |
Left | 6 | 0 |
Height(バーの幅です) | 42 | 42 |
Width(バーの長さです) | 350 | 350 |
SpecialEffect | fmSpecialEffectSunken | デフォルトのまま |
BackColor(青に設定) | デフォルトのまま | &H8000000D& |
枠に「フレームコントロール」を使う理由
枠の部分にもバーと同じ「ラベルコントロール」を重ねて使うことも可能です。
ですが、「フレームコントロール」ならフレーム内に配置したコントロールをグループ化して管理できます。位置調整なども「フレーム」を動かせば内部のコントロールも一緒に移動できるなど、いろいろと都合がいいんです。内部の「ラベル」位置の調整も「フレーム」内での位置で調整できます。
「コマンドボタン」とテキスト表示用の「ラベル」を追加
・「コマンドボタン」= 実行途中でキャンセルできるようにボタンを設置
・「ラベル」 = 進捗状況を数値で表示できるように設置
サイズなどの設定は省略します。(自由に設定して構いません)
VBAソースコードを設定します
VBAコードは、UserForm と標準モジュールに分けて設定します。
UserForm に設定するVBAコード
Option Explicit
'キャンセル処理用フラグ
Public IsCancel As Boolean
'ユーザーフォーム起動時の初期化
Private Sub UserForm_Initialize()
Caption = "ProgressBar Sample"
'フレームとラベルの位置は同一にする
With Me.Label1
.Left = 0
.Top = 0
.Width = 0
.Visible = True 'False
End With
'キャンセルフラグにFalseを設定
IsCancel = False
End Sub
'キャンセルボタンクリックイベント
Private Sub CommandButton1_Click()
'キャンセルフラグにTrueを設定
IsCancel = True
End Sub
・3行目は、キャンセル処理用にBoolean型の変数をグローバルで宣言しています。
・6~17行目の UserForm_Initialize イベントです。
ユーザーフォーム起動時の初期化設定を行っています。
・20~23行目は CommandButton1_Click イベントです。
「キャンセル」ボタンが押されると、キャンセルフラグが True になります。
標準モジュールに設定するVBAコード
プログレスバーのように動作させるための設定を行います。
Option Explicit
Private Declare Sub Sleep Lib "KERNEL32" (ByVal dwMilliseconds As Long)
'[実行ボタン]押下でプログレスバー開始
Sub Button_Click()
Dim i As Long
Dim strMsg As String
With UserForm1
'マウスカーソルを待機中に固定
Application.Cursor = xlWait
'プログレスバーFormをモードレスで表示
.Show vbModeless
'進捗表示用ラベルの初期表示
.Label2.Caption = "進捗状況: 0 / 100 %"
strMsg = "処理が完了しました!"
'Bar値のカウンターを初期化
i = 0
Do
'0-100までループさせる設定
If i = 100 Then Exit Do
'滞留処理を実行
DoEvents
'処理の重さによって待機時間を要調整
Sleep 50 '50ミリ秒待機に調整 1=1ミリ秒
'Application.Wait でもOK
'Application.Wait [Now() + "0:00:00.05"]
'カウントアップ
i = i + 1
'ラベル幅によって調整 350なので3.5倍している
.Label1.Width = (i * 3.5)
'進捗状況を%で表示(必要に応じて処理件数表示なども)
.Label2.Caption = "進捗状況:" & Format(CStr(i), "@@@") & " / 100 %"
'キャンセルボタンが押された場合の処理
If .IsCancel = True Then
strMsg = "処理を中断しました!"
Exit Do
End If
Loop
End With
'マウスカーソルをデフォルトに戻す
Application.Cursor = xlDefault
'メッセージ表示
MsgBox strMsg, vbInformation
'プログレスバーFormを閉じる
Unload UserForm1
End Sub
・コード内のコメントで大体の動作説明をしていますので参照願います。以下補足です。
・2行目で、Win32API で Sleep を使えるように宣言しています。
・24行目で Sleep を使っています。Application.Wait を使う方法もあります。
・メッセージを変数に代入して状況に応じたメッセージを表示するようにしています。
・Do….Loop 内に DoEvents を入れて「キャンセル」ボタンに対応できるようにしています。
・DoEvents を挟むと画面のちらつきが起きるのでマウスを「待機中」表示にしています。
・UserForm を Unload はメッセージを表示した後に実行するようにしています。
(お好みで、先に Unload してからメッセージを表示しても問題ありません)
実際の動作を確認します
ワークシートに「実行ボタン」を設置し、Button_Click を実行できるようにしています。
実際に操作している動画がこちらです。
実行が完了するまでの動作と「キャンセル」ボタンが押されたときの動作です。
ちゃんと「プログレスバー」になっていますね。無事成功しました(^^)/
まとめ(おわりに)
以上、VBA で UserForm と標準コントロールの「ラベル」と「フレーム」を使ってプログレスバーと同じように動作させることができました。
これで使用環境に限定されることなく「プログレスバー」を動作させることができますね。
まとめと感想など
これでプログレスバー用の UserForm を動的に作成・解放するための準備が整いました。次回はいよいよ「プログレスバー」を動的に作成・解放できるように頑張りましょう(^^)
枠にフレームを使うのは、フレーム内に設置したラベルの Top や Leftプロパティがフレームからの位置になるから扱いやすいということがわかりました。
★★★ ブログランキング参加中! クリックしてね(^^)/ ★★★
【今後の記事について】
今回の記事はいかがだったでしょうか。皆さまのお役に立てたなら幸いです(^^;
「汎用でだれでも使えて活用できるように考えてる」というポリシーで、記事を継続して書いていきたいと思っています。どうぞよろしくお願いしますm(_ _)m
【検討中の今後の記事内容は・・・・】
・実務に役立つものを提供できるよう常に検討しています(^^ゞ
・その他雑記的に「プチネタなど」もいろいろ考えていきたいと思っています・・・・
・今後の記事にご期待ください(^^)/
過去記事のサンプルファイルをダウンロードできます
リンク先に今回記事のサンプルファイルを登録しています!
過去の記事で使用したサンプルファイルをダウンロードできるようにページを設置していますので、こちら(このリンク先)からご利用ください
【今回わかったことは】
・標準コントロールの「ラベル」と「フレーム」でプログレスバーと同じ動作を実現できることがわかりました