ExcelVBAでPlease Wait
メッセージを作成しようとしています。これは、SQLクエリを処理しているユーザーに、プロセスがまだ進行中であることを通知するためです。このメッセージをユーザーフォームに表示したいと思います。
現在、ユーザーはSQL DBに接続し、データベースとその他のオプションを選択し、[移動...]を押しても、フォームはアンロードされません。 Goポイントで、メッセージPlease Wait
でポップアップする別のフォームがありますが、このフォームはアンロードされません。つまり、SQL実行コマンドは実行されません。
Please Wait
ユーザーフォームを呼び出すための私のコード(ラベルを含む):
Call WaitShowSQl.ExecuteCall KillWaitCall WaitShow
SQl.Execute
Call KillWait
私が持っている別のコードモジュールでは:
Sub WaitShow()
Wait.Show
End Sub
Sub KillWait()
Unload Wait
End Sub
次のコードでwait
というユーザーフォームがあります。
Private Sub UserForm_Activate()
Call PleaseWait
End Sub
Sub PleaseWait()
Wait.Label1.Caption = "Calculating...Please Wait!"
End Sub
これで、コードを実行するときに、ランタイムは次のことを実行するためにモジュールを移動しません。
SQl.ExecuteSQl.Execute
プログラムの進行状況をステータスバーで表示できますが、ユーザーフォームのポップアップメッセージはこのプログラムに非常に役立ちます。
Form.Showメソッドのデフォルトの動作は、フォームをモーダルダイアログとして表示することです。探しているのはモードレスダイアログボックスなので、次のように指定する必要があります。
Sub WaitShow()
Wait.Show vbModeLess
End Sub
更新:
モードレスダイアログを使用できない場合は、コメントに記載されているように、他のオプションがあります。それらの1つは、待機ユーザーフォームにSQLの実行を実行させることです。これは次のように行うことができます:
待機フォームで、最初に変数を宣言します
Private mySomeParameter1 As String
Private mySomeReturnValue1 As String
'Input parameters to the form
Public Sub Init(ByVal some_parameter1 As String, ...)
... Initialize your SQL, NOT execute it
End Sub
'Output values from the from
Public Sub GetReturns(ByRef some_return_value1 As String, ...)
... set the output parameters...
End Sub
'Do the work
Private Sub UserForm_Activate()
Call PleaseWait
'Either call DoEvents or a manual Refresh to let the label display itself
Call ExecutSQL ' A function that executes the SQL
Unload Me
End Sub
そして主な形で:
Sub WaitShow()
Wait.Init(the parameters...)
Wait.Show
Wait.GetReturns(the results...)
End Sub
さらに別のオプションは、待機フォームを完全にスキップし、代わりにメインフォームに「待機中」の画像を表示し、SQL処理が完了したときに非表示にすることです。
ユーザーがExcelの処理が完了するのを待っている間に、進行状況バーを表示する方法は次のとおりです。
https://stackoverflow.com/a/10791349/138938
あなたの場合、クエリの妥当な「平均」時間を推測し、進行状況バーをその時間のパーセンテージで更新することができます。これにより、Excelが機能しており、慌てる必要がないことをユーザーに安心させることができます。
非常に小さいサイズに設定されたフォームのコマンドボタンを使用します。フォームの読み込み時に非表示になり、「お待ちください、処理しています...」というキャプションが付いています。
フォームのIniliatliseイベントでボタンのサイズを変更します(top、left、width、heightプロパティを使用してフォームサイズにサイズ変更するだけです)。もちろん、お好きなサイズにできます。
時間のかかるコードの直前にコマンドボタンを表示し、コードの最後で再び非表示にします。
いくつかの「DoEvents」が必要ですが、完全に機能します。
私のソリューションは、他のソリューションよりもはるかにエレガントで印象的ではありません。参考までに、私のスクリプトはFOR ... NEXTループ内で多数のパートナーの処理を行っており、現在処理中のパートナーで画面を更新したいと思います。
「メッセージ」というワークシートタブを作成しました。セルA1をできるだけ幅と高さを拡大し、好きな配色が好きなフォントを選びました。私のスクリプトは、ScreenUpdatingをオフにすることから始まります。そして私は・・・それから私は
Sheets("Messages").Select
Cells(1, 1).Value = "Processing " & Partner
Application.ScreenUpdating = True
Application.ScreenUpdating = False
この後、必要なシートに戻ります。特別なことは何もありませんが、高速で簡単で、必要なことを実行します。 :)