見出し画像

【VBAマクロ】AccessからExcel出力して請求書を作成する方法その4(VBA編)

お待たせしました!

このシリーズもパート4までやってきて、やっとVBAの内容です。

本当は、クエリの部分をもうちょっと書きたかったんですが、あまりにも長いとクレームが来そうなのでライトに進めます。笑

クエリの件については、別記事でアップしますね。

まずはレコードセットの存在を知る

画像1

これ系の機能を実装するにあたって、必ず知っておきたいのがレコードセットの存在についてです。

分かりやすく言えばテーブルのことなんですが、詳しく表現するとテーブル内にある1行が1レコードになります。

それが集まってレコードセットって集合体になる感じですね。

テーブルだけでなく、選択クエリの結果でもレコードセットが確認できますよね。

選択クエリの結果は、そこだけ見ればテーブルとなんら変わりはありません。

このレコードセットの中を1行ずつ見て、その情報を取得したり出力したりするのがレコードセットの操作。

今回は請求書エクセルへの出力になるので、クエリの結果をレコードセットとして取得して、1行ずつエクセルへ吐き出す処理をVBAで書きます。

ごちゃごちゃ言わんと、とりあえず書きます!

もう能書きたれてもしゃーないので、レコードセット操作のサンプルを書いていきます。

イメージしやすいように、下記の請求書を想定して書いていきましょう。

請求書サンプル

このフォーマットから分かることは、固定的な項目と流動的な項目が存在する点です。

〇〇御中とか請求書NOとか、下記の備考欄は1ページに一つしかないので固定になります。

一方で請求内訳は、その時々で数が違ってくるのでレコードを読み取ってエクセルへ書き込みの流れ。

この点に注意しながら作っていきます。

Private Sub payment(from As Date, to As Date)

    Const conStartRow = 10
    Const conStartCol = 2
    const conEndCol = 4

    Dim rs(1As DAO.Recordset
    Dim qd As DAO.QueryDef
    Dim xlApp As Object
    Dim xlBook As Object
    Dim xlSheet As Object
    Dim iRow, iCol
    
        With DoCmd //請求情報をテーブルへ格納
            .SetWarnings False
            .OpenQuery("q_delete_paymentItem"//t_paymentItemを一旦削除
            .OpenQuery("q_insert_paymentItem"//t_paymentItemへ追加
            .SetWarnings True
        End With
      
        Set rs(0) = CurrentDB.OpenRecordset("q_paymentInfo"//基本情報をグループ化
        With rs(0)
            If .EOF Then
                MsgBox "該当データなし"
                Else
                    Set xlApp = CreateObject("Excel.Application")
                        xlApp.Visible = True //可視化
                    Do Until .EOF
                        Set xlBook = xlApp.Workbooks.Open("[パス名]")
                        Set xlSheet = xlBook.Worksheets("[シート名]")
                        //請求基本情報
                        xlSheet.Range("[顧客名のセル]").Value = !顧客名.Value
                        xlSheet.Range("[住所のセル]").Value = !住所.Value
                        xlSheet.Range("[連絡先のセル]").Value = !連絡先.Value
                        //請求内訳
                        Set qd = .QueryDefs("q_paymentItem")
                            qd.Parameters("[顧客名?]").Value = !顧客名.Value
                        Set rs(1) = qd.OpenRecordset
                        With rs(1)
                            iRow = conStartRow
                            Do Until .EOF
                                For iCol = conStartCol To conEndCol
                                    xlSheet.Cells(iRow, iCol).Value = .Fields(iCol + 1).Value
                                Next iCol
                                iRow = iRow + 1
                                .MoveNext
                            Loop
                            .Close
                        End With
                        xlBook.SaveAs "C:¥請求書" & !顧客名.Value & ".xlsx"
                        //要注意
                        xlApp.Workbooks("請求書" & !顧客名.Value & ".xlsx").Close False
                        .MoveNext
                    Loop
                    With xlApp
                        .Visible = False
                        .Quit
                    End With
                    Set qd = Nothing
                    Set xlSheet = Nothing
                    Set xlBook = Nothing
                    Set xlApp = Nothing
            End If
            .Close
        End With
        Erase rs
End Sub

思ったより複雑になりました(笑)

できるだけ簡単に書こうと思いましたが、思いのほか長いコードになってしまいました。

前提として、この請求書フォーマットは請求内訳が12項目までしか表示できません。

したがって、13以上の請求内訳には対応していないことをご了承ください。

13以上の項目にも対応したコードを紹介しようと思っていたんですが、あまりにも長ったらしいコードになってしまうので、今回は12項目までを想定した内容になっております。

今回はレコードセットを請求基本情報と請求内訳に分割して、それらをエクセルファイルへ書き込む内容にしました。

まずはクエリ。

基本情報クエリをループで回すことを最初にデザインします。

次に、基本情報をパラメータとした請求内訳のループをデザインしましょう。

今回は1顧客1ファイルなので、Loopの最後にBookを保存して閉じる工程が入ってきます。

この時に陥りやすいのが、コメントで「要注意」と記載した構文。

普通に考えればxlApp.Workbooks(C:¥[Boook名])と書いてしまいそうですが、これだとエラーになります。(何回もハマりました)

ここはファイル名だけを記載して、xlApp.Workbooks([Boook名])とするのが正解。

地味ですが、結構大事なポイントです。

請求書出力にここまで大変なんか!と思った方

すみません。大変なんです。

ただエクセル関数を駆使すれば、一行だけVBA書いてエクスポートさせる方法もあります。

今回、敢えてややこしい方法を紹介したのは、色んなレポート出力で使える汎用性の高い考え方だからです。

指定されたエクセルフォーマットへ出力するのって、本当に至難の技。

出来れば一行目がカラムで二行目からデータが始まっていて、セル結合とかも無い方が嬉しいものです。

でも現実はそうではありません。

クエリからエクセル出力までの流れを自分なりにデザインできれば、どんな形式でも対応できるので是非頑張って会得してくださいね。

画像3


この記事が気に入ったらサポートをしてみませんか?