全銀固定長データを1件だけ読んでみた

2019/5/14追記：複数データ版別記事でUPしました。
[続　全銀固定長データ～複数件データを読む（Power Query）](https://qiita.com/tanuki_phoenix/items/d15a16d7eca96a059f5a)

1ファイルに1件だけしか入っていないケースを前提に、読み取るクエリを作ったので、書き残しておきます。
（当方、固定長データは実務で使ったことがないです。~~何件も読む必要がある方はご自分で工夫してみてください。~~）


###用意するもの
#####固定長のデータ
今回は下記サイトのPDF「CSVファイルのデータ項目説明」をもとに、作成しました。
　[CSVファイルのサンプルダウンロード|ジャパンネット銀行](https://www.japannetbank.co.jp/service/payment/web_all/csv_download.html)

下記を詳細エディタに貼るとテーブルになるはずです。

```query:全銀固定長データ
let
    ソース = Json.Document(
                    Binary.Decompress(Binary.FromText("i45WMjQyNFCAg/d797zfN+/93jXv93W93zf//b6O9/sa3u+b/X7vZgX8wMDCwNDAwNgYXdgAXcTQ0sDAyARDoYKCEVHaEUZYmLzf1/x+7973+1re7933ft/c9/umAd2p8X7vNuwuBANDEIHXJxYIdTAGXvXUApZ0sQUTKMXGAgA=",BinaryEncoding.Base64),
                                      Compression.Deflate
                    )
            ),
    ソース1 = ソース{0}{0}
in
    ソース1
```

#####固定長の区分表
今回は同じくPDFから拾いました。下記を詳細エディタに貼るとテーブルになるはずです。

```query:桁指定シート
let
    ソース = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("lZTbToNAEIbfhWsuoPUQn4X0XQgbBZSG1thSbUxKbS0apU1MNFmxPswyHK76Ci6tAZp2YbkggeX7d2bnn1lFEQjSCQqI9gsWBuNKEAWZPgSNCEIEqdk/9Ea0j+2LKXRERYg9H4x5sSYKrTpJ/sUfJbKWyToI14/pJAgxLoeTpYZi6HWp4oRTFjnzjOaD4RKl12riWuUEm2p3+cmn3LLobgnYKYdsN9Q2DplOeqnep97HY5/fPyoE+wnwIh68gv1FRed1whAboN1nIWpRVvP+rx7wLKeq+b1SsVCWI9U839bmDfxMQzyL7HFkqnkla3I/5hcLPuoRG3bAHuZj1Zaqs9/2AU0ldbvF7DLp4Sp5tveGvfqU7gL8ab62Cfr1MQ40txx57W4GSwf/gbPZkvcRvSYT14tnuBbOm7669KyGNzIyw16OjQn0jMQzwu/PaLCi+Bm3pHCtxaEpBlfiyYpxFs0jiGJmxfbyBRvs/AE=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [項目名 = _t, 桁数 = _t, 区分 = _t]),
    変更された型 = Table.TransformColumnTypes(ソース,{{"項目名", type text}, {"桁数", Int64.Type}, {"区分", type text}})
in
    変更された型
```

###処理の流れ
1. 固定長データを、桁指定シートの指示にしたがい、区分別に分割し、1文字ずつばらしたリストで持つ。
2. 区分名を引数にして、桁指定シートのとおりに分割する処理をカスタム関数で作成。
3. 区分名だけのテーブルにカスタム関数を適用

###クエリのコード
####区分別に1文字ずつばらすクエリ

```query:全銀各要素
let
    Source = 桁指定シート,
    #"Grouped Rows" = Table.Group(Source, {"区分"}, {{"区分別桁数計", each List.Sum([桁数]), type number}}),
    #"Added Index" = Table.AddIndexColumn(#"Grouped Rows", "インデックス", 0, 1),
    #"Added Custom" = Table.AddColumn(#"Added Index", "累計文字数", each List.Sum( List.FirstN(#"Added Index"[区分別桁数計],[インデックス]) )),
    #"Added Custom1" = Table.AddColumn(#"Added Custom", "Value", each List.Range(全銀固定長データ,if [累計文字数]=null then 0 else [累計文字数],[区分別桁数計])),
    #"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"区分別桁数計", "インデックス", "累計文字数"}),
    #"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"区分", "Name"}})
in
    #"Renamed Columns"
```
####パースするカスタム関数

```query:fx_区分別パース
(区分名 as text)=>
let
    区分名で絞込 = Table.SelectRows(桁指定シート, each ([区分] = 区分名)),
    文字列リストの取得 = Table.AddColumn(区分名で絞込,"Value",
                                each 全銀各要素{[Name=[区分]]}[Value]
                        ),
    インデックス列追加 = Table.AddIndexColumn(文字列リストの取得, "インデックス", 0, 1),
    累積文字数列追加 = Table.AddColumn(インデックス列追加, "累積文字数",
                             each List.Sum( List.FirstN(インデックス列追加[桁数],[インデックス]) )
                      ),
    項目別文字列の取得 = Table.AddColumn(累積文字数列追加, "カスタム", each 
                                List.Range([Value],
                                            if [累積文字数]=null then 0 else [累積文字数],
                                            [桁数])
                        ),
    文字列の連結 = Table.AddColumn(項目別文字列の取得, "カスタム.1", 
                             each List.Accumulate([カスタム],"",(state,current)=>state&current)
                  ),
    不要行削除 = Table.RemoveColumns(文字列の連結,{"桁数", "区分", "Value", "インデックス", "累積文字数", "カスタム"})
in
    不要行削除
```
####カスタム関数を適用した完成品

```query:完成品
let
    Source = 桁指定シート,
    #"Removed Columns" = Table.RemoveColumns(Source,{"項目名", "桁数"}),
    #"Removed Duplicates" = Table.Distinct(#"Removed Columns"),
    #"Invoked Custom Function" = Table.AddColumn(#"Removed Duplicates", "データ", each fx_区分別パース([区分]))
in
    #"Invoked Custom Function"
```

###環境
Excel（Office365 バージョン1904）
Power Queryバージョン：2.68.5432.241 32 ビット