広告

【プチネタ】Excelのウィンドウ枠の固定が想定外の所に掛かっちゃう!を解消する

別記事に掲載したサンプルコード中にある以下の箇所で、不具合が発生。
Set EX = New Excel.Application
Set BK = EX.Workbooks.Add
Set ST = BK.Worksheets(1)
    (略)
ST.Rows("2:2").Select       
EX.ActiveWindow.FreezePanes = True
 

<不具合の内容>
・きちんと1行目が固定されるファイルもあれば、何故か5目くらいで縦方向にウィンドウ枠の固定がかかってしまうファイルがある。
・(記事内のサンプルコードだと、1種類のテーブルしか貼付してませんが、実務で作ったコードでは)引数で渡したレコードセット用のクエリの違いによって、成功/不成功が分かれる。レコードセット用に渡しているクエリごとに、Excelに対する編集内容も異なっているのも影響してる?

ということでGoogle先生に聞いてみた。

(2024/6/13追記)「ST.Range("A1").Select」の「Selectができないエラー」が発生する場合あり。複数シートに処理を繰り返していく場合でした。原因と解決方法追記しています。
  • 「FreezePanesプロパティ」に対応するオブジェクトは「ActiveWindow」だけ。(RowsとかWorkSheetの方がキモチしっくりくるけど)
  • 「ActiveWindow」だけが対象なので、タスクバーとかにしまっていると=Activeじゃないからだめらしい。(でもコレは今回の不具合には関係ない。ちなみにExcelのVisibleプロパティは、指定(記述)なしになっています。)
  • ユーザーが「ActiveWindow」を操作している状態の様に、ウィンドウ枠の固定をかけるセルが、Excelの画面内でばっちり見えてないとダメっぽい
  • つまり、レコードセット用に渡したクエリの種別により、その後の編集によるExcel内の画面遷移も異なっているので、FreezePanesを設定する時点で、ActiveWindow内に表示されているセル領域が異なっていたのが原因と推測。
  • (2024/6/13追記)以下のコードを流用し、複数のシートに対してデータ貼付→ウィンドウ枠固定を繰り返すプログラムを作った所、Selectメソッドでエラーが発生。SelectはActive状態のシートにしか使えないことが原因でした。「Set ST = BK.Worksheets(1)」で、シート型変数「ST」に、ワークシート格納して操作している=【ワークシートをActiveにしている訳ではない】からです。
以上に基づき、下記の様に修正してみたところ、解決に至りました!

Set EX = New Excel.Application
Set BK = EX.Workbooks.Add
Set ST = BK.Worksheets(1)
    (略)
'ウィンドウ枠の固定
  ST.Activate '(2024/6/13追記)Selectでエラーが起きる場合は追加してください
ST.Range("A1").Select
With EX.ActiveWindow
.SplitRow = 1  ’←固定される行数を指定
.FreezePanes = True
End With
  • どうよ?A1セルをSelectするっつう原始的かつ効果的なこの一手!(笑)Select文書くのがやっぱりちょっと悔しいのは「マクロの記録」時代を思い出しちゃうからですな。まあでも、一刻も早くちゃんと動くようにするのがお仕事ですから。
  • そして「SplitRowプロパティ」とは、「ウィンドウ枠の固定」と「ウィンドウの分割」に共通(共用)のプロパティだそうで、だから本件のように(Workbooks.Addで生まれた)まっさらなワークシートに使う分にはいいけども、「ウィンドウの分割」が既にかかってたりする所へ使っちゃったりすると、変なことになるらしいですぞ。
というわけで関連記事のサンプルコードも修正してあります。