質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

フォルダ内にある複数の.xlsxファイルに対して同じ処理を実行し、末尾に"_集計"を付けて保存したい。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,434

score 1

前提・実現したいこと

▪フォルダ内にある複数の.xlsxファイルに対して同じ処理を行いたい。
(プログラミングを初めて2週間の初心者です。初めて質問を投稿するため、質問の仕方が悪いかもしれませんがよろしくお願いいたします。)

現在会社の業務の効率化のために、半期ごとの売上実績のデータから製品の型名ごとに合計数量をまとめて、"元データ名_集計"という名前の.xlsxファイルを生成するというプログラミングを書いています。
現在は元データおよび生成されるデータのファイルパスは.pyファイルと同じ場所に指定しており、処理を行う.xlsxファイルの指定は、input()を使用し、元データ名を記入させるという方法を取っています。
しかし、これでは1件ずつしか処理が行えないことに加え、元データ名の記入ミス等が発生すると考えています。
そのため、以下の内容を実現したいです。

・フォルダ内にあるすべての.xlsxファイルについて同様の処理を行いたい。
・生成前データフォルダ、生成後データフォルダをそれぞれ作り、生成前データフォルダに格納した.xlsxファイルすべてに対して処理を行ったものを生成後データフォルダに保存したい。
・生成後のデータは"元データ名_集計.xlsx"という名前にしたい。

発生している問題・エラーメッセージ

まだ、なにもコーディングを行えていないため、エラーメッセージもありません。

該当のソースコード

import pandas as pd
import openpyxl as px

in_filepath_wo_extention = "./" + input("今回集計したいファイルのファイル名(拡張子抜き)を入れてください。(例:73上_HC_実績)")

in_filepath = in_filepath_wo_extention + '.xlsx'
out_filepath = in_filepath_wo_extention + '_集計.xlsx'

#元データからデータフレームの読み込み
df = pd.read_excel(in_filepath)

#小分類の列から型名ごとにデータを抽出
get_v3 = df.query('小分類.str.contains("C13440-20CU")', engine='python')
get_fusion = df.query('小分類.str.contains("C14440-20UP")', engine='python')
get_fusionbt = df.query('小分類.str.contains("C15440-20UP")', engine='python')
get_spark = df.query('小分類.str.contains("C11440-36U")', engine='python')
get_lightning = df.query('小分類.str.contains("C14120")', engine='python')
get_42U30 = df.query('小分類.str.contains("C11440-42U30")', engine='python')
get_52U30 = df.query('小分類.str.contains("C11440-52U30")', engine='python')
get_vga = df.query('小分類.str.contains("C12741-03")', engine='python')
get_qvga = df.query('小分類.str.contains("C14041-10")', engine='python')
get_imagem = df.query('小分類.str.contains("C9100-23B")', engine='python')
get_imagem1k = df.query('小分類.str.contains("C9100-24B")', engine='python')
get_gemini = df.query('小分類.str.contains("A12801-01")', engine='python')
get_gemini2c = df.query('小分類.str.contains("A12801-10")', engine='python')

#型名ごとに別シートに転記
with pd.ExcelWriter(out_filepath) as writer:
    get_v3.to_excel(writer, sheet_name="C13440-20CU")
    get_fusion.to_excel(writer, sheet_name="C14440-20UP")
    get_fusionbt.to_excel(writer, sheet_name="C15440-20UP")
    get_spark.to_excel(writer, sheet_name="C11440-36U")
    get_lightning.to_excel(writer, sheet_name="C14120-20P")
    get_42U30.to_excel(writer, sheet_name="C11440-42U30")
    get_52U30.to_excel(writer, sheet_name="C11440-52U30")
    get_vga.to_excel(writer, sheet_name="C12741-03")
    get_qvga.to_excel(writer, sheet_name="C14041-10U")
    get_imagem.to_excel(writer, sheet_name="C9100-23B")
    get_imagem1k.to_excel(writer, sheet_name="C9100-24B")
    get_gemini.to_excel(writer, sheet_name="A12801-01")
    get_gemini2c.to_excel(writer, sheet_name="A12801-10")


wb = px.load_workbook(filename = out_filepath)
wb.create_sheet("集計", 0)

sheet1 = wb["集計"]

#「集計」シートに以下の内容を記入
sheet1["B1"] = "型名"
sheet1["C1"] = "数量"
sheet1["B2"] = "C13440-20CU"
sheet1["B3"] = "C14440-20UP"
sheet1["B4"] = "C15440-20UP"
sheet1["B5"] = "C11440-36U"
sheet1["B6"] = "C14120-20P"
sheet1["B7"] = "C11440-42U30"
sheet1["B8"] = "C11440-52U30"
sheet1["B9"] = "C12741-03"
sheet1["B10"] = "C14041-10U"
sheet1["B11"] = "C9100-23B"
sheet1["B12"] = "C9100-24B"
sheet1["B13"] = "A12801-01"
sheet1["B14"] = "A12801-10"

