_基本

オートフィルターは厄介?FindやEndが使えなくなる【エクセルマクロ】

本サイトで好評な記事がパーツ化です。
パーツ化する事でVBAの開発は楽になりますが、
オートフィルター(AutoFilter)が原因で、パーツが利用できない場合があります。

パーツ化とは

ExcelVBAマクロ初級者からの脱却が、処理のパーツ化(プロシージャの分割)と考えています。
マクロを作る上で基本機能をパーツ化する事で、開発時間の削減に繋がります。

分かりやすく説明すると、エクセルの「関数」と同様です。
SUM関数であれば セル内に「=SUM(1+2+3)」と記載すれば、セルには「6」と表示されますよね。
値を渡せば正しい値で返ってくる動きです。

エクセル操作に起因する処理をパーツ化していると、オートフィルターによって思わぬ動きをしてしまいます。

最終行取得する処理はオートフィルタNG

マクロでツールを作った際、使用頻度の高い「最終行」取得処理は、オートフィルタをかけた状態だと、最終行取得できません。(フィルターがかかった状態での最終行を取得します)

オートフィルタNG例

ExcelVBAマクロ「最終行」「最終列」の判断処理をパーツ化する
ExcelVBAマクロ-他ブック他シートの「最終行」「最終列」取得処理をパーツ化する
ExcelVBAマクロ-ヘッダー行を加味して「最終行」取得処理をパーツ化する

原因

最終行取得処理は、ワークシート上で「Ctrl + ↑(上矢印)」を押した時と動きと同一です。
こちらの処理はオートフィルタの影響を受けてしまうため、同一動作のマクロでの処理も影響を受けてしまいます。

■動作
オートフィルタがかかっている  → フィルタしている状態での最終行を取得する。
オートフィルタがかかっていない → ワークシートの最終行を取得する。

FindメソッドはオートフィルタNG

オートフィルタNG例

【VBA入門】マクロでセルを検索する(Findメソッド)
【VBA入門】マクロで指定条件のセルを全て抽出する(FindNext/FindPreviousメソッド)
ExcelVBAマクロ「検索したワードで該当したセル行、セル列」の判断処理をパーツ化する

原因

セルを検索する「Findメソッド」は、エクセルの「Ctrl + F」で検索と、同様とこちらの記事で説明しました。
こちらの処理はオートフィルタの影響を受けてしまうため、同一動作のマクロでの処理も影響を受けてしまいます。

■動作
オートフィルタがかかっている  → フィルタしている状態での検索結果を取得する。
オートフィルタがかかっていない → ワークシート内、全ての検索結果を取得する。

 

まとめ

オートフィルタによって動作が異なる例を挙げました。これらは全てエクセルで人が操作する動作と、マクロが同じ動きをする為の弊害です。解決策はオートフィルタは必要以上に使わない。もしくは、マクロ実行前にオートフィルタを必ず外すような運用が必要です。

VBAマクロを利用する以上、ユーザーのエクセル操作からは逃げられません。
エクセルを使って開発するマクロのメリットであり、デメリットです。思わぬ不具合を発生せず、ユーザーが使いやすいシステム開発を心がけたいものです。

コメント

タイトルとURLをコピーしました