レイアウトやデザインをすごく気にする場合の帳票印刷を考えてみる

# 概要
日本語プログラミング言語「プロデル」を用いて、レイアウトなどを一切気にしない場合に限った簡単な帳票印刷プログラムは昨年記事にしたところです。（拙稿「レイアウトやデザインを一切気にしない場合の帳票印刷を考えてみる」https://qiita.com/sanei_media/items/f68f8a2ca52de5da6680 ）
では、レイアウトをすごく気にする場合はどうでしょうか。すこし考えてみます。

# 準備する物
帳票として印刷したいデータを用意します。本記事ではCSVデータを使用します。例として、下図のようなBtoBの発注データを用意しました。
![p01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307195/72e48ff8-90da-112d-47cc-f960562fb996.jpeg)

:::note
上記のようなデータを作成する画面については、拙稿「表部品でカーソルを右に動かせるか考えてみる」（https://qiita.com/sanei_media/items/98915b81491f9ec182b6 ）をご参考ください。
:::

# 作り方
#### １　ウィンドウを作る
![p02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307195/5fa61f09-67d9-616e-bd38-d3d67da43ef5.jpeg)
単純にデータの内容をすべて印刷するだけであるなら、印刷ボタンだけでよいのですが、今回は発行条件として「計上した日」「計上番号」「仕入先」を絞り込めるようにしました。
さらに、重複発行がないように、すでに発行したものか、まだのものかも条件付けできるようにしました。（ただしこの機能はまだ研究中のため、今回の記事には出てきません。）

```
発注計上データというデータ表を作る
	発注計上データに{「計上番号」、「計上日」、「指定納期」、「仕入先」,「納品先」,「コード」,「商品」,「メーカー名」、「規格」、「単価」,「数量」,「単位」,「金額」,「摘要」、「備考」}という列を加える
	発注計上データへ「（ファイル名）.csv」から読み込む
```
はじめの手順に計上されたデータを読み込むプログラムを組み込みます。このデータから印刷対象のデータを抽出することになります。
```
		発注書データというデータ表を作る
		発注書データに{「計上番号」、「指定納期」、「仕入先」,「納品先」,「コード」,「商品」,「メーカー名」、「規格」、「単価」,「数量」,「単位」,「金額」,「摘要」、「備考」」}という列を加える

		計上番号一覧は、発注計上データの1列目を一覧で取得したもの
		計上日付一覧は、発注計上データの2列目を一覧で取得したもの
		仕入先一覧は、発注計上データの4列目を一覧で取得したもの
		データ行数は、1
		計上日付一覧のすべての計上日付についてそれぞれ繰り返す
			対象伝票日付は、計上日付を日時形式化したものの日付
			
			もし、対象開始日＜＝対象伝票日付　かつ　対象終了日＞＝対象伝票日付　ーー日付で洗い出し
			かつ　開始発注番号の内容＜＝計上番号一覧の[データ行数]番目の内容　かつ　終了発注番号の内容＞＝計上番号一覧の[データ行数]番目の内容　　ーー計上番号で洗い出し
			かつ　開始仕入先の内容＜＝仕入先一覧の[データ行数]番目の内容　かつ　終了仕入先の内容＞＝仕入先一覧の[データ行数]番目の内容　なら　ーー仕入先で洗い出し	
				　　　
					発注書データに｛「計上番号」＝計上番号一覧の[データ行数]番目の内容、「指定納期」＝発注計上データの3列目を一覧で取得したものの[データ行数]番目の内容,「仕入先」＝仕入先一覧の[データ行数]番目の内容
					,「納品先」＝発注計上データの5列目を一覧で取得したものの[データ行数]番目の内容,「コード」＝発注計上データの6列目を一覧で取得したものの[データ行数]番目の内容,「商品」＝発注計上データの7列目を一覧で取得したものの[データ行数]番目の内容
					,「メーカー名」＝発注計上データの8列目を一覧で取得したものの[データ行数]番目の内容,「規格」＝発注計上データの9列目を一覧で取得したものの[データ行数]番目の内容,「単価」＝発注計上データの10列目を一覧で取得したものの[データ行数]番目の内容
					,「数量」＝発注計上データの11列目を一覧で取得したものの[データ行数]番目の内容,「単位」＝発注計上データの12列目を一覧で取得したものの[データ行数]番目の内容,「金額」＝発注計上データの13列目を一覧で取得したものの[データ行数]番目の内容,「摘要」＝発注計上データの14列目を一覧で取得したものの[データ行数]番目の内容
					,「備考」＝発注計上データの15列目を一覧で取得したものの[データ行数]番目の内容｝を追加する

				もし終わり
					　　　　　	
			もし終わり
				データ行数は、データ行数+1		
		繰り返し終わり

発注書プレビューのキャンバス1をプリンタ1へ印刷プレビュー

```
発行ボタンが押された時の手順で、対象データを抽出し、発行すべきデータのみのデータ表をつくります。最後にそのデータをもって後述のキャンバスにレイアウトし、注文書として発行します。

