エクセルで領収書を作成します。
ユーザーフォームのVBAを使って印刷全体をコントロールできるようにします。
マルチページをつかいつつコンパクトに仕上げます。
こんにちは、じゅんぱ店長(@junpa33)です。
今回は、領収書印刷をコントロールするためのパネル(ユーザーフォーム)作成と設定を行います。
エクセルVBAでの領収書作成は、今回の記事が最終回となります。
これまでの流れについては、先の記事でご確認ください。
コンテンツ
印刷をコントロールするユーザーフォームのデザイン

ユーザーフォームを作成して、印刷していくための操作ボタンを設置したコントロールパネルを完成させます。
レイアウトスタイル的には、タブによるページ切り替えで、単独印刷画面と連続印刷画面を表示できるようにします。
それでは、
作業ごとに区切りながら説明していきます。
ユーザーフォームを表示する
 ユーザーフォームの挿入と表示は簡単 エクセルVBA
   ユーザーフォームの挿入と表示は簡単 エクセルVBA  VBEからユーザーフォームボタンをクリック

すると、このような感じになります。

この ” User Form ” で作業していきますが、適宜 拡大縮小をしてください。
ユーザーフォーム表示のタイミング設定
ユーザーフォームの表示されるタイミングは、”発行データ入力シート”が開かれる時に可視化します。
「印鑑を自動で挿入」の記事で解説したことと同様に、
”発行データ入力シート”がアクティブの時に表示される設定とします。
シートモジュール(発行データ入力のシートモジュール)に以下のコードを記述します。
コード⑨
Private Sub Worksheet_Activate()
        If コントロールパネル.Visible Then Exit Sub
        コントロールパネル.Show vbModeless
End Sub
このように記述してください。
コントロールパネルの”発行日入力ボックス”設定
 テキストボックスをユーザーフォームに設置する
   テキストボックスをユーザーフォームに設置する  まず最初に
”User Form”名称を”コントロールパネル”に変更します。

つぎに

ツールボックスボタンの中の”A のラベルボタン”をおしてタイトル付けをします。

発行年月日を入力できる設定をします。
ツールボックスボタンの中の”ab| のテキストボタン”をおしてテキスト入力ボックスをセットします。

同様に作業を繰り返して、
「(元号)(ねん)年 (つき)月 (にち)日」を完成させてください。

コマンドボタンを配置します。
ツールボックスからコマンドボタン(プッシュ型のボタンマークのもの)を選択してください。

入力した発行日情報をデータ利用する
- 元号の代入先としての変数・・・・Gen
- 年の代入先としての変数・・・・・Nen
- 月の代入先としての変数・・・・・Tuk
- 日の代入先としての変数・・・・・Nit
ここで設定する変数は、このプロジェクトのモジュール間を跨いで利用しますので、変数宣言もそれが可能になる宣言方法で行います。
テキスト入力ボックスに入力したデータをVBAコード化します。
コードの入力ウインドウを開きます。

「日付を入力したときに”日付入力ボタン”をクリックして、データを確定」するコードです。
ユーザーフォームモジュール(コントロールパネルのモジュール)に記述します。
コード⑩
Private Sub 日付入力_Click()
        Gen = コントロールパネル.Controls("元号").Value
        Nen = コントロールパネル.Controls("ねん").Value
        Tuk = コントロールパネル.Controls("つき").Value
        Nit = コントロールパネル.Controls("にち").Value
End Subこのようになります。

次に変数の宣言のためのコードを記述します。
コードの設置場所は”標準モジュール”に記述した”コード①”の上 一番最初です。そこに置いてください。
関連記事
 宣言方法で変数の適用範囲を変える エクセルVBA
   宣言方法で変数の適用範囲を変える エクセルVBA  コード⑪
    Public Gen As String
    Public Nen As Variant
    Public Tuk As Variant
    Public Nit As Varianこのようになります。

さらに、コード②の中に処理コード⑫を設置します。設置場所に注意ください。
これで発行日の和暦を表示します。
”元号” の部分は、「平成」でも「令和」でもOKです。
コード⑫
    If Nen = "" Then Nen = "  "
    If Tuk = "" Then Tuk = "  "
    If Nit = "" Then Nit = "  "
    Range("B" & aR).Value = Gen & Nen & "年" & Tuk & "月" & Nit & "日"
    Range("H" & aR).Value = "済"このようになります。

タブで変わるマルチページを設置する
1件毎選択して印刷していくボタンを設置します。
マルチページの設置方法についてはこちら↓の記事でも確認していただけます。
 マルチページをユーザーフォームに設置する
   マルチページをユーザーフォームに設置する    エクセルVBAマルチページ作成。秘密鍵コードで非表示化!
   エクセルVBAマルチページ作成。秘密鍵コードで非表示化!  まず、ツールボックスの”マルチページ”ボタンを選択してタブでページ切り替えができるようにします。