# 各型名の販売数量の合計値を「集計」シートに記入
sheet1["C2"] = sum(get_v3.数量)
sheet1["C3"] = sum(get_fusion.数量)
sheet1["C4"] = sum(get_fusionbt.数量)
sheet1["C5"] = sum(get_spark.数量)
sheet1["C6"] = sum(get_lightning.数量)
sheet1["C7"] = sum(get_42U30.数量)
sheet1["C8"] = sum(get_52U30.数量)
sheet1["C9"] = sum(get_vga.数量)
sheet1["C10"] = sum(get_qvga.数量)
sheet1["C11"] = sum(get_imagem.数量)
sheet1["C12"] = sum(get_imagem1k.数量)
sheet1["C13"] = sum(get_gemini.数量)
sheet1["C14"] = sum(get_gemini2c.数量)

#上記の処理を行ったデータを保存
wb.save(out_filepath)
wb.close()

試したこと

https://watlab-blog.com/2019/07/29/bundle-resize/

こちらの方の記事を参考にしようと試みましたが、処理内容の複雑さが違ったためfor文内にどのように処理を入れればよいかが分からず困っています。

globを使用して、フォルダ内のデータをまとめて読み込むというところまでは理解できたつもりですが、その後読み込んだファイル1つ1つに同じ処理を適用する部分のコーディングの仕方が分からない状況です。

補足情報(FW/ツールのバージョンなど)

pythonのバージョンは3.8.6です。
上記の他にどのような情報を提供すればよいかもわかっていない状況のため、必要な情報があればお申し付けいただけますと幸いです。
何卒よろしくお願い申し上げます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • takutakuya

    2020/10/16 01:47

    .xlsxファイルに対する処理自体は提示していただいたコードで問題なくできていて、それと同じ処理を複数のファイルに一括でできるようにしたい、という認識で合ってますでしょうか?

    キャンセル

  • arumi_k

    2020/10/16 02:03

    takutakya様 ご指摘の通りです。現状のコードでやりたい処理自体はできております。

    キャンセル

回答 1

checkベストアンサー

+1

Pythonのファイルと同じフォルダーにある.xlsxファイルを全て読み込んで、同じ処理をし、ファイル名の末尾に「_集計」を付けて保存するコードです。

import glob
import openpyxl

file_list = glob.glob('*.xlsx')

print(file_list)

for file in file_list:
    wb = openpyxl.load_workbook(file)
    ws = wb["Sheet1"]
    ws["C1"].value = ws["A1"].value + ws["B1"].value
    rename_file = file.replace('.xlsx', '_集計.xlsx')
    wb.save(rename_file)
    print(file,'->',rename_file)


.xlsxファイルへの処理自体はA1セルとB1セルの和をC1セルに追加する単純なものにしています。

追記

pandasも使われていたので、pandasバージョンも作ってみました。
ファイル名をfor文の中で回していること自体は変わっていません。

import glob
import pandas as pd

file_list = glob.glob('*.xlsx')

print(file_list)

for file in file_list:
    df = pd.read_excel(file)
    df['C'] = df['A'] + df['B']

    rename_file = file.replace('.xlsx', '_集計.xlsx')

    df.to_excel(rename_file, index=False)

    print(file, '->', rename_file)


openpyxlpandasを組み合わせて使われていますが、pandasだけでも実現できそうな感じはします。

for文について

何度も追記してすみません。
for文に関しては説明不要かもしれませんが、念の為。
globでPythonファイルと同じフォルダーにある.xlsxファイルのファイル名をリスト形式で取得しています。
そのリストを上記のコードではfile_listに格納しています。
file_listの中身は下記のようになっています。

['test2.xlsx', 'test1.xlsx']


このfile_listfor文で使っていますが、for文の中のfileという変数にfile_listにあるファイル名を1つずつ取り出して格納され、for文の中の処理が実行されます。

そのため、file_listにあるファイル名の数だけ処理が実行されます。

不明点があれば、遠慮なくコメントください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/10/16 16:51

    https://itojisan.xyz/trouble/10228/

    この辺りの方法で解決できると良いのですが。

    キャンセル

  • 2020/10/16 20:52

    ありがとうございます!
    読み取り専用のチェックを消すことはできなかったのですが、なぜか実行できるようになりました!
    参考になりました。ありがとうございます。

    キャンセル

  • 2020/10/16 23:35

    よかったです^^

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Pythonに関する質問
  • フォルダ内にある複数の.xlsxファイルに対して同じ処理を実行し、末尾に"_集計"を付けて保存したい。