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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

2476閲覧

Python openpyxl for文 if について

退会済みユーザー

退会済みユーザー

総合スコア0

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2021/10/02 04:21

編集2021/10/02 04:51

※下記プログラム内容のイメージ
①コピーしたい値のあるシートを開く
②複数あるコピー先シートをfor文にて順番に開く(for key, value in so_dict.items)
③コピー元のエクセルを5行目から順次取得(for row in ws1.iter_rows(min_row=5))
④ifにて3列目に空白セルがある場合はその行を飛ばす
⑤セルのコピー、セルの貼付け、文字入力を行う
⑥保存
⑦コピー元のエクセルデータ、6行目・・・最終行まで上記内容の繰り返しをしてコピー先のエクセル
データ全てに反映させたい。

現在、下記内容のプログラムを実行するとエラーがでます。
どのように修正したらいいか教えていただけないでしょうか。

Python

1import os 2import openpyxl 3import datetime 4 5hh = datetime.date.today().year#シート名取得のための記述 6sheet_name = (str(hh - 1992) + '期')#コピー先シート名取得 7wb1 = openpyxl.load_workbook('C:\Users\1.xlsm',data_only=True)#コピー元ブック読込 8ws1 = wb1['検針表']#コピー元シート読込 9 10for key, value in so_dict.items():#コピー先ファイル取得 11 for v in value: 12 wb = openpyxl.Workbook(f'C:\Users\個別表\{key}\{v}.xlsx') 13 ws = ['sheet_name']#コピー先シート取得 14 for row in ws1.iter_rows(min_row=5):#5行目から順次(iter_rows)取得 15 if row[2].value is None:#2行目(fow[2])空白セルのある行は飛ばして処理 16 continue 17 kensin = ws1.cell(row = 1, column = 5).value#セルコピー 18 ws.cell(row = ws.max_row + 1,column = 9, value = kensin)#セル貼付け 19 kensin1 = ws1.cell(row = 1, column = 6).value#セルコピー 20 ws.cell(row = ws.max_row + 1,column = 3, value = kensin1)#セル貼付け 21 kensin2 = ws1.cell(row = 1, column = 7).value#セルコピー 22 ws.cell(row = ws.max_row + 1,column = 5, value = kensin2)#セル貼付け 23 ws.cell(row = ws.max_row + 1,column = 2).value = ('ガス料金')#指定セルに文字入力 24 wb.save(f'C:\Users\個別表\{key}\{v}.xlsx') 25 26[エラー内容] 27--------------------------------------------------------------------------- 28AttributeError Traceback (most recent call last) 29<ipython-input-33-f2b603949271> in <module> 30 16 continue 31 17 kensin = ws1.cell(row = 1, column = 5).value#セルコピー 32---> 18 ws.cell(row = ws2.max_row + 1,column = 9, value = kensin)#セル貼付け 33 19 kensin1 = ws1.cell(row = 1, column = 6).value 34 20 ws.cell(row = ws2.max_row + 1,column = 3, value = kensin1) 35 36AttributeError: 'list' object has no attribute 'cell' 37 38 39[補足資料] 40so_dict = {1: ['1-1 可茂','1-2 幸内','1-3 土屋','1-4 田中'],2: ['2-1 渡辺','2-2 渡辺','2-3 土屋','2-4 田舎'],3: ['3-1 今瀬','3-2 今瀬','3-3 加藤','3-4 古田']} 41辞書の内容としては、key=フォルダ名 value=エクセルファイル名 となります。 42 43・・・下記内容で値だけ取得すると 44for row in ws1.iter_rows(min_row=2): 45 if row[2].value is None: 46 continue 47 values = [] 48 for col in row: 49 values.append(col.value) 50 print(values) 51「出力内容」 52['地区', None, '氏名', '前回指針', '今回指針', '使用量 ', '売掛金'] 53['室①', None, '1-1 可茂', 1, 10, 9, 7290] 54['室①', None, '1-2 幸内', 1, 11, 10, 3800] 55['室①', None, '1-3 土屋', 1, 12, 11, 8420] 56['室①', None, '1-4 田', 1, 13, 12, 8980] 57・・・長くなるので省略します。 58 59 60となります。氏名ごとにエクセルブックがありますので、この各行の必要な値を 61コピー、貼付らけした、次の人のエクセルブックを開いてまた、コピー貼り付けしたいです。 62コピー元のデータとコピー先のファイルの並びは同じになっていますのでfor文で順次コピー元 63のリストからコピーして貼付けで問題なく処理できるようにしたつもりです。 64 65お手数おかけしますがご教授お願いいたします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