先ほど作成した「コントロールパネル」の「日付入力」ボタンの下に設置してください。
このような感じです。

次に、タブの文字を大きくハッキリ表示させます。
プロパティの選択で ” multiPage1 ” をプルダウンメニューから選択します。
”Font”のところで文字のスタイルを変更してください。
” Page1 ” を「連続印刷」
” Page2 ” を「単独印刷」 と設定してください。

印刷をコントロールするVBAコード作成

ユーザーフォーム上に単独印刷と連続印刷の2種類のコントロールページを作ります。
単独印刷ページをつくる
- 印刷指定のため選択したセルの行番号・・・・aR
- 印刷指定した宛先名・・・・・・・・・・・・PVa
それでは次に単独印刷のために必要な項目を設定していきます。
作業の流れ
先ほどと同じように、ツールボックスボタンの中の”A のラベルボタン”をおしてラベルを付けます。
| Caption | オブジェクト名 | 内容 | 
|---|---|---|
| 「一件づつ印刷をする場合の設定をします。」 | ||
| 「印刷対象宛名」 | ||
| 「宛名をクリックすると最新に更新します。」 | ||
| 「印刷宛名」 | 
ツールボックスからコマンドボタン(プッシュ型のボタンマークのもの)を選択してください。
| Caption | オブジェクト名 | 
|---|---|
| 「印刷スタート」 | 
このような感じで仕上げてください。カラーリングは適宜設定されたらと思います。

ラベル部分のコード設定
 ラベルをユーザーフォームに設置する
   ラベルをユーザーフォームに設置する  ラベル「宛名をクリックすると最新に更新します。」を実行するコードを記述します。
4のラベルのところでクリックすると今印刷される宛先が表示されるというコードです。
”印刷宛名”の表示部分を”ダブルクリック”するとコードウインドが表示されますので、そこに記入してください。
ユーザーフォームモジュール(コントロールパネルのモジュール)での記述になります。
 部品化プロシージャーでCallステートメントは必須
   部品化プロシージャーでCallステートメントは必須  コード⑬
Private Sub 印刷宛名_Click()
        宛名確認
End Subと記述してください。

つぎに”宛名確認”のマクロ(VBA)を標準モジュール(module1)に記述します。
コード⑭
Sub 宛名確認()
    Dim PVa As String
        Worksheets("発行データ入力").Select
        aR = ActiveCell.Row
        PVa = Range("D" & aR).Value
        コントロールパネル.印刷宛名.Caption = PVa
End Sub
このようになります。
印刷スタートボタンの起動設定
 コマンドボタンをユーザーフォームに設置する
   コマンドボタンをユーザーフォームに設置する  「印刷スタート」ボタンの設置をしていきます。
先ほどと同じように、「印刷スタート」ボタンをダブルクリックするとコードウインドが開きます。
ユーザーフォームモジュール(コントロールパネルのモジュール)での記述になります。
このように記述してください。
コード⑮
Private Sub 一件印刷_Click()
        一件を印刷
End Sub
”一件を印刷”のマクロ(VBA)を標準モジュール(module1)に記述します。
コード⑯
Sub 一件を印刷()
        Call 領収書作成
        Worksheets("領収書").PrintOut from:=1, To:=2, Preview:=True
        Worksheets("発行データ入力").Select
End Subコードの「領収書作成」は”一件を印刷”の命令(マクロ)の中にあって、領収書作成のマクロを実行しなさいということです。

”印刷スタートボタン”を押すと印刷プレビュー画面が表示されるようになります。
プレビューを確認したうえで印刷するような設定です。
印刷するときはプレビュー画面上の「印刷」をクリックしてください。
これで単独印刷の設定は完了です。
連続印刷ページをつくる
- コントロールパネルで印刷を指定した始点番号・・・・STA
- コントロールパネルで印刷を指定した終点番号・・・・STO
- 印刷指定した始点のデータがあるセルの行番号・・・・Arow
- 印刷指定した終点のデータがあるセルの行番号・・・・Orow
- 印刷指定の始点・終点番号の入力エラーに番号を付与・ErrNo
- メッセージボックスからの返答を代入する変数・・・・rea
- 印刷指定された支店・終点番号を探す関数・・・・Match
- ユーザーからの返答を動作に反映させる関数・・・MsgBox
 VBAで使うMatch関数 活用度アップでテッパン関数に!
   VBAで使うMatch関数 活用度アップでテッパン関数に!    メッセージボックス MsgBox実際の使い方を最速に理解
   メッセージボックス MsgBox実際の使い方を最速に理解  次に連続印刷のために必要な項目を設定していきます。
