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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

836閲覧

Python for文について

退会済みユーザー

退会済みユーザー

総合スコア0

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/10/10 03:32

下記プログラム内容ですが、コピー先ブックを開いた後に、別ブックの行を上から順番にfor文で回し、一行目の値を抽出したらその値をコピー先ブックへ貼付けし、上書き保存するということをしたいと考えています。コピー元の値はあくまで、一行ずつで、一行コピー貼付け、保存、次のブックを開いて、先ほどコピーした次の行を、コピー貼付け、保存・・・という流れを作成したいです。
私が考えた内容だと、コピー元の行の値をすべて拾ってきて、各ファイルに貼付けするような結果しか得られませんでした。if文を使用して条件指定をし、ファイルを開くたび、行を指定したいのですが、どのようにしていいかわかりません。

このように記述すると、for文で読んできた番号の行のみを出力することはわかりましたが、このif b != 4:の数字の4の部分をfor b in range(4,Sheet_Max2,1):このfor文で値をとってくるたび同じように数字を4,5,6,7・・・と増やしていければいいのかと思い色々試行錯誤して実行しましたが結局自分ではできませんでした。
for b in range(4,Sheet_Max2,1):
if b != 4:
break

お手数おかけしますが、どのようにしたらいいかご教授お願いいたします。

Python

1#コピー先ファイル一つずつ開く 2for key, value in so_dict2.items(): 3 for v in value: 4 wb = openpyxl.load_workbook(f'C:\テスト用\個別表2\{key}\{v}.xlsx') 5 ws = wb[sheet_name]#コピー先シート取得 6 Sheet_Max2 = ws1.max_row#シートの最終行を取得する コピー元シート 7 #コピー元ファイルの列行を取得する 8 for b in range(4,Sheet_Max2,1): 9 if ws1.cell(row=b, column=3).value is None: 10 break 11 Sheet_Max1 = ws.max_row#シート最終行を取得 コピー先シート 12 for a in range(Sheet_Max1, 0, -1): 13 if ws.cell(row=a, column=2).value is not None: 14 ws.cell(row=a+1,column=2).value = ('料金') 15 kensin = ws1.cell(row=b,column=3).value#セルコピー 16 ws.cell(row=a+1,column=3,value=kensin)#セル貼付け 17 break 18 wb.save(f'C:\テスト用\個別表2\{key}\{v}.xlsx')#上書き保存

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

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

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

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

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

guest

回答2

0

ループの入れ子として実装するのは無理があると思いますよ。先に進む前に一呼吸置いて、根本的にもっと分かりやすい方法がないか、見直すべきだと思います。

処理が入れ子になるのはなるべく避けて、独立した小さな処理ブロックに分けるようにした方が良いと思います。
そして個々の処理ブロックは、自分が理解できる範囲の処理の大きさに収めるようにした方が良いと思います。
そうでないと、先に行って、改修したくなったり不具合があったりしたときに、自分では何もできなくなってしまうと思いますよ。

質問文に記載されているコードの範囲で思いつくのは zip 関数を使う方法ですが、全体的に見直したときにそれが一番いい方法かどうかも、私には分かりません。参考までに考え方のみ下に示しておきますが…
(コピー先ファイルの数と、転記したい値の数は同じで、抽出したリストの中での位置も一致しているという前提です)
(説明のために一部変数名を日本語にしています)
(コピー先ファイルの最終行を見つけるコードも関数にして、本体のロジックから切り離した方がいいと思います)

python

