売上から送り状csvを生成


「一応、商社」なので出荷する商品がたくさんあります。
送り状はドットプリンターに汎用の送り状を印字を行っておりました。
送り状はお届け先、ご依頼主、商品、割れ物注意等が書かれたラベルです。
運送会社は送り状を張り付けてトラックに載せます。

運送会社が自社の送り状印字システムで印字して欲しいと頼んでくるようになりました。
運送会社の送り状印字システムは下記のとおり。

- ヤマトB2クラウド
- 佐川急便 e飛伝II
- 西濃 カンガルーマジック2
- 福山通運 iStar-X (アイスターテン)

私のところに運送会社の営業マンがやってきた。

## 弊社の送り状印字システムを導入のお願い
運送会社の営業マン：

- 送り状をレーザープリンター/サーマルプリンターで手軽に発行
- 自社システムで発行した送り状は追跡が楽
- 今月の運送料金もWebで閲覧印刷可能

私：

- 納品書と照らし合わせていちいち手入力は面倒
- 手間が増えるからダメ。

営業マン：

- 送り状のデータをインポートできます。

私：
弊社の売上のデータから御社のシステムに合わせた形式にcsvを作ればインポートできるんだね。
インポートができるのであれば弊社社員の手間も減らせる。
OK。
導入しよう。

## 外部データをどう作る?

売上で必要なデータは下記の通りになるだろう。

### 弊社データ



|売上伝票no|明細no|商品名|得意先名|得意先住所|
|:--|:--|:--|:--|:--|
|1|1|魔法のランプ|○×電化|京都府京都市|
|2|1|魔法のランプ|xx電化|大阪府吹田市|


運送会社の送り状のデータはこんな感じ。
説明しやすいように簡略化してます。

### 運送会社に渡す外部データ

|お問合せ番号|管理番号|元着区分|請求先cd|お届け先名|お届け先住所|ご依頼主名|ご依頼主住所|品名|
|:--|:--|:--|:--|:--|:--|:--|:--|:--|
|運送屋が採番|売上伝票no|着払or元払|弊社を表すコード|得意先名|得意先住所|弊社|弊社の住所|ワレモノ|

売上データから運送会社の送り状を作るときに気になる点は2つ。
これらの問題を解決できれば外部データが作れるに違いない。

- 項目名が全く違う
- 売上データにない項目

### 項目名を変える
SQL文でASを使って項目名を変えちゃいます。
下記のようにSQL文を実行しましょう。

```sql:ASを使って項目名を変更
 SELECT
 	売上伝票no AS 管理番号,
 	得意先名 AS お届け先名,
 	得意先住所 AS お届け先住所
 FROM
 	売上
 WHERE
 	売上伝票no=1
 GROUP BY
 	売上伝票no,
 	得意先名,
 	得意先住所
```

|管理番号|お届け先名|お届け先住所|
|:--|:--|:--|
|1|○×電気|京都府京都市|

これで項目名は解決ですね。

下記の項目は売上には無い。
どうしましょうか？

- お問い合わせ番号
- 元着区分
- 請求先cd
- ご依頼主名
- ご依頼主住所
- 品名

### 売上にない項目行を作る
実はSQL文で項目名を作れるんですよ。
下記のように実行します。

```sql:項目名を作る
 SELECT
 	"" AS お問合せ番号,
 	"0" AS 元着区分,  --元払 0 着払 1 元払が多い
 	"1234" AS 請求先cd,
 	"弊社" AS ご依頼主名,
 	”京都府京都市のどこか” AS ご依頼主住所,
 	"ワレモノ" AS 品名1
 FROM
 	売上
 WHERE
 	売上伝票no=1
```

|お問合せ番号|元着区分|請求先cd|ご依頼主名|ご依頼主住所|品名1|
|:--|:--|:--|:--|:--|:--|
| |1|1234|弊社|京都府京都市のどこか|ワレモノ|

これでイケる！

### 完成版?
行の位置とかを合わせて成型すると下記のようなSQL文になります。

```sql:完成形
 SELECT
  	"" AS お問合せ番号,
  	売上伝票no AS 管理番号,
  	"0" AS 元着区分,  --元払 0 着払 1 元払が多い	
  	"1234" AS 請求先cd,
  	得意先名 AS お届け先名,	
  	得意先住所 AS お届け先住所,
  	"弊社" AS ご依頼主名,
  	”京都府京都市のどこか” AS ご依頼主住所
  	"ワレモノ" AS 品名1
	FROM
  	売上
 WHERE
  	売上伝票no=1
 GROUP BY
 	売上伝票no,
 	得意先名,
 	得意先住所
 ```


|お問合せ番号|管理番号|元着区分|請求先cd|お届け先名|お届け先住所|ご依頼主名|ご依頼主住所|品名1|
|:--|:--|:--|:--|:--|:--|:--|:--|:--|
| |1|0|1234|○×電化|京都府京都市|弊社|弊社の住所|ワレモノ|

