ACCESS2003 Aアクロバットでの印刷方法
- アクセスから2種類のドキュメントを連続してプリントアウトする方法について相談です。
- 商品図面と顧客リストを順番通りにプリントアウトする方法がわかりません。
- ネットで調べた結果、『WaitForSingleObject』関数を利用する方法があるようですが、難しいため助言を求めています。
- ベストアンサー
ACCESS2003 Aアクロバットを介しての印刷
実はアクセスから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 '****
- Nick925
- お礼率87% (34/39)
- その他(データベース)
- 回答数4
- ありがとう数7
- みんなの回答 (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)では印刷終了後には アクロリーダーは自動的に閉じました。
その他の回答 (3)
- nicotinism
- ベストアンサー率70% (1019/1452)
これで良いのかな?よく分からんけど (^^ゞ 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に付きっ切りになってしまいます。 出来たら印刷終了を以ってプログラムが自動的に閉じられ、ルーチンも自動的に再開できないかと虫の良い事を考えています。 もう少し苦しんでみます。有難うございました。
- nora1962
- ベストアンサー率60% (431/717)
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を待機状態とし、その終了を以ってアプリの待機も解除するという様なことは無理でしょうか?
- chieffish
- ベストアンサー率44% (1149/2554)
顧客リストもPDFにして図面と結合したら?
お礼
有難うございます。PDF図面はマスターで内容変更はありませんが、顧客リストは瞬間瞬間に変わってゆくデータベースですので毎回PDF化をするとしてもかなり負荷と時間のかかるルーチンになると思われます。 出来たら顧客リストは現行のままデータベースから直に出力処理したいと思っていますが、上手く行かない場合の代替案として検討させていただきます。
関連するQ&A
- objIE 2個目のサイズが適用されません。
VBAです。 Dim objShell As Object Dim objIE As New InternetExplorer Const READYSTATE_COMPLETE As Long = 4 Sub test1() Set objShell = CreateObject("Shell.Application") objIE.Visible = True objIE.Top = 0 objIE.Left = 0 objIE.Width = 100 objIE.Height = 100 objIE.navigate "http://www.goo.ne.jp/" objIE.Navigate2 "http://www.goo.ne.jp/", 2048 Set objIE = Nothing Set objShell = Nothing Set objShell = CreateObject("Shell.Application") objIE.Visible = True objIE.navigate "http://www.goo.ne.jp/" objIE.Navigate2 "http://www.goo.ne.jp/", 2048 'できない objIE.Top = 20 objIE.Left = 20 objIE.Width = 100 objIE.Height = 100 Set objIE = Nothing Set objShell = Nothing End Sub のように二つのブラウザを立ち上げて サイズを変えたいのですが 2個目のサイズが適用されません。 エラーにもなりません。 なぜでしょうか?
- ベストアンサー
- オフィス系ソフト
- VBAでIE操作をするサンプル
VBAでIE操作をするサンプルをネットでいくつか見ているのですが Sub Sample1() Dim objShell As Object Dim objIE As New InternetExplorer Set objShell = CreateObject("Shell.Application") objIE.Visible = True objIE.Navigate "http://www.yahoo.co.jp/" Set objIE = Nothing Set objShell = Nothing End Sub Sub Sample2() Dim objIE As InternetExplorer Set objIE = CreateObject("InternetExplorer.application") objIE.Visible = True objIE.Navigate "http://www.yahoo.co.jp/" Set objIE = Nothing End Sub ではどちらを使った方がいいのでしょうか? 圧倒的にSample2の方がネットでは多いのですが Sample1のやり方もあることを知りました。 Sample1の方法でブラウザを開くメリットはあるのでしょうか?
- ベストアンサー
- Visual Basic
- 削除が実行されない
以下のvbsを実行しても rmdir が実行されません どうしたらよいでしょうか Dim objShell Dim wExec Dim strResult Set objShell = CreateObject("WScript.Shell") objShell.CurrentDirectory = "C:\Users\xxx\Desktop\test" objShell.Exec ("cmd /c dir 201406* /b/ad/s >> ログ.txt") Set wExec = objShell.Exec ("cmd /c for /R %d in (201406*) do rmdir /S /Q ""%d""") Set wExec = Nothing Set objShell = Nothing
- 締切済み
- Visual Basic
- VBのコードが理解できません 解説いただけないでしょうか?
Dim ObjIE As Object Dim ObjShell As Object Dim ObjWindow As Object Dim WinExist As Boolean WinExist = False Set ObjShell = CreateObject("Shell.Application") For Each ObjWindow In ObjShell.Windows If TypeName(ObjWindow.Document) = "HTMLDocument" Then WinExist = True Set ObjIE = ObjWindow End If Next Set ObjShell = Nothing If Not WinExist = True Then Set ObjIE = CreateObject("InternetExplorer.Application") End If ObjIE.Navigate "http://nantokakantoka.html" ObjIE.Visible = True このコードを解説いただけないでしょうか? 特に WinExist For Each ObjWindow In ObjShell.Windows If TypeName(ObjWindow.Document) = "HTMLDocument" Then が何をしているのか分からないんです。
- ベストアンサー
- Visual Basic
- ipconfig /all を環境変数へ代入方法
http://d.hatena.ne.jp/necoyama3/20081218/1229604217 にて、ipconfigコマンドを実行して標準出力を取得する方法があり、下記VBSで きちんと動くのですが、 ------------------------------- Dim objShell Dim wExec Dim sCmd Set objShell = CreateObject("WScript.Shell") ' コマンド生成 sCmd = "ipconfig" ' コマンド実行 Set wExec = objShell.Exec("%ComSpec% /c " & sCmd) Do While wExec.Status = 0 Loop Result = wExec.StdOut.ReadAll MsgBox Result Set wExec = Nothing Set objShell = Nothing ----------------------------------- sCmdを下記に差し替えると、動かなくなります。 sCmd = "ipconfig /all" もしくは sCmd = "systeminfo" これらコマンドに差し替えてもVBSを動かす方法は ありますでしょうか。 直接、コマンドラインで ipconfig /all や systeminfoを入力する場合は きちんと出力されます。
- ベストアンサー
- その他(ソフトウェア)
- VBAでWebに値を入力
VBAでWebに値を入力する操作を考えています。 エクセルシートのA1に入っている値をWeb上に入力する操作なのですが、 以下のコードを実行すると「AllLog.keyword.Value = t」の部分でエラーになります。 googleではkeywordのところを「q」、yahooではkeywordのところを「p」にすれば問題ないのですが、 神奈川中央交通のページではエラーになってしまいます。 なぜですか?? Sub google() Dim objIE As InternetExplorer '参照設定:Microsoft Shell Controls and Automation Dim objShell As Shell Dim WinFlg As Boolean Dim objWin As Object Dim AllLog As Object On Error GoTo EndProcess Set objShell = New Shell For Each objWin In objShell.Windows If TypeName(objWin) = "IWebBrowser2" Then WinFlg = True Set objIE = objWin Exit For End If Next Set objShell = Nothing If WinFlg = False Then MsgBox "IEオブジェクトが取得できません", vbCritical Exit Sub End If EndProcess: If Err() > 0 Then MsgBox Err.Description End If With objIE Set AllLog = .Document.all t = Cells(1, 1) AllLog.keyword.Value = t End With Set objIE = Nothing End Sub
- ベストアンサー
- Visual Basic
- エクセルVBAで、IEからコピーするには
エクセル2000,win2000,IE6です。 次のような、コードを書きました。 Sub t03ccc() Dim objIE As Object 'IE オブジェクト参照用 Dim objShell As Object 'Shell オブジェクト参照用 Dim objWindow As Object 'Window オブジェクト参照用 Set objShell = CreateObject("Shell.Application") For Each objWindow In objShell.Windows '起動中のタイトルを探して。 If Left(objWindow.document.Title, 7) = "Office系" Then Set objIE = objWindow 'オブジェクトを代入 Msg = "Office系" Exit For End If Next If Msg <> "Office系" Then MsgBox "・・・スクリーニング結果一覧・・・がありません" Exit Sub End If objIE.ExecWB 17, 0 'OLECMDID_SELECTALL = 17 全てを選択 objIE.ExecWB 12, 0 'OLECMDID_COPY = 12 コピー Sheets("Sheet3").Select Rows("1:200").ClearContents Range("A1").Select ActiveSheet.Paste '''' objIE.Quit Set objIE = Nothing Set objShell = Nothing Set objWindow = Nothing End Sub これで、エクセルとIEしか開いてないときは巧くいくのですが、 エクスプローラーを同時に開くと実行時エラー438が出ます。 よろしくお願いします。
- ベストアンサー
- オフィス系ソフト
- エクセルのデータからフォルダを作成
エクセル選択・読み込み→フォルダ作成先指定・処理 →作成した空のフォルダを表示 という手順のプログラムです。 コモンダイアログで選んだエクセルのデータを元に、 新しいフォルダを作成したいと思っています。 エクセルには番号(一列目)、氏名(二列目)などが入っており 一人分の情報が一行目に、二人目の情報が二行目・・・という風に一行ずつに入っています。 指定した作成先に、そのエクセルで読み込んだ人数分だけ 空のフォルダを作成し、なおかつ一列目に入っていた番号を フォルダ名にしたいのですが、どうすればいいでしょうか。 途中まで作ってみましたが後が続きません。 よろしくお願いします。 Private Const BIF_RETURNONLYFSDIRS As Long = &H1 Dim objShell As New Shell Dim objFolder As Folder Private Sub Command1_Click() Set objShell = New Shell Set objFolder = objShell.BrowseForFolder(Me.hWnd, "フォルダを選択してください", BIF_RETURNONLYFSDIRS) If objFolder Is Nothing Then MsgBox "ファイルを開く作業をキャンセルします" Else End If Set objShell = Nothing End Sub
- ベストアンサー
- Visual Basic
- ACCESSのCSV出力に関して
教えて下さい。 ACCESSであるテーブルのデータをCSV出力しようとして、以下のような記述をしました。 結果、問題なく出力されましたが、データだけでなく、項目も出力しようと考えています。 その際にはどのような記述をすれば良いでしょうか? 初歩的な質問で申し訳ありません。 教えて下さい。 《内容》 Dim cnn As ADODB.Connection Dim rst As ADODB.Recordset Dim stSQL As String Dim stTBL As String Dim myWSH As Object 'WScript Dim myDesktopPath As String Dim stPath As String 'フルパス Dim objFSO As Object 'FileSystemObject Dim fsoTS As Object 'TextStream Dim tmp As Variant 'データ Dim re As Variant 'データ件数 Dim stDocName As String Const ForAppending = 8 stTBL = "t_合算" 'テーブル名 '開始メッセージ stDocName = "「" & stTBL & ".CSV」 ファイルをデスクトップに作成します" If MsgBox(stDocName, vbYesNo) = vbNo Then Exit Sub 'デスクトップパス取得 Set myWSH = CreateObject("WScript.Shell") myDesktopPath = myWSH.SpecialFolders("Desktop") Set myWSH = Nothing 'フルパス stPath = myDesktopPath & "\" & stTBL & ".CSV" '読み取り専用でセット Set cnn = CurrentProject.Connection stSQL = "SELECT * FROM " & stTBL Set rst = cnn.Execute(stSQL) If rst.EOF Then stDocName = "出力するデータがありませんでした" Else '文字列データ格納 (全データ出力、カンマ区切り) tmp = rst.GetString(adClipString, , ",", vbNewLine) '出力 Set objFSO = CreateObject("Scripting.FileSystemObject") With objFSO If .FileExists(stPath) Then '既存ファイル削除 Call .DeleteFile(stPath) End If Set fsoTS = .OpenTextFile(stPath, ForAppending, True) '文字列一括書き出し fsoTS.WriteLine tmp re = fsoTS.Line - 2 End With Set fsoTS = Nothing: Set objFSO = Nothing stDocName = re & " 件の CSVデータを出力しました。" End If MsgBox stDocName, vbOKOnly
- ベストアンサー
- オフィス系ソフト
- VBSでとある条件の時に処理をやらずに終了させる方法
VBSでとある条件の時に処理をやらずに終了させる方法で悩んでいます。 Dim ObjIE Dim ObjShell Dim ObjWindow Dim WinExist WinExist = False Set ObjShell = CreateObject("Shell.Application") For Each ObjWindow In ObjShell.Windows If TypeName(ObjWindow.Document) = "HTMLDocument" Then WinExist = True Set ObjIE = ObjWindow End If Next Set ObjShell = Nothing If Not WinExist = True Then Set ObjIE = CreateObject("InternetExplorer.Application") End If ・ ・ ・ ・ 例えばこのように起動しているIEを探します そこでもしYahoo!JAPANが起動していたら以降の処理をやらずに終わらせたいのですが・・・ どのような記述にすればよいでしょうか?
- ベストアンサー
- Visual Basic
お礼
出来ました!完璧なシーケンスで複数種類のドキュメントが順番どおり出力されました。 感謝感激です。何とお礼を言ってよいやら... 本当に有難うございました。