1# Excel ワークシートの特定列を指定して値のある最終行を見つける関数 2def max_row_with_value(ws, column): 3 for i in range(ws.max_row, 0, -1): 4 if ws.cell(row=i, column=column).value is not None: 5 return i 6 7# コピー先ファイルパスを取得 8コピー先ファイルパスのリスト = [] 9for key, value in so_dict2.items(): 10 for v in value: 11 コピー先ファイルパスのリスト.append(f'C:\テスト用\個別表2\{key}\{v}.xlsx') 12 13# 転記する値を取得 14転記する値のリスト = [] 15Sheet_Max2 = ws1.max_row 16for b in range(4, Sheet_Max2 + 1, 1): 17 copy_value = ws1.cell(row=b, column=3).value 18 if copy_value is None: 19 break 20 転記する値のリスト.append(copy_value) 21 22# コピー先ファイルに値を転記 23for ファイルパス, 転記する値 in zip(コピー先ファイルパスのリスト, 転記する値のリスト): 24 wb = openpyxl.load_workbook(ファイルパス) 25 ws = wb[sheet_name] 26 max_row = max_row_with_value(ws, column=2) 27 ws.cell(row=max_row+1, column=2).value = ('料金') 28 ws.cell(row=max_row+1, column=3, value=転記する値) 29 wb.save(ファイルパス)

投稿2021/10/10 04:58

編集2021/10/10 05:06
etherbeg

総合スコア1195

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

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

退会済みユーザー

退会済みユーザー

2021/10/10 05:11

ethe rbeg様 お世話になっております。 出先ですので、戻り次第パソコンで調べながら内容の確認いたします。 見ただけでは全然理解出来ませんでした。 私の知識不足です。 ご指摘誠にありがとうございます。 勉強させて頂きます。
guest

0

ベストアンサー

for b in range(4,Sheet_Max2,1):の4がどこから来たか分かりませんが…

4が初期値であれば、forの一番外側で、int_var = 3として置いて、for文で4から増やしたいたびにint_var+=1とすれば、4の部分が都度増えていきます。
for b in range(int_var,Sheet_Max2,1):
という形で試してください。

3で初期化して、forの度に1足したらforの初期値は4になりますね。

Python3

1 2int_var = 3 # <---- 追加 3 4 5#コピー先ファイル一つずつ開く 6for key, value in so_dict2.items(): 7 for v in value: 8 wb = openpyxl.load_workbook(f'C:\テスト用\個別表2\{key}\{v}.xlsx') 9 ws = wb[sheet_name]#コピー先シート取得 10 Sheet_Max2 = ws1.max_row#シートの最終行を取得する コピー元シート 11 #コピー元ファイルの列行を取得する 12 13 14 int_var+=1 # <---- 追加 15 # for b in range(4,Sheet_Max2,1): 16 for b in range(int_var ,Sheet_Max2,1): # <---- 修正 17 if ws1.cell(row=b, column=3).value is None: 18 break 19 Sheet_Max1 = ws.max_row#シート最終行を取得 コピー先シート 20 for a in range(Sheet_Max1, 0, -1): 21 if ws.cell(row=a, column=2).value is not None: 22 ws.cell(row=a+1,column=2).value = ('料金') 23 kensin = ws1.cell(row=b,column=3).value#セルコピー 24 ws.cell(row=a+1,column=3,value=kensin)#セル貼付け 25 break 26 wb.save(f'C:\テスト用\個別表2\{key}\{v}.xlsx')#上書き保存 27

投稿2021/10/10 03:46

編集2021/10/10 03:51
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2021/10/10 04:13 編集

fourteenlength様 ご返信ありがとうございます。 4の値は、行を4行目から取得したかったためにそのようにしています。 早速教えていただいた内容を実行しました。 指定行からの値を拾ってきてはいるのですが、その後ろの値も入ってきてしまいます。 1番目のブック には4行目を貼付け 2番目のブック には5行目を貼付け としたいのですが、今の内容だと、 1番目のブックには 4行目以降すべての行が貼付けされ 2番目のブックには 5行目以降すべての行が貼付け 3番目のブックには 6行目以降すべての行が貼付け という形になっています。 どのように修正したらよろしいでしょうか。 お手数おかけしますがご教授お願いいたします。
退会済みユーザー

退会済みユーザー

2021/10/10 04:41

fourteenlength様 for b in range(int_var,Sheet_Max2,1):#<---- 修正 if b != int_var: break 上記内容で、一行ずつ取得できました。 数日悩んでおりましたので大変うれしいです。 誠にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問