合計で500ポイント差し上げます。プログラムについて質問いたします。お力を貸してください。


今、あるフォルダにpdfのファイルがたくさんはいっています。

ここから、あるエクセルのA列に沿って指定されたpdfを次々と印刷していくプログラムを作りたいです。

ツールはAcrobat,ghost script,Presto!ManagerなどがありプリンタはBrotherのMyMioという複合機です。


今はblue windというコマンドラインでpというコマンドを印刷に割り当てて印刷していますが(p file.pdfで印刷できる)連続して印刷できないので、とても不便です。さらになぜか、立ち上がったAcrobatをいちいち終了してから次の印刷を行わないと、Acrobatが「その名前のファイルは見つかりません」との旨のエラーを出します。ここは、blue wind特有のエラーかもしれませんのでよくわからなかったら気にしなくていいかもしれません。


とにかく、A列に書いてある a.pdf b.pdf c.pdf・・・の印刷が連続的に実行できれば文句がないです。


gs、Acrobatなどのパスは必要ならば、設定しなおすので適当な一般的な値を設定しておいてください。

その他質問も答えたいと思います。

よろしくお願いします。

回答の条件
  • 1人3回まで
  • 登録:2007/01/10 00:28:36
  • 終了:2007/01/16 12:04:12

ベストアンサー

id:openseed No.2

openseed回答回数51ベストアンサー獲得回数62007/01/10 01:14:38

ポイント400pt

似た質問が過去にあるようです。

http://q.hatena.ne.jp/1147713104

以下のURLが参考にVBScriptまたは、VBA でスクリプトを書くのが容易だとおもいます。

http://puremis.net/excel/code/083ja.shtml

http://blog.so-net.ne.jp/nakagami/2006-07-06


ん? この質問はコードが必要ということですか?

id:ReoReo7

ありがとうございます。できれば欲しいですね^-^;

2007/01/10 02:40:25

その他の回答(3件)

id:Mook No.1

Mook回答回数1312ベストアンサー獲得回数3912007/01/10 00:58:42

ポイント700pt

エクセルからPDFファイルを印刷するがとても参考になるかと思います。

VBA で実行するサンプル(上記のページの例を一部変更したもの)です。

赤い部分をご自身の環境に合わせて変更するれば、動くかと思います。

' --- PDF ファイルのおかれているパス
Const PDFFilePath = "C:\PDFFiles\"
' --- プリンタ設定
Const PrinterName As String = """Microsoft Office Document Image Writer"""
Const DriverName As String = """Microsoft Office Document Image Writer"""
Const PortName As String = """Microsoft Office Document Image Writer port:"""

'---------------------------------------------------------------------
Sub PrintingPDF()
'---------------------------------------------------------------------
    Dim myShell As Object
    Set myShell = CreateObject("WScript.Shell")
    
    Dim lastLine As Long
    lastLine = Range("A65535").End(xlUp).Row
    
    Dim FileName As String
    Dim i As Long
' --- A列を順番に印刷
    For i = 1 To lastLine
        FileName = PDFFilePath & Cells(i, "A").Value
        myShell.Run ("AcroRd32.exe /t " & FileName & " " & PrinterName & " " & DriverName & " " & PortName)
    Next
' --- 終了時のメッセージ
    MsgBox "Data has been sent. " & vbLf & _
        "Please close the instanse of Acrobat Reader after printed."
End Sub
id:ReoReo7

いつもながらさすがです。

早速試してみます。


-追記-

試してみました。

しかしうまくいかないです。

プログラムはバグはないようです。プログラムを改良してA1-A10まで実行できるようにしましたが、出力完了の(Data has been sent.)メッセージは出るものの、そのうちの一部しか実行できないようです。(一部または大部分印刷されない箇所がランダムにできてしまう。)

100%印刷を実行するプログラムにしたいです。

それから、プログラムの仕様を2点変更したいです。

(1)開始は、アクティブセルからとし、どんどん下を参照していって、空白の行でプログラムを停止するようにしたいです。どうしたらいいでしょうか。

(2)参照セル名が"a.pdf"ではなく" a.pdf "でも実行できるようにする(スペースを無視する)

