【VBA】ユーザーフォームを表示する位置を自由に指定する方法まとめ(サンプルコードセットあり)

このページでは、ユーザーフォーム(以下「フォーム」)の表示位置を指定する方法を紹介します。

サンプルコードをコピペするだけで、フォームを画面の左上、左下、右上、右下などへ、簡単に表示することができるようになります。

解像度の違うディスプレイで実行しても表示位置が自動調整されるほか、余白の指定もできます。

タスクトレイ通知のようなちょっとカッコいい右下表示も簡単に実装できるので、ぜひお試しください。

目次

フォーム表示位置の考え方

VBAでの基本的なフォーム表示位置の指定方法は次のとおりです。(興味ない方はスキップしてください。)

基本的な指定方法(手動指定)

フォームの表示位置を指定する基本コードは次のとおりです。

Sub Form_ManualPosition()
'表示位置固定指定
    
    With SampleForm
        .StartUpPosition = 0
        .Left = 200
        .Top = 150
        .Show vbModeless 'フォームを表示
    End With
    
End Sub

まず「StartUpPosition = 0」はフォームの表示位置を手動で指定することを意味します。

さらに「Left = 200」で左から200ポイント、「Top = 150」で上から150ポイントというように左上からの位置を「ポイント」で指定します。

このように指定した位置へフォームの左上角が来るようにフォームが表示されます。

つまり、ディスプレイの左上を起点として表示位置を指定するのが通常の方法となります。

画面サイズを取得して表示位置を指定する

例えば、左上に表示するには、LeftとTopを両方0に指定してやるか、LeftとTopの行を削除してやればOKです。

具体的にコードを示すと次のようになります。(LeftとTopの行を削除)

Sub Form_ManualPosition()
'表示位置固定指定
    
    With SampleForm
        .StartUpPosition = 0
        .Show vbModeless 'フォームを表示
    End With
    
End Sub

しかし、左下、右上、右下はどうでしょう?

例えば自分の使っているディスプレイで表示位置を探し出したとしても、解像度が違うディスプレイでは表示位置がずれてしまいます。

場合によってはディスプレイの外に表示されてしまい、画面上のどこにもフォームが確認できないなんてことにもなりかねません。(この場合、マウスの操作範囲外になるため、操作不能に陥ります。)

このような事態を防ぐため、フォームを左下、右上、右下などの特殊な位置に表示したい場合、ディスプレイ解像度に合わせて表示位置を動的に取得できるコードが望ましいことになります。

次項で紹介するセットコードは、通常左上である起点を、左下、右上、右下にするようなイメージです。

表示位置を指定できるセットコード

こちらがディスプレイ解像度に合わせて表示位置を動的に調整するためのサンプルコードのセットです。

次のコードを新しい標準モジュールに丸ごとコピペしてもらえればそのまま使用できます。(カスタマイズも自由です。)

Option Explicit
Option Private Module


'ディスプレイ解像度取得API関数
Private Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long


Function GetDispSize(GetType) As Long
'ディスプレイ解像度を取得
'引数に取得する方向を指定(幅/高)
'幅:0 or "W"/高:1 or "H"
    
    If GetType = 0 Or GetType = "W" Then
        GetDispSize = GetSystemMetrics(0)
    ElseIf GetType = 1 Or GetType = "H" Then
        GetDispSize = GetSystemMetrics(1)
    Else
        GetDispSize = 0
    End If
    
End Function


Sub FormPosi_LeftTop(objForm As Object, _
                     Optional MarginLeft As Long, _
                     Optional MarginTop As Long, _
                     Optional ShowMode As Long)
'【左上表示】
'フォーム起動前に実行することで画面左上へ表示
'第一引数:対象フォームオブジェクト
'第二引数:左余白(整数指定)
'第三引数:上余白(整数指定)
'第四引数:表示モード[0=表示なし/1=Normal/2=Modeless]
'例:Call FormPosi_LeftTop(UserForm, 0, 5, 2)
    
    With objForm
        
        'フォームポジションをセット
        .StartUpPosition = 0
        .Left = 0 + MarginLeft
        .Top = 0 + MarginTop
    
    End With
    
    'フォーム表示
    Call CmnFormOpen(objForm, ShowMode)
    
