職場に持ち込む都合上、ついでに記事にします。
実務で使う場合は、ご自分で検証して、自己責任でお願いします。
やりたいこと
住民税の特別徴収のデータから、eLTAX指定のCSV様式(変換後)に変換します。
変換前
市区町村コード | 市区町村名 | 指定番号 | 給与件数 | 給与税額 |
---|---|---|---|---|
500001 | 甲子町 | 999999 | 1 | 1000 |
500002 | 乙丑町 | 999999 | 2 | 2000 |
500003 | 丙寅町 | 999999 | 3 | 3000 |
500004 | 丁卯町 | 999999 | 4 | 4000 |
500005 | 戊辰町 | 999999 | 5 | 5000 |
500006 | 己巳町 | 999999 | 6 | 6000 |
※後述の模擬データからデータに起こせます。
変換後
※空欄に見える箇所は、下記の通り、nullと半角スペースと両方あります。
CSVとして保存するネタを作るコード
模擬データを変換し、パラメータを使って、生成するクエリを作ります。
Power Queryの技術的には難しくないですけど、可読性が上がるよう、努めました。
パラメータ(年月)
システムなどから出るデータに年月が入っていない、入っていても表の枠外となる例が多いと思うので、パラメータを採用しました。こんな感じで登録します。
このうち年と月を使って、後述のクエリ内で「平成ベース」で年月4桁を生成することになります。
Excelシート内でパラメータを指定する方法については、下記記事を参考にしてください。
パラメータテーブルと、その値を取るカスタム関数|Power Query
模擬データ(t_sample)
こんな感じのデータが得られる(成形する)ものとします。たいていはPower Queryでたぶん乗りきれるはずです。
自治体コードも架空なので、このデータのまま読み込みをかけると、その旨、エラーが出ると思います。
※空のクエリを作り、詳細エディタで、下記コードを貼ると、模擬データができます。
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjUAAkMlHaXnUzY9XTvh+ZRdQLYlGAAZIAlDoAKlWB2oUiOgyJOdM5/smIimFCRhhKLUGKR0x8yn61vRlIIkjFGUmoCVNj7tXY+mFCRhgqLUFCjyrKPrxb4NaEpBEqYoSs2AIk+3b3y6fTOaUpCEGVhpLAA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [市区町村コード = _t, 市区町村名 = _t, 指定番号 = _t, 給与件数 = _t, 給与税額 = _t]),
変更された型 = Table.TransformColumnTypes(Source,{{"給与件数", type number}, {"給与税額", type number}})
in
変更された型
クエリのコード
let
ヘッダーレコード = Table.FromRows({{1,99}}),
エンドレコード = Table.FromRows({{9," "}}),
//以下、データレコードの作成
納付年月の指定 = Table.AddColumn(t_sample, "納付年月",
each Text.Format("#{0}#{1}",{Date.Year(年月)-2000+12,Number.ToText(Date.Month(年月),"00")})
),
おまけ列の生成 = Table.AddColumn(納付年月の指定, "その他セット",
each [データ区分=3,督促=0,延滞=0,合計件数=[給与件数],合計税額=[給与税額],備考=null,ダミー=" "]
),
レコードの展開 = Table.ExpandRecordColumn(おまけ列の生成, "その他セット", Record.FieldNames(おまけ列の生成[その他セット]{0})),
仕様通りに並び替え = Table.SelectColumns(レコードの展開,{"データ区分", "市区町村コード", "納付年月", "指定番号", "給与件数", "給与税額", "督促", "延滞", "合計件数", "合計税額", "備考", "ダミー"}),
//列名をColumn1~にする。
データレコード = Table.RemoveFirstN( Table.DemoteHeaders(仕様通りに並び替え),1 ),
//以下、トレーラーコードの作成
トレーラーの中身 = Table.FromRecords({
[区分= 8,給与件数合計=List.Sum(t_sample[給与件数]),給与税額合計=List.Sum(t_sample[給与税額]),
退職件数=null,退職税額合計=null,総件数=給与件数合計,総税額=給与税額合計,ダミー=" "]
}),
トレーラーレコード = Table.RemoveFirstN( Table.DemoteHeaders(トレーラーの中身),1 ),
//合成して仕上げ
合成 = Table.Combine({ヘッダーレコード,データレコード,トレーラーレコード,エンドレコード}),
変更された型 = Table.TransformColumnTypes(合成,
//{{Column1,type text},・・・,{Column12,type text}}ということ。
List.Transform( {1..12},each {Text.Format("Column#{0}",{_}),type text} )
)
in
変更された型
おまけ:CSVファイルに保存するVBAコード
一応、作ってみました。「ブックとじない版」は僕の技術力では面倒だったので、今日は諦めました。
Sub ExportCSV_and_Close()
If MsgBox("保存後、CSV出力します。よろしいですか?", vbYesNo) = vbNo Then
MsgBox "処理を取り消しました。"
Exit Sub
End If
ActiveWorkbook.Save
Dim path As String
Dim TargetSheetName As String
path = "C:\Users\Public\Documents\特徴住民税.csv"
TargetSheetName = "特徴住民税"
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Sheets(TargetSheetName).Select
ActiveWorkbook.SaveAs Filename:=path, FileFormat:=xlCSV
MsgBox "出力完了しました。"
Application.DisplayAlerts = True
ActiveWorkbook.Close
End Sub
解説
CSV仕様について
全銀CSVと似ています。以下、簡単に構造を説明します。
ヘッダーレコード
ただの始まりの印。データによらず一定。
データレコード
肝心のデータ部分。1納付先1行で、必要な分だけ行を増やせばいいです。
ちなみに、同じ自治体を複数行に分けて入れると、eLTAX側で合算集計をしてくれる雰囲気でした。
トレーラーレコード
データレコードの集計値を入れるところ。
エンドレコード
ただの終わりの印。データによらず一定。
※作成する際は必ず、公式ドキュメントを読みましょう。Excel手作業でも十分作れますよ。
個人住民税(特別徴収)CSVレイアウト仕様書(CSVフォーマット)|eLTAX
参考
eLTAXからの納税について
eLTAXには昨年、ダイレクト方式の納税制度ができました。これを導入してしまえば、eLtaxのwebサイトにログイン後、CSVをデータアップロードするだけで、納付できてしまいます。
納付担当あるいは住民税納税チェックをする人がeLTAXにアクセスできる、という組織であれば、おすすめです。
eLTAX自体や共通納税の始め方は、公式のホームページを見てください。
共通納税とは | eLTAX 地方税ポータルシステム
納付にはPCdeskはweb版を使おう。
PCdeskはeLTAXサービスを使うためのソフトウェアで、実務的には、そのデスクトップ版かweb版を使うことになります。
僕が試した限り、デスクトップ版はエラーメッセージが貧弱で、取り付く島もありません。
他方、web版ではエラーメッセージが細かく出て、どこが仕様に合っていないか分かります。なので、仕様とずれたファイルを作った場合でも、エラーメッセージを読めば、修正して読み込みに成功までたどり着ける可能性が高いです。
PCdesk(WEB版)|eLTAX 地方税ポータルシステム
記事の改訂履歴
うまくいかない箇所など出てくれば、随時修正します。
初版:2020/1/11 14:45
二訂:2020/1/14 23:45:おまけ列の生成にて、督促、加算をそれぞれnullから0に修正。nullだとエラーになりますね。すみません。