vbaでrangeオブジェクトを使う場合、気をつけなければいけないことがある。
それは、rangeオブジェクトを使うシートをアクティブにしないといけないということ
なぜそうなのかは謎。おそらくマイクロソフトもそれは仕様としか言わないと思う。
ただし、いつもそうかと言うとそうでもない気がしていて、、、、rangeオブジェクトを使ってるところで、エラーが出るならその手前でアクティブにするということをやっている。
worksheet.active
こんな感じのコードが必要になる。
(※抽象化して書いているので、そのままはつかない。)
備忘理由
毎回忘れてしまっていて、何回か試行錯誤してから、『そう言えば、、、』って思い出す。完全に備忘対象だ。マクロ自体そんなに書かないしそんなものといえばそんなものなんだけど、、、
chatGPTくんに聞いてみた。
chatGPTくんに質問してみた。
『rangeオブジェクトを使う際にそのシートをアクティブにしないといけないのはなぜ?』
そうすると、想定外の長文となんと、サンプルコードもついてきた。でも、やっぱりあんまり、納得感がない。サンプルコードも間違っていると思う。(まだ、試していない)
ーーー以下、ChatGPT回答
rangeオブジェクトを使用する場合、シートをアクティブにする必要がある理由は、以下の2つの主要な理由が考えられます。
- データの範囲の指定:rangeオブジェクトを使用するときに、操作したいデータの範囲(セルの範囲)を指定する必要があります。ただし、シートがアクティブでない場合、どのシートのデータを指定するかを明確にすることができません。アクティブなシートを設定することで、明示的にデータの範囲を指定することができます。
- ワークシートの操作:rangeオブジェクトを使用する場合、データの取得、更新、削除などの操作を行います。しかし、非アクティブなシートでこれらの操作を行うことはできません。アクティブなシートを設定することで、対象のシートで操作を実行することができます。
例えば、以下のようなコードを考えてみましょう。
pythonCopy codeimport openpyxl
# Excelファイルを開く
workbook = openpyxl.load_workbook('example.xlsx')
# シートをアクティブにする
worksheet = workbook.active
# A1からB5までの範囲を取得する
data_range = worksheet['A1:B5']
# データの操作を行う(例:データの表示)
for row in data_range:
for cell in row:
print(cell.value)
この例では、まずworkbook.active
を使用してアクティブなシートを取得し、その後、worksheet['A1:B5']
でデータの範囲を指定しています。もしアクティブなシートを設定せずにworksheet['A1:B5']
を実行した場合、正確なデータの範囲が明示されていないため、エラーが発生する可能性があります。
したがって、rangeオブジェクトを使用する際には、操作したいデータの範囲を明確にするために、対象のシートをアクティブにする必要があるのです。
ちょっと期待外れのこたえだったけどやっぱりchatGPTはすごいなと思う。即答してくれるから。
まとめ
rangeオブジェクトを使うにはそのシートをアクティブにする必要がある。