素晴らしい！
運送会社の送り状のデータになっている。
これをcsvに吐き出してインポートしてやればOKだね。
発送の社員に聞いてみよ。

### 納品先
発送の社員：
「納品先があるんだよ。
お届け先は納品先。」

！？

情報を整理しましょう。


|売上伝票no|明細no|商品名|得意先名|得意先住所|納品先印字区分|納品先名|納品先住所|
|:--|:--|:--|:--|:--|:--|:--|:--|
|1|1|魔法のランプ|○×電化|京都府京都市|1|アラジン|中国|
|2|1|魔法のランプ|xx電化|大阪市|0|||		

納品先印字区分があります。

納品先印字区分が1の時、

- 納品先名

納品先印字区分が0の時、

- 得意先名

にできないかな。

### Case式を使う
Case式を使えば解決。

```sql:case式
 SELECT
 	CASE WHEN 納品先印字区分=1 THEN 納品先名
 	ELSE 得意先名
 	END お届け先名
 FROM
 	売上
 WHERE
 	売上伝票no=1
 GROUP BY
 	得意先名,
 	納品先名
```

|お届け先名|
|:--|
|アラジン|

よし！

ご依頼主も書き換える必要がありますね。

ご依頼主も書き換え

```sql
 SELECT
 	CASE WHEN 納品先印字区分=1 THEN 得意先名
 	ELSE "弊社"
 	END ご依頼主名
 FROM
 	売上
 WHERE
 	売上伝票no=1
 GROUP BY
 	得意先名
```

|ご依頼主名|
|:--|
|○×電化|

住所等も一気に変更すると下記のようになるでしょう。

```sql
 SELECT
 	CASE WHEN 納品先印字区分=1 THEN 得意先名
 	ELSE "弊社"
 	END ご依頼主名,
 	CASE WHEN 納品先印字区分=1 THEN 得意先住所
   	ELSE "京都府京都市のどこか"
   	END ご依頼主住所,
 	CASE WHEN 納品先印字区分=1 THEN 納品先名
   	ELSE 得意先名
   	END お届け先名,
   	CASE WHEN 納品先印字区分=1 THEN 納品先名
    ELSE 得意先住所
    END お届け先住所
 FROM
 	売上
 WHERE
 	売上伝票no=1
 GROUP BY
 	ご依頼主名,
 	ご依頼主住所,
 	納品先名,
 	納品先住所
```


|ご依頼主名|ご依頼主住所|お届け先名|お届け先住所|
|:--|:--|:--|:--|
||○×電化|京都府京都市|アラジン|中国|

### 納品先も加味したSQL文と結果

```sql
  SELECT
  	"" AS お問合せ番号,
  	売上伝票no AS 管理番号,
  	"0" AS 元着区分,  --元払 0 着払 1 元払が多い	
  	"1234" AS 請求先cd,
  	CASE WHEN 納品先印字区分=1 THEN 納品先名
  	ELSE 得意先名
  	END お届け先名,	
  	CASE WHEN 納品先印字区分=1 THEN 納品先住所
  	ELSE 得意先住所 
  	END お届け先住所,
  	CASE WHEN 納品先印字区分=1 THEN 得意先名
  	ELSE "弊社" 
  	END ご依頼主名,
  	CASE WHEN 納品先印字区分=1 THEN 得意先住所
  	ELSE ”京都府京都市のどこか”
  	END ご依頼主住所,
  	"ワレモノ" AS 品名1
	FROM
  	売上
 WHERE
  	売上伝票no=1
 GROUP BY
 	売上伝票no,
 	得意先名,
 	得意先住所,
 	納品先印字区分,
 	納品先名,
 	納品先住所
 ```	


|お問合せ番号|管理番号|元着区分|請求先cd|お届け先名|お届け先住所|ご依頼主名|ご依頼主住所|品名1|
|:--|:--|:--|:--|:--|:--|:--|:--|:--|
||1|0|1234|アラジン|中国|○×電化|京都府京都市|ワレモノ|

このデータをCSVに出力すれば運送会社の送り状印字システムにインポートできます。

## 終わりに
実際のヤマト[B2Cloud](http://b2-dlserver.kuronekoyamato.co.jp/b2cloud/pdf/b2cloud_manual_05.pdf) や[カンガルーマジック2]( http://km2.seino.co.jp/support/km2/manual/kantan/kantan_B08.pdf) の送り状外部データの行数は44行もあります。
この概念を使えばSQL文とDBからのCSV出力だけで送り状外部データを作り出すことができるでしょう。

一度出力したデータよりも新しいものを出力するみたいな処理も必要だとは思いますが、
ここでは説明しません。
PowerShellで良ければ [PowerShellでDBから最新のデータをCSVで取得](https://qiita.com/arachan@github/items/dcadded6694e0be91539) を参照ください。