初心者のためのExcelマクロ超入門(絶対できるVBA開発)

マクロがまったくわからない人のためにエクセルマクロやVBAについてできるだけわかりやすく書いています。Twitter:@shuhhohhey

初心者のためのExcel エクセルマクロVBA入門-上級編:フォームの内容を保存したい

ユーザーフォームはごくごく小さいアプリケーション

今回は上級編です。初心者の方はほぅ・・・こんなこともできるのねぇくらいに読んでいただければ幸いです。私のブログで実はあまり扱ってないものがあるのです。それが

ユーザーフォーム


です。はい。これは独自に自分でテキストボックスやチェックボックスなんかを配置して、独自に処理ができるようにしたもので、誤解を恐れずに言うならごくごく小さなツール、アプリケーションのようなものです。各画面の部品ごとにイベント設定ができて、入力した値などをエクセルのシートに反映したりすることができます。
さっそく例を出してしまいますが、簡単な画面を作ってみます。VBEを開いてプロジェクトを右クリック→挿入→ユーザーフォームでユーザーフォームを作ることができます。

f:id:drumer2sh:20131218111400p:plain


下の図がユーザーフォームの初期画面です。


f:id:drumer2sh:20131218111405p:plain


画面の大きさは自由に変えることができますし、ツールボックスから必要なコントロールを選んで配置します。このコントロールもコントロールオブジェクトと言います。やっぱりこれもオブジェクトですね。

例えばテキストボックスとチェックボックスを配置しています。ついでに保存ボタンとわかりやすいようにラベルも配置します。


f:id:drumer2sh:20131218111421p:plain

フォームの値をカスタムプロパティに保存する

なんかこれだけでもちょっと独自なフォームっぽくてかっこいいですね。
さて、これでボタンを押すと保存されるようにしたいのですが、どこに?が問題になってきます。一番簡単なのはシートを非表示にしてそこにフォームの内容を保存して、呼び出しの時もそれを読み込んで表示する。という感じですかね。
ですが、今回はカスタムドキュメントプロパティというものを使ってみたいと思います。これを使うとエクセルファイル自体に値を保存することができます。

まぁ、やってみましょう。保存ボタンをダブルクリックすると、ボタンが押された時のイベントプロシージャが作成されます。

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画面デザインにしたり、または、シートの内容から、データを抽出してみるためのツールとして使ったりなど、様々なことに利用することができます。
エクセルマクロを作るのなら、このユーザーフォームも利用してみるとより利便性が高まるかもしれません。
もちろん、必要な時に限ります。なぜならユーザーフォームは結局のところ別画面であり、一度呼び出したり、閉じたりという動作をユーザーに強いる可能性が大きいからです。(もちろん自動で閉じたり開いたりもできますが…)


是非!初心者のみなさんもチャレンジしてみてください!


今日はここまで!


かしこ