2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Python】数式をセルに設定する。

Last updated at Posted at 2021-02-16

pythonを使用してExcelファイルの操作を勉強しています。
本日の気づき(復習)は、セルの数式に関してです。
pythonでExcelを操作するため、openpyxlというパッケージを使用しています。

image.png
と、
image.png
の、2枚のシートを持つ「合計」と言うブックを
image.png
この様な、数式を使ったシートにしたいです。

したいことは以下の3点です。

  1. セルF6~F15:前月の販売金額をコピーし貼り付ける。
  2. セルG6~G15:相対参照で数式を縦方向にコピーする。
  3. セルE3~G3 :相対参照で数式を横方向にコピーする。

なんだか、だんだんと通常のExcel業務に近づいてきた気がします。

1. 前月の販売金額をコピーし貼り付ける。

f-sringsとVLOOKUP関数

ただ単にコピーして貼り付けたのでは味気ないのでf-sringsと
VLOOKUP関数を使用してみます。

wb = load_workbook('合計.xlsx')

lastmonth = '202101'
month = '202102'

ws_lastmonth = wb[lastmonth]
ws = wb[month]

for row in ws.iter_rows(min_row=6, max_row=ws.max_row):
    row_count = row[0].row
    row[5].value = f'=VLOOKUP(C{row_count},{lastmonth}!$C$6:$E$15,3,FALSE)'

VLOOKUP関数は便利なのですが第4引数の「TRUE」「FALSE」がどうにも微妙な理解で
「TRUE」の近似値検索が数字ならまだ解るのですが文字列となると・・・。
とりあえず私は、「FALSE」しか使ったことがないです。

2. 相対参照で数式を縦方向にコピーする。

Translatorオブジェクト

f-sringsを使って数式を作ろうとも考えたのですが
openpyxlに、既存の数式を相対参照でコピーする機能が用意されていたので
こちらを使ってみます。

# コピー元の数式をセルG6に設定
cell = Translator(コピーする数式,
                  origin=相対参照の元となるセル番地).translate_formula(コピーする方向のセル番地)

なんだか、Excelの数式をドラッグしてコピーしていく方法と似てますね。

# コピー元の数式をセルG6に設定
ws['G6'] = '=E6-F6'

for row_no in range(7, ws.max_row + 1):
    cell_no = f'G{row_no}'
    ws[cell_no] = Translator(ws['G6'].value,origin='G6').translate_formula(cell_no)

今回は縦方向なのでこんな感じでしょうか。

3. 相対参照で数式を横方向にコピーする。

こちらは横方向に相対参照なので

ws['E3'] = '=SUM(E6:E15)'

for col_no in range(6, ws.max_column + 1):
    col_alphabet = ws.cell(row=1, column=col_no).column_letter
    ws[f'{col_alphabet}3'] = Translator(
        ws['E3'].value, origin='E3').translate_formula(f'{col_alphabet}3')

こんな感じでしょうか。

最後に上記の記述を纏めて

from openpyxl import load_workbook
from openpyxl.formula.translate import Translator

wb = load_workbook('合計.xlsx')

lastmonth = '202101'
month = '202102'

ws_lastmonth = wb[lastmonth]
ws = wb[month]

origin_cell_no_col = 'E3'
ws[origin_cell_no_col] = '=SUM(E6:E15)'

origin_cell_no_row = 'G6'
ws[origin_cell_no_row] = '=E6-F6'

# 202101シートのデータを張り付ける
for row in ws.iter_rows(min_row=6, max_row=ws.max_row):
    row_count = row[0].row
    row[5].value = f'=VLOOKUP(C{row_count},{lastmonth}!$C$6:$E$15,3,FALSE)'

# 各数値の合計を表示
for col_no in range(6, ws.max_column + 1):
    col_alphabet = ws.cell(row=1, column=col_no).column_letter
    ws[f'{col_alphabet}3'] = Translator(
        ws[origin_cell_no_col].value, origin=origin_cell_no_col).translate_formula(f'{col_alphabet}3')

# 前月販売分との差額を表示
for row_no in range(7, ws.max_row + 1):
    cell_no = f'G{row_no}'
    ws[cell_no] = Translator(ws[origin_cell_no_row].value,
                             origin=origin_cell_no_row).translate_formula(cell_no)

wb.save('合計_集計後.xlsx')

出来ました!
どうにか再利用性を高めるために、関数にしてみたかったのですが
自分にはまだまだ敷居が高かったようです・・・。特にネーミングセンス。

他にも、f-sringsとTranslatorオブジェクトの使い所の見分け方や

【1】の処理と【2】の処理はどちらも同じなので、一つにまとめることはできないかなと。
2020/02/17追記
自分なりに解消策を考えてみました。

from openpyxl import load_workbook
from openpyxl.formula.translate import Translator

wb = load_workbook('合計.xlsx')

lastmonth = '202101'
month = '202102'

ws_lastmonth = wb[lastmonth]
ws = wb[month]

# 起点となるセルの数式を設定
ws['E3'] = '=SUM(E6:E15)'
ws['F6'] = f'=VLOOKUP(C6,{lastmonth}!$C$6:$E$15,3,FALSE)'
ws['G6'] = '=E6-F6'

# 行で相対参照
for col_no in range(6, ws.max_column + 1):
    col_alphabet = ws.cell(row=1, column=col_no).column_letter
    ws[f'{col_alphabet}3'] = Translator(
        ws['E3'].value, origin='E3').translate_formula(f'{col_alphabet}3')

# 列で相対参照
for col_no in range(6, ws.max_column + 1):
    col_alphabet = ws.cell(row=1, column=col_no).column_letter
    for row_no in range(7, ws.max_row + 1):
        cell_no = f'{col_alphabet}{row_no}'
        ws[cell_no] = Translator(ws[f'{col_alphabet}6'].value,
                                 origin=f'{col_alphabet}6').translate_formula(cell_no)

wb.save('合計_集計後.xlsx')

と、記述をしてみたはいいのですが
まだまだ記述を纏める事が出来そうです。宿題は変わらず山積みです!

勉強を進めていく中で一つずつ解決していきたいですね!

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?