読者です 読者をやめる 読者になる 読者になる

GarbageCompany

満つらざるとも屈せず

ExcelのRange.Replaceメソッドの仕様について

Excelで色々やってて、衝撃を受けた仕様があったのでメモ。

 

Excelには「置換機能」があり、セル内の文字列を置き換えることが出来ます。このダイアログでは色々オプションを指定可能で、選択したオプションはExcelプロセスが記憶し、同プロセス内でもう一度置換ダイアログを表示した場合には予め同じように選択された状態になります。

f:id:machine913:20160304105708p:plain

 

それから、Excelマクロにも同じく置換機能を持った「Replaceメソッド」が存在します。これは内部的には上記の置換機能と同じ処理のようで、リファレンスにも「オプション設定はダイアログと共有だから注意してね!Replaceメソッドを使う時は全オプションをちゃんと指定した方がいいよ!」と記述されています。

Range.Replace メソッド (Excel)

 

とここまでは「そういう仕様」ということでいいのですが、「Replaceメソッドにはダイアログで言う『検索場所』に相当するオプションが無い」という大穴が空いています。

 

検索場所オプションは「置換対象が同シートのみか、ブック全体か」という極めて重要なオプションなのですが、この重要なオプションが直前のユーザ操作によって変動する上、マクロからは制御不可能ということになります。しかもオプションの記憶はExcelプロセス単位なので、マクロが記述されたExcelだけでなく、同プロセスで開いた他ファイルからも影響を避けられません。

 

例えば、「特定の範囲(Range)の文字を置換する」というマクロを組んでいて、事前に別のファイルで「ブック全体を置換」という作業をしていたら、マクロでの置換範囲も勝手にブック全体になってしまい、知らない間に知らないセルが置き換わってしまうわけです。というか、なった。ウソみたいだろ、Excel上に持ってるマスタを基準にマクロであれこれやってたら、知らない間にマスタが置き換わってるんだぜ。

 

結構前からこの仕様らしいんですが、これ誰も何も言わないんだろうか。場合によっては相当クリティカルな挙動になると思うんですが…。