End Sub


Sub FormPosi_LeftLow(objForm As Object, _
                     Optional MarginLeft As Long, _
                     Optional MarginLow As Long, _
                     Optional ShowMode As Long)
'【左下表示】
'フォーム起動前に実行することで画面左下へ表示
'第一引数:対象フォームオブジェクト
'第二引数:左余白(整数指定)
'第三引数:下余白(整数指定)
'第四引数:表示モード[0=表示なし/1=Normal/2=Modeless]
'例:Call FormPosi_LeftLow(UserForm, 0, 30, 2)
    
    With objForm
        
        'フォームサイズ取得
        Dim frmHeight As Long
        frmHeight = .Height
        
        'ディスプレイ解像度取得
        Dim DispHeight As Long
        DispHeight = GetDispSize(1)
        
        'ピクセル→ポイント変換
        DispHeight = DispHeight * (72 / 96)
        
        'フォームポジションをセット
        .StartUpPosition = 0
        .Left = 0 + MarginLeft
        .Top = DispHeight - frmHeight - MarginLow
    
    End With
    
    'フォーム表示
    Call CmnFormOpen(objForm, ShowMode)
    
End Sub


Sub FormPosi_RightTop(objForm As Object, _
                      Optional MarginRight As Long, _
                      Optional MarginTop As Long, _
                      Optional ShowMode As Long)
'【右上表示】
'フォーム起動前に実行することで画面右上へ表示
'第一引数:対象フォームオブジェクト
'第二引数:右余白(整数指定)
'第三引数:上余白(整数指定)
'第四引数:表示モード[0=表示なし/1=Normal/2=Modeless]
'例:Call FormPosi_RightTop(UserForm, 0, 5, 2)
    
    With objForm
        
        'フォームサイズ取得
        Dim frmWidth As Long
        frmWidth = .Width
        
        'ディスプレイ解像度取得
        Dim DispWidth As Long
        DispWidth = GetDispSize(0)
        
        'ピクセル→ポイント変換
        DispWidth = DispWidth * (72 / 96)
        
        'フォームポジションをセット
        .StartUpPosition = 0
        .Left = DispWidth - frmWidth - MarginRight
        .Top = 0 + MarginTop
    
    End With
    
    'フォーム表示
    Call CmnFormOpen(objForm, ShowMode)
    
End Sub


Sub FormPosi_RightLow(objForm As Object, _
                      Optional MarginRight As Long, _
                      Optional MarginLow As Long, _
                      Optional ShowMode As Long)
'【右下表示】
'フォーム起動前に実行することで画面右下へ表示
'第一引数:対象フォームオブジェクト
'第二引数:右余白(整数指定)
'第三引数:下余白(整数指定)
'第四引数:表示モード[0=表示なし/1=Normal/2=Modeless]
'例:Call FormPosi_RightLow(UserForm, 0, 30, 2)
'Windowsのタスクバー高は約30ピクセル
    
    'タスクバー高さ指定
    Dim TaskBarHeight As Long
    TaskBarHeight = 30
    
    With objForm
        
        'フォームサイズ取得
        Dim frmWidth As Long, frmHeight As Long
        frmWidth = .Width
        frmHeight = .Height
        
        'ディスプレイ解像度取得
        Dim DispWidth As Long, DispHeight As Long
        DispWidth = GetDispSize(0)
        DispHeight = GetDispSize(1)
        
        'ピクセル→ポイント変換
        DispWidth = DispWidth * (72 / 96)
        DispHeight = DispHeight * (72 / 96)
        
        'フォームポジションをセット
        .StartUpPosition = 0
        .Left = DispWidth - frmWidth - MarginRight
        .Top = DispHeight - frmHeight - MarginLow
    
    End With
    
    'フォーム表示
    Call CmnFormOpen(objForm, ShowMode)
    
End Sub


Sub CmnFormOpen(objForm As Object, _
                Optional ShowMode As Long)
'モード指定表示
'第一引数:対象フォームオブジェクト
'第二引数:表示モード[1=Normal/2=Modeless]
    
    If ShowMode = 1 Then
        objForm.Show
    ElseIf ShowMode = 2 Then
        objForm.Show vbModeless
    End If
    
End Sub

