VBAを使ったエクセルの複数ユーザーフォームに関する簡単な小技


次回使うときに忘れてもすぐに思い出せるようにまとめた備忘録的なエクセルのユーザーフォームの基本的な使い方のメモです。

エクセルの構成としてシートは「Sheet1」1枚、ユーザーフォームは2枚でUserForm1からUserForm2を起動させます。

UserForm1上にはコマンドボタン2個とテキストボックス3個が配置されています。





Sheet1上のグラフを表示するデータはC行~E行の1列目から例えば「i」番目までにある前提でVBAは動作しています。

エクセルのVBAのコードをできるだけ増やしたくないので、基本はユーザーフォームの部品プロパティで初期設定は基本は行うようにします。

例)
最初のユーザーフォームの表示位置
部品サイズに対して自動的に画像を合わせる
部品毎の色、サイズ、フォントの種類、初期表示コメント等





今回はVBAの基本的な使い方はある程度、知ってる前提で、簡単にユーザーフォームを使う手順だけの説明です。



Module1のコード


複数のユーザーフォームを立ち上げる

Sub UserForm1_open()
'ユーザーフォームが開いてる時はシートを最小化
    Application.DisplayFullScreen = False
    Application.WindowState = xlMinimized
'複数ユーザーフォームを表示するために「0」を設定 
    UserForm1.Show 0
End Sub

エクセルからユーザーフォームが起動させると、エクセルシートは最小化されて表示されなくしています。こうする事によって見た目、専用アプリが立ち上がったような雰囲気を出しています(笑)


複数のユーザーフォーム画面をまとめて閉める

Sub UserForm1_close()
'ユーザーフォーム画面を閉じる
    Unload UserForm1
    Unload UserForm2
'エクセルの画面を通常状態に戻す
    Application.WindowState = xlNormal   
End Sub

複数のユーザーフォームを閉じたあとに、最初に最小化したエクセルシートを通常の画面に戻します。


ユーザーフォーム上にグラフを表示させる

Sub Disp_Graph()
'ファイル化する前に画像の大きさを指定
    Sheets("Sheet1").Select
    ActiveWindow.Zoom = 100
'エクセルファイルと同じ場所にグラフをファイル化(bmp/jpg)
    Worksheets("Sheet1").ChartObjects("Chart 1").Chart.Export ThisWorkbook.Path & "\sample1.bmp"
'ここではボタンにグラフを表示
    UserForm1.CommandButton1.Picture = LoadPicture(ThisWorkbook.Path & "\sample1.bmp")
End Sub

ユーザーフォームに直接グラフを作画する機能はないので一度、画像ファイルを作成してから、読込んでボタンなどに貼り付けて表示させます。画像ファイルは処理後に消す事もできますが、今回はエクセルファイルと同一フォルダに残っています。

画像の大きさは自動的にボタン等の部品サイズに合わせられますが、縮小しすると画像が汚くなります。実際に使うときは表示させて確認が必要です


グラフの表示範囲を変更する

Sub Disp_change()
'表示範囲を変更したいグラフを選択
    Sheets("Sheet1").Select
    ActiveSheet.ChartObjects("Chart 1").Activate
'グラフの表示範囲を変更
    ActiveChart.Axes(xlCategory).MinimumScale = UserForm1.TextBox1.Value
    ActiveChart.Axes(xlCategory).MaximumScale = UserForm1.TextBox2.Value
'マクロを読み込ん事で表示が変化
    Call Disp_Graph   
End Sub

データが多い場合、全体表示にすると細かい部分の分解能が悪くなるので、ユーザーフォーム上で自由に表示範囲を指定して詳細が見れるようにします。


グラフのデータ範囲を変更する

Sub Graph_range()
Sheets("Sheet1").Select
'C1~Di範囲の「i」の値をテキストボックスで設定
    i = UserForm1.TextBox3.Value
    ActiveSheet.ChartObjects("Chart 1").Activate
    ActiveChart.SetSourceData Source:=Range(Sheets("Sheet1").Cells(1, 3), Sheets("Sheet1").Cells(1 + i, 5))
'マクロを読み込ん事で表示が変化
    Call Disp_Graph 
End Sub

後でエクセルのデータを追加した場合など、再度、エクセル上でグラフを作り直さなくてもユーザーフォーム上からデータ範囲を変更することで対応が可能です。


表示した画像を消去する

Sub Graph_Clear()
'画像をクリアする場合はNULLデータを読み込む
    UserForm1.CommandButton1.Picture = LoadPicture(ThisWorkbook.Path & "")
'次の処理が重くて画像更新でいない場合は
    DoEvents
'重たい処理が以下に続く
  ........
End Sub

画像等を消す場合は読込むデータを空にすればOKですが、たまに処理が上手くいかな場合があります。そのときは「おまじない」コマンドを追加します。







UserForm1のコード


複数のユーザーフォームを起動する

Private Sub CommandButton1_Click()
'UserForm1の画像を張付けたボタンをクリックした時
  UserForm2.Show 0
End Sub

ユーザーフォームを連続して起動すれば複数同時に表示されますが、今回はUserForm1から子画面のUserForm2を起動する方法です。


右上「×」ボタンですべてのユーザーフォーム画面を閉じる

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
'UserForm1の「×」ボタンでUserForm2も連動して閉じる
'但し、UserForm2の「×」ボタンの時はUserForm1は連動しない
    Application.WindowState = xlNormal
    Unload UserForm2
End Sub

ユーザーフォームは右上の「×」ボタンで閉じる事がありますが、UserForm1のコードにUserForm2を閉じるコマンドを追加しておくとUserForm1を閉じると同時にUserForm2を閉じる事ができます。このときに同時にエクセル画面を元に戻します。


外部アプリを起動する

Private Sub CommandButton2_Click()
Dim FX As Long
    ChDir ThisWorkbook.Path
'外部アプリを「メモ帳」を起動
    FX = Shell("notepad.exe", vbNormalFocus)
    If FX = 0 Then MsgBox "起動に失敗しました"
End Sub

ユーザーフォームを起動しているときに他のアプリを起動して使い勝手を向上させたい場合の使用例です。


クリックが確認できるようにボタン表示文字を変える

Private Sub CommandButton2_Click()
'UserForm1の画像を張付けたボタンをクリックした時
   UserForm1.CommandButton2.Caption = "処理中"
 'ここの1例は他のマクロ(例えばbeginX())を呼び出し処理
   'Call begin
   UserForm1.CommandButton2.Caption = "開始"
End Sub

ボタン表示には最初「開始」、クリックすると「処理中」、終了すると自動的に元の「開始」に戻ります。処理に時間がかかるときにクリックが上手くできたか確認人するのに有効な方法。