検証環境
- Win11Pro(24H2)
- Excel2024_64bit(Ver2412/Build16.0.18324.20092)
- Win10Home(22H2)
- Excel2024_64bit(Ver2411/Build16.0.18227.20082)
症状
Print_Titles及びPrint_Areaを@を付けて参照すると値が#NAME?
になって範囲を参照できなくなる
以降、下記症状も発生する
- VBAにてEvaluateにPrint_Titles及びPrint_Areaを含む参照を渡すとエラーになる
- VBAにてNamesでPrint_Titles及びPrint_Areaを呼び出そうとするとエラーになる
- PageSetupのPrintArea及びPrintTitleColumns並びにPrintTitleRowsを呼び出す前に該当セルのformulaを呼び出すと、印刷範囲・タイトル行・タイトル列がクリアされる
- 【3】を行うと以降印刷範囲・タイトル行・タイトル列の設定ができなくなり、PageSetupのPrintArea及びPrintTitleColumns並びにPrintTitleRowsも空になる
1.【4】の状態になると、 印刷範囲・タイトル行・タイトル列は空なのに名前定義にはPrint_Titles及びPrint_Areaが残ったままになり消せなくなる
大きく三つのバグに分けられる
- 一つ目は参照の値が
#NAME?
になり参照ができなくなる - 二つ目はWorkSheet#Names及びWorkSheet#EvaluateでPrint_Titles及びPrint_Areaが呼び出せなくなる
(Application#Names / Applicatoin#Evaluateで絶対アドレスを指定しても同様) - 三つ目は印刷範囲・タイトル行・タイトル列がクリアされて変更できなくなる
再現方法
一つ目及び二つ目の再現方法
- 新規作成でまっさらブックを作成
- 【印刷タイトル】→【印刷タイトル】を設定する
わかりやすいように行タイトルのみを設定 - ブックを保存する ← ★これがトリガー
- 新規シートを作成する
- 新規に作成したシートの適当なセルで【2】で作成した範囲のPrint_Titlesを@付きで参照して確定する
数式は【=@Sheet1!Print_Titles
】で、値は参照範囲の最初の値が表示される
★この時点で二つ目のバグが発生する - 【5】のセルをF2なりで開きそのまま確定する
- 数式が【
=@Sheet1!_xlnm.Print_Titles
】(_xlnm.
が勝手に追加される)になり、値が【#NAME?
】になる
三つ目の再現方法
上記バグ発生後、下記コードで再現
Sheet1
Sub Hoge()
' Sheet2のA1でSheet1のPrint_Titlesを参照しているものとする
Dim formula As String
Dim printTitleRows As String
formula = Sheet2.Range("A1").formula
printTitleRows = Me.PageSetup.printTitleRows
Debug.print _
"Formula : " + formula + vbLf + _
"PrintTitleRows : " + printTitleRows
End Sub
出力結果
Formula : =Sheet1!_xlnm.Print_Titles
PrintTitleRows :
ちなみにこっちだと問題がない
Sheet1
Sub Foo()
' Sheet2のA1でSheet1のPrint_Titlesを参照しているものとする
Dim formula As String
Dim printTitleRows As String
' formulaより先にprintTitleRowsを呼び出しているのがキモ
printTitleRows = Me.PageSetup.printTitleRows
formula = Sheet2.Range("A1").formula
Debug.print _
"Formula : " + formula + vbLf + _
"PrintTitleRows : " + printTitleRows
End Sub
出力結果
Formula : =Sheet1!_xlnm.Print_Titles
PrintTitleRows : $1:$1
対処法
一つ目と二つ目の対処法は見つからなかった
三つ目に関しては、PrintArea及びPrintTitleColumns並びにPrintTitleRowsのそれぞれをformulaを呼び出す前に呼び出しておくことで回避できることが分かった
ThisWorkbookのOpenイベントの先頭にでも仕込んでおけばよさそう
ThisWorkbook
Private Sub Workbook_Open()
Dim ws As Worksheet
Dim tmp As Variant
For Each ws In Me.Worksheets
With ws.PageSetup
tmp = .printArea
tmp = .PrintTitleColumns
tmp = .printTitleRows
End With
Next
End Sub
おまけ
検証中VBAをいじらなくても印刷タイトルの範囲が空になる症状が多々あったけどトリガーが見つからなかった。
あと、範囲が空になっていても名前定義が生きているからなのか開き直すと範囲が復活するという特徴もあることが分かった。
軽く調べた感じ情報がなかったんだけどおま環なのかな?
会社の別バージョンのExcelでも再現できたからおま環じゃないと思うんだけど。
ページタイトルとか結構使うものだと思うのだが、それを参照するってのがかなりニッチな使い方なのかな?