行単位印刷をページ単位印刷に変更する方法

タグの編集
投稿者 DAI  (社会人) 投稿日時 2015/7/7 12:10:15
初めて投稿させて頂きます。

VB初心者です。

現状、ある帳票をドットプリンタに出力しているのですが、
それをDocuWorks Printerに出力したい考えています。
そして、そのプログラムの中を確認するとPrinterオブジェクトを使用せず、
Win32 API(?)を使用しているようです。

行単位印刷からページ単位印刷に変更するには、
プログラムを大幅に修正しないといけないのか、
それとも簡単な修正で対応出来るのでしょうか?
もし簡単な方法があるのであれば教えて頂きたいと思います。

開発環境:Windows7 VB6.0
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2015/7/8 18:26:05
> VB初心者です。
VB6 って、17年前の開発ツールですよね…ご苦労様です。


> Win32 API(?)を使用しているようです。

そもそも、それが Win32 API であるかどうかすら分からない状況なのでしょうか?

どう書き換えるべきか、という質問なのであれば、
現状のコードが、いずれの API を使って記載されているのか
書いていただかないと…判断材料が少なすぎます。(^^;
(WritePrinter で RAW データを送りつけるような実装になっているのかな…)


> プログラムを大幅に修正しないといけないのか、
> それとも簡単な修正で対応出来るのでしょうか?

元のコードが、WritePrint で行データを送り込んでいる場合や、
Open ステートメントで LPT1 等を開いているケースだとすれば、
コードの大幅な書き換えが必要になりそうです。

とはいえ、前のプリンターがドットインパクトだったからといって、
プログラムが、ライン出力になっているとは限りません。たとえば、
「上下余白無しの横長用紙」に対するページ帳票出力として
実装されているケースもあるためです。
その場合は、用紙設定を見直すなどすれば対応できるかも知れませんね。



> それをDocuWorks Printerに出力したい考えています。
私自身は、そのプリンターを扱った経験が無いのですが、出力方法としては
DocuWorks SDK ベースの API (Declare 関数だったり COM インターフェイスだったり)を
使う方法、Printer オブジェクトを使う方法、帳票ツール類(CrystalReports 等)に
頼る方法などが考えられます。
投稿者 DAI  (社会人) 投稿日時 2015/7/9 09:43:16
魔界の仮面弁士さん 回答して頂いて有難うございます。

説明不足で申し訳ありません。少しプログラム内容を記述します。

プログラムの上部で

Public Declare Function WritePrinter Lib "winspool.drv" (ByVal _
    hPrinter As Long, pBuf As Any, ByVal cdBuf As Long, _
    pcWritten As Long) As Long

と設定。


例えば区切り線行を印刷する場合の記述

Function Kugiri_Line()

    sWrittenData = "=================================================="
    lReturn = WritePrinter(lhPrinter, ByVal sWrittenData, Len(sWrittenData), lpcWritten)

    sWrittenData = vbCrLf
    lReturn = WritePrinter(lhPrinter, ByVal sWrittenData, Len(sWrittenData), lpcWritten)

End Function

のように記述してあります。
このようなケースが帳票ヘッダ部や明細部と多数あります。
(sWrittenDataに色々なデータを移送し、WritePrinterを実行しています。)

現状、色々とウェブから情報を入手し、Printer オブジェクトを使用して
テストをしているところですが、なかなか思うようには進んでいない状態です。
(縦倍角文字や横倍角文字などで苦戦しています)


それと、「DocuWorks Printer」というのは、
通常、このプリンタに出力するとユーザーフォルダにPDFファイルのようなものが
作成されるのですが、現在はプログラムを実行しても「文書が作成できません」と
メッセージを表示して、ファイルが出来ていない状況です。
プログラムをデバッグしながら原因を調査中です。
投稿者 (削除されました)  () 投稿日時 2015/7/9 11:07:55
(削除されました)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2015/7/9 11:11:15
> 例えば区切り線行を印刷する場合の記述
WritePrinter を使うのであれば、RAW コマンドは String で渡すのではなく、
Byte 配列で受け渡した方が安全かと思いますよ。


> 現状、色々とウェブから情報を入手し、Printer オブジェクトを使用して
ページ帳票なら、Visual Basic 付属の Crystal Reports では駄目でしょうか。
今時のツールと比べると、設計が古いので罫線処理などの使い勝手は劣りますが、
コマンドを発行する方法よりは、開発しやすそうですが。

まぁ、既存資産の移植というのであれば、大幅な改定だと手戻りが多くなるので
リメイクとと修正のどちらが早いのかは微妙なところですが。


> (縦倍角文字や横倍角文字などで苦戦しています)
プリンター言語は何ですか? PostScript? 201PL?

プリンターにもよりますが、ESC/P 系だと、コマンドとしては
 [1C],[57],[49],四倍角にしたい文字列,[1C],[57],[48]
 [1B],[57],[49],横倍角にしたい文字列,[1C],[57],[48]
 [1C],[21],[08],縦倍角にしたい文字列,[1C],[21],[00]
あたりでしたっけ? 最近使ってないのでうろ覚えですが。


ページプリンタの場合、そういった倍角のための手続きは
そもそも用意されていなかったと思います。一部の機種では、
プリンターフォントとして2倍角文字を持っているものもありますが、
それが無い場合には、文字列としてではなく画像として出力することで
対応するという手があります。
(PDF 出力などが目的の場合、OCR が効かなくなってしまいますが…)


> ユーザーフォルダにPDFファイルのようなものが作成されるのですが、
DocuWorks文書、でしたっけ。
利用経験や開発経験は無いですが、動作デモなら見たことがあります。
古いバージョンなので、今とは状況が異なるのかもしれませんが。


> 現在はプログラムを実行しても「文書が作成できません」と
ライセンス? 設定?
たとえば Excel から DocuWorks Printer に印刷した場合も、
同じようなエラーになるのでしょうか?
投稿者 shu  (社会人) 投稿日時 2015/7/9 11:12:51
API宣言をなくし自作モジュールにWritePrinterを作成すると
変更が少なくてすむ気がします。

WritePrinterの内容としては
バッファ用コレクション変数、ラインバッファ用文字列変数を用意しておく(Dimではない。
モジュール変数にするとよいかと思います)
(1)ラインバッファの文字列変数に受け取った文字列を連結
※改行の手前までとする
(2)改行があればバッファ用変数にラインバッファを追加、ラインバッファをクリア
(3)バッファが1ページ相当量になったらPrintオブジェクトにて1ページ印刷し
 バッファをクリア

こんな感じの処理にしておくとどうでしょう?
改行忘れ、ページ量に満たない場合も考えフラッシュ処理もあった方がよいかもしれません。

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2015/7/9 12:06:56
調べてみたら、DocuWorks には HP-GL やら ESC/P やら 201H やら、
豊富なプリンタ言語のエミュレーションサポートがあるようですね。

元のプリンタ言語が使えるなら、無理に Printer オブジェクトに変えなくても、
WritePrinter のままでもいけないかな…。
(改ページなどの処置は追加する必要が出てくるかもしれませんが)


> (縦倍角文字や横倍角文字などで苦戦しています)
参考までに、倍角フォントの作成例。
(下記は 2 つの URL にも見えますが、実際には一つの URL です)
http://web.archive.org/web/20020615075306/http://www.netlaputa.ne.jp/~stadt/vb/t03/fontw.lzh

上記では、縦横比の異なるフォントを用いて、
フォームのデバイスコンテキストに描画しています。

プリンターへのデバイスコンテキストに渡して、TextOut API 等で文字列描画すれば
印刷にも使えるかも知れませんが…その結果が DocuWork Printer 側で
どのように出力されるかはわかりません。
投稿者 DAI  (社会人) 投稿日時 2015/7/9 14:47:45
魔界の仮面弁士 さん
shu さん

貴重なご意見有難うございます。

現在、shuさんが言われている
API宣言をなくし自作モジュールにWritePrinterを作成して対応しています。

Public Declare Function WritePrinter Lib "winspool.drv" (ByVal _
    hPrinter As Long, pBuf As Any, ByVal cdBuf As Long, _
    pcWritten As Long) As Long

             ↓

Public Function WritePrinter(ByVal hPrinter As Long, ByVal pBuf As String, _
                                       ByVal cdBuf As Long, pcWritten As Long) As Long
    Printer.Print pBuf
End Function

上記の対応をしたことによって帳票は作成出来ているのですが、
やはり縦倍角・横倍角に・・・。
(プログラムに点在する制御コードなどの削除も同時に行っています)


今回、縦倍角・横倍角対応のイメージを下記に記述します。

     コード1    コード2        コード3
                    YYYYY
     XXXXX    YYYYY    ZZZZZ
                       ↑
 「Y」を縦倍角で印字したい
  一段目の「Y」と二段めの「Y」を合わせて一文字として印字、
  今回ですと縦倍角の「Y」が5文字分印字されます。
  (イメージが分かりづらくて申し訳ありません)

お二方の意見を参考にし、色々とテストしてみたいと思います。


最後に質問に対する回答をさせて頂きます。

>たとえば Excel から DocuWorks Printer に印刷した場合も、
>同じようなエラーになるのでしょうか? 

普通にExcel等から印刷しても問題なく出力されます。
また、上記の自作モジュールからの印刷でも問題なく出力させれます。

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2015/7/9 15:53:43
> やはり縦倍角・横倍角に・・・。
かつてのワープロ時代には良く使われていましたが、今となっては表現しにくいですね。

とはいえ、倍角表現が必要な案件も少なからずあるようで、
市販の帳票ツールには倍角指定が可能なものが幾つかありますね。
(HTML の世界なら、CSS3 の transform scale が使えるのですけれども)


(案1)倍角指定を廃止し、別の表現方法に置き換える。
(案2)CreateFont/CreateFontIndirect のAPI で、縦横比の異なるフォントを作成する。
(案3)文字列を Print するのではなく、横長文字な画像を PaintPicture する。
(案4)Office の Word や OpenOffice の Writer などでの印刷に切り替える。


案2 は先ほど紹介した URL のような手順です。2000年ごろまでは、実際に
VB5 や VB6 から印刷するようなサンプルを公開しているサイトもあったのですが…。


案4 は、いわゆる「文字幅」指定。Word なら .Font.Scaling プロパティですかね。
文字サイズを倍にして文字幅を 50% にすれば、縦倍角になります。
(作り直しになってしまうので、今回は使いにくいでしょうけれども)
投稿者 (削除されました)  () 投稿日時 2015/7/9 16:33:02
(削除されました)
投稿者 DAI  (社会人) 投稿日時 2015/7/9 16:35:46
魔界の仮面弁士 さん

いろいろなご意見有難うございます。

基本的に「案1」 で対応したいと考えます。
また、時間があれば「案2」についてもテスト等を行えればと思っております。

本当に有難うございました。