category name  »  page title date

ウィンドウのサイズと位置を記憶する

ブックを開いたときに、以前の画面のサイズや位置を再現したいな、と思うことがあります。大して本質的なことではないのですが、ストレスが減ります。それで、やってみました。
理屈は簡単です。
ブックが閉じる前にその時のウィンドウのサイズと位置をワークシートに記録しておきます。次にブックが開いた時に、その値を読み取って、ウィンドウを調整する、というただそれだけのことです。
問題なのは、たとえば閉じる前にマルチ・ディスプレイで作業していて、次に開いたのがノート・パソコンだったなどという際に、思わぬところに画面が飛んで、場合によるとディスプレイの外に出てしまって何も表示されなくなった、などということが起こることです。以下は、そのことも考慮して必要な補正を組み込みました。

まず、サイズと位置を記録する4つのセルを適当なワークシートに確保して、それぞれ "WindowTop", "WindowLeft" などと名前をつけておきます。ここでは、グローバルな名前にしました。記録するときは、ThisWorkbook の Workbook_BeforeClose イベントで ActiveWindow の各プロパティをこのセルに記録します。
開いたときは、同様に Workbook_Open イベントでその逆を行います。さっき言った補正は、多少いいかげんかも知れませんが、この段階で施しています。

標準モジュール      KeepWindowLocation(), RelocateWindow()

'----- ワークシート上に記録するセルの名前
Private Const windowTopCellName = "WindowTop"
Private Const windowLeftCellName = "WindowLeft"
Private Const windowHeightCellName = "WindowHeight"
Private Const windowWidthCellName = "WindowWidth"
'----- 補正の時の画面マージン
Private Const windowMargin = 8

'----- 現在の画面位置、サイズを記録
Public Sub KeepWindowLocation()
      With ActiveWindow
            Range(windowTopCellName) = .top
            Range(windowLeftCellName) = .left
            Range(windowHeightCellName) = .height
            Range(windowWidthCellName) = .width
      End With
End Sub

'----- 画面位置、サイズを再現
Public Sub RelocateWindow()
Dim top, left, height, width
      With ActiveWindow
            top = Range(windowTopCellName)
            left = Range(windowLeftCellName)
            height = Range(windowHeightCellName)
            width = Range(windowWidthCellName)
            adjustLocation top, left, height, width
            .top = top
            .left = left
            .height = height
            .width = width
      End With
End Sub
'----- 必要なら補正
Private Sub adjustLocation(ByRef top, ByRef left, ByRef height, ByRef width)
Dim wHeight, wWidth
      With ActiveWindow
            '現在のディスプレイの大きさを取得
            .WindowState = xlMaximized
            wHeight = .height
            wWidth = .width
            .WindowState = xlNormal
            '現在のディスプレイの大きさにあわせて補正
            If top < 0 Then top = windowMargin
            If left < 0 Then left = windowMargin
            If height > wHeight Then height = wHeight - windowMargin * 2
            If width > wWidth Then width = wWidth - windowMargin * 2
            If top + height > wHeight Then top = windowMargin
            If left + width > wWidth Then left = windowMargin
      End With
End Sub

ThisWorkbook

Private Sub Workbook_BeforeClose(Cancel As Boolean)
      KeepWindowLocation
End Sub

Private Sub Workbook_Open()
      RelocateWindow
End Sub

このほかにも、たとえば、参照したファイルのパスなども、記録しておいて次の時に再現できるようになっていると、何かと気持ちがよいものです。ほかにも、記録再現したいものはあるでしょう。ここに追加していけば、それができます。

筆者はだいたい "Setting" というワークシートを用意して、こういう記録を一切合切入れ込むようにしています。その際、最初のセル名はすべてローカルにして、他とぶつからないようにしていますが、Range(cellName) = の替わりに ThisWorkbook.Worksheets("Setting").Range(cellName) = などといちいち書くのが厄介なので、

Private Const settingSheetName = "Setting"
Public Property Get GetSetting(cellName)
      GetSetting = ThisWorkbook.Worksheets(settingSheetName).Range(cellName).value
End Property
Public Property Let LetSetting(cellName, value)
      ThisWorkbook.Worksheets(settingSheetName).Range(cellName).value = value
End Property

というプロパティを設けて使っています。蛇足ながら。