初心者のためのExcel エクセルマクロVBA入門-上級編:フォームの内容を保存したい
ユーザーフォームはごくごく小さいアプリケーション
今回は上級編です。初心者の方はほぅ・・・こんなこともできるのねぇくらいに読んでいただければ幸いです。私のブログで実はあまり扱ってないものがあるのです。それが
ユーザーフォーム
です。はい。これは独自に自分でテキストボックスやチェックボックスなんかを配置して、独自に処理ができるようにしたもので、誤解を恐れずに言うならごくごく小さなツール、アプリケーションのようなものです。各画面の部品ごとにイベント設定ができて、入力した値などをエクセルのシートに反映したりすることができます。
さっそく例を出してしまいますが、簡単な画面を作ってみます。VBEを開いてプロジェクトを右クリック→挿入→ユーザーフォームでユーザーフォームを作ることができます。
下の図がユーザーフォームの初期画面です。
画面の大きさは自由に変えることができますし、ツールボックスから必要なコントロールを選んで配置します。このコントロールもコントロールオブジェクトと言います。やっぱりこれもオブジェクトですね。
例えばテキストボックスとチェックボックスを配置しています。ついでに保存ボタンとわかりやすいようにラベルも配置します。
フォームの値をカスタムプロパティに保存する
なんかこれだけでもちょっと独自なフォームっぽくてかっこいいですね。
さて、これでボタンを押すと保存されるようにしたいのですが、どこに?が問題になってきます。一番簡単なのはシートを非表示にしてそこにフォームの内容を保存して、呼び出しの時もそれを読み込んで表示する。という感じですかね。
ですが、今回はカスタムドキュメントプロパティというものを使ってみたいと思います。これを使うとエクセルファイル自体に値を保存することができます。
まぁ、やってみましょう。保存ボタンをダブルクリックすると、ボタンが押された時のイベントプロシージャが作成されます。
Private Sub CommandButton1_Click() End Sub
ここにカスタムドキュメントプロパティにテキストの値やチェックボックスの値を追加します。
Private Sub CommandButton1_Click() With ThisWorkbook .CustomDocumentProperties.Add Name:="Text1", LinkToContent:=False, _ Type:=msoPropertyTypeString, Value:=UserForm1.TextBox1.Value .CustomDocumentProperties.Add Name:="Check1", LinkToContent:=False, _ Type:=msoPropertyTypeBoolean, Value:=UserForm1.CheckBox1.Value End With End Sub
上級編なので細かい説明は省きますが、ワークブックオブジェクトにあるCustomDocumentProperties プロパティを使います。これを使うとDocumentProperties コレクションを参照できるので、そのAddメソッドを利用することで、独自のキーと値を設定できます。今回ならText1とCheck1にそれぞれフォームの値を設定しています。
これで、ファイルのプロパティにカスタムとしてキーと値が保存されます。
フォーム呼び出し時にカスタムプロパティから読み込む
フォームを読み込む時も同じように、今度は値を参照して、各フォームにセットします。フォームが呼び出された時に、一番最初にPrUserForm_Initialize()メソッドが実行されますので、その中に読み込み処理を書いておきます。
Private Sub UserForm_Initialize() With ThisWorkbook Me.TextBox1.Value = .CustomDocumentProperties("Text1").Value Me.CheckBox1.Value = .CustomDocumentProperties("Check1").Value End With
ですね。CustomDocumentPropertiesで設定したキーを使ってその値をフォームに設定しています。後は、シートにボタンでも作ってあげて、フォームを呼び出せばOKです。フォームを呼び出すなんて基礎すぎるので上級では説明しません。
ここまでが基本です。ここで、上級者は考えます。
- これだと既にキーが存在する場合にもエラーになりそうだな。
- これだとカスタムプロパティにキーがなかったらエラーになるな
こんなことを考えるのです。
※初心者の方へ※
これはもう癖みたいなもんで、経験則として理解しています。DocumentPropertiesはコレクションです。キーと値をセットで持っている状態なので同じキーが存在するとおかしなことになります。また、登録されていないキーを指定してもいけないのです。コレクションオブジェクトというものを理解していると、こんなことを考えられるのです。何度も試行錯誤してマクロを組んでプログラミングを理猪してオブジェクトを理解して、何個もマクロツールを作っていけばそのうち理解できると思いますし、実際に作って動かしてテストをすれば、これくらいはすぐにわかります。
ですので、このままでは、ちゃんと動きませんので、キーをチェックして存在するかどうかを判断し、キーがあればそのキーに設定すればよく、なければ新規で追加する。また読み込む時もやはりキーを指定して、キーがあれば、その中の値を設定する。という動きをしなければいけません。
存在チェック用のメソッドを作成します。
''''''''''''''''''''''''''''''''''''''''''''' ' キー値の存在確認 ''''''''''''''''''''''''''''''''''''''''''''' Private Function isExistKey(ByVal key As String) As Boolean Dim property As Variant For Each property In ThisWorkbook.CustomDocumentProperties If property.Name = key Then isExistKey = True Exit Function End If Next isExistKey = False End Function
これは今あるCustomDocumentPropertiesからキーを取り出して、それが調べるキーと一致しているか?を判定します。後はこいつを保存する時と読み込む時に使ってあげればいいのです。
Private Sub CommandButton1_Click() With ThisWorkbook If isExistKey("Text1") Then .CustomDocumentProperties("Text1").Value = UserForm1.TextBox1.Value Else .CustomDocumentProperties.Add Name:="Text1", LinkToContent:=False, _ Type:=msoPropertyTypeString, Value:=UserForm1.TextBox1.Value End If If isExistKey("Check1") Then .CustomDocumentProperties("Check1").Value = UserForm1.CheckBox1.Value Else .CustomDocumentProperties.Add Name:="Check1", LinkToContent:=False, _ Type:=msoPropertyTypeBoolean, Value:=UserForm1.CheckBox1.Value End If End With End Sub Private Sub UserForm_Initialize() With ThisWorkbook If isExistKey("Text1") Then Me.TextBox1.Value = .CustomDocumentProperties("Text1").Value End If If isExistKey("Check1") Then Me.CheckBox1.Value = .CustomDocumentProperties("Check1").Value End If End With
これで、完璧です。ユーザーフォームはこんな風に設定画面として使ってみたり、エクセルに情報を入力する時にまとめて入力できるように1画面デザインにしたり、または、シートの内容から、データを抽出してみるためのツールとして使ったりなど、様々なことに利用することができます。
エクセルマクロを作るのなら、このユーザーフォームも利用してみるとより利便性が高まるかもしれません。
もちろん、必要な時に限ります。なぜならユーザーフォームは結局のところ別画面であり、一度呼び出したり、閉じたりという動作をユーザーに強いる可能性が大きいからです。(もちろん自動で閉じたり開いたりもできますが…)
是非!初心者のみなさんもチャレンジしてみてください!
今日はここまで!
かしこ