実行コードの記載方法

上記で紹介したコードを呼び出し、個別に実行するコードの記述方法(使い方)を説明します。

共通引数について

左上に表示する呼び出しコードを例に解説します。

Call FormPosi_LeftTop(SampleForm1, 0,5, 2)

  1. フォームのオブジェクト名
  2. (省略可)左右余白(ポイント指定)
  3. (省略可)上下余白(ポイント指定)
  4. (省略可)フォーム表示指定

それぞれ補足すると、

①は「SampleForm1」というフォームのオブジェクト名を指定しています。Caption(フォームを表示したときに上に表示されるタイトル)ではなく、オブジェクト名を指定することに注意してください。

②と③は余白を整数で指定します。指定にあたっては次のように表示位置によって少し意味が変わる点に注意してください。

  • ②:左側を基準に表示するものは左端から、右側を基準に表示するものは右端からの余白
  • ③:上側を基準に表示するものは上端から、下側を基準に表示するものは下端からの余白

②③とも、省略した場合は「0」扱いになります。

④はフォームを表示する方法を0~2の整数で指定します。「1」を指定した場合はモーダルモード、「2」を表示した場合はモードレスモードで表示します。(下記参照)

なお、④を省略した場合は「0」扱いになり、フォームを表示しません。指定フォームの位置のみセットされるので、この処理後にそのフォームを通常表示させると、指定位置にフォームを表示させることができます。

モーダルモード/モードレスモードについて

モーダルモード

  • 1つしか開けない
  • 開いている間はそのフォームの操作のみ可能
  • 開いている間はプログラムの進行がストップ

モードレスモード

  • 複数フォームを開くことができる
  • 開いている間も他のフォームやシートの操作が可能
  • プログラムの進行は継続される

表示位置別の実行コードサンプル

前項の引数指定方法を踏まえ、表示位置別実行コードの記述例を記載しておきます。

表示位置:左上

Call FormPosi_LeftTop(SampleForm1, 0, 5, 2)

SampleForm1を、左端から0ポイント、上端から5ポイントの余白を空けて、モードレスモードで表示する。

表示位置:左下

Call FormPosi_LeftLow(SampleForm2, 0, 30, 2)

SampleForm2を、左端から0ポイント、下端から30ポイントの余白を空けて、モードレスモードで表示する。

なお、下端から30ポイントというのはタスクバーの標準的な高さです。タスクバーを2段以上で表示している場合は調整が必要です。

表示位置:右上

Call FormPosi_RightTop(SampleForm3, 0, 5, 2)

SampleForm3を、右端から0ポイント、上端から5ポイントの余白を空けて、モードレスモードで表示する。

表示位置:右下

Call FormPosi_RightLow(SampleForm4, 0, 30, 2)

SampleForm4を、右端から0ポイント、下端から30ポイントの余白を空けて、モードレスモードで表示する。

下端の30ポイントは左下の例で記載したとおり、タスクバーの高さです。

(参考)ディスプレイ解像度のポイント変換

先に紹介したセットコードではディスプレイ解像度をAPI関数(GetSystemMetrics)で取得しています。

この関数で取得されるディスプレイ解像度は「ピクセル」という単位で取得されます。

対して、Excelでは通常「ポイント」という単位を利用します。

このため、ピクセルをExcelVBAで利用するためにはポイント換算してやらないと扱いにくい点に注意してください。

セットコード内のコメントを読めばわかるとおり、次のようにポイント換算しています。

ポイント = ディスプレイ解像度(ピクセル) × ( 72 ÷ 96 )

ちょっとした豆知識ですが、覚えておくと役に立つかもしれません。どうぞ参考まで。

まとめ

ユーザーフォームの表示位置を、ディスプレイ解像度に合わせて動的に取得するコードを紹介させていただきました。

サンプルコードは少し長いですが、API関数でディスプレイ解像度を取得していること以外、単純にStartUpPositionを利用して表示位置を算出しているにすぎません。

本体コードは丸ごとコピペで使えるようパーツ化してあるので、意味を理解してもらう必要もありません。

VBAツールはフォームの表示位置など、ちょっとしたことでも使い勝手が変わるものです。

ぜひ、あなたのツールに取り入れてみてください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次