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

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

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

Anacondaは、Python本体とPythonで利用されるライブラリを一括でインストールできるパッケージです。環境構築が容易になるため、Python開発者間ではよく利用されており、商用目的としても利用できます。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

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

Python

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

Q&A

解決済

1回答

394閲覧

Pythonでwhile文のループ時に挙動が変わってしまう

pythonwakaran

総合スコア1

Anaconda

Anacondaは、Python本体とPythonで利用されるライブラリを一括でインストールできるパッケージです。環境構築が容易になるため、Python開発者間ではよく利用されており、商用目的としても利用できます。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2024/07/05 11:36

実現したいこと

Python初心者です。初書き込み失礼します。
Pythonを使用してエクセルを開いたままエクセル上で更新されるデータを同じシートの別のセルに転記してそのシートをcsvファイルとして保存し、csvデータを読み込むためのプログラムを作成中です。

発生している問題・分からないこと

while文にてClass1~8をループさせているのですが、Class6の挙動が1回目と2回目で違ってしまい、2回目の挙動が望まない動作をしてしまいます。
具体的にはClass5が実行されたあとはエクセルへのデータ転記→Sheet0.csvの保存→Sheet1.csvの保存となるはずなのですが、2回目のwhile文の動作でSheet0、Sheet1の保存→データの転記→もう一度Sheet0、Sheet1の保存となり同名データがあるため上書き保存の警告で動作が中断します。1回目の動作と同じ挙動にしたいです。宜しくお願いします。

エラーメッセージ

error

1エラーメッセージはありません。

該当のソースコード

python,

1import os 2import xlwings as xw 3import win32com.client 4 5 6# Class1 7class FileDeleterSheet2: 8 def __init__(self, file_path_sheet2): 9 self.state = 'initial' # 初期状態 10 self.file_path_sheet2 = file_path_sheet2 11 12 # Sheet2.csvを削除 13 def delete_file_sheet2(self): 14 try: 15 if os.path.exists(self.file_path_sheet2): 16 os.remove(self.file_path_sheet2) 17 print(f"File {self.file_path_sheet2} has been deleted successfully.") 18 else: 19 print(f"File {self.file_path_sheet2} does not exist.") 20 except PermissionError: 21 print(f"Permission denied. Cannot delete {self.file_path_sheet2}.") 22 except Exception as e: 23 print(f"An error occurred: {e}") 24 25 self.state = 'updated' # インスタンス変数を更新 26 27 print("Class1実行完了") 28 29 30# 使用例 31file_path_sheet2= "C:\\Users\\PC_User\\Desktop\\test_file_dummy\\Sheet2.csv" 32deleter = FileDeleterSheet2(file_path_sheet2) 33deleter.delete_file_sheet2() 34 35 36 37# Class2 38class DummyFileCreator: 39 def __init__(self, sheet_name, dummy_folder, save_folder): 40 self.state = 'initial' # 初期状態 41 self.wb = xw.books.active 42 self.sht = xw.sheets[sheet_name] 43 self.dummy_folder = dummy_folder 44 self.save_folder = save_folder 45 self.dummy_file_path = None 46 self.csv_file_path = None 47 48 # フォルダ内のファイル数をカウントする 49 def count_files(self): 50 try: 51 file_list = os.listdir(self.dummy_folder) 52 return len(file_list) 53 except FileNotFoundError: 54 return 0 55 56 # Sheet(ダミーファイル + 2)の名前に変更するための設定 57 def save_dummy_csv(self): 58 file_count = self.count_files() 59 dummy_file_name = f'Sheet{file_count + 2}.csv' 60 self.dummy_file_path = os.path.join(self.dummy_folder, dummy_file_name) 61 self.sht.api.SaveAs(self.dummy_file_path, FileFormat=6) 62 # ここで CSV ファイルを保存する処理を実装してください 63 print(f"ダミーファイルSheet{file_count +2}を作成しました") 64 65 self.state = 'updated' # インスタンス変数を更新 66 67 print("Class2実行完了") 68 69 70# 使用例 71if __name__ == "__main__": 72 dummy_folder_path = "C:\\Users\\PC_User\\Desktop\\test_file_dummy" 73 save_folder_path = "C:\\Users\\PC_User\\Desktop\\test_file_save" 74 handler = DummyFileCreator("Sheet1", dummy_folder_path, save_folder_path) 75 handler.save_dummy_csv() 76 77 78 79 80# Class3 81class FileDeleterSheet0: 82 def __init__(self, file_path_sheet0): 83 self.state = 'initial' # 初期状態 84 self.file_path_sheet0 = file_path_sheet0 85 86 # Sheet0.csvを削除 87 def delete_file_sheet0(self): 88 try: 89 if os.path.exists(self.file_path_sheet0): 90 os.remove(self.file_path_sheet0) 91 print(f"File {self.file_path_sheet0} has been deleted successfully.") 92 else: 93 print(f"File {self.file_path_sheet0} does not exist.") 94 except PermissionError: 95 print(f"Permission denied. Cannot delete {self.file_path_sheet0}.") 96 except Exception as e: 97 print(f"An error occurred: {e}") 98 99 self.state = 'updated' # インスタンス変数を更新 100 101 print("Class3実行完了") 102 103# 使用例 104file_path_sheet0= "C:\\Users\\PC_User\\Desktop\\test_file_save\\Sheet0.csv" 105deleter = FileDeleterSheet0(file_path_sheet0) 106deleter.delete_file_sheet0() 107 108 109 110# Class4 111class FileDeleterSheet1: 112 def __init__(self, file_path_sheet1): 113 self.state = 'initial' # 初期状態 114 self.file_path_sheet1 = file_path_sheet1 115 116 # Sheet1.csvを削除 117 def delete_file_sheet1(self): 118 try: 119 if os.path.exists(self.file_path_sheet1): 120 os.remove(self.file_path_sheet1) 121 print(f"File {self.file_path_sheet1} has been deleted successfully.") 122 else: 123 print(f"File {self.file_path_sheet1} does not exist.") 124 except PermissionError: 125 print(f"Permission denied. Cannot delete {self.file_path_sheet1}.") 126 except Exception as e: 127 print(f"An error occurred: {e}") 128 129 self.state = 'updated' # インスタンス変数を更新 130 print("Class4実行完了") 131 132# 使用例 133file_path_sheet1 = "C:\\Users\\PC_User\\Desktop\\test_file_save\\Sheet1.csv" 134deleter = FileDeleterSheet1(file_path_sheet1) 135deleter.delete_file_sheet1() 136 137 138 139 140# Class5 141class SheetRenamer: 142 def __init__(self, sheet_index, new_name): 143 self.state = 'initial' # 初期状態 144 self.xl_app = win32com.client.GetObject(Class='Excel.Application') 145 self.workbook = self.xl_app.Workbooks(1) # 1 番目のワークブックを指定 146 147 148 def rename_sheet(self, sheet_index, new_name): 149 try: 150 sheet = self.workbook.Sheets(sheet_index) 151 sheet.Name = new_name 152 print(f"Sheet {sheet_index} の名前を {new_name} に変更しました。") 153 except Exception as e: 154 print(f"エラー: {e}") 155 156 self.state = 'updated' # インスタンス変数を更新 157 print("Class5実行完了") 158 159# クラスをインスタンス化 160renamer = SheetRenamer(sheet_index=1, new_name='Sheet1') 161renamer.rename_sheet(sheet_index=1, new_name='Sheet1') 162 163 164 165 166 167# Class6 168class Class6Test6: 169 def __init__(self, sheet_name, output_folder): 170 self.state = 'initial' # 初期状態 171 172 self.wb = xw.books.active 173 self.sht = xw.sheets[sheet_name] 174 self.output_folder = output_folder 175 self.file_number = 1 176 self.count = 0 177 178 179 def job(self): 180 a1value = self.sht.range('A1').value 181 self.sht.range('A' + str(self.sht.cells.last_cell.row)).end('up').offset(1, 0).value = a1value # 1 182 a1value = self.sht.range('B1').value 183 self.sht.range('B' + str(self.sht.cells.last_cell.row)).end('up').offset(1, 0).value = a1value # 2 184 185 186 187 print(f"Job executed: {a1value}") # デバッグ用プリント文 188 189 190 def save_csv(self): 191 csv_file_name1 = f'Sheet{self.file_number - 1}.csv' #Sheet0のCSV保存設定 192 csv_file_path1 = os.path.join(self.output_folder, csv_file_name1) 193 194 csv_file_name2 = f'Sheet{self.file_number}.csv' #Sheet1のCSV保存設定 195 csv_file_path2 = os.path.join(self.output_folder, csv_file_name2) 196 197 198 # シート保存とクリアタイミングの設定 199 self.sht.api.SaveAs(csv_file_path1, FileFormat=6) #Sheet0のCSV保存 200 self.sht.api.SaveAs(csv_file_path2, FileFormat=6) #Sheet1のCSV保存 201 print(f"Saved CSV: {csv_file_path1}, {csv_file_path2}") # デバッグ用プリント文 202 203 last_row = self.sht.cells.last_cell.row 204 if last_row >= 3: 205 self.sht.range(f'A2:B{last_row}').clear_contents() 206 self.file_number += 1 207 self.count = 0 208 209 210 def run(self): #実行ファイルメソッド 211 for _ in range(11): # 11回のイテレーションを実行 212 self.job() # self.job メソッドまたは関数を実行 213 print(f"Iteration: {_}") # デバッグ用プリント文 214 215 # 最後にシートを保存 216 self.save_csv() 217 self.state = 'updated' # インスタンス変数を更新 218 219 print("Class6実行完了") 220 221 222 223# 使用 224if __name__ == "__main__": 225 exporter = Class6Test6(sheet_name="Sheet1", output_folder="C:\\Users\\PC_User\\Desktop\\test_file_save") 226 exporter.run() 227 228 229 230# Class7 231class Class7Test7: 232 def __init__(self): 233 self.state = 'initial' 234 235 def test7(self): 236 237 print("test7") 238 239 self.state = 'updated' # インスタンス変数を更新 240 241 print("Class7実行完了") 242 243class7test7 = Class7Test7() 244class7test7.test7() 245 246 247# Class8 248class Class8Test8: 249 def __init__(self): 250 self.state = 'initial' 251 252 def test8(self): 253 254 print("test8") 255 256 self.state = 'noneupdated' # インスタンス変数を更新しない 257 258 print("Class8実行完了") 259 260class8test8 = Class8Test8() 261class8test8.test8() 262 263 264def main(): 265 class1_instance = FileDeleterSheet2(file_path_sheet2) 266 class2_instance = DummyFileCreator("Sheet1", dummy_folder_path, save_folder_path) 267 class3_instance = FileDeleterSheet0(file_path_sheet0) 268 class4_instance = FileDeleterSheet1(file_path_sheet1) 269 class5_instance = SheetRenamer(sheet_index=1, new_name='Sheet1') 270 class6_instance = Class6Test6(sheet_name="Sheet1", output_folder="C:\\Users\\PC_User\\Desktop\\test_file_save") 271 class7_instance = Class7Test7() 272 class8_instance = Class8Test8() 273 274 275 while class8_instance.state != 'updated': 276 class1_instance.delete_file_sheet2() 277 class2_instance.count_files() 278 class2_instance.save_dummy_csv() 279 class3_instance.delete_file_sheet0() 280 class4_instance.delete_file_sheet1() 281 class5_instance.rename_sheet(sheet_index=1, new_name='Sheet1') 282 class6_instance.job() 283 class6_instance.save_csv() 284 class6_instance.run() 285 class7_instance.test7() 286 class8_instance.test8() 287 288 break 289 290 291 print("Done!") 292 293if __name__ == "__main__": 294 main() 295 296 297

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

原因が不明で、AIチャットでもお手上げでした。

補足

特になし

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

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

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

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

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

TakaiY

2024/07/05 11:57

質問にあるコードは1つのファイルですか? そして、このファイルを実行していますか?
pythonwakaran

2024/07/05 13:36

コメントありがとうございます。該当のソースコードで完結した一つの.pyファイルです。実行するとwhileによるループ時にClass6にて最初の挙動と違う動作をします。
pythonwakaran

2024/07/05 13:39

質問者です。文字数オーバーで記載できなかったので問題箇所のターミナル表示をここのコメント欄に記載させて頂きます。(class5からclass6までの動作) 一回目の動作 Class5実行完了 Job executed: test2 Iteration: 0 Job executed: test2 Iteration: 1 Job executed: test2 Iteration: 2 Job executed: test2 Iteration: 3 Job executed: test2 Iteration: 4 Job executed: test2 Iteration: 5 Job executed: test2 Iteration: 6 Job executed: test2 Iteration: 7 Job executed: test2 Iteration: 8 Job executed: test2 Iteration: 9 Job executed: test2 Iteration: 10 Saved CSV: C:\Users\PC_User\Desktop\test_file_save\Sheet0.csv, C:\Users\PC_User\Desktop\test_file_save\Sheet1.csv Class6実行完了 2回目の動作 Class5実行完了 Job executed: test2 Saved CSV: C:\Users\PC_User\Desktop\test_file_save\Sheet0.csv, C:\Users\PC_User\Desktop\test_file_save\Sheet1.csv Job executed: test2 Iteration: 0 Job executed: test2 Iteration: 1 Job executed: test2 Iteration: 2 Job executed: test2 Iteration: 3 Job executed: test2 Iteration: 4 Job executed: test2 Iteration: 5 Job executed: test2 Iteration: 6 Job executed: test2 Iteration: 7 Job executed: test2 Iteration: 8 Job executed: test2 Iteration: 9 Job executed: test2 Iteration: 10 ここでエクセルの上書き保存警告にて動作が中断されます。 以上になります。引き続きよろしくお願いします。
pythonwakaran

2024/07/07 08:30

コメントありがとうございます。display_alertsというものがあったのですね。知りませんでした。今回は解決したので、次回上書き保存警告で困った場合は一度検討してみます!
guest

回答1

0

ベストアンサー

該当のソースコードで完結した一つの.pyファイルです

とのことなので、まずは、ざっと見たところのコードの問題点を指摘します。

このコードは複数のソースコードを1つにまとめたものだと推測します。
元になったファイルは、ぞれぞれのパートを実行可能なように作ってあったのだと 思われます。このようなファイルは単に結合してしまうと、元のファイルの実行部分をひきづっているため、予期しない動作をします。

なので、まずは、余計な動作をしていると思われる部分をすべて削除する必要があると思います。
また、削除候補にした箇所には、main関数で使っている変数の定義も含まれているので、それらの定義はmain関数の中に移すのがいいでしょう。

削除部分の例をあげると

30行目から

python

1# 使用例 2file_path_sheet2= "C:\\Users\\PC_User\\Desktop\\test_file_dummy\\Sheet2.csv" 3deleter = FileDeleterSheet2(file_path_sheet2) 4deleter.delete_file_sheet2()

70行目から

python

1# 使用例 2if __name__ == "__main__": 3 dummy_folder_path = "C:\\Users\\PC_User\\Desktop\\test_file_dummy" 4 save_folder_path = "C:\\Users\\PC_User\\Desktop\\test_file_save" 5 handler = DummyFileCreator("Sheet1", dummy_folder_path, save_folder_path) 6 handler.save_dummy_csv()

間にもいくつもあり、最後は260行目

python

1class8test8 = Class8Test8() 2class8test8.test8()

これらの部分は、それぞれのClassの必要な処理をこのタイミングで起動しています。
それは本来ここでは実施すべきでないところだと思います。

これらを消すことで、やっと main関数にある処理のみ実施されるようになります。

投稿2024/07/05 14:17

編集2024/07/05 14:21
TakaiY

総合スコア13337

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

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

pythonwakaran

2024/07/05 15:12

コメントありがとうございます。すぐにはできそうにないので明日以降上記の削除・修正を試してみます!解決もしくは疑問あったらまたコメント等(解決したらベストアンサー)させて頂きます!
pythonwakaran

2024/07/07 08:39

遅くなりましたが、問題は解決しました!不要部分を削除してmain関数にできるだけ以降したところ、while文のループ挙動だけになり、そこでwhile文の挙動のほうがおかしいことに気付いたので、ためしにclass6の class6_instance.job() class6_instance.save_csv() の二つを停止させて class6_instance.run() だけを動作させたら、望んでいた挙動になりました! ご助力頂き、ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.40%

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

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

質問する

関連した質問