dポイントプレゼントキャンペーン実施中!

[環境] WinXpHomeSP2
Excel2002SP3

Excelのユーザーフォーム上にあるコマンドボタンをクリックすると、アクティブになっているシートを印刷するプログラムを作成しています。
印刷前に印刷ダイアログを表示し、プリンタの設定およびプレビューを可能にしたいため、
Application.Dialogs(xlDialogPrint).Show
を使用しています。
ユーザーフォームはその直前でいったんHideし、上記コードの直後に再度Showしています。

表示された印刷ダイアログの「プレビュー」ボタンをクリックすると、Hideしたはずのユーザーフォームがプレビュー画面の前面に表示されてしまい、プレビュー画面、ユーザーフォーム画面のどちらのボタンも効かなくなって制御不能となってしまいます。

プレビューしてもユーザーフォームが立ち上がってこなくなる方法を教えてください。

A 回答 (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)の処理内容が分かれば
もっと的確な回答が寄せられるでしょう。
 

 
 
    • good
    • 0
この回答へのお礼

ご回答ほんとうに感謝いたします。

ご教示いただいたことをもとに、以下のように修正しました。
1.ActivateイベントからInitializeに書き直した。
2.CommandButton1_Clickの流れ全体を見直し、UserForm.Showの後にあった処理をその前に持ってきた。
No4さんの回答を参考にさせていただき、結局UserForm.Showはなくなりましたが、全体にコードがすっきりしました。

情報不足の中、的確なご回答をいただき、ほんとうにありがとうございました。

お礼日時:2007/11/11 21:35

修正


割り込み失礼しました。
  ↓
割り込み失礼します。
でした。(^^;
    • good
    • 0

こんにちは。



割り込み失礼しました。

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


----------------------------------------------------------------------
    • good
    • 0
この回答へのお礼

コードまで書いていただき、ほんとうにありがとうございます。
早速そのまま使わせていただきました。
結果、かなり理想に近い動作に仕上がり、あと一息で完成となりそうです。
どうもありがとうございました。

お礼日時:2007/11/11 21:38

 


何はともあれ、実際のコードをアップしてみてください。

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が使えれば良いのですが...。

補足日時:2007/11/08 23:24
    • good
    • 0

Application.Dialogs(xlDialogPrint).Show



の後に

If response = ok Then
  UserForm1.Show    ←ユーザーフォームの名称
End If

とすれば、印刷OKのボタンを押したときにユーザーフォームが現れると思います。

この回答への補足

ご教示ありがとうございます。

If response = ok Then ...
としてみましたが、
コンパイルエラー 変数が定義されていません。
となってしまいます。

補足日時:2007/11/08 14:30
    • good
    • 0
この回答へのお礼

ダイアログの結果を受け取る方法はわかりました。
Dim response As Boolean

response = Application.Dialogs(xlDialogPrint).Show
If response = true Then

ですね。
ありがとうございました。

お礼日時:2007/11/08 23:00

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!