- ベストアンサー
MsgBoxがあるとTextBox表示が出ない
- Excel VBA初心者の独学中です。Sheet上のTextBoxにデータを表示させた後、同時にMsgBoxにもデータを表示させたいと思っています。しかし、実行してみると、MsgBoxは表示されるものの、TextBoxはブランクのままです。考えられる原因は、TextBoxのデータ表示に時間がかかり、先にMsgBoxが表示されてしまっている可能性があります。
- 同時にデータを表示させる方法はあるのでしょうか?安定して同時にデータを表示させる方法を知りたいと思っています。以下はプロシージャの例です。
- Sub テスト() Worksheets("Sheet1").TextBox1.Value = Time MsgBox "Timeは" & Time & "です。" End Sub
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
この現象を解説するには、Windowsプログラムの動作とExcelの作り、それぞれの命令の実装方法が関係しています。 >Worksheets("Sheet1").TextBox1.Value = Time テキストボックスにデータを入れます。 >MsgBox "Timeは" & Time & "です。" ダイアログを出してその中に表示します。 実はこの中に書かれていない処理があるのですが、わかりますでしょうか。 『TextBoxの内容を更新表示する』という処理が入っていないのです。 それではなぜテキストボックスの内容が表示されるかというと、バックグラウンドで一定間隔で表示をリフレッシュしているから、代入したデータが表示されてくるんです。 データの代入と、その表示が非同期で行われている。これがWindowsプログラムというモノです。 ただし、Msgbox を表示している間、その表示更新処理は走りません。 これは、Msgboxが「モーダル」で表示されるため、その他の処理が全て止まってしまうためです。(対義語: モーダル←→モードレス) つまり、TextBox1にデータ代入をした瞬間に、たまたま画面更新処理が走ったときだけ、テキストボックスの内容が表示されます。 しかしActiveXコントロールは特にその更新が遅く、大概は、更新前にMsgboxが表示されてしまいます。 そしてダイアログが出ている間は画面更新されません。 これはもう、Windowsプログラム、Excelと言うプログラムがそういう作りになっているからなので、このプログラムで同時表示されるのはよほど運が良いときのみ、と言うことになってしまいます。 これって例えば、いくつもActiveXコントロールがあって、たくさん代入した後にMsgboxを表示する、なんていう場合。 コントロールが全部真っ白のままMsgboxが表示されるか、一気に全部表示されてからMsgboxが表示されるか、なんてことになってしまいます。 これを解決するには、ダイアログボックスが表示されている間にも画面更新処理が走れば良いんです。 ただし Msgbox 命令はモーダル専用で、モードレスに出来ません。 そこでユーザーフォームを作り、モードレスで、表示します。 参考) Excelのフォームをモードレス表示する、閉じる、隠す:VBA/マクロ便利Tips - @IT >https://www.atmarkit.co.jp/ait/articles/1410/20/news025.html ※こちらで表示しても、ダイアログ表示した瞬間は、テキストボックス内容が表示されていないかもしれません。でもすぐに、表示されるはずです。 まあ、画面更新が止まってしまう Msgbox が悪いので、もうこれはこういうものだ、と思っておいた方が良いかもしれません。
その他の回答 (4)
- imogasi
- ベストアンサー率27% (4737/17069)
>Sheet上にTextBox(ActiveXコントロール)を置き と質問に書いてあるじゃないか。 実際は図形の中にテキストボックスを入れている?それならそのように書くべき。 ーー (1)内容や必要な解決策の課題レベル 誰でも質問しても良い、それができる、からといって、何でも質問すべきではないと思う。 常識的に、読者・回答者のレベルを超えるところの、超上級者でない判らない質問、大学院でなどでも研究課題レベル、プロの出くわす問題、APIその他の技量を要する問題など。 ここで回答がなされるのは、OKWAVE利用者でそのカテゴリを登録したものに質問が配信される。 これを読むだけの処理するのでも、相当の時間を取る。回答も数時間かかることも多い。 その基礎的なスキルを得るに必要な期間たるや、数十年だと思う。 ・初心者ほど珍奇な解決策を思い付き、それに拘った回答を求める傾向を感じる。 解決策の大枠から、まず教えを乞うべきだと思う。 (2)質問者の現状の力量 ・表現力 質問者が、質問内容を文章などで正確に表現できない者が質問する例が多いが、読者・回答者 にとって迷惑。 ・回答理解力 普通のレベルの回答をしたつもりでも、理解できない質問者のレベル。 ーーー (1)、(2)とも、(自己・他者とも)判定は難しいので、質問してみるしかないが、一応考えてほしい。
- kon555
- ベストアンサー率51% (1842/3559)
こちらの環境ではうまく再現しないので勘での回答になってしまいますが、TextBox1.Value~の後にSleep関数やDoEventsを入れて一瞬待機させてみるといいかもしれないですね。 参考ページはこちら https://liclog.net/sleep-function-vba-macro-catia-v5/ https://takeichi.work/excelvba-sleep/
お礼
ご回答ありがとうございました。質問投稿前にWaitメソッドを使った方法でのNGは確認済でしたが、Sleep関数もやはり同様にSleep時間だけMsgBoxの表示を遅らせても効果は有りませんでした。ご検討いただきありがとうございました。
- imogasi
- ベストアンサー率27% (4737/17069)
>独学中の初心者です 変な方に迷い込まないこと。 シートにテキストボックスを張り付けるなど、標準的でなくおかしい。 シートのセルという(データを受け付ける)仕組みがあるのに、シートに直接テキストボックスを張り付ける有用性は、初心者では見つけにくいと思う。 何でも変なことして、動きの理由が判らず、質問するのはおかしい。回答者も珍奇な質問が出されて大変だ。今後の課題として、あたためておいて、VBA(特にコントロール)を使って経験していくうえで、納得する時期が来るかもしれない。 ーー テキストボックスは、1文字入力後でも、その入力データが捉えられるが、普通は入力データの終りというものがあり、それは入力者にしかわからず、ユーザーフォームなどでは、コマンドボタンを1つ、入力完了通知イベント用に設けて、そのボタンの押し下げた、段階のテキストボックスのデータを、必要なデータとして、使うのではないか。それなしでは使いずらいと思う。 シートにテキストボックスを張り付けるのでなく、ユーザーフォームにテキストボックスを張り付けけ、入力完了ボタンを設け、このボタンのクリックイベントの中で、UserForm1.Txtbox1.Textを変数に受け取り、その変数をMsgboxで表示すれば質者ことは考えなくて済む。 また、ユーザーフォームには、普通は、その他の項目のデータも1対として、同時に入力する道具なのだ。 エクセルVBAのコントロールの本など1本も読んでないのではないか。VBAの中級以上の課題でもあり、その点も考え、質問を連発するとすれば、どうかと思う。
お礼
不明な点だけを最小限にサンプル化して投稿したのですが、全部を書き出さないといけないのでしょうか。絵の中にTextBoxを埋め込みたい用法なのですが、それはシートのセルにデータを貼り付けることではありません。また流れの中でTextBoxに表示させたいのであって、その時にボタンの押し下げという操作は考えていません。質問すること自体ご不満に思われているように受け取りましたが、ここは質問の場ではなかったのでしょうか。善意で回答していただける人に質問しているつもりでしたが、質問することがどうかと思われるならば、私はその理由が理解できませんが、ご回答は望みません。質問することで不快な思いをさせてしまったのであればお詫び致します。
- neKo_quatre
- ベストアンサー率44% (735/1636)
Worksheets("Sheet1").TextBox1.Value = Time Worksheets("Sheet1").TextBox1.Update() MsgBox "Timeは" & Time & "です。" で、テキストボックスが更新されないでしょうか。
お礼
早速のご回答ありがとうございました。 残念ながら「Worksheets("Sheet1").TextBox1.Update()」が赤くエラー表示されて解決しませんでした。このステートメントの意味がWEBでも検索しましたが私には理解できませんでした。
お礼
MsgBoxをユーザーフォームのモードレス表示に替えることで解決しました。テキストボックス(に限らずActiveX コントロール)の画面表示動作についても教えていただき納得しました。ハードも含めた画面出力動作によるものと理解しました。ご教授大変ありがとうございました。