【EXCEL VBA】UserFormを使ってみよう その2

VBA

この記事は前回の「UserFormを使ってみよう その1」で作成したUserFormのレイアウトにプログラムを設定していく記事です。

「クリックしたらプログラムが実行される」というような流れを「イベント処理」といいます。

今回作成するプログラムは以下の通りです。

  • エクセルシートの入力フォームボタンをクリックしたら、UserFormが呼び出されるプログラム
  •  UserFormが表示される前に実行されるプログラム
    • 年月日を入力するテキストボックスに年月日が入力された状態で表示される
    • 作業者の名前をドロップダウンリスト形式で選択できるようになっている。
  • 「開始時間」及び「終了時間」のボタンをクリックしたら現在の時間が入力されるプログラム
  • 「登録」ボタンをクリックしたらエクセルのシートにUserFormの各項目が反映されるプログラム

以上の3つです。上から順番に説明、解説していきます。

スポンサーリンク

エクセルシートの入力フォームボタンをクリックしたら、UserFormが呼び出されるプログラム

UserFormを呼び出すためには、標準モジュールファイルを作成しなければなりません。
UserFormはエクセルから直接呼び出せないためです。

VBAのタブにある「挿入」から「標準モジュール」を選択してください。

作成した標準モジュールファイルに下記の要領で表示したいフォームのオブジェクト名を呼び出してください。

Sub show_userform1() UserForm1.Show 'UserForm1がオブジェクト名 End Sub

この記述だけでUserFormは呼び出せます。

入力フォームボタンをクリックしたら、UserFormが表示される前に実行されるプログラム

UserFormが呼び出される直前に初期設定をしてくれるプログラムコードを記述していきます。
記述要領は下記の通りです。

Private Sub UserForm_Initialize()
  ここにプログラムを記述していきます。
End Sub

この呼び出しは手入力せず、ドロップダウンリストから選択するようにしましょう。
理由は、UserFormが複数ある場合に違うところに記述してしまう可能性がある為です。
以下で選択方法を示します。

まず、UserFormを編集画面で表示し、UserForm上でダブルクリックします。

上記の画像の上でダブルクリックすると下記の画像のようなコードを記述する画面が表示されます。
完成形ファイルを使って記事を書いているので、いろいろなコードが記述されていますが、気にしないでください。

そのあと、上記の画像のようにコードを記述する画面の右上にドロップダウンリスト形式で選択できるところがありますので、そこで「Initialize」を選択してください。
すると、新しいコードが記述されます。その中に今からコードを記述していきます。

年月日を入力するテキストボックスに年月日が入力された状態で表示される。

このコードは一行で終了します。

Private Sub UserForm_Initialize()
  t_time.Text = Date 't_timeの部分はテキストボックスにつけたオブジェクト名です。
End Sub

=の右側の「Date」の部分は現在の日時が入っている関数です。
頻繁に使用すると思いますので、覚えておいて損はないです。

作業者の名前をドロップダウンリスト形式で選択できるようにする。

この部分は大前提でデータベースシートの作業者名があるテーブルを使用して表示していきます。
リストを一つ一つ記述していく方法もありますが、属人化してしまうので、誰でも編集しやすいようにデータベースシートのようなところから引っ張ってきてあげる方が親切かなと思います。

今回のコードは短いですが、なかなか理解しづらいと思いますので、わからないところがあればコメント等へ質問してもらえればと思います。

  1. 「name」というオブジェクト変数を宣言します。
  2. オブジェクト変数nameにテーブルをセットします。
  3. For Each文を使ってテーブル内の作業者名一つ一つをコンボボックスに追加していきます。

以上がドロップダウンリストを作成する方法ですが、3番目が理解しづらいと思います。
理由は自分が最初わからなかったからです笑

まず、下記のコードの3行目がリストをひとつずつ登録している行です。

Private Sub UserForm_Initialize()
  For Each n In Sheets("データベース").ListObjects("作業者名").DataBodyRange
    cb_name.AddItem n.Value
  Next n
End Sub

cb_nameというコンボボックスに【AddItem】というメソッドを使用して、For Each文の変数nの値を登録しています。

次に2行目の【n】がどのような動作をしているのか確認していきます。
結果から説明しますと、【In】より右の部分がひとつずつ代入されて、繰り返し処理が行われています。
【In】より右側の部分は配列になっています。今回は[A,B,C,D,E,F,G,H]となっています。この配列を左から順番に変数【n】に入れて、3行目を繰り返しています。

以上でUserFormが表示されると年月日が入力された状態でコンボボックスがリストから選択できる状態になりました。
まだ、ボタンを押しても何も実行されませんが、入力する準備は整いましたので、【F5】を押して確認してみてください。

「開始時間」及び「終了時間」のボタンをクリックしたら現在の時間が入力されるプログラム

ボタンをクリックしたら処理が実行される処理はClickを使用します。

UserFormの「開始時間」をダブルクリックすると記述する画面が表示されます。
その中に下記のコードを記述してください。

Private Sub start_Click()
  t_start.Value = Time
End Sub

テキストボックス「t_start」にTime関数を使用して現在時刻を代入しています。
終了時間もダブルクリックし、オブジェクト名を変更し、入力すれば完成です。

「登録ボタンをクリックしたらエクセルのシートにUserFormの各項目が反映されるプログラム

最後に登録ボタンを押したらUserFormのすべての値をシートの各項目に入力していくプログラムを記述していきます。

今回のプログラムコードは以下の流れです。

  • 変数【lastrow】に最終行に次の行番号を代入する。
  • lastrowを活用して、各項目の値をセルに入力していく。

以上です。
下記のコードが完成したコードです。
lastrowにはテーブルの値行数を【ListRows.Count】で取得し、テーブルを作成している場所が2行目からなので、その次の行に入力したいので、+1足して合計+3を追加しています。

Private Sub CommandButton1_Click()
  Dim lastrow As Integer

  With Sheets("作業記録")
    lastrow = .ListObjects("作業記録").ListRows.Count + 3

    .Cells(lastrow, 1).Value = lastrow - 2
    .Cells(lastrow, 2).Value = t_time.Text
    .Cells(lastrow, 3).Value = t_start.Text & "~" & t_finish.Text
    .Cells(lastrow, 4).Value = cb_name.Text
    .Cells(lastrow, 5).Value = work.Text

  End With
End Sub

以上で超絶シンプルですが、UserFormを使った作業内容を入力するプログラムが完成しました。
下記に完成したプログラムコードを記述しておきます。

Private Sub CommandButton1_Click()
    Dim lastrow As Integer
    
    With Sheets("作業記録")
        lastrow = .ListObjects("作業記録").ListRows.Count + 3
        
        .Cells(lastrow, 1).Value = lastrow - 2
        .Cells(lastrow, 2).Value = t_time.Text
        .Cells(lastrow, 3).Value = t_start.Text & "~" & t_finish.Text
        .Cells(lastrow, 4).Value = cb_name.Text
        .Cells(lastrow, 5).Value = work.Text
    End With
End Sub

Private Sub start_Click()
    t_start = Time
End Sub

Private Sub finish_click()
    t_finish = Time
End Sub
 
Private Sub UserForm_Initialize()
    Dim name As Object
    Set name = Sheets("データベース").ListObjects("作業者名")
    For Each n In name.DataBodyRange
        cb_name.AddItem n.Value
    Next n
    
    t_time.Text = Date
End Sub

コメント

タイトルとURLをコピーしました