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

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

(Office VBA)【決定版】マルチディスプレイ環境でユーザーフォームを親ウィンドウの中央に表示する・前編

f:id:dz_dzone:20170814233145j:plain

はじめに

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

基本的な処理の流れ

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

  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セルの左上を原点とした座標)で、ワークシートにオートシェイプなどを描画する目的に使うものです。したがって、ユーザーフォームを中央に表示させるような用途には使用できません。

オブジェクト 用途
Windowオブジェクトの座標値 ウィンドウやフォームなどをディスプレイのどの位置に表示させるか
Workbookオブジェクトの座標値 オートシェイプなどをワークシートのどの位置に表示させるか

取得した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

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

下図は概念図です。myUserFormは親ウィンドウ(ActiveWindows)の中央にあります。
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

後編に続く

後編では、実際にマクロのどこにどのように記述するかを解説します。
dz11.hatenadiary.jp