今コメント欄に書いて下さった方がいるので、そちらを試してみます。できることならばマクロがいいですが・・・^-^A;

2007/01/10 14:56:42
id:openseed No.2

openseed回答回数51ベストアンサー獲得回数62007/01/10 01:14:38ここでベストアンサー

ポイント400pt

似た質問が過去にあるようです。

http://q.hatena.ne.jp/1147713104

以下のURLが参考にVBScriptまたは、VBA でスクリプトを書くのが容易だとおもいます。

http://puremis.net/excel/code/083ja.shtml

http://blog.so-net.ne.jp/nakagami/2006-07-06


ん? この質問はコードが必要ということですか?

id:ReoReo7

ありがとうございます。できれば欲しいですね^-^;

2007/01/10 02:40:25
id:b-wind No.3

b-wind回答回数3344ベストアンサー獲得回数4402007/01/10 01:42:51

ポイント22pt

コマンドラインで印刷できる状態にあるなら、シェルスクリプトかそれに類するものを使用するのがいいんじゃないでしょうか。


自分は VBScript 等は解らないので、Cygwin を入れて bash 使うのがありなら、スクリプトは提示できるのですが。

http://journal.mycom.co.jp/special/2002/cygwin/

id:ReoReo7

シェルスクリプトですね。

2007/01/10 02:40:42
id:Mook No.4

Mook回答回数1312ベストアンサー獲得回数3912007/01/10 16:18:55

ポイント1pt

あまり変わらないかもしれませんが、追加仕様と若干の修正です。

'---------------------------------------------------------------------
Sub PrintingPDF()
'---------------------------------------------------------------------
    Dim myShell As Object
    Set myShell = CreateObject("WScript.Shell")
    
' --- 指定セルの確認
    If ActiveCell.Column <> 1 Or ActiveCell.Columns.Count > 1 Then
        MsgBox "A列の単一セルが選択されていません"
        Exit Sub
    End If
        
' --- 開始行を設定
    Dim printLine As Long
    printLine = ActiveCell.Row
        
    Dim FileName As String
' --- A列のアクティブセルから空白セルが出るまで順番に印刷
    Do While Len(Cells(printLine, "A").Value) > 0
' --- セル内の前後のスペースを削除
        FileName = PDFFilePath & Trim(Cells(printLine, "A").Value)
' --- ファイルの有無を判定
        If Dir(FileName, vbNormal) = "" Then
            MsgBox "[" & FileName & "]が存在しません"
        Else
' --- ファイルパスにダブルコーテーションを付加
            FileName = """" & FileName & """"
' --- デフォルトプリンタを使用
            myShell.Run "AcroRd32.exe /t " & FileName, 0, True
' ** --- プリンタを指定 ---
' **        myShell.Run "AcroRd32.exe /t " & FileName & " " & PrinterName & " " & DriverName & " " & PortName, 0, True
        End If
        printLine = printLine + 1
    Loop
' --- 終了時のメッセージ
    MsgBox "データを送信しました。" & vbLf & "プリント終了後 Acrobat Reader を閉じてください"
End Sub
id:ReoReo7

すばらしい!使用は私の望みどおりになりました。

が、しかし・・!

やはり1つ飛ばしとかでしかファイルが印刷されませんね。なぜでしょう。コメント欄にコードを示します。パスもつけました。