一連の作業
先ほどと同様に作業します。
”ラベル”を4つ設置します。
先ほどと同じように、ツールボックスボタンの中の”A のラベルボタン”をおしてラベルを付けます。
| Caption | オブジェクト名 | 内容 | 
|---|---|---|
| 「連続して印刷をする場合の設定をします。」 | ||
| 「伝票番号 開始番号」 | ||
| 「伝票番号 終了番号」 | ||
| 「入力番号確認」 | 
伝票番号を入れるテキストボックスを設置します。
ツールボックスボタンの中の”ab| のテキストボタン”をおしてテキスト入力ボックスをセットします。
| テキストボックス | オブジェクト名 | 
|---|---|
| 開始番号のテキストボックス | |
| 終了番号のテキストボックス | 
コマンドボタンを配置します。
ツールボックスからコマンドボタン(プッシュ型のボタンマークのもの)を選択してください。
| Caption | オブジェクト名 | 
|---|---|
| 「入力確認」 | |
| 「印刷開始」 | 
このような感じになります。

連続印刷の伝票番号チェックVBAコード
コントロールパネルのコードウインドに以下のコードをタイプしてください。
“入力確認ボタン”を押したときの動きを指示しています。始点終点の伝票番号を入力しているかいないかの条件分岐をしています。
そのあと「領収書連続印刷準備」というマクロでModuleウインドに移ります。
ユーザーフォームモジュール(コントロールパネルのモジュール)での記述になります。
コード⑰
Private Sub 入力確認ボタン_Click()
        If コントロールパネル.Controls("伝票番号始点") _
                                        .Value = "" Then
           MsgBox "印刷開始伝票番号がありません。", _
                                    vbOKOnly, "メッセージ"
           Exit Sub
        End If
        If コントロールパネル.Controls("伝票番号終点") _
                                        .Value = "" Then
           MsgBox "印刷終了伝票番号がありません。", _
                                    vbOKOnly, "メッセージ"
           Exit Sub
        End If
        コントロールパネル.番号確認.Caption = _
            Me.伝票番号始点.Value & "から" & _
            Me.伝票番号終点.Value & "まで印刷します。"
        Call 領収書連続印刷準備
End Sub
標準モジュール(Module1)の一番最初に記述します。
コード⑱
  Public STA As Long
  Public STO As Long
  Public Arow As Variant
  Public Orow As Variant
  Public ErrNo As Long標準モジュール(Module1)に記述します。
始点終点番号の正誤をチェックするコードです。
 Gotoステートメントでコードをジャンプ!毒と薬の2面性
   Gotoステートメントでコードをジャンプ!毒と薬の2面性  コード⑲
Sub 領収書連続印刷準備()
        ErrNo = 0
        STA = コントロールパネル.伝票番号始点.Value
        STO = コントロールパネル.伝票番号終点.Value
        Worksheets("発行データ入力").Select
        On Error GoTo Err_trap1
        Arow = WorksheetFunction.Match(STA, Range("A:A"), 0)
       
        On Error GoTo Err_trap2
        Orow = Application.WorksheetFunction _
                                .Match(STO, Range("A:A"), 0)
        If Arow > Orow Then
           MsgBox "伝票番号は昇順で指定してください。" _
                                        , vbYes, "メッセージ"
           Exit Sub
        End If
        Exit Sub
Err_trap1:
        MsgBox "印刷開始伝票番号が存在していません。" _
                                        , vbYes, "メッセージ"
        コントロールパネル.伝票番号始点.Value = ""
        コントロールパネル.伝票番号終点.Value = ""
        ErrNo = 1
        Exit Sub
Err_trap2:
        MsgBox "印刷終了伝票番号が存在していません。" _
                                        , vbYes, "メッセージ"
        コントロールパネル.伝票番号始点.Value = ""
        コントロールパネル.伝票番号終点.Value = ""
        ErrNo = 1
