none
VB.NETからのワード文章の印刷について RRS feed

  • 質問

  • 場違いであればご容赦くださいませ。

    山田@RCSと申します。


    VB.NETよりワードの印刷を行うべくコーディングしております。
    Windowsフォームアプリからワード文章を印刷する場合、
    事前バインディングか遅延バインディングかはともあれ、
    大きな流れとしては

    1.ワードのアプリケーションオブジェクト作成。
    2.ActivePrinterプロパティに使用プリンタ名のセット。
    3.目的のワード文章ファイルのオープン。
    4.PrintOutコマンドでの直接印刷、
        もしくは文章の表示(表示後編集のため)。
    5.処理後アプリケーションオブジェクトの後始末。

    のような手順かと思います。

    ここで、印刷を行うワード文章の種類により、両面印刷・片面印刷を
    切り替えたい場合は、物理的なプリンタが1つだったとしても
    通常ですと項番2で割り付けるべくプリンタとして
    予め両面用・片面用として準備しておき、都度目的に合わせて使い分ける
    ということが、一般的な手順かと思いますが...



    例えば、アプリケーションからではなく直接WORDを起動して、
    目的のファイルを印刷する場合。

    メニューの[開く]から、対象の文章を選んで表示した後
    目的に合わせて、プリンタのプロパティより片面・両面設定変更後
    印刷が可能ですよね。
    (ここでデフォルトプリンタのまま、両面印刷に変更しても、開いている
     ドキュメント印刷には、反映されるが、デフォルトプリンタ自体の設定は
     変更されていない。)

    これらの、手動の操作は、コーディングでは実現できないのでしょうか?

    自分なりに、生成されたWORDオブジェクトオブジェクトからプリンタ設定値
    変更に関して直接アクセスできるプロパティなりメソッドなりが見当たらない
    ため、そもそも変更は不可能と考えるべきなおかも知れませんが。

    ActivePrinterプロパティでは確かにプリンタ名称しか指定しないため
    この時点で、WORDオブジェクト内に使用するプリンタのオブジェクト
    データは実際に作られているわけではなく、実際にPrintOutコマンド
    実行時に、指定されたプリンタ情報を参照しているだけという様な
    解釈もできますが、そういうことなのでしょうか?




    プリンタの情報を一旦保存しておき、プリンタ自体を予め
    System.Drawing.Printing.PrintDocumentクラスなどで
    設定変更し、変更したものをActivePrinterプロパティで指定する
    処理が終わった後に、保存しておいたプリンタ情報を復元する。

    ですがこの方法ですと、同一アプリケーションから複数のWORDオブジェクト
    を起動する場合で、かつそれぞれ起動したワード文章で印刷方式が異なる
    場合には、対応できないとも考えます。


    やはり、最終的な結論としては、印刷目的に合わせてプリンタを
    複数作成するという手段しかないのでしょうか?

    2013年8月22日 6:15

回答

  •  やってできないことはありませんが、お勧めは…できない、かなぁ。

     ネイティブでは、DocumentProperties 関数で取得した DEVMODE 構造体を、CreateDC 関数に引き渡して印刷イメージを作成させます。よって、DEVMODE 構造体をあらかじめ保存しておくことで、ご希望のような印刷を実現できます。ユーザー デフォルトの印刷設定も、DocumentProperties 関数で変えられるんじゃないかなぁ?一応、最新の英語の方にリンクさせていますが、関数については日本語のリファレンスもあります。確認してください。VB アプリでは、これらを P/Invoke で呼び出せば、できます。

     ただ、DEVMODE 構造体には、プリンタ ドライバ毎の拡張部というオマケがついています。このため、プリンタ毎に DEVMODE 構造体を管理しなければなりません。dmDuplex が両面印刷の定義ですが、ここを使用しているか、拡張部を使用しているか、ドライバ依存なのでわかりません。また、ドライバのバージョンよって、拡張部の内容が変わるかもしれません。つまり、ドライバをバージョンアップする毎に情報を作り直さなければならないかもしれません。そういうところが、お勧めできないところです。

     なお、プリンタ ドライバには、V3 と V4 があります。上の話は V3 ドライバの場合です。Windows Vista 以降で推奨されている V4 ドライバの方は、わかりません。


    Jitta@わんくま同盟

    • 回答としてマーク RNC-COM 2013年8月26日 2:00
    2013年8月22日 11:59