2007/01/10 19:57:11
  • id:openseed
    なんだか、AcrobatReaderに バージョン依存がありそうなので、コメントにします。VBは苦手なので、JScript で書いてみました。


    a.bat:
    ---------------------------------------
    set PATH=%PATH%;C:\Program Files\Adobe\Reader 8.0\Reader
    cscript a.js Book1.xls
    pause

    ---------------------------------------

    a.js:
    ---------------------------------------
    var excelFile = WScript.Arguments.Item(0);
    var objExcel = WScript.GetObject(excelFile);

    var shell = WScript.CreateObject("WScript.Shell");
    var limit = 100;
    for(var i=1;i<=limit;i++){
    var filename = objExcel.Sheets("Sheet1").Cells(i, 1).value + "";
    if(filename == "undefined"){break;}

    WScript.echo(filename);
    var oExec = shell.Exec('AcroRd32.exe /cjs /t "' + filename + '"');
    while(oExec.Status == 0){WScript.Sleep(10);}
    }

    ---------------------------------------


    印刷には、a.bat を実行してください。

    15ファイルくらいでテストしましたが、大丈夫そうです。
    ただし、自己責任でお願いします・・・。

    ※ テストは、Acrobat Reader 8 を利用してます。
    サンプルにあった、プリンター名&ドライバー&ポートを指定するとうまく動きませんでした・・・(デフォルトのプリンタを利用)T_T


    追加の参考URL:
    http://scripting.cocolog-nifty.com/blog/2006/12/pdf_4c95.html

  • id:Mook
    なるほど。参考になりました。
    指定しない場合はデフォルトプリンタへ出力されるなら、提示したVBAも
      myShell.Run ("AcroRd32.exe /t """ & FileName & """" )
    だけでよさそうですね(最後から6行目)。提示したサンプルはパスにスペースがあった場合うまく動かないかもしれませんので、その際は前後に " を入れてください。
    (上記では修正)


    参考URL は参考になりましたが、そこにも /c /j の説明はなかったので、ちょっと気になるところです。
  • id:openseed
    Mook さんのサンプルで十分でしたよね・・・。
    寝ぼけていたので、「ありがとうございます。できれば欲しいですね^-^;」のコメントにつられて、暇つぶししてました・・・。

    今改めて、サンプルを読ませてもらい、ExcelのCellsの扱いを勉強させていただきました。


    ぼけてました、/cjs のオプションは以下から参照しましたm(_ _)m。
    http://scripting.cocolog-nifty.com/blog/2007/01/pdfadobereader7_8a57.html

    ここでも、ちゃんと紹介されていませんし、私もちゃんと調べていませんが、このオプション(/cjs)を利用しないと、同じAcrobatのインスタンスが再利用(?)され、最終的にWindowが閉じませんでした・・・。

    参考まで。
  • id:ReoReo7
    ありがとうございます。a.bat試してみます。
  • id:Mook
    openseed さん、
    わざわざ回答をいただき、ありがとうございました。
    紹介いただいた URL も大変参考になりました。


    なかなかきちんとした情報が見当たらなかったのですが、PDF にはコマンドベースでのオプションが多数あるようですね。


    今回の質問はよい勉強になりました。
    そういう意味では、ReoReo7 さんにも感謝です。
  • id:ReoReo7
    以下のように作りました。
    しかし、ところどころ抜けてしまいます・・・。
    a.pdf b.pdf c.pdf d.pdf
    を4つの行に並べておいて、全て印刷したいのに

    b.pdf d.pdf

    の2つのみが順不同で印刷されたりして大変不便です。
    以下使っているプログラム。


    ' --- PDF ファイルのおかれているパス
    Const PDFFilePath = "C:\kakomon\pdf\"
    ' --- プリンタ設定
    Const PrinterName As String = """Brother MFC-425CN USB Printer"""
    Const DriverName As String = """Brother MFC-425CN USB Printer"""
    Const PortName As String = """Brother MFC-425CN USB Printer port:USB002"

    '---------------------------------------------------------------------
    Sub PrintIt()
    '---------------------------------------------------------------------
    Dim myShell As Object
    Set myShell = CreateObject("WScript.Shell")

    ' --- 指定セルの確認
    ' If ActiveCell.Column <> 1 Or ActiveCell.Columns.Count > 1 Then
    ' MsgBox "A列の単一セルが選択されていません"
    ' Exit Sub
    ' End If

    ' --- 開始行を設定
    Dim printColumn As Long
    printColumn = ActiveCell.Column
    Dim printLine As Long
    printLine = ActiveCell.Row

    Dim FileName As String
    ' --- A列のアクティブセルから空白セルが出るまで順番に印刷
    Do While Len(Cells(printLine, printColumn).Value) > 0
    ' --- セル内の前後のスペースを削除
    FileName = PDFFilePath & Trim(Cells(printLine, printColumn).Value)
    ' --- ファイルの有無を判定
    If Dir(FileName, vbNormal) = "" Then
    MsgBox "[" & FileName & "]が存在しません"
    Else
    ' --- ファイルパスにダブルコーテーションを付加
    FileName = """" & FileName & """"
    ' --- デフォルトプリンタを使用
    ' myShell.Run "AcroRd32.exe /t " & FileName, 0, True
    ' ** --- プリンタを指定 ---
    myShell.Run "AcroRd32.exe /t " & FileName & " " & PrinterName & " " & DriverName & " " & PortName, 0, True
    End If
    printLine = printLine + 1
    Loop
    ' --- 終了時のメッセージ
    MsgBox "データを送信しました。" & vbLf & "プリント終了後 Acrobat Reader を閉じてください"
    End Sub
  • id:Mook
    コードを確認しましたが、問題ないように見えます。

    ここからさきは、地道なデバッグ作業になるかと思いますが、
      myShell.Run ....
    の後の行に、
      MsgBox FileName & "を印刷しました。"
    のように待ちを入れ、どうなるか確認してみてはどうでしょうか。
    これで、もし問題なく出るようでしたら、コマンドを連続して実行していることが原因と考えられます。

    その場合、MsgBox のかわりに Sleep などの待ち時間を入れることで対策が取れます。
    具体的には、Sub ... の 前(Const の後ろあたり)に
      Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    を挿入
      myShell.Run ....
    の後の行に、
      Sleep 3000 ' --- 3秒の待ち時間
    のような感じです。
  • id:ReoReo7
    現在実行してみています。2つくらいならうまくいっています。
    次は20個にトライします。
  • id:ReoReo7
    待ちですが、問題なく出ます。
    そこで、ウェイトをいれてみました。
    Sleep 9000なので9秒ですね。

    しかし、20個のうち3個うまくいきませんでした。
    比較して特別大きいファイルでもないのに・・(10K~30KBです)

    USBプリンタかAdobeのリーダーのせいかもしれませんね。

    しかし勉強になるプログラムをありがとうございました。


    現在 openseedさんのa.batがうまくいっているので引き続き試してみます。
  • id:ReoReo7
    a.batで大丈夫そうです。すばらしい。
    マクロに比べたら遥かにスローです。が、
    このくらいの速度じゃないとAdobe Readerがついていけないものかもしれません。
  • id:Mook
    うまくいって何よりです。
    今回は openseed さんに脱帽ですね。

    推測ですが、今回の問題は /csj オプションが鍵だったように思います。Run も Exec もアプリケーションの終了待ちを行うのですが、 Run の終了待ちがうまくいかないのが原因だったように思います。


    これは バッチ(JScript)で行うか VBA で行うかででの差ではなく、コマンドの使用方法の差です。なので VBA で下記のようにすれば同様だと思います。

    ~~~~~~~~~~~~~~~~~~~~~~
    Const PDFFilePath = "C:\PDFFiles\"
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

    Sub PrintingPDF()
      Dim myShell As Object
      Set myShell = CreateObject("WScript.Shell")
      
      Dim oExec As Object
      Dim startLine As Long
      startLine = ActiveCell.Row

      Dim lastLine As Long
      lastLine = ActiveCell.End(xlDown).Row

      Dim printColumn As Long
      printColumn = ActiveCell.End(xlDown).Column

      Dim printLine As Long  
      Dim FileName As String
      Dim strMsg As String
      For printLine = startLine To lastLine
        FileName = """" & PDFFilePath & Trim(Cells(printLine, printColumn).Value) & """"
        msgStr = msgStr & FileName & vbNewLine
        Set oExec = myShell.Exec("AcroRd32.exe /cjs /t " & FileName)
        Do While oExec.Status = 0
          Sleep 100
        Loop
      Next
      MsgBox msgStr & "を印刷しました。"
    End Sub
    ~~~~~~~~~~~~~~~~~~~~~~
  • id:ReoReo7
    ありがとうございます。
    今は時間がないですが、後で試してみたいと思います。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません