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

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

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

openpyxlは、Excel2007以降のファイル(xlsx/xlsm/xltx/xltm)を読み書きするためのPythonライブラリです。

Python

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

Q&A

解決済

2回答

4201閲覧

openpyxlを使用し、エクセルのコメントやメモをコピーして別のファイルに貼り付ける方法

Zhiye

総合スコア7

openpyxl

openpyxlは、Excel2007以降のファイル(xlsx/xlsm/xltx/xltm)を読み書きするためのPythonライブラリです。

Python

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

0グッド

0クリップ

投稿2021/02/06 11:46

実施していること

2つのエクセルファイルのセルに記入された数値やコメントをopenpyxlを使用して
別の1つのファイルにコピー&ペーストしています。
下記コードであれば、セルの数値はコピー&ペーストできます。

import openpyxl import_file_path = 'C:\Users\01_test' export_file_path = 'C:\Users\01_output\2次版_集計済.xlsx' workbook2 = openpyxl.load_workbook(export_file_path) worksheet2 = workbook2['sheet1'] for i in range(1,3): workbook1 = openpyxl.load_workbook(import_file_path+'\'+'2次版_test_0'+str(i)+ '.xlsx') worksheet1 = workbook1['sheet1'] for i in range(8,60): for j in range(42,153): copy = worksheet1_01.cell(row=i,column=j).value if copy == None: continue else: worksheet2.cell(row=i,column=j,value=copy)   workbook2.save(export_file_path)

困っていること/実施したこと

困っていること:
セルの値はコピー&ペーストできるが、コメントのコピー&ペーストができない。

実施したこと:
コメントのコピー&ペーストのため、

from openpyxl.comments import Comment ・・・ copy_02 = worksheet1_01.cell(row=i,column=j).comment.text ```を挿入

import openpyxl
from openpyxl.comments import Comment

import_file_path = 'C:\Users\01_test'
export_file_path = 'C:\Users\01_output\2次版_集計済.xlsx'

workbook2 = openpyxl.load_workbook(export_file_path)
worksheet2 = workbook2['sheet1']

for i in range(1,3):
workbook1 = openpyxl.load_workbook(import_file_path+''+'2次版_test_0'+str(i)+ '.xlsx')
worksheet1 = workbook1['sheet1']
for i in range(8,60):
for j in range(42,153):
copy_01 = worksheet1_01.cell(row=i,column=j).value
copy_02 = worksheet1_01.cell(row=i,column=j).comment.text
if copy_01 == None:
continue
elif copy_02 == None:
continue
else:
worksheet2.cell(row=i,column=j,value=copy_01,comment=copy_02)
workbook2.save(export_file_path)

結果は、下記の通りでした。 copy_02 = worksheet1_01.cell(row=i,column=j).comment.text AttributeError: 'NoneType' object has no attribute 'text' ### 実施したいこと コメントもあわせてコピー&ペーストしたいですが、いろいろ調べてみるものの解決策が見つかりません。 勉強不足で誠に申し訳ありませんが、解決策をアドバイス頂ければありがたいです。 ### 環境 Python 3.7 openpyxl 3.0.4 Anaconda custom (64-bit) Excel office365

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

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

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

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

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

Daregada

2021/02/06 12:16

iとjでループさせる範囲のセルのすべてにコメントが付いているんですか?
Zhiye

2021/02/06 12:44

ご質問ありがとうございます。 すべてにコメントはついていません。このため、コメントのないセルは copy_02 == None: continue で、対応しようと考えています。 (上記の方法は、セルに数値が入っている場合できました) 宜しくお願い致します。
guest

回答2

0

ベストアンサー

エラーの原因は、「コメントが付いていない場合にはcommentプロパティそのものがNoneになるのに、それを調べる前にcomment.textを読もうとするから」です。実際には、commentプロパティの値をそのままコピーすればよく、comment.textを使う必要はありません。

ほかにも、問題点がいくつかあります。

  • 3重のforループで使われる変数名がi, i, jとなっていて、(動作には問題ないが)コードを読むときに混乱する。後の2つは、rowcolumnにしたほうが読みやすい。
  • 提示されたソースのforループの中に、未定義のworksheet1_01が突然出てくる。これはworksheet1の誤り(だよね?)。
  • cell(...)のオプション引数としてセルの値を設定することはできるが、コメントを設定することはできない。commentプロパティを使って設定する。
  • 末尾のworkbook2.save(export_file_path)は、一番外側のforループが終了した後に書けばいい。
  • シート名が「Sheet1」だとエラーになる。コードにsheet1と書いてあり、大文字小文字を区別するため。

内側のforループを以下のように書き換えてください。セルに値だけ書いてある場合、コメントだけ書いてある場合、両方書いてある場合すべてに対応します。

Python

1 for row in range(8, 60): 2 for column in range(42, 153): 3 cell = worksheet1.cell(row=row, column=column) 4 if cell.value: 5 worksheet2.cell(row=row, column=column, value=cell.value) 6 if cell.comment: 7 worksheet2.cell(row=row, column=column).comment = cell.comment

補足

最近のExcelで利用できる「スレッド化されたコメント」(名前付きで表示され、返信などが可能)の場合、コピー先のシートにコメント情報はコピーされるものの、スレッド化されたコメントに対応したExcelで開いても、コメントとして表示されない。さらに、Excelで保存操作を行なうと、コメント情報が削除された状態で保存されてしまう。

対策として、古い形式のコメント(スレッド化されたコメントに対応したExcelでは、「メモ」と呼ばれる)を適当なauthor名で作成し、コピー先のシートに書き込むコードを示す。
コメントのテキストに追加される余分な注意書きの行([スレッド化されたコメント」から「コメント:」まで)を正規表現で置換(削除)しているので、コードの先頭付近にimport reを追加すること。

Python

1 for row in range(8, 60): 2 for column in range(42, 153): 3 cell = worksheet1.cell(row=row, column=column) 4 if cell.value: 5 worksheet2.cell(row=row, column=column, value=cell.value) 6 if cell.comment and cell.comment.text: 7 comment_text = cell.comment.text 8 comment_text = re.sub(r"^[スレッド化されたコメント]$(?:.|\s)+^コメント:$\n {4}", "", comment_text, flags=re.MULTILINE) 9 worksheet2.cell(row=row, column=column).comment = Comment(comment_text, "anonymous")

投稿2021/02/06 13:12

編集2021/02/07 03:34
Daregada

総合スコア11990

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

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

Zhiye

2021/02/07 01:43

エラーの原因や、プログラムのお作法までもご教示頂き本当にありがとうございました。 Python初心者で勉強不足の私にとっては大変ありがたいです。 未定義の“worksheet1_01”は誤植です。ご迷惑をおかけしました。 ご教示頂いたコードで試したところ、Excel2018以前の“コメント”はコピー&ペーストできたものの、 2018以降(365含む)の“コメント”はコピー&ペーストできませんでした。 新機能の“コメント”のコピー&ペーストをご存じでしたらご教示頂ければありがたいです。 何卒宜しくお願い致します。
Daregada

2021/02/07 03:24

集計済みの文書の中身(zipでまとめられたxmlファイル)を見ると、新しい形式(スレッド化されたコメント)はコピーされていますが、スレッド化されたコメントに対応しているExcelで開いても表示されませんね。そして、上書き保存するとコメント情報が削除されています。 古い形式のコメントに変換するのであればなんとかなるので、回答に補足しておきます。
Zhiye

2021/02/07 22:34

早々にご返信頂きありがとうございました。 Execl365で作成したコメントが、旧コメント(新しいバージョンでいう“メモ”)に変換できました。 非常に勉強になりました。 今後とも宜しくお願い致します。
guest

0

一個のセルにコメントをつけるサンプルプログラムです。

python

1import openpyxl 2from openpyxl.comments import Comment 3 4wb = openpyxl.Workbook() 5ws = wb.worksheets[0] 6ws.cell(1, 1, value = 42) 7ws.cell(1, 1).comment = Comment('Hello SPAM!', 'John') 8wb.save('testcomment.xlsx')

これを実行すると、コメントのついたエクセルファイルができていました。

これから考えると、以下で動くと思います。

python

1 for i in range(8,60): 2 for j in range(42,153): 3 copy_01 = worksheet1_01.cell(row=i,column=j).value 4 copy_02 = worksheet1_01.cell(row=i,column=j).comment 5 if copy_01 == None: 6 continue 7 elif copy_02 == None: 8 continue 9 else: 10 worksheet2.cell(row=i,column=j,value=copy_01) 11 worksheet2.cell(row=i,column=j).comment=copy_02

投稿2021/02/06 13:09

ppaul

総合スコア24670

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

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

Zhiye

2021/02/07 01:39

早々にご回答頂きありがとうございました。また、サンプルプログラムからどのように変更するかを記載いただき大変勉強になりました。 取り急ぎ、お礼まで。引き続きよろしくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問