End Sub
このようになります。
印刷スタートボタンを設定します。
コントロールパネルのコードウインドに以下のコードを記述してください。
このコードはメッセージウインドウを出してチェックを促します。
コード⑳
Private Sub 印刷開始_Click()
        rea = MsgBox("印刷を始めますか?", vbYesNo + _
                vbQuestion + vbDefaultButton2, "メッセージ")
        If rea = vbNo Then Exit Sub
        If コントロールパネル.Controls("伝票番号始点") _
                                            .Value = "" Then
           MsgBox "印刷開始伝票番号がありません。" _
                                    , vbOKOnly, "メッセージ"
           Exit Sub
        End If
        コントロールパネル.番号確認.Caption = _
                    Me.伝票番号始点.Value & "から" & _
                    Me.伝票番号終点.Value & "まで印刷します。"
        If コントロールパネル.Controls("伝票番号終点") _
                                                .Value = "" Then
           MsgBox "印刷終了伝票番号がありません。" _
                                        , vbOKOnly, "メッセージ"
           Exit Sub
        End If
        コントロールパネル.番号確認.Caption = _
                    Me.伝票番号始点.Value & "から" & _
                    Me.伝票番号終点.Value & "まで印刷します。"
        Call 領収書連続印刷実行
        コントロールパネル.番号確認.Caption = ""
End Sub
標準モジュール(Module1)に記述します。
コード㉑
Sub 領収書連続印刷実行()
    Call 領収書連続印刷準備
    If ErrNo = 1 Then Exit Sub
    For n = Arow To Orow
        Worksheets("発行データ入力").Select
        Range("A" & n).Select
        領収書作成
        Worksheets("領収書").PrintOut from:=1, To:=2
    Next n
    Worksheets("発行データ入力").Select
    コントロールパネル.伝票番号始点.Value = ""
    コントロールパネル.伝票番号終点.Value = ""
End Sub

連続印刷については、”印刷スタート”ボタンを押すと、印刷プレビュー画面なしに、すぐに印刷が始まります。
印刷プレビュー画面を表示すると、動作がすべて一旦停止してしまうので、連続にならないからです。
以上でVBAコード記入作業は終わりです。
お疲れさまでした。
ユーザーフォーム全体の見栄えをチェック

これで入力したデータがすべて領収書テンプレートに表示されるようになりました。
最後に領収書テンプレートの文字サイズや文字の配置を整えて、見栄えをチェックしてください。
VBAでこれらの表示設定のセットはすべて可能ですが、ここはセルの書式設定を使ったほうが速くて簡単です。
- 発行先名 文字の大きさ14
- 領収金額 文字の大きさ14で太字
- 内訳金額 配置を右詰め
他にも気になるところは適宜 設定変更してください。
ユーザーフォームのVBAで印刷をコントロールのまとめ

これでオリジナルな領収書の作成方法の解説は終了です。
”発行データ入力シート”のセルには数式などは全く入っていませんので、データはそのまま加工利用することがでます。
記述しましたコードをご利用に応じてカスタマイズして、さらに自分なりに使いやすくしてください。
完成品のエクセル「領収書作成.xlsm」をダウンロードできるようにしています。
<このDLしたエクセルファイルはVBAコードを保護していますので改変はできません。>
最終形のダウンロードはこちらから↓。
このソフトはご自分で業務でお使いいただくのはフリーですが、
転載や転売については許可しておりませんので、ご使用にならないよう固くお断りいたします。
短期間でエクセルVBAの独学習得を目指したいなら

エクセルVBAを独学する独習方法は、学習者それぞれ十人十色、多種多様と思われます。
けれども、
出来るだけ効率よく学習するためには、いくつかの大切なポイントがあります。
独学でもVBA習得の中級クラスに達するのはそんなに難しいことではありません。
先人が行った勉強方法をあなたがそのまま利用すればよいということです。
 エクセルVBAを独学で習得する!ために大切な7つのポイントを解説します
   エクセルVBAを独学で習得する!ために大切な7つのポイントを解説します  独習のための大切な7つのポイントは、上記記事にて解説しています。
出来るだけ多くの実例に触れること!
正直、VBAの学習について自分の周りの仕事(業務)からだけ実例を得るのでは効率良い習熟は無理です。
ハッキリ言って、
本当に短い期間でVBA習得を成功させたいなら、今使っている参考書が良書かどうかを判断し、新ツールとしてオンライン学習も取り入れて行うことが、
手っ取り早く短期間習得できるというのは間違いないでしょう。
エクセルVBAを独習するのに参考書は欠かせません。 参考書選びは自分に合った「相棒」にできるものを選んでいきたいです。
 エクセルVBAの独習でおすすめ参考書を7冊選ぶ。良書との出会いは大切です
   エクセルVBAの独習でおすすめ参考書を7冊選ぶ。良書との出会いは大切です  
今回の記事はここまでです。 最後までご覧いただき有難うございました。
<記事内容についての告知>
VBAコードの記述記事においては、その記述には細心の注意をしたつもりですが、掲載のVBAコードは動作を保証するものではりません。 あくまでVBAの情報の一例として掲載しています。 掲載のVBAコードのご使用は、自己責任でご判断ください。 万一データ破損等の損害が発生しても当方では責任は負いません。
 
                





