Microsoft Access 掲示板

目次(索引)作成 / 11

39 コメント
views
5 フォロー
11
hiroton 2021/05/13 (木) 11:48:32 d3c7a@f966d

適当なデータを作って試してみたら確かにうまくいかないですね
レポートのイベントの発生メカニズムの研究(hatena chipsさん)

画像1

ページ跨ぎが発生した場合に目次データが重複しないよう

    If FormatCount = 1 Then

と制御を入れたんですが、FormatCount = 1だけだとうまく目的のデータにならないようです。画像を見てわかる通り、目次データの取得は「実際の描画があったら目次データを作成する(ページ番号を取得する)」とする必要がありそうです。hirotonはうまい方法を知りません

目次データを取得している詳細_Formatイベントは描画前の処理なので、このタイミングで「描画があったかどうか?」は知りようがありません。やるとすれば、印刷しようとしている余白に印刷できる高さがあるかどうかを計算するという方法になると思います。現在の印刷位置情報や、印刷領域の残り高さが必要になるのでかなり大変です


条件を限定すれば、いくらか簡単な方法でチェックすることもできそうです

同一ページ印刷プロパティ「はい」
単独で1ページを超えるような出力がない(上図の例なら詳細は最大でも9行(1ページで収まる)場合)

であれば、「FormatCount = 2があれば、それが描画ページ」とすることができます。ただ、FormatCount = 1のときはFormatCount = 2があるかどうかわからないので、「仮データを置いて、次の明細に移動したら仮データの確定処理をする」様にします

Option Compare Database
Option Explicit

Dim indexText As String
Dim keepIndexString As String

Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    Static preItemName As String
    
    '仮データの確定処理
    If preItemName <> Me!薬品名 Then
        indexText = indexText & keepIndexString
        preItemName = Me!薬品名
    End If
    
    '仮データを作成
    keepIndexString = Left(Me!薬品名 & String(12, "・"), 12) & Format(Me.Page, "@@@") & vbCrLf

End Sub

Private Sub レポートフッター_Format(Cancel As Integer, FormatCount As Integer)
    Static isExecuted As Boolean
    Dim arr
    Dim s
    Const colCount = 3  '1ページの段数
    Const rowCount = 30 '1ページの行数
    Dim CNT As Long
    Dim colName As String

    If Not isExecuted Then
        '最後の明細の仮データの確定処理
        indexText = indexText & keepIndexString
    
        '並び替えのために配列にする
        arr = Split(indexText, vbCrLf)
        '配列を並び替え
        Call ArrayListSort(arr)
    
        '段組みに振り分ける
        CNT = 0
        For Each s In arr
            colName = "txt目次" & CNT \ rowCount Mod colCount
            Me(colName) = Me(colName) & s & vbCrLf
            CNT = CNT + 1
        Next

        isExecuted = True
    End If
End Sub

'ArrayListSort関数は省略
通報 ...