etherbeg

2021/10/02 07:17 編集

"AttributeError: 'list' object has no attribute 'cell'" というエラーメッセージをあなたはどう解釈しましたか。"--->" でどの行でそのエラーが発生しているかも示してくれています。
退会済みユーザー

退会済みユーザー

2021/10/02 07:41

etherbeg様 返信ありがとうございます。 エラー内容も調べましたが、いまいち自分のプログラムの内容をどう修正していいかわかりません。 お手数ですが、教えていただけないでしょうか。
etherbeg

2021/10/02 07:42

"AttributeError: 'list' object has no attribute 'cell'" を日本語に訳すことはできますか。
退会済みユーザー

退会済みユーザー

2021/10/02 07:48

etherbeg様 早速ご返答ありがとうございます。 リストにセルという属性はありません。という意味だということは調べて理解しました。 for row in ws1.iter_rows(min_row=5):#5行目から順次(iter_rows)取得!! ここで取得している値はリストになっていて、そこからセルは抽出できませんという意味でしょうか?
etherbeg

2021/10/02 08:15

そうですね、あるオブジェクトのcellという属性にアクセスしようとしているが、そのオブジェクトにはcellという属性はない、そしてそのオブジェクトとはlistオブジェクトである、ということですね。 属性という言葉は、ドットに続く名前すべてに対して使われます。変数の値のこともあるし、メソッドのこともあります。ですので、  オブジェクト.cell もしくは  オブジェクト.cell() という形で cell が使われている部分で、エラーが発生しているということになります。 その部分は "--->" でエラーメッセージが具体的に示してくれています。  ---> 18 ws.cell(row = ws2.max_row + 1,column = 9, value = kensin)#セル貼付け の行ですね。この行で cell が使われているのは  ws.cell(...) の部分ですね。 プログラムを書いた人間は、この ws という変数に入っているオブジェクトには、cell という属性(ここではメソッド)があるという前提でプログラムを書いているわけですが、実際にプログラムを実行してみたら、ここの ws という変数には list オブジェクト(Pythonの組み込みオブジェクトであるlist)が入っていて、そのオブジェクトには cell という属性はありませんよ、とエラーメッセージが教えてくれています。 原因は、 ① wsに入っているオブジェクトが、期待しているものと違う ② wsに入っているオブジェクトは期待通りだが、属性名を間違って指定しているか、もしくはオブジェクトの理解が間違っていて、そのオブジェクトにはない属性を指定している この二つのどちらかです。 この場合はどちらですか?
退会済みユーザー

退会済みユーザー

2021/10/02 08:57

etherbeg様 ご返信ありがとうございます。詳細な説明も誠にありがとうございます。 原因は②だと思っています。 理由としては、質問の中に書かせてもらった、補足資料にある「出力内容」のリストで行ごとに欲しい情報は抜出せています。そのリストから欲しい部分を抽出してセルに張り付けることができればいいのですが、 私が自分なりにプログラムを分解して疑問に感じたことは、 for row in ws1.iter_rows(min_row=5):#5行目から順次 この処理で出力した値はリストになって出力されるのであれば、リストからセルを取得することは可能なのかな?と疑問でした。 リストとして出力されているのであれば、リストから欲しい値を抽出して、それをセルに入力する別の記述方法があるのかな?と思いました。 そうだとすると、この処理の仕方では、下に続くプログラム内容のセルコピー、貼付けという作業自体が出来ないものなのかな?と疑問に思い、違った方法でプログラムを書く必要があるのかな?と思い始めていたところです。 どうしていいかわからず、掲示板に質問させていただいた流れになっております。
etherbeg

2021/10/02 09:52

