印刷したの?実際?

勝手に印刷されるのではなくて、プレビューにして内容を確認してから自分で好きに印刷したい、とお客さんが言うので、そうすることになりました。
印刷したかどうかをデータに持っているので(←同じデータを何度も印刷してしまうのを防ぐため)、プレビューにしてしまうとそれが取れないのではないかと思ったのですが。
いやー、浅はかでした。
実際に印刷したか(あ、この「印刷した」は「紙として正しく出力された」ではなくて、「印刷指示を出した」ということです)は取得できるようです。
インターネットってすごいですね。(今さら。)




こんな感じです。

適当なモジュールに以下を記述。


Declare Function apiIsWindowEnabled Lib "user32" _
Alias "IsWindowEnabled" (ByVal hWnd As Long) As Long
Public Function gIsPrinted(rpt As Report) As Boolean
Dim blnRtn As Boolean
blnRtn = False
If apiIsWindowEnabled(rpt.hWnd) = 0 Then
blnRtn = True
End If
gIsPrinted = blnRtn
End Function

さらに適当なモジュールに以下を記述。


Private Dim mblnIsPrinted As Boolean
Public Sub gSetIsPrinted(byval blnIsPrinted As Boolean)
If blnIsPrinted = True Then
mblnIsPrinted = True
End If
End Sub
Public Sub gClearIsPrinted()
mblnIsPrinted = False
End Sub
Public Function gGetIsPrinted() As Boolean
gGetIsPrinted = mblnIsPrinted
End Sub

レポートのレポートヘッダのフォーマット時イベントを以下のように記述。


Private Sub レポートヘッダー_Format(Cancel As Integer, FormatCount As Integer)
' 印刷したか否かをセット
Call gSetIsPrinted(gIsPrinted(Me))
End Sub

印刷部分。(一度に一つのレポートしか印刷しないという前提です。)
印刷したらTrueが、印刷しなかったらFalseが返されます。


Public Function gPrintReport(ByVal strReportName As String) As Boolean
Dim blnRtn As Boolean
blnRtn = False
' 印刷状態を初期化
Call gClearPrintInfo_IsPrinted
' プレビューで開く
Call DoCmd.OpenReport(strReportName, acViewPreview)
' 開かれているレポートがなくなるまで待ち
Do Until Reports.Count <= 0
Call Application.Echo(True)
DoEvents
Loop
' 印刷したかどうかを取得
If gGetPrintInfo_IsPrinted() = True Then
blnRtn = True
End If
PrintReport = blnRtn
End Function

追記(2007/6/14)
「開かれているレポートがなくなるまで待ち」の部分、SysCmdメソッドの第一引き数にacSysCmdGetObjectStateを指定すると、オブジェクトが開いてるかどうか分かるっぽいので、それを利用して閉じるまで待つ処理が作れます。そっちの方がスマートですね。(というか、元のがひどいよ。)
ここがそのものずばりです。