#### ２　キャンバスを作る
![p03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307195/daae35ff-238a-0e88-4603-25493304ad99.jpeg)
抽出したデータを発注書にレイアウトするためのキャンバスを配したウィンドウを作ります。
はじめの手順にキャンバスを描くためのプログラムを組み込みます。合わせて用紙サイズをA4に指定します。
```
　　プリンタ1というプリンタを作る
	プリンタ1の用紙サイズは、「A4」
	選択図形は、無
	処理中は、×
	発注書データ表図形(キャンバス1)を作って表図形とする
	表図形をキャンバス1に加える
	表図形の位置は、｛10,10｝
	表図形の背景色を白に変える
　　　　　　そのはみ出し描画は、×
	表図形のページは、-1
	表図形のデータは、発注書データ
	キャンバス1のページは、0
	スライダ1の最大値を表図形の総ページ数に変える
	キャンバス1の内部大きさは、{(表図形の幅+20)*1.5,(表図形の高さ+20)*1.5}
	キャンバス1を更新する
```

#### ３　キャンバスに発注書をレイアウトする
##### 　①表題部（ヘッダ）
```
　　文字を描くーータイトル「発注書」
	その内容を「発　注　書」に変える
	その文字色を黒色に変える
	その位置を｛420,35｝に変える
	その文字配置を中央に変える
	そのフォントを「ＭＳ 明朝,20,太字」に変える

　　	文字を描くーー発注先（仕入先）
	その内容を「株式会社　サンプル商会　御中」に変える
	その文字色を黒色に変える
	その位置を｛50,80｝に変える
	そのフォントを「ＭＳ 明朝,12,下線」に変える
```
表題部に必要なデータを位置を指定して描きます。上記はあくまで例なので、必要なデータを適切なポジションに配置しましょう。別のデータ（CSVなり、INIなり）から読み込んでくる必要があることもあるでしょう。

##### 　②枠線
```
	セル高さは、50ーー高さ
	余白は、250ーーヘッダのサイズに合わせて増やす（下へ下がる）
	列数は、6ーー表の項目数
	表示行数は、[(プリンタ1の用紙大きさの高さ-余白*2)/セル高さを切り捨てたもの]の整数
	【ページサイズ:サイズ】は、サイズ(（列数+1）*100,(表示行数+1)*セル高さ)を作ったもの
	四角形を描いて枠図形とするーー外枠線
	枠図形の位置と大きさは、{30,余白,ページサイズの幅+50,ページサイズの高さ+1}
　　　　　　その太さを3に変える
　　　　　　
	自分の大きさは、{プリンタ1の用紙大きさの幅,プリンタ1の用紙大きさの高さ}
	自分の線色は、透明

　　　　//見出し
　　　　	横位置は、30
	列番号を1から列数まで増やしながら繰り返すーー縦罫線
		線を描く
	　　　　　　　　その始点は、｛横位置,余白｝
	　　　　　　　　その終点は、｛横位置,余白+ページサイズの高さ-1｝
	　　　　　　文字を描いてセル(1,列番号)とする
	　　　　　　　　その位置は、｛横位置,余白｝ーー文字の行内の高さ
		もし　列番号は、１ならーー商品コード
		　　　　　　文字を描くーー商品コード見出し
			その内容を「商品コード」に変える
			その文字色を黒色に変える
			そのフォントを「ＭＳ 明朝,9,太字」に変える
			その位置を｛横位置+5,余白+15｝に変える
		　　　　　　横位置=横位置+80
		他でもし　列番号は、２　ならーー商品名
		　　　　　　文字を描くーー商品名見出し
			その内容を「商品名」に変える
			その文字色を黒色に変える
			そのフォントを「ＭＳ 明朝,9,太字」に変える
			その位置を｛横位置,余白+5｝に変える

　　ーー（中略）ーー

	繰り返し終わり
	横位置は、30
	カウンタは、1
	縦位置は、セル高さ+余白
```
まず、外枠の四角を描き、次に縦罫線を描きます。合わせて、表部分のみだしも文字で描きます。
```
	行番号を1から表示行数まで増やしながら繰り返すーー横罫線
	　　　　　　
	　　　　　　もし　行番号は、１ならーー見出しのみ
			線を描く
			　その始点は、｛30,縦位置-5｝
			　その終点は、｛ページサイズの幅+77,縦位置-5｝
			　縦位置は、セル高さ+余白
			　その太さを2に変える
		でないなら
			線を描く
			その始点は、｛30,縦位置｝
			その終点は、｛ページサイズの幅+77,縦位置｝	
		もし終わり
		
		横位置は、30
```
次に横罫線を描きます。この時に出力する各項目も文字で描きます。なので、「行番号を~繰り返す」の「繰り返し終わり」はまだ先にあります。

