以前にExcelのマクロで作成したものと同じものをPythonで作成してみました。
以前の記事 → JDLIBEX出納帳 年間推移表(月次推移表)を作成するExcelのマクロ
JDLIBEX出納帳には、貸借対照表や損益計算書の科目の金額について月次推移を確認する画面が無いので作成しています。
今回は損益計算書の科目の金額についての月次推移表をPythonで作成しました。
月ごと、科目ごとに金額を集計する方法は今回使った方法以外にもいろいろあると思います。
集計を行なっているのは最後の方だけで、記述のほとんどは科目・補助科目の一覧を作成することに費やされています。
import pandas as pd
val = input('file name: ')
df = pd.read_csv(val,header = 2\
,encoding = 'cp932',\
names = ('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'))
#補助科目コードがない場合は0を入れる
df.fillna({'G': 0, 'Q': 0},inplace = True)
#科目・補助科目の一覧作成
df_karikata = pd.read_csv(val,header = 2\
,usecols = [3,4,6,7],encoding = 'cp932'\
,names = ('D','E','G','H'))
df_karikata.fillna({'G': 0, 'Q': 0},inplace = True)
df_kashikata = pd.read_csv(val,header = 2\
,usecols = [13,14,16,17],encoding = 'cp932'\
,names = ('D','E','G','H'))
df_kashikata.fillna({'G': 0, 'Q': 0},inplace = True)
#借方と貸方を合わせて一つのDataFrameにする
df_kamoku = pd.concat([df_karikata,df_kashikata])
#資産・負債の科目の行を,削除するためにindexを振り直す
df_kamoku.reset_index(drop = True,inplace = True)
#資産・負債の科目の行をリストにする
df_drop = df_kamoku[(df_kamoku['D'] < 600) | (df_kamoku['D'].isnull())]
#資産・負債の科目の行を削除する
df_kamoku.drop(df_drop.index,inplace = True)
#重複の削除
df_kamoku.drop_duplicates(inplace = True)
#sort
df_kamoku.sort_values(['D','G'],inplace = True)
#indexを振り直す
df_kamoku.reset_index(inplace = True,drop = True)
j = len(df_kamoku)
kikan = [20190101,20190201,20190301,20190401\
,20190501,20190601,20190701,20190801\
,20190901,20191001,20191101,20191201\
,20191331,20191332]
#期間ごとの金額のリストを作成し、DataFrameに列を追加する
for k1,k2 in zip(kikan[0:13],kikan[1:14]):
new_columns = \
[df[(df['C']>=k1) & (df['C']<k2) & (df['D']==df_kamoku.iat[i,0]) & (df['G']==df_kamoku.iat[i,2])].L.sum()\
- df[(df['C']>=k1) & (df['C']<k2) & (df['D']==df_kamoku.iat[i,0]) & (df['G']==df_kamoku.iat[i,2])].M.sum()\
- df[(df['C']>=k1) & (df['C']<k2) & (df['N']==df_kamoku.iat[i,0]) & (df['Q']==df_kamoku.iat[i,2])].V.sum()\
+ df[(df['C']>=k1) & (df['C']<k2) & (df['N']==df_kamoku.iat[i,0]) & (df['Q']==df_kamoku.iat[i,2])].W.sum()\
for i in range(j)]
df_kamoku.insert(len(df_kamoku.columns),str(k1)[0:6],new_columns)
df_kamoku.rename(columns={'D': '科目コード','E': '科目名','G': '補助科目コード','H': '補助科目名'}, inplace=True)
df_kamoku.to_excel('jdl_suii.xlsx',index = False)
CSVファイルを読み込んでDataFrameを作成し、DataFrameで編集して最後にExcelのワークシートに書き込みしています。
集計の部分は記述が長くてわかりづらいですが、内包表記を使用して1列分のリストを作成して勘定科目の右側の列に1列づつ、決算月を含めて13ヶ月分追加しています。
書き込みするExcelのワークシートの書式についてはDataFrameでは特に考慮されていないため、別途プログラムを作成して調整しています。
罫線を削除し、フォントを「メイリオ」にして、数値の書式を「#,##0」にしています。
また、列幅についてもある程度調整しています。
import openpyxl
from openpyxl.styles import Font
from openpyxl.styles.borders import Border,Side
from openpyxl.utils import get_column_letter
import unicodedata
def get_east_asian_width_count(text):
count = 0
for c in text:
if unicodedata.east_asian_width(c) in 'FWA':
count += 2
else:
count += 1
return count
wb = openpyxl.load_workbook('jdl_suii.xlsx')
ws = wb['Sheet1']
side = Side(style = None)
border = Border(top = side,bottom = side,left = side,right = side)
for row in ws.rows:
for cell in row:
cell.font = Font(name='メイリオ')
cell.number_format = '#,##0'
cell.border = border
for col in ws.columns:
max_length = 0
column_name = get_column_letter(col[0].column)
for cell in col:
if get_east_asian_width_count(str(cell.value)) > max_length:
max_length = get_east_asian_width_count(str(cell.value))
if col[0].column < 5:
adjusted_width = (max_length + 2)
ws.column_dimensions[column_name].width = adjusted_width
else:
adjusted_width = (max_length + 2) * 1.3
ws.column_dimensions[column_name].width = adjusted_width
wb.save('jdl_suii.xlsx')
ws.column_dimensions[ ]の、[ ]の中には
0 とか 1 の数字は入れることができず、
‘A’ とか ’B’ などの文字しか入れることができないようなのでget_column_letterをimport しました。