ユーザーフォームへのコントロール配置を効率的に行う?

ユーザーフォームを効率的に作る

コントロールはNewできるか

やってみた。

なお、ユーザーフォームは、

akashi-keirin.hatenablog.com

このときのものを使う。

f:id:akashi_keirin:20170923093524j:plain

オブジェクト名が「BtnLeft」なので、BtnLeft型の変数が宣言できると思ったが、

f:id:akashi_keirin:20170923093534j:plain

あえなく撃沈w Newする以前の問題www

コントロールをNewして量産し、フォーム上に動的に配置していく、ということはできない模様。

コントロールをまとめて扱う

ならば、複数のコントロールを配列にぶち込んで、まとめて設定できないか、やってみた。

f:id:akashi_keirin:20170923093547j:plain

CommandButton型の変数が宣言できるので、

Dim btns(2) As CommandButton
Set btns(0) = Me.BtnLeft
Set btns(1) = Me.BtnCenter
Set btns(2) = Me.BtnRight

みたいにしたらぶち込めるんじゃないかと思ってやってみたら、

f:id:akashi_keirin:20170923093610j:plain

おお、無事通過! できたみたい。

ということは、まとめて取り扱えるということか。

各コマンドボタンのプロパティをまとめて設定する

無事に3つのコマンドボタンを配列にぶち込むことができたので、Forループを使えば、規則的にプロパティを設定できるはず。

次のようなコードで設定を試みた。

リスト1 フォームモジュール
Public Sub init(ByVal formCaption As String, _
                ByVal btnLeftName As String, _
                ByVal btnCenterName As String, _
                ByVal btnRightName As String)
  With Me
    .Caption = formCaption
    .BtnLeft.Caption = btnLeftName
    .BtnCenter.Caption = btnCenterName
    .BtnRight.Caption = btnRightName
  End With
  Dim btns(2) As CommandButton
  Set btns(0) = Me.BtnLeft
  Set btns(1) = Me.BtnCenter
  Set btns(2) = Me.BtnRight
  Dim i As Integer
  For i = 0 To 2
    With btns(i)    '……(1)'
      .Height = 25    '……(2)'
      .Width = 90
      .Top = 10    '……(3)'
      .Left = 5 + ((90 + 5) * i)
    End With
  Next
  Me.Height = 65    '……(4)'
  Me.Width = 295
End Sub

Private Sub UserForm_Terminate()_    '……(5)'
  MsgBox Me.secretName
End Sub

このユーザーフォームの擬似コンストラクタ。引数を渡したいので、UserForm_Initializeは使わない。

(1)からの6行

With btns(i)
  .Height = 25
  .Width = 90
  .Top = 10
  .Left = 5 + ((90 + 5) * i)
End With

は全てWithでまとめているので、配列btnsにぶち込んだそれぞれのコマンドボタンに対する処理。

(2)からの2行

.Height = 25
.Width = 90

でボタンの大きさを設定し、

(3)からの2行

.Top = 10
.Left = 5 + ((90 + 5) * i)

でフォーム上の位置を設定。

Topプロパティは固定で良いが、Leftプロパティはボタンの横幅とボタン同士の間隔分だけ右へずらしていかないといけないので、こんなふうに設定している。まあ、中学校レベルの数学ですわな。

あとは、(4)からの2行

Me.Height = 65
Me.Width = 295

でフォーム全体の大きさを設定しておしまい。

あと、ユーザーフォーム終了時に、追加したプロパティ「secretName」をメッセージ表示するように、(5)の

Private Sub UserForm_Terminate()
  MsgBox Me.secretName
End Sub

デストラクタを作った。

実行

次のコードで実行。

スト2 標準モジュール
Option Explicit

Public Sub userFormTest()
  Dim uFrm As UserFormTemplate
  Set uFrm = New UserFormTemplate
  With uFrm
    .init "アホ", "ボケ", "クズ", "デコスケ"
    .secretName = "ち~んw"
    .Show
  End With
End Sub

これは、このときとほとんど同じ。追加プロパティ「secretName」をイミディエイトに表示する代わりに、ユーザーフォーム終了時のメッセージ表示にした関係でDebug.Printがなくなっただけ。

実行結果

f:id:akashi_keirin:20170923093626j:plain

おおっ、ボタンが整然と配置されておる!

で、フォームを閉じると、

f:id:akashi_keirin:20170923093635j:plain

むかつくwww

おわりに

未だに便利な使いどころは思いつかないけれど、何らかの有効な使い道はある……はず……だよね?(弱気)

@akashi_keirin on Twitter