実はアクセスから2種類のドキュメントを連続してプリントアウトしたいと思っています。
ひとつは商品図面(PDF)でもうひとつはその商品の顧客リストです。かつ現場で間違わないように必ず(1)商品図面→(2)顧客リストの順番で出力する事が必須となります。
しかし(1)はAcrobatを介しての出力で(2)はアクセスからのダイレクト出力の為か、VB上での順番とは逆に実際には(2)→(1)の順番となってしまいます。
必ず(1)→(2)の出力順となるような方法はありませんでしょうか?
ネットで調べたところ『WaitForSingleObject』なる関数があるようですが、素人の私ではこれが使えるのかどうか難しくて判りません。
下記がモジュールの内容です。宜しくアドバイスお願いします。
'**** (1)選択肢から選んだ商品図pdfを印刷する ****
pass1 = "C:\商品図面\" & rstTable!図番 & ".pdf" & ""
name1 = Dir(pass1)
Dim objShell As New Shell32.Shell
Dim objShellDP As Shell32.IShellDispatch2
Set objShellDP = objShell
Call objShellDP.ShellExecute(pass1, , , "print", vbNormalFocus)
Set objShellDP = Nothing
Set objShell = Nothing
'**** (2)該当する商品の顧客リストを印刷する ****
DoCmd.OpenReport "R_顧客リスト", acViewNormal, "", "", acNormal
'****
No.4ベストアンサー
- 回答日時:
WaitForSingleObject は呼び出し元がフリーズしたように感じるので
別解です。
Option Explicit
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'http://www.wmifun.net/library/win32_printjob.html
Function WaitPrintIn(ByVal DocName As String) As Boolean
Dim strComputer As String
Dim objWMIService As Object
Dim colPrintJobs As Object
Dim objPrintJob As Object
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colPrintJobs = objWMIService.ExecQuery _
("SELECT * FROM Win32_PrintJob WHERE Document = '" & DocName & "'")
If colPrintJobs.Count > 0 Then
WaitPrintIn = True
End If
End Function
Function WaitPrintOut(ByVal DocName As String) As Boolean
Dim strComputer As String
Dim objWMIService As Object
Dim colPrintJobs As Object
Dim objPrintJob As Object
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colPrintJobs = objWMIService.ExecQuery _
("SELECT * FROM Win32_PrintJob WHERE Document = '" & DocName & "'")
If colPrintJobs.Count = 0 Then
WaitPrintOut = True
End If
End Function
Sub こまんど()
Dim Pass1 As String
Dim oFs As Object
Dim oShell As Object
Dim sName As String
Set oFs = CreateObject("Scripting.FilesystemObject")
Set oShell = CreateObject("Shell.Application")
Pass1 = "C:\商品図面\" & rstTable!図番 & ".pdf"
sName = oFs.getFilename(Pass1)
Call oShell.ShellExecute(Pass1, , , "print", vbNormalFocus)
Do Until WaitPrintIn(sName) = True '印刷処理に取り掛かるまで待機
Sleep 500
DoEvents
Loop
Do Until WaitPrintOut(sName) = True '印刷が終わるまで待機
Sleep 500
DoEvents
Loop
MsgBox ""
'DoCmd.OpenReport "R_顧客リスト", acViewNormal, "", "", acNormal
'もしかしたら↑の一行だけをサブモジュールにして呼び出した方が良いかも
'途中省略
Set oFs = Nothing: Set oShell = Nothing
MsgBox "おしまい"
End Sub
※試したわけではない(紙とインクがもったいない・・)ので結果は不明です。
とりあえず、お試しあれ。
投稿用にインデントの代わりに全角スペースを使っています。
なお、こちら(Windows7 AcroRD32 Ver10.1.1)では印刷終了後には
アクロリーダーは自動的に閉じました。
出来ました!完璧なシーケンスで複数種類のドキュメントが順番どおり出力されました。
感謝感激です。何とお礼を言ってよいやら...
本当に有難うございました。
No.3
- 回答日時:
これで良いのかな?よく分からんけど (^^ゞ
Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, _
ByVal dwMilliseconds As Long) As Long
Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
'--- Win32 API 定数の宣言 ---
Global Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
Global Const INFINITE As Long = &HFFFF
Sub WaitRun()
Dim TaskId As Long 'タスクID
Dim hProc As Variant 'プロセスハンドル
' 外部プログラムの実行
TaskId = Shell("C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe /p " & "E:\PDF\20111111120222.pdf", 2)
' プロセスハンドルの取得
hProc = OpenProcess(PROCESS_ALL_ACCESS, False, TaskId)
' プロセスのオープン
If OpenProcess(PROCESS_ALL_ACCESS, False, TaskId) <> vbNull Then
' プロセスのシグナル待ち
Call WaitForSingleObject(hProc, INFINITE)
' プロセスクローズ
CloseHandle hProc
End If
beep: beep
MsgBox ""
End Sub
ネタ元はこちらです。丸写しです・・・
http://www.moug.net/tech/exvba/0150034.html
私もあれからネットで探したモジュールのサンプルを改造して色々試してみました。外部プログラムでの作業が終了するまでルーチンを待機させる為には"WaitForSingleObject"関数が有効というところまではわかりましたが、外部プログラムそのものをマニュアルで閉じないと待機解除にならず、それでは担当者がPCに付きっ切りになってしまいます。
出来たら印刷終了を以ってプログラムが自動的に閉じられ、ルーチンも自動的に再開できないかと虫の良い事を考えています。
もう少し苦しんでみます。有難うございました。
No.2
- 回答日時:
Yahoo知恵袋でも答えたのですが、結局
> Call objShellDP.ShellExecute(pass1, , , "print", vbNormalFocus)
が非同期処理になっているために、Adobe Readerの起動を待たずに
> DoCmd.OpenReport "R_顧客リスト", acViewNormal, "", "", acNormal
を実行してしまいます。
あちらの回答のようにプロセスIDを元に待つようにすれば、とりあえずは回避できるように思いますが、Adobe Readerの仕様上、印刷がが終了してもプログラムのプロセスは自動終了しません。ユーザーにAdobe Readerの終了を行ってもうら必要があると思いますが、それは構いませんか?
有難うございます。実は金曜日までに仕上げるつもりで焦っていたのでYahoo!にも並行で質問させていただきました。こちらで併せて御礼申し上げます。
今回実は出力しようと思っている書類はACCESSからのダイレクト出力が2種類、Accrobat経由が2種類ありpdfは選択する商品によって枚数も多種多様です。
その4種類を順番に出力し且つ予め選択しておいた複数の商品を上から順番にひとつのルーチンでバッチ処理したいと考えています。
従って全ての出力が完了するまで、途中でマニュアル操作を加えるのは出来る限り避けたいと思っています。(都合の良い話で申し訳ありません)
先ほどネットで検索していたら"Shell"と"WaitForSingleObject"を組み合わせる事でシェルで実行したプロセスが完了するまでアプリの実行を待機できるとの記事を読みました。
"ShellExecute"を"Shell"に換えてAcrobat.exeの場所を特定する事でpdfのプリント中はVBを待機状態とし、その終了を以ってアプリの待機も解除するという様なことは無理でしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBA★PDFをPDFアプリで印刷しようと思っていますが上手くゆきません 1 2022/06/06 22:04
- Visual Basic(VBA) VBAでの共有パスにつきまして 1 2023/03/04 17:24
- Excel(エクセル) 製品番号での整列と、検索に関して 3 2023/06/28 19:20
- Visual Basic(VBA) VBAコードが作動せず、どこに問題があるのか教えて下さい。 3 2023/06/13 13:20
- Visual Basic(VBA) access count数を変数に格納 2 2022/03/30 19:21
- その他(買い物・ショッピング) 商品にラベルを貼って出荷するまでのの手順にについて 2 2022/09/29 15:26
- Excel(エクセル) フォルダ内のワードファイルをPDFに一括変換するVBA 3 2023/06/09 16:51
- Excel(エクセル) エクセルVBA、間違っているコード内容を正して頂けませんか? エクセルワークシートに納品書を作ったの 2 2023/08/02 21:13
- 経営情報システム accessでの請求管理について 12 2022/06/11 16:20
- 事件・犯罪 キャンペーン商品が品切れのスシロー。「人気商品が品切れ」を待機客に告知させるのは営業妨害か? 5 2022/07/22 13:30
このQ&Aを見た人はこんなQ&Aも見ています
-
風水の観点で選ぶ観葉植物とは?置き場所や上げたい運気ごとの注意点を紹介!
観葉植物で運気をアップするコツを、風水デザイン1級建築士の福島昌彦さんに伺った。
-
Access レポート印刷時のイベントについて
Access(アクセス)
-
ACCESS VBA レポートプレビューを一定時間が経過後自動的に閉じるようにする方法は?
Visual Basic(VBA)
-
VBAで印刷スプール終了の判定をする
Visual Basic(VBA)
-
-
4
Accessでのレポート印刷待機方法
Visual Basic(VBA)
-
5
ACCESSで印刷プレビューをした後の印刷ボタンを押したイベント取得につて
その他(プログラミング・Web制作)
-
6
フォームの高さを数値で指定したいのですが
Excel(エクセル)
-
7
プリンターを指定して印刷するには
Visual Basic(VBA)
-
8
アクセス IIfとSum関数を同時に使いたい場合
Access(アクセス)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Access VBAでクエリーのレコー...
-
Access フォームのデータがテー...
-
データベースの1要素に複数デー...
-
Access 既に開いているフォー...
-
テーブル1 2 3 の結合
-
Excel 2019 のピボットテーブル...
-
エクセルVBAで5行目からオート...
-
「直需」の意味を教えてください
-
Access テキスト型に対する指定...
-
BLOB型のPDF出力の方法
-
ACCESSのクエリで集計で、先頭...
-
作番ってどういう意味でしょうか?
-
エクセルグラフの凡例スペース
-
アクセス メモ型 255文字...
-
Oracle 2つのDate型の値の差を...
-
accessで重複を防ぎたい
-
Accessのリンクテーブルのパス...
-
Accessでテーブル名やクエリ名...
-
Accessレコードの追加や変更が...
-
3つの表を1つに縦に連結する
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Access VBAでクエリーのレコー...
-
Access IF文でテーブルに存在し...
-
データベースの1要素に複数デー...
-
ワードでの単純作業の効率化に...
-
Access フォームのデータがテー...
-
ACCESS で マクロの中でフィ...
-
Accessデータベースで行と列を...
-
ワードで保存するファイル名の...
-
別のDBからテーブルをコピーす...
-
ADOでレコードを閉じるタイミン...
-
Accessで名寄せグループの関係...
-
シングルクォーテーションとダ...
-
Access 縦(行)のデータを横(列)...
-
Access クエリ このレコードセ...
-
顧客IDを入力すると顧客名や住...
-
(ACCESS)連番取得について
-
Access2000 単票フォーム上の...
-
Access 既に開いているフォー...
-
文字化け、記号の含まれるフィ...
-
Access2013VBA 複数のテーブル...
おすすめ情報