JIKOKENNJIYOKU-NIKKI【21st Century】

明日から本気出すわ。

プログラミング初心者のおっさんが事務作業をほぼ自動化できた話。

 

昨日、プログラミング初心者のおっさんが事務作業を半自動化できた話を書きました。

 

at251.hatenablog.com

 

で、今日、ほぼ自動化することに成功しました(笑)

 

ほぼ自動化の妨げとなっていたのは、なんだったのか。

 

① 転記元の書類が「派遣リスト(.xlsx)」

② 転記先の書類が「報告書(.xlsx)」

となってまして。

 

具体的に言いますと、①から②にデータを転記するときに、

①の4列目と6列目が②に不要なデータだったんですね~。

 

でも、その不要なデータたちがくっついてきちゃうから、手作業で列を削除しなくちゃだったわけですよ。

かっこわりー。

 

で、頭の中でああでもない、こうでもないって考えていたんですわ。

昨日の日記ではpandas関数のdropを用いれば、、、みたいなことを書いていたんですが、

そもそも、openpyxlでコードが書かれていたので、pandasじゃねーな、と。

 

note.nkmk.me

 

ちょっと調べてみたら、自分がやりたいことは、openpyxlの方が実現できそうなこともわかったので、このまま続行することに。

 

じゃあ、どーすっかなー、とかんがえてみました。

元々のコードが以下になります。


import openpyxl, pprint


file_list = "test_original_list.xlsx" # 転記元の派遣一覧
file_report = "reportlist.xlsx" # 報告書のテンプレート
file_out_report = "out-report.xlsx" # 生成する報告書ファイル

# 転記元の派遣一覧を読み込む
wb = openpyxl.load_workbook(file_list,data_only=True)
ws = wb["schedule"] # scheduleのシートを選択

 

# 報告書のテンプレートを読みこむ
wb_rp = openpyxl.load_workbook(file_report)
ws_rp = wb_rp.active

list_data = ws["C4:M200"] # 任意の範囲を取得

 

# 派遣情報を書き込む
for y, row in enumerate(list_data):
for x, cell in enumerate(row):
if(cell is None) or (cell.value is None):continue
v = cell.value
ws_rp.cell(row=3+y+1, column=0+x+1, value=v)

 

# 新しく保存する
wb_rp.save(file_out_report)
print("ok")

 

以上。

これを実行すると、out-reportという報告書ファイルが作成されるんですが、

さきほど言った通り、列を手作業で削除しなくてはならない。

 

そうだ、転記元の派遣一覧を読み込むときに、不要な列(4列目と6列目)を削除しちゃえばいいんじゃね?

それには繰り返し処理のwhileが使えるんじゃね?

 

で、以下のようにコードを追記してみました(赤字部分)。

※ 転記先の様式「reportlist.xlsx」もあわせて編集したけどそこの作業については省略。


import openpyxl, pprint


file_list = "test_original_list.xlsx" # 転記元の派遣一覧
file_report = "reportlist.xlsx" # 報告書のテンプレート
file_out_report = "out-report.xlsx" # 生成する報告書ファイル

 

# 転記元の派遣一覧を読み込む
wb = openpyxl.load_workbook(file_list,data_only=True)
ws = wb["schedule"] # scheduleのシートを選択

 

# 繰り返し処理で不要な列(元々の4列目(月)と6列目(時間)を削除)
i=4
while i <= 6:
ws.delete_cols(i)
i += 2
list_data = ws["C4:M200"] # 任意の範囲を取得

 

# 報告書のテンプレートを読みこむ
wb_rp = openpyxl.load_workbook(file_report)
ws_rp = wb_rp.active

 

# 派遣情報を書き込む
for y, row in enumerate(list_data):
for x, cell in enumerate(row):
if(cell is None) or (cell.value is None):continue
v = cell.value
ws_rp.cell(row=3+y+1, column=0+x+1, value=v)

 

# 新しく保存する
wb_rp.save(file_out_report)
print("ok")

 

すると、4列目はうまく削除できたのに、6列目は残ってしまい元の7列目が削除されてしまいました。

原因は、繰り返し処理のときの2回目にあるな、と。

【1回目】

i=4        # iを初期化して4を代入
while i <= 6:    # iが6以下であれば、以下の作業を繰り返す
ws.delete_cols(i)    # i列を削除します!
i += 2         # iに2を足してwhile 条件式( i <= 6 )に戻るぜ!

 

【2回目】

i=6        # iは4に2を足して6になたよ~
while i <= 6:    # iが6以下だから、以下の作業を繰り返すよ~
ws.delete_cols(i)    # i列、つまり6列目を削除するよ~!

          # ↑【1回目】で、4列目が削除されたあとなので

          # 元の7列目(現6列目)が削除されてしまった。
i += 2         # iに2を足してwhile 条件式に戻るぜ!

 

→戻ったら i=8だから繰り返し処理を終わるぜ!

 

なので、修正しました。削除したい元の6列目は2回目の処理では5列目になっているはず。

なので、i = 4で繰り返し処理を開始して、i = 5で処理を終えれば良いのでは?

 

繰り返し処理とlist_dateの取得範囲を微調整(2列削除したので範囲も2列分減らした)(赤字部分

import openpyxl, pprint


file_list = "test_original_list.xlsx" # 転記元の派遣一覧
file_report = "reportlist.xlsx" # 報告書のテンプレート
file_out_report = "out-report.xlsx" # 生成する報告書ファイル

 

# 転記元の派遣一覧を読み込む
wb = openpyxl.load_workbook(file_list,data_only=True)
ws = wb["schedule"] # scheduleのシートを選択

 

# 繰り返し処理で不要な列(元々の4列目(月)と6列目(時間)を削除)
i=4
while i <= 5:
ws.delete_cols(i)
i += 1
list_data = ws["C4:K200"] # 任意の範囲を取得

 

# 報告書のテンプレートを読みこむ
wb_rp = openpyxl.load_workbook(file_report)
ws_rp = wb_rp.active

 

# 派遣情報を書き込む
for y, row in enumerate(list_data):
for x, cell in enumerate(row):
if(cell is None) or (cell.value is None):continue
v = cell.value
ws_rp.cell(row=3+y+1, column=0+x+1, value=v)

 

# 新しく保存する
wb_rp.save(file_out_report)
print("ok")

 

そうしたら、ちゃんと動きました!

スッキリしたわ~