雨過天晴

Excelでの帳票入力用のフォームの作り方

2020.08.15

category: 日々のつれづれ

tags: ,

img from: Unsplash

こういう↓感じの支払い用の申請書をしょっちゅう作るのですが、いちいち記入するセルを選択して~文字入れて~数字入れて~が面倒くさくなったので、Enterキーでばばばばっと入れられるようにフォームを作りました。

普段はweb系ばかりで、VBA(Visual Basic)を触ることはあまりないので、ひたすらググる…面倒くさい…どっかに記録残しとこう…。
という備忘録です。

もとの帳票Excelファイルがある状態から、今回は入力用のフォームを作ります。

  • 日付は入力が面倒なのでダブルクリックで「今日」(=TODAY()でもいいのですが、時折日付を手入力することがあり。
  • 金額は複数請求書についてのものをまとめて申請することがあるので、とりあえず3セルの金額の合計を帳票に飛ばすことにします。もちろん金額は1件でも大丈夫にします
  • 印刷までばばばばっと行きたいので、印刷プレビューボタンを作ります
  • フォームを閉じるとかセルの値を消すとかそういうボタンも作っておきます

とりあえずフォームを作ります

上部リボン(バージョンはExcel2010です)の開発タブから一番左のVisual Basicをクリック。
(「開発」タブがない場合は「ファイル」→「オプション」→「リボンのユーザー設定」で開発タブを表示する、にする)

こういうのが開きます↓

Visual Basicのウィンドウの「挿入」から「ユーザーフォーム」を選択。

フォーム作成画面と、ツールボックスが出てきます。欲しい形のフォームを適当になんやかんやします。テキストは「ラベル」でしか入れられないのかなたぶん。
今回は、ラベル・テキストボックス、ボタンのみなので、そんなにややこしくないはずです。

いい感じにできたら、左側の「プロパティ」ウィンドウ内の「(オブジェクト名)」をわかりやすいものに変えます。作った順にTextBox1…2…とか番号ふられるので、ぱっと見て分かりやすい名前に変えておきます。
あとでコードを書くときに、どの部品がどれかすぐ分かるようにしておかないと面倒極まりないです。
見栄えは色とか背景色も結構いじれるので、いろいろ触ってみてください。

それから一回Visual Basicの画面を閉じます。
エクセルのシートに戻り、とりあえずどうなるか見たいので、フォームを出すボタンを設置してみます。

こういうボタンを作っておきます。
先ほどと同じ「開発」タブから挿入→フォームコントロールでボタンを作ります。テキストは適当にわかりやすく入れておきます。

ボタンを作っただけではなにも起きないので、押したらフォームを開くようにマクロを登録します。作ったボタンの上で右クリック、「マクロの登録」を選択します。

マクロ名はなんでもいいのでわかりやすくしておきます。

マクロを選択、真っ白な編集画面が出ますので、下記コードを記入します。
(「フォームを出す」はマクロ名、「inputForm」はプロパティで名前を変えたフォームの名前です)
ちなみにコードは「Sub」から「End Sub」までが一つのかたまりです。

Sub フォームを出す()
inputForm.Show
End Sub

ここまでできたらボタンを押してみます。
フォームが表示されるはず。です。フォームは普通のウィンドウと同じく「×」で閉じられます。

ここまで出来たら保存しておきます。

ファイルの種類を通常のエクセルファイル(拡張子xlsx)ではなく、マクロ有効ブック(拡張子xlsm)にするのを忘れないようにします。
通常のエクセルファイルにするとここまでの苦労が全部消えます……。

フォームのデータをシートに飛ばします

いよいよ、フォーム側のコードを書きます。
もう一度「開発」タブの「Visual Basic」を開きます。

今回、フォームの部品それぞれに、プロパティで上画像のような名前を付けています。入力フォーム自体は「inputForm」と名付けています。

名前を付け終わっていたら、フォーム上で右クリックで「コードの表示」。
下記のコードを書きます。
さっきと違ってSubの前にPrivateがついていますが、これはモジュール内だけで動くのか(Private Sub)、他のモジュールからも呼び出せるのか(Sub)という違いだそうです。今回の場合はどちらでも動きそうな気がします。

' 日付テキストボックスをダブルクリックで今日の日付
' 普通に任意の日付の入力もできます
Private Sub TextBox_day_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
TextBox_day.Text = Format(Date, "yyyy/mm/dd")
Cancel = True
End Sub

' 金額テキストボックスの初期値を「0」に
Private Sub UserForm_Initialize()
Me.TextBox_price1.Text = 0
Me.TextBox_price2.Text = 0
Me.TextBox_price3.Text = 0
End Sub

' セルへ入力ボタンを押すとテキストボックスの各値をシート(シート名たこ焼き)へ転記
' セルの指定は例えばセル「C8」なら「Cells(8、"C")」と行から指定する
' 金額セルは金額の合計を入力しています
' 転記後、入力フォームのテキストボックスの値を消去する
Private Sub Button_send_Click()
With Worksheets("たこ焼き")
.Cells(8, "C").Value = TextBox_day.Text
.Cells(9, "C").Value = TextBox_purpose.Text
.Cells(10, "C").Value = TextBox_payfor.Text
.Cells(12, "E").Value = Val(TextBox_price1.Text) + Val(TextBox_price2.Text) + Val(TextBox_price3.Text)
End With
TextBox_day.Text = ""
TextBox_purpose.Text = ""
TextBox_payfor.Text = ""
TextBox_price1.Text = 0
TextBox_price2.Text = 0
TextBox_price3.Text = 0
End Sub

' フォームを閉じるボタン
Private Sub Button_close_Click()
Unload inputForm
End Sub

' 印刷ボタンを押すと印刷プレビュー表示
Private Sub Button_print_Click()
Unload inputForm
ActiveSheet.PrintPreview
End Sub

' テキストクリアボタンを押すと入力フォームの値をクリア
Private Sub Button_textclear_Click()
TextBox_day.Text = ""
TextBox_purpose.Text = ""
TextBox_payfor.Text = ""
TextBox_price.Text = ""
End Sub

' シート(書類本体)(シート名はたこ焼き)の値をクリアする
Private Sub Button_delete_Click()
With Worksheets("たこ焼き")
.Cells(8, "C").Value = ""
.Cells(9, "C").Value = ""
.Cells(10, "C").Value = ""
.Cells(12, "E").Value = ""
End With
End Sub

書けたら「終了してMicrosoft Excelへ戻る」して、フォームを出すところから試してみます。

もしエラーが出るようなものなら書いている間にエラーメッセージがガシガシ出てくるので直します。

その他いろいろ

【追記1】
エクセルファイルを開くと同時にフォームを開きたい場合は、「プロジェクト」ウィンドウから「ThisWorkbook」を選択右クリック。
「コードの表示」をして、下記コードを書くとファイルオープン時に実行されます。

Private Sub Workbook_Open()
inputForm.StartUpPosition = 1
inputForm.Show vbModeless
End Sub

【追記2】
Enterキーを押したときにどの順番に飛ぶかを指定したいときは「タブオーダー」の設定をします。
「Visual Basic」のウィンドウから「表示」→「タブオーダー」で、お好みの順番に並び替えます。