日本語入力ソフトとVBAの覚え書き

・各種日本語入力ソフトの辞書解説 ・ちょっと楽になるExcel VBA集

(Office VBA) マルチディスプレイ環境でユーザーフォームを親ウィンドウの中央に表示する(1)


f:id:dz_dzone:20170814233145j:plain
マルチディスプレイ環境(マルチモニタ環境)で、ユーザーフォームを使ったマクロを表示させると、現在ブックを表示させているディスプレイとは別のディスプレイにフォームが表示されてしまうことがあります。これを防ぎ、現在開いているブックの中央付近に表示させる方法を紹介します。

処理の流れ

流れとしては以下のようになります。

  1. 親ウィンドウ(ブック)の表示座標とサイズを取得する
  2. ユーザーフォームをロードする(表示はまだ)
  3. ユーザーフォームのサイズを取得する
  4. ユーザーフォームの表示位置を計算する
  5. 位置を指定してユーザーフォームを表示する

親ウィンドウの表示座標とサイズを取得する

WindowsオブジェクトのTop, Left, Width, Height の各プロパティを使います。

' ** 親ウィンドウの位置を取得
Dim Tx1 As Long, Lx1 As Long, Wx1 As Long, Hx1 As Long
With ActiveWindow
  Tx1 = .Top
  Lx1 = .Left
  Wx1 = .Width
  Hx1 = .Height
End With

注意点:ここで使う座標プロパティはWindowオブジェクトの座標です。Workbookオブジェクトの座標はワークシート座標(A1セルの左上を原点とした座標)ですので、この用途には使用できません。

取得したTop, Leftがマイナス値になると、本当は計算に全く問題ないはずなのになぜか表示がおかしくなることが多いので、マイナス値を取得した場合は強制的にゼロにしています。再度確認してみたらマイナスでも大丈夫でした。後述する UserForm.StartupPosition = Manual が抜けてただけだったかもしれません。

ユーザーフォームをロードする

' ** ユーザーフォームをロード
Load myUserForm

ユーザーフォームのサイズを取得するために予めロードしておきます。この時点ではロードしているだけで表示させていません。

ユーザーフォームのサイズを取得する

前提としてユーザーフォームのデザイナ上あるいはコードでWidthとHeightが設定されているものとします。

'**UFのサイズを取得
Dim Tx2 As Long, Lx2 As Long, Wx2 As Long, Hx2 As Long
With myUserForm
  Wx2 = .Width
  Hx2 = .Height
End With

ユーザーフォームの表示座標を計算する

f:id:dz_dzone:20190507172053j:plain

'**ユーザーフォームの表示位置を計算
Tx2 = Tx1 + ((Hx1 - Hx2) / 2)
Lx2 = Lx1 + ((Wx1 - Wx2) / 2)

座標を指定してユーザーフォームを表示する

'**ユーザーフォームを表示
With myUserForm
  .StartUpPosition = Manual  '**Top,Leftを指定するときに必ず必要
  '                             これがないとLeftがずれます
  .Left = Lx2                '**X座標
  .Top = Tx2                 '**Y座標
  .Show                      '**ユーザーフォームを表示
End With

表示サンプル

f:id:dz_dzone:20190508085605j:plain