実はアクセスから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で質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Access2013VBA 複数のテーブル...
-
シングルクォーテーションとダ...
-
Accessデータベースで行と列を...
-
Access VBAでクエリーのレコー...
-
Access IF文でテーブルに存在し...
-
Access レコードロックについて...
-
ACCESS で マクロの中でフィ...
-
Access フォームのデータがテー...
-
ACCESSについて質問させ...
-
Access 縦(行)のデータを横(列)...
-
ファイルメーカーの集計につい...
-
別のDBからテーブルをコピーす...
-
Access2000 フォームからレコ...
-
データベースの1要素に複数デー...
-
Access 既に開いているフォー...
-
顧客IDを入力すると顧客名や住...
-
Excel 2019 のピボットテーブル...
-
エクセルVBAで5行目からオート...
-
「直需」の意味を教えてください
-
Oracle 2つのDate型の値の差を...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Access フォームのデータがテー...
-
Access IF文でテーブルに存在し...
-
Access VBAでクエリーのレコー...
-
ワードでの単純作業の効率化に...
-
ACCESS で マクロの中でフィ...
-
データベースの1要素に複数デー...
-
顧客IDを入力すると顧客名や住...
-
Accessで名寄せグループの関係...
-
別のDBからテーブルをコピーす...
-
シングルクォーテーションとダ...
-
Access 縦(行)のデータを横(列)...
-
Accessデータベースで行と列を...
-
ワードで保存するファイル名の...
-
Access 既に開いているフォー...
-
ADOでレコードを閉じるタイミン...
-
Access クロス集計クエリについて
-
ACCESS2003 Aアクロバットを介...
-
Access レコードロックについて...
-
Access2000 単票フォーム上の...
-
ファイルメーカーの集計につい...
おすすめ情報