すべての返信

  •  やってできないことはありませんが、お勧めは…できない、かなぁ。

     ネイティブでは、DocumentProperties 関数で取得した DEVMODE 構造体を、CreateDC 関数に引き渡して印刷イメージを作成させます。よって、DEVMODE 構造体をあらかじめ保存しておくことで、ご希望のような印刷を実現できます。ユーザー デフォルトの印刷設定も、DocumentProperties 関数で変えられるんじゃないかなぁ?一応、最新の英語の方にリンクさせていますが、関数については日本語のリファレンスもあります。確認してください。VB アプリでは、これらを P/Invoke で呼び出せば、できます。

     ただ、DEVMODE 構造体には、プリンタ ドライバ毎の拡張部というオマケがついています。このため、プリンタ毎に DEVMODE 構造体を管理しなければなりません。dmDuplex が両面印刷の定義ですが、ここを使用しているか、拡張部を使用しているか、ドライバ依存なのでわかりません。また、ドライバのバージョンよって、拡張部の内容が変わるかもしれません。つまり、ドライバをバージョンアップする毎に情報を作り直さなければならないかもしれません。そういうところが、お勧めできないところです。

     なお、プリンタ ドライバには、V3 と V4 があります。上の話は V3 ドライバの場合です。Windows Vista 以降で推奨されている V4 ドライバの方は、わかりません。


    Jitta@わんくま同盟

    • 回答としてマーク RNC-COM 2013年8月26日 2:00
    2013年8月22日 11:59
  • > Jitta@わんくま同盟 様

    レスありがとうございます。

    内容を拝見しまして、二つ確認と言いますか...

    1つ目として、DocumentProperties関数で、指定したプリンタの現状のDEVMODE構造体を

    取得することになると思いますが、これにはダイアログを表示させてプリンタを選ぶ操作が必要に

    なると思います。

    実は、この辺りの、手動の操作も割愛し、ダイアログなどを非表示で取得することが、今回の私どもの

    要件になるので、DocumentProperties関数がダイアログ非表示で実行できればよいのですが

    残念ながら、私にはその方法が見つけ出せませんでした。

    また2つ目ですが

    CreateDCで作成した、プリンタのデバイスコンテキストに、Word文章自体を引き渡して
    StartDoc関数、EndDoc関数でくくって印刷を行うという事でしょうか?

    となりますと、Word文章自体を、イメージ(画像データ)として扱い作成したプリンタデバイスコンテキストに

    指定する?!というような手段になりますか?

    恥ずかしながら、ワード文章をプリンタデバイスコンテキストに引き渡すと言う概念がピンと来ていません。

    ご指摘にありましたとおり、DEVMODE構造体に関しては、私も以前から、プリンタドライバ毎の影響があるため

    両面印刷などは、アプリケーションのみでの自動切換えなどは難しいなと考えてはいたので、実は避けて通れるなら

    と考えていたところでした。

    やはり、状況を踏まえると、プリンタをその環境ごとに用意しながら、システムから利用すると言うように方針を決めたいと思います。

    貴重なご意見ありがとうございました。

    2013年8月26日 2:00
  •  ごめんなさい、返信に気づかなかった。

    1つ目として、DocumentProperties関数で、指定したプリンタの現状のDEVMODE構造体を取得することになると思いますが、これにはダイアログを表示させてプリンタを選ぶ操作が必要になると思います。

     はい、たいていはそうですが、ダイアログを表示させないこともできます。ダイアログが表示されるのは、fMode に DM_IN_PROMPT が指定されているときです。これを設定しなければ、ダイアログを表示せずに設定を変更できます。

    また2つ目ですがCreateDCで作成した、プリンタのデバイスコンテキストに、Word文章自体を引き渡して StartDoc関数、EndDoc関数でくくって印刷を行うという事でしょうか?

     いえ、「ユーザー デフォルトの印刷設定も、DocumentProperties 関数で変えられるんじゃないかなぁ?」の部分ですが、次のような手順になります。

    1. まず、印刷前の準備手順として、印刷したい設定内容をプリンターのユーザーデフォルト印刷設定に設定する。
    2. その状態の DEVMODE を、アプリケーション設定として保存する。
    3. 上記2手順が済めば、印刷設定をどのように変更しても OK。以下、目的の印刷を行う場合の手順。
    4. アプリケーションで、「現在の DEVMODE の設定」を取得し、退避する。
    5. アプリケーションで、準備手順で取得した印刷用の印刷設定に変更する。
    6. アプリケーションから Word を、印刷用に起動する。
    7. 印刷終了後、退避しておいた「現在の DEVMODE の設定」に戻す。

     実は、いろいろと聞くと上記の様に行っているらしいアプリケーションがありまして、そのアプリケーションの導入実績から、問題はないんじゃないかと思います。もちろん、拡張部が問題になりますので、そこはしっかり確認が必要ですが。


    Jitta@わんくま同盟

    2013年9月2日 12:18