Pythonを使って、住信SBIネット銀行の入出金明細とデビットカードの利用明細からJDLIBEX出納帳への入力用csvファイルを作成します。
前提として、JDLIBEX出納帳の「電子明細」~「明細取込」は使っていません。
住信SBIネット銀行
Pythonのコードは以下の通り。
import pandas as pd # 消費税の計算で四捨五入を行うため from decimal import Decimal, ROUND_HALF_UP def r_round(x): return int(Decimal(str(x)).quantize(Decimal('0'),rounding=ROUND_HALF_UP)) import os import unicodedata import shutil os.chdir(r'C:\Users\XXXXX\XXXXX') # JDLのデータ入力用CSVファイルの1行目から4行目(4行目はタイトル)をコピーする shutil.copyfile('org.csv','py_yokin.csv') # 住信SBIネット銀行の入出金明細を読み込み df_temp = pd.read_csv('nyushukinmeisai_20241101.csv',encoding='cp932') # '出金金額(円)'、'入金金額(円)'の記載内容にコンマ「,」が使用されているのでそれを削除する df_temp.replace(',', '',inplace = True,regex=True) # 列を追加する df_temp['承認番号']='' df_temp['内容2']=df_temp['内容'] # 後でstr.isdecimal()を使用したいので.astype('str')とする # CSVファイルを読み込む際にdtype=strと指定すると、'出金金額(円)'、'入金金額(円)'の空欄にnanが入らないので、isdecimalを使用したときにエラーが出る # いったんCSVファイルを読み込んだ後で.astypeを使用すると、'出金金額(円)'、'入金金額(円)'の空欄にnanが入る # また、df_temp = df_temp.astype('str')という書き方ではだめで、新しいdataframeを指定する df_temp2 = df_temp.astype('str') df_temp2.loc[df_temp2['出金金額(円)'].str.isdecimal(),'出金'] = df_temp2['出金金額(円)'] df_temp2.loc[df_temp2['入金金額(円)'].str.isdecimal(),'入金'] = df_temp2['入金金額(円)'] df = df_temp2.astype({'出金': float,'入金': float}) # 半角に変換する関数 全角の空白も半角の空白に置き換わる def hankaku(text): return unicodedata.normalize('NFKC', text) # デビットカードを利用している場合(df['内容']に文字列'デビット'が含まれている場合)は、'承認番号'にデビットカードの承認番号(半角)を入れる df.loc[df['内容'].str.contains('デビット'), '承認番号'] = df['内容'].map(hankaku).str[5:11] # デビットカードの利用明細を読み込み df_temp = pd.read_csv('meisai_20241101111932126.csv',encoding='cp932',dtype=str) # Excelのvlookup関数に似た処理を行う df_temp.set_index('承認番号',inplace=True) dic_debit = df_temp['お取引内容'].to_dict() # '承認番号'をキーにしてデビットカードのCSVファイルの'お取引内容'を検索し、'内容2'に入れる df.loc[df['内容'].str.contains('デビット'), '内容2'] = df['承認番号'].map(dic_debit) # '内容2'の文字列について # 英数字は半角にする df['内容2'] = df['内容2'].map(hankaku) # 前後の空白を削除 df['内容2'] = df['内容2'].str.strip() # 半角の空白は全角の空白にする df['内容2'] = df['内容2'].str.replace(' ',' ') # 出金のデータ作成 # JDLの入力用データと同じ列数のdataframeを作成して、内容をコピーする # indexを指定しないと、['A']にデータが入らない df_out = pd.DataFrame(index = df.index, columns=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','AA','AB','AC','AD']) #要素の転記 df_out['A'] = '1000' df_out['B'] = '0' df_out['C'] = df['日付'].str[0:4] + df['日付'].str[5:7] + df['日付'].str[8:10] df_out['D'] = '183' df_out['E'] = '' df_out['F'] = '' df_out['G'] = '1' df_out['H'] = '' df_out['I'] = '' df_out['J'] = '' df_out['K'] = '' df_out['L'] = df['出金'] df_out['M'] = 0 df_out['N'] = '131' df_out['O'] = '' df_out['P'] = '' df_out['Q'] = '3' df_out['R'] = '' df_out['S'] = '' df_out['T'] = '' df_out['U'] = '' df_out['V'] = df['出金'] df_out['W'] = 0 df_out['X'] = df['内容2'] df_out['Y'] = '' df_out['Z'] = '' df_out['AA'] = '0' df_out['AB'] = '' df_out['AC'] = '0' df_out['AD'] = 'no' # df['出金金額(円)']に金額が入っているデータとindexが一致するデータを抽出する df_out_dec = df_out[df['出金金額(円)'].str.isdecimal()] # 入金のデータ作成 # JDLの入力用データと同じ列数のdataframeを作成して、内容をコピーする # indexを指定しないと、['A']にデータが入らない df_in = pd.DataFrame(index = df.index, columns=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','AA','AB','AC','AD']) # 要素の転記 df_in['A'] = '1000' df_in['B'] = '0' df_in['C'] = df['日付'].str[0:4] + df['日付'].str[5:7] + df['日付'].str[8:10] df_in['D'] = '131' df_in['E'] = '' df_in['F'] = '' df_in['G'] = '3' df_in['H'] = '' df_in['I'] = '' df_in['J'] = '' df_in['K'] = '' df_in['L'] = df['入金'] df_in['M'] = 0 df_in['N'] = '319' df_in['O'] = '' df_in['P'] = '' df_in['Q'] = '3' df_in['R'] = '' df_in['S'] = '' df_in['T'] = '' df_in['U'] = '' df_in['V'] = df['入金'] df_in['W'] = 0 df_in['X'] = df['内容2'] df_in['Y'] = '' df_in['Z'] = '' df_in['AA'] = '0' df_in['AB'] = '' df_in['AC'] = '0' df_in['AD'] = 'no' # df['入金金額(円)']に金額が入っているデータとindexが一致するデータを抽出する df_in_dec = df_in[df['入金金額(円)'].str.isdecimal()] # 出金データと入金データを連結する # sort_indexを行うことにより、データの並び順が元の入出金明細と同じになる df_concat = pd.concat([df_out_dec, df_in_dec]).sort_index() # '内容2'の文字列から、勘定科目等を判定する df_concat.loc[df_concat['X'] == 'AAAAA, ['N','Q']] =['319','1'] df_concat.loc[df_concat['X'] == 'BBBBB', ['D','G']] = ['314','11'] df_concat.loc[df_concat['X'].str.contains('CCCCC'), ['D','G','I','J','K']] = ['843','11','仕 入','10%','内税'] df_concat.loc[df_concat['X'] == 'DDDDD', ['D','G','I','J','K']] = ['846','11','仕 入','10%','内税'] # 必要に応じて消費税額を計算 df_concat.loc[df_concat['J'] == '10%', 'M'] = df_concat['L'] - (df_concat['L']/1.1).map(r_round) # 金額の入っている列をint型に変換する df_concat_int = df_concat.astype({'L': int,'V': int}) #csvファイルに書き込み df_concat_int.to_csv('py_yokin.csv',mode = 'a',encoding = 'cp932',header = False,index = False)
デビットカードを使用している場合への対応
デビットカードを使用している場合、預金の入出金明細の「内容」欄には
デビット 696377
のようにしか記載されませんので(数字は承認番号で、全角)、その詳細については別途デビットカードの利用明細を見ないとわかりません。
それで、デビットカードの利用明細についてもdataframeにして、入出金明細のdataframeから承認番号をキーにしてデビットカードの利用明細の「お取引内容」を参照できるようにしました。