リストからセルを取得することはできませんね。リストから値を抽出するのはリストの機能のうちですが、抽出した値をセルに入力するのはリストの機能ではできませんね。 ここで行おうとしている「エクセルファイルのシートからセルの値を読み取る」「エクセルファイルのシートのセルに値を書き込む」はどうして可能なのでしょうか? Pythonにそのような機能があるから? 違います。 質問者さんが自分でそのようなプログラムを書いたから? 違います。 そのようなプログラムを書いた人が、それを openpyxl というライブラリにまとめて、それを誰でもが利用できるように公開してくれているからです。openpyxl で決められた文法に従って openpyxl の機能を使うことによって初めて、エクセルファイルのシートからセルの値を読み取ったり、セルに値を書き込んだりすることが可能になります。 エラーが発生している  ws.cell(row = ws2.max_row + 1,column = 9, value = kensin) の箇所でしようとしていることは何ですか? エクセルファイルのワークシートの所定のセルに値を書き込むことですよね。 原因は②だとおっしゃいますが、ws にPythonの組み込みオブジェクトであるlistが入っているのが期待通りであるなら、リストにはエクセルファイルのワークシートの所定のセルに値を書き込むメソッドが備わっているということですか? 違いますよね。 ws には、openpyxl を使うことによって得られるオブジェクトが入っている必要があります。それで初めて、そのオブジェクトの cell() メソッドを使って、あるエクセルファイルのあるシートのあるセルに、値を設定することができます(セルに値を設定する方法はそれだけではありませんが)。 cell() メソッドを持っているのは、openpyxl のどんなオブジェクトでしょうか? そのオブジェクトは、エクセルファイルの何を、プログラム的に表現したものでしょうか? そのオブジェクトを取得して ws 変数に入れるには、どのようなコードを書けば良いでしょうか? こちらのサンプルコードをじっくり読んで、考えてみてください。 https://openpyxl.readthedocs.io/en/stable/usage.html#write-a-workbook
退会済みユーザー

退会済みユーザー

2021/10/02 10:28

etherbeg様 ご返信ありがとうございます。 また、色々なことを投げかけていただきとても感謝感激しております。 openpyxl、listのことも教えていただきありがとうございます。誰かが用意してくれた機能を使用して、何かを実現させようとしているという認識は正直ありませんでした。用意されたものにもルールがあり、それを理解しなければいけないということも勉強させていただきました。 頂いたサンプルコードを今から見て理解を深めたいと思います。 返信は明日になるかもしれませんが、見た結果はまた報告させてください。 よろしくお願いいたします。
etherbeg

2021/10/02 11:04

もし英語に抵抗がなければ https://openpyxl.readthedocs.io/en/stable/tutorial.html も一通り目を通すといいでしょうね。 急いで返信していただかなくて大丈夫ですよ。実際のコードにどう反映させたらいいかも考えながら、じっくり読んでみてください。
退会済みユーザー

退会済みユーザー

2021/10/02 11:53

etherbeg様 ご親切にありがとうございます。 頂いた二つ目の内容も見させていただきます。 また、お時間の件もお心遣いありがとうございます。 しっかり勉強して、答えがでたらご連絡いたします。 また、行き詰ることもあるかと思いますのでその時はご教授お願いいたします。 それでは、またご連絡いたします。 よろしくお願いいたします。
etherbeg

2021/10/04 12:28

課題が解決したのなら、自分で回答欄に解決方法を書き込んだ上で、質問のステータスを受付中から解決済に変更してください。
etherbeg

2021/10/04 12:31

課題の解決のためにコメントをしていたので、課題が解決済みであれば、無理にこれ以上のコメントの返信をしていただく必要はありません。
退会済みユーザー

退会済みユーザー

2021/10/04 12:36

etherbeg様 お世話になります。 先ほど解決しました。 ありがとうございます。 エラーは解決しましたが、まだ自分がやりたい処理内容を実行するまでにはまだ時間がかかりそうですので頑張ります。
退会済みユーザー

退会済みユーザー

2021/10/04 12:38

ws = ['sheet_name']#コピー先シート取得 この部分の記述が間違っていたみたいです。 おそらく、それ以外にも問題はあると思いますがとりあえずエラーはでなくなりました。 下記記述でエラー解決しました。 ws = [sheet_name]#コピー先シート取得
etherbeg

2021/10/04 12:44

早速対応ありがとうございました。 ws = [sheet_name] じゃなくて ws = wb[sheet_name] ですよね。
退会済みユーザー

退会済みユーザー

2021/10/04 12:47

そうです。 すみません、修正しました。
退会済みユーザー

退会済みユーザー

2021/10/04 12:48

別内容で先ほど、掲示板に質問しましましたので、よろしければ、その内容も見ていただけると幸いです。 お手数おかけしますがよろしくお願いいたします。
guest

回答1

0

ベストアンサー

ws = ['sheet_name']#コピー先シート取得

ws = wb[sheet_name]#コピー先シート取得

にてエラー出力されなくなりました。
ありがとうございます。

投稿2021/10/04 12:41

編集2021/10/04 12:47
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問