- ベストアンサー
[ExcelVBA] Application.Dialogs(xlDialogPrint).Show とユーザーフォームについて
[環境] WinXpHomeSP2 Excel2002SP3 Excelのユーザーフォーム上にあるコマンドボタンをクリックすると、アクティブになっているシートを印刷するプログラムを作成しています。 印刷前に印刷ダイアログを表示し、プリンタの設定およびプレビューを可能にしたいため、 Application.Dialogs(xlDialogPrint).Show を使用しています。 ユーザーフォームはその直前でいったんHideし、上記コードの直後に再度Showしています。 表示された印刷ダイアログの「プレビュー」ボタンをクリックすると、Hideしたはずのユーザーフォームがプレビュー画面の前面に表示されてしまい、プレビュー画面、ユーザーフォーム画面のどちらのボタンも効かなくなって制御不能となってしまいます。 プレビューしてもユーザーフォームが立ち上がってこなくなる方法を教えてください。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
再度の登場 onlyromです。 >UserForm1をいったんHideした後にまたShowするため、※1が実行され その後は新しくUserForm1が立ち上がったのと同じ動作をします。 Showすれば必ずActivateイベントが発生します。 その処理は、 UserForm_Initializeイベントに書くと拙いのですか? Initializeイベントであれば、HideしてShowしても そこを通りませんので実行されません。 絶対Activateイベントに書かなければならないコードであり、 かつ、今回のように場合によっては、Activateイベントのコードを 実行させたくない時は 実行させるかさせないか判断させるための変数を モジュール変数としてとっておきそれを利用する手もあります。 それから、 >このUserForm1が閉じられた後、※2を実行してしまうため、エラーになってしまいうまくいきません。 これは、Showの前で、※2を実行すればいいのではありませんか? '-------------------------------------- Dim MyFlag as Boolean '-------------------------------------- Private UserForm_Activate() If MyFlag = True then Exit Sub ーーー処理ーーー End Sub '-------------------------------------- Private Sub CommandButton1_Click Dim blResponse AS Boolean :(帳票出力準備) ●● MyFlag = True ●● UserForm1.Hide blResponse = Application.Dialogs(xlDialogPrint).Show :(帳票出力後始末) If blREsponse Then MsgBox "出力終了" End If ▲▲ : (※2) ▲▲ UserForm1.Show ●● MyFlag = False ●● End Sub '-------------------------------------------------- UserformActivateイベントで何をしてるのか (※2) で何をしてるのか分かりませんので これくらいのアドバイスしかできませんが、 さらに言うと UserForm.Showの後に、(※2)のように何かの処理をさせるコードを書くことはありません。 書くとすれば、UserFormをYesNoのMsgBoxのように使う場合です。 また上記アドバイスでは、UserFormの使い方が不明でしたので (※2)とShowを入れ替えていますが、 通常、UserFormが閉じられたときの処理は、 UserForm_QueryClose などに書きます。 Activateイベントの処理内容、(※2)の処理内容が分かれば もっと的確な回答が寄せられるでしょう。
その他の回答 (4)
- Wendy02
- ベストアンサー率57% (3570/6232)
修正 割り込み失礼しました。 ↓ 割り込み失礼します。 でした。(^^;
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 割り込み失礼しました。 Excel2002SP3という条件なら、 >ユーザーフォームがプレビュー画面の前面に表示されてしまい、プレビュー画面、ユーザーフォーム画面のどちらのボタンも効かなくなって制御不能となってしまいます。 私の読み違えでなかったら、それは、Zオーダーの前面に来る来ないは別にして、Modalモード(=ShowModal または、.Show ) が、Trueにしてあるからではありませんか? 単に、False にすれば、Hide にしなくてもよいと思います。 あえて、UserForm が邪魔というなら、以下のようなコードにすればよいと思います。 ただ、UserForm のプロパティの 「ShowModal : False または、.Show(False)」には変わりありません。 ---------------------------------------------------------------------- Private Declare Function CloseWindow Lib "user32.dll" _ (ByVal hWnd As Long) As Long Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _ (ByVal lpClassName As String, _ ByVal lpWindowName As String) As Long Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" _ (ByVal hWnd As Long, _ ByVal nIndex As Long, _ ByVal dwNewLong As Long) As Long Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" _ (ByVal hWnd As Long, _ ByVal nIndex As Long) As Long Private Declare Function DrawMenuBar Lib "user32.dll" _ (ByVal hWnd As Long) As Long Private Const GWL_STYLE As Long = -16 Private Const WS_THICKFRAME As Long = &H40000 Private Const WS_MINIMIZEBOX As Long = &H20000 Private Sub CommandButton1_Click() Dim strClassName As String Dim hWnd As Long Dim ret As Long strClassName = "ThunderDFrame" '97:ThunderXFrame" hWnd = FindWindow(strClassName, Me.Caption) ret = CloseWindow(hWnd) Application.Dialogs(xlDialogPrint).Show End Sub Private Sub UserForm_Initialize() Dim strClassName As String Dim hWnd As Long Dim lngNewLong As Long Dim ret As Long strClassName = "ThunderDFrame" '97:ThunderXFrame" hWnd = FindWindow(strClassName, Me.Caption) lngNewLong = GetWindowLong(hWnd, GWL_STYLE) ret = SetWindowLong(hWnd, GWL_STYLE, _ lngNewLong Or _ WS_THICKFRAME Or _ WS_MINIMIZEBOX) ret = DrawMenuBar(hWnd) End Sub ----------------------------------------------------------------------
お礼
コードまで書いていただき、ほんとうにありがとうございます。 早速そのまま使わせていただきました。 結果、かなり理想に近い動作に仕上がり、あと一息で完成となりそうです。 どうもありがとうございました。
- onlyrom
- ベストアンサー率59% (228/384)
何はともあれ、実際のコードをアップしてみてください。 Private Sub CommandButton1_Click() ● ここのコードをアップ ● End Sub
補足
ありがとうございます。 最初は下記のようにコードを記述していました。 Private Sub UserForm_Activate : End Sub Private Sub CommandButton1_Click : UserForm1.Hide Application.Dialogs(xlDialogPrint).Show UserForm1.Show : End Sub 質問した後、ANo1様のアドバイスをもとに、以下のようにコードを変更しました。 UserForm1は印刷する、しないにかかわらず必ず表示させておきたいのです。 Private Sub UserForm_Activate : (※1) End Sub Private Sub CommandButton1_Click Dim blResponse AS Boolean :(帳票出力準備) UserForm1.Hide blResponse = Application.Dialogs(xlDialogPrint).Show :(帳票出力後始末) If blREsponse Then MsgBox "出力終了" End If UserForm1.Show : (※2) End Sub 上記のように変更し、一見うまくいったように見えましたが、UserForm1をいったんHideした後にまたShowするため、※1が実行され、その後は新しくUserForm1が立ち上がったのと同じ動作をします。 このUserForm1が閉じられた後、※2を実行してしまうため、エラーになってしまいうまくいきません。 UserForm1を表示させたままでxlDialogPrintが使えれば良いのですが...。
- nekoron07
- ベストアンサー率37% (69/184)
Application.Dialogs(xlDialogPrint).Show の後に If response = ok Then UserForm1.Show ←ユーザーフォームの名称 End If とすれば、印刷OKのボタンを押したときにユーザーフォームが現れると思います。
お礼
ダイアログの結果を受け取る方法はわかりました。 Dim response As Boolean response = Application.Dialogs(xlDialogPrint).Show If response = true Then ですね。 ありがとうございました。
補足
ご教示ありがとうございます。 If response = ok Then ... としてみましたが、 コンパイルエラー 変数が定義されていません。 となってしまいます。
お礼
ご回答ほんとうに感謝いたします。 ご教示いただいたことをもとに、以下のように修正しました。 1.ActivateイベントからInitializeに書き直した。 2.CommandButton1_Clickの流れ全体を見直し、UserForm.Showの後にあった処理をその前に持ってきた。 No4さんの回答を参考にさせていただき、結局UserForm.Showはなくなりましたが、全体にコードがすっきりしました。 情報不足の中、的確なご回答をいただき、ほんとうにありがとうございました。