2023/10/17

Notes - Excel 連携:#23)明細データの出力

第 20 回からスタートした『帳票の作成』シリーズの 4 回目です。

今回は帳票の明細行となるノーツのデータを Excel に出力する部分を作成します。今回は、Notes - Excel 連携としては目新しい操作はありません。予めご了承ください。

なお、ノーツデータを Excel シートに出力する方法については、第 4 回 でくわしく紹介しております。必要に応じてご確認ください。


出力データの取得方法

今回の帳票では、指定した年月度の使用量データのみを出力対象とします。

そこで、対象データを検索するためのビュー vXlsSchUsage を作成します。青字のカラムはソートを設定しています。

このビューに対して検索して、対象文書を取得することとなります。

ただ、NotesView クラスの GetAllDocumentsByKey メソッドのデザイナーヘルプには、次のような記述があります(日本語で記載されていた 8.5 より抜粋)。

   このメソッドで返される文書は特定の順序で表示されることはありません。

ちなみに 12.0.2 のヘルプでも引き続き記載されていました。

   Documents returned by this method are in no particular order, ...

この記述は、『検索結果の NotesDocumentCollection オブジェクト内の文書の並び順がビューの順序と同じである保証はない』と理解しました(詳細に検証したわけではありませんので、解釈の間違いかもしれません)。

そこで、今回は、GetDocumentByKey を使用して最初の文書を取得し、ビュー経由で次の文書を順に取得する方法で実現します。この方法であれば、ビューのソート順に確実に従うことができます。また、出力順を変更したい場合にはビューの調整だけで済むので便利ですね。

Function xPrintUsages(voSheet As Variant, _
                       ByVal viYear As Integer, ByVal viMonth As Integer) As Integer
   Dim ns As New NotesSession
   Dim ndb As NotesDatabase
   Dim nv As NotesView
   Dim nd As NotesDocument
   Dim asKey(1) As Integer
   Dim iDoc As Integer '出力した行数

   Set ndb = ns.CurrentDatabase
   Set nv = ndb.GetView("vXlsSchUsage")
   nv.AutoUpdate = False

   asKey(0) = viYear
   asKey(1) = viMonth

   Set nd = nv.GetDocumentByKey(asKey, True)
   While Not (nd Is Nothing)
      iDoc = iDoc + 1
      Call xPrintUsage(voSheet, iDoc, nd) '明細出力

      '次の文書
      Set nd = nv.GetNextDocument(nd)
      If Not (nd Is Nothing) Then
         '年月が変わった場合ループ終了
         If Not(nd.Year(0) = viYear And nd.Month(0) = viMonth) Then
            Set nd = Nothing
         End If
      End If
   Wend

   xPrintUsages = iDoc
End Function

このループ処理では、ループの継続判定で2つのポイントがあります。

1点目は、次の文書の年月度が変わる場合の対応です。次の文書取得後、年月度を確認し、一致しない場合は Nothing をセットしてループを停止させています。

2点目は、次の文書が Nothing となる可能性があることです。ループで処理した文書がビューの最後の文書だった場合は、nd は Nothing となります。この状態で1点目の判定を行うとエラーとなります。そこで、事前に文書が Nothing であるかを判定しています。

なお、この関数の戻り値は、出力した行数としています。


明細データの出力

先ほどのリストでコールしている xPrintUsage が明細データを1行分出力する関数です。その関数のコードは次の通りとなります。

Function xPrintUsage(voSheet As Variant, _
                                ByVal viDoc As Integer, vnd As NotesDocument)
   Dim iRow As Integer
   iRow = viDoc + xciHeaderRows 'ヘッダエリア行数を加算

   '使用量出力
   voSheet.Cells(iRow, 2).Value = vnd.Device(0)    'デバイス名
   voSheet.Cells(iRow, 3).Value = vnd.BnW_Count(0)  '白黒
   voSheet.Cells(iRow, 4).Value = vnd.BnW_Unit(0)
   voSheet.Cells(iRow, 6).Value = vnd.Col_Count(0)    'カラー
   voSheet.Cells(iRow, 7).Value = vnd.Col_Unit(0)
End Function

引数の viDoc は、何行目の明細データかを表す数値です。これにヘッダの行数(後述)を加算して、Excel シート内の行番号を決定しています。


メインプログラム

作成した明細データを出力する関数をメインプロブラムからコールします。出力した明細の行数は後続の処理で使用しますので、変数 iDoc で受けて保持しています。

また、ヘッダエリアの行数を定数として登録しています。

Option Declare
Private Const xciHeaderRows = 5 'ヘッダエリア行数

Sub Initialize
   Dim oXls As Variant
   Dim oSheet As Variant
   Dim iDoc As Integer

   Set oXls = CreateObject("Excel.Application")
   Call oXls.Workbooks.Add
   Set oSheet = oXls.Workbooks(1).WorkSheets(1)

   '帳票の初期化
   Call xInit(oSheet)

   '使用量出力(年月度指定)
    iDoc = xPrintUsages(oSheet, 2023, 10)


   'Excel を UI に表示
   oXls.Visible = True
End Sub

ここまでのプログラムを実行すると、次のようになります。少しだけ帳票ぽくなってきましたね。

次回は、合計を Excel で計算させるため、セルに計算式をセットする方法について紹介します。


前回 Notes - Excel 連携 次回

0 件のコメント:

コメントを投稿