##### 　③表部にデータを出力する
```
　　　　　　列番号を1から列数まで増やしながら繰り返す	ーーここから中身
			もし　発注書発行の発注書データの1列目を一覧で取得したものの[カウンタ]番目は、無　なら
				繰り返しから抜ける
			でないなら
				文字を描いてセル(行番号+1,列番号)とするーー受注内容
	　　　　　　　　　　		その大きさ調整を×に変える
	　　　　　　　　　　	もし　列番号は、１ならーー商品コード
		　　　　　　		横位置＝横位置
		　　　　　　		その位置と大きさは、｛横位置,縦位置,80,セル高さ｝
		　　　　　　		その文字配置を右に変える
		　　　　　　		その垂直文字配置を中央に変える
		　　　　　　		そのフォントを「ＭＳ 明朝,10.5」に変える
		　　　　　　		その内容を[発注書発行の発注書データの5列目を一覧で取得したものの[カウンタ]番目の内容]に変える
				他でもし　列番号は、２　ならーー商品名
					その大きさ調整を○に変える
					横位置＝横位置+80ーー横位置＝110
					その位置と大きさは、｛横位置,縦位置+3,230,（セル高さ-2）/2｝
					その内容を[発注書発行の発注書データの6列目を一覧で取得したものの[カウンタ]番目の内容]に変える
					そのフォントを「ＭＳ 明朝,10.5,太字」に変える
　　ーー（中略）ーー

			もし終わり
　　　　　	繰り返し終わり
	　　　　　　縦位置=縦位置+セル高さ
　　　　　　	カウンタを増やす
	繰り返し終わり（★）
```
★印の部分で横罫線からの繰り返しが終わります。文字を描く際は当然、横罫線や縦罫線と重ならないように位置と大きさを細かく調整する必要があります。（理想的な配置に調整できるまで、ままかかります。）

##### 　④フッター部
```
	四角形を描いて枠図形とするーー外枠線
	枠図形の位置と大きさは、{30,1000,745,100}
	
	文字を描くーーメッセージ
	その内容を「備　考」に変える
	その文字色を黒色に変える
	その文字サイズを9に変える
	その位置を｛30,1005｝に変える
```
フッター部分に必要な事項があれば、最後に描きます。これでおおむね完了です。

# 完成例
![p04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307195/2075d1fb-8f48-91b7-5c72-dd1deda149ea.jpeg)

# 最後に
今回は発注書を例にとりましたが、納品書や請求書など様々な帳票に生かすことができます。特に請求書については、今年10月からインボイス制度が始まることもあり、需要があるのではないでしょうか。
ただ、私の力不足もあり、今回紹介したプログラムもまだ未完成です。研究していく必要があると感じる次第です。
なお、開発中プログラムのため、必要なプログラムを一部割愛しております。予めご了承ください。

# 参考文献
「CSVファイルの内容をプリンタへ帳票印刷する」（https://rdr.utopiat.net/cgi/progbbs/forump.php?mode=view&id=86 ）：この記事で紹介しているプログラムは、プロデル開発者のゆうと氏より公開されてるこのプログラムをベースにしました。