Microsoft Access 掲示板

目次(索引)作成

39 コメント
views
5 フォロー

VBA全くの素人で、医薬品集の索引作成に悪戦苦闘中です。見様見真似で『目次(索引)ページを自動作成』を参考に、レポートフッターにテキストボックス「txt目次」を作成し、レポート詳細の薬品名とページをはきだしていますが、薬品名を五十音順に並び替えるにはどのようにしたらよいでしょうか? 宜しくお願い致します。

Option Compare Database
Option Explicit
Const RowCount = 30
Dim Cnt As Integer

Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    If Me.Pages = 0 Then
        If Cnt \ RowCount <= 3 Then
            Me("txt目次" & Cnt \ RowCount) = Me("txt目次" & Cnt \ RowCount) & Left(Me.薬品名 & String(12, "・"), 12) & Format(Me.Page, "@@@") & vbCrLf
        End If
        Cnt = Cnt + 1
    End If
End Sub

Private Sub レポートヘッダー_Format(Cancel As Integer, FormatCount As Integer)
    Me.Page = 0
    Cnt = 0

End Sub

名前なし
作成: 2021/05/05 (水) 16:15:54
通報 ...
1
hiroton 2021/05/06 (木) 12:26:17 9f9a7@f966d

レポートフッターにテキストボックス「txt目次」を作成

Me.Page = 0関係はヘッダーに出力したいとき用のテクニックなので消してしまいましょう

薬品名を五十音順に並び替える

フッターに出力するタイミングで並び替えの処理が必要ですね。また、段組みにするのは並び替えの後の必要があるので、詳細_Formatのタイミングではデータを拾うだけでよさそうです

Option Compare Database
Option Explicit
Dim data As String

Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    data = data & Left(Me!薬品名 & String(12, "・"), 12) & Format(Me.Page, "@@@") & vbCrLf
End Sub

Private Sub ページフッターセクション_Format(Cancel As Integer, FormatCount As Integer)
    Dim arr
    Dim s
    Const RowCount = 30
    Dim CNT As Long

    '並び替えのために配列にする
    arr = Split(data, vbCrLf)
    '配列を並び替え
    Call ArrayListSort(arr)

    '段組みに振り分ける
    CNT = 0
    For Each s In arr
        Me("txt目次" & CNT \ RowCount) = Me("txt目次" & CNT \ RowCount) & s & vbCrLf
        CNT = CNT + 1
        If CNT >= 120 Then Exit For 'RowCount * 4
    Next
End Sub

Sub ArrayListSort(ary() As Variant)
    Dim aryList As Object
    Dim s
    
    '// .NET FrameworkのArrayListクラスを利用する
    Set aryList = CreateObject("System.Collections.ArrayList")

    For Each s In ary
        Call aryList.Add(s)
    Next
    Call aryList.Sort
    ary = aryList.ToArray
End Sub

並び替えの方法はいろいろあります。楽そうな方法を公開しているサイトがあったのでそちらから借りてきました。VBAの配列を.NETのArrayListのSortで並べ替え(Excel作業をVBAで効率化さん)

動作確認していないので問題があったら教えてください。
それと、「薬品名」はすべて五十音ですか?「葛根湯」とかあると、漢字はすべてカナの後とかなったりします

2
norinori 2021/05/06 (木) 15:25:22

hiroton さん、有難うございます。感激です! レポートフッターにテキストボックスを作成し、このままコードをコピペしたところコンパイルエラー(型が一致しません)と出た為、Private Sub ページフッターセクション → Private Sub レポートヘッダーセクション とし、プレビューしたところエラーは出ませんが、何もはきだしていない状態です。どこをどうすれば良いのか分からず、とりあえずご報告いたしました。

3
hiroton 2021/05/06 (木) 16:14:23 9f9a7@f966d

コンパイルくらい試すべきでした。すみません

まずは並び替え用の関数の修正

Sub ArrayListSort(ary() As Variant)
↓
Sub ArrayListSort(ary As Variant)

それと、「レポートフッター」でしたね

Private Sub ページフッターセクション_Format(Cancel As Integer, FormatCount As Integer)
↓
Private Sub レポートフッター_Format(Cancel As Integer, FormatCount As Integer)

Private Sub ページフッターセクション → Private Sub レポートヘッダーセクション とし

レポートフッターですよね?
レポート フッターのフォーマット時に[イベント プロシージャ]を設定してください

4
norinori 2021/05/06 (木) 21:25:40

hiroton さん、有難うございます。
感激です!! 以下のように修正しました。
薬品名が並び変わっています!!
ただ、ある範囲までの薬剤が繰り返しはきだされていて、300ページ程になっています。
自分で何とかしようと思ったのですが、どこに問題があるのかもわかりません。
レポートフッターにテキストをtxt目次0~3まで作成しています。他に必要な情報はありますでしょうか? 
宜しくお願い致します。

Option Compare Database
Option Explicit
Dim data As String

Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    data = data & Left(Me!薬品名 & String(12, "・"), 12) & Format(Me.Page, "@@@") & vbCrLf
End Sub

Private Sub レポートフッター_Format(Cancel As Integer, FormatCount As Integer)
    Dim arr
    Dim s
    Const RowCount = 30
    Dim CNT As Long

    '並び替えのために配列にする
    arr = Split(data, vbCrLf)
    '配列を並び替え
    Call ArrayListSort(arr)

    '段組みに振り分ける
    CNT = 0
    For Each s In arr
        Me("txt目次" & CNT \ RowCount) = Me("txt目次" & CNT \ RowCount) & s & vbCrLf
        CNT = CNT + 1
        If CNT >= 120 Then Exit For 'RowCount * 4
    Next
End Sub

Sub ArrayListSort(ary As Variant)
    Dim aryList As Object
    Dim s

    '// .NET FrameworkのArrayListクラスを利用する
    Set aryList = CreateObject("System.Collections.ArrayList")

    For Each s In ary
        Call aryList.Add(s)
    Next
    Call aryList.Sort
    ary = aryList.ToArray
End Sub

5
hiroton 2021/05/07 (金) 09:42:32 eb8fa@f966d

ページフッターやtxt目次など、配置した後デフォルトから変更しているプロパティがありますよね?それを提示してください


ある範囲までの薬剤が繰り返しはきだされていて

提示したコードは複数ページにまたがることを想定していないので次のページが出力されるとするとレポートフッター_Formatが全く同じように動いて全く同じ内容が出力されます

300ページ程になっています。

コード自体にページを増やす処理はないのでレポート上の設定に問題があると思われます。txt目次印刷時拡張「はい」とか設定されていませんか?
上記のとおり、レポートフッターが出力されるたび全く同じページが出力されるので、そのページが次のページを出力するような内容の場合無限ループしてしまいます

6
norinori 2021/05/07 (金) 16:59:21

hiroton さん、何度も有難うございます。

ページフッターやtxt目次など、配置した後デフォルトから変更しているプロパティがありますよね?
 → フォント、行間を変更したくらいです。
xt目次に印刷時拡張「はい」とか設定されていませんか?
 → はい。ご指摘通り印刷時拡張になっていましたので、「いいえ」にしました。索引ページとしては1ページになり限られた薬剤数のみ印字されました。

また、複数ページにまたがる事をお伝えしていませんでした。
薬剤数450-500、3段組みの設定を考えており数ページに及びます。
変更点をご指導頂けますでしょうか?

7
hiroton 2021/05/10 (月) 08:54:05 修正 245f0@f966d

「txt目次0~3」なら「0,1,2,3」の4段じゃないですか?

印刷時拡張を使って複数ページになるなら目次データの生成処理を初回の1回だけ処理するようにすればいいですね

それと、印刷時拡張かつ段組みとすると、30行ずつ3段目まで振り分けたらまた1段目に戻す必要がありますね

レポートフッター_Formatを次のように変更します

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
        '並び替えのために配列にする
        arr = Split(Data, 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
8
hiroton 2021/05/10 (月) 09:22:10 245f0@f966d >> 7

それと、詳細セクションも複数ページにまたがることがあったりしますか?
ページ跨ぎが発生すると詳細_Formatもその都度発生するので、dataに薬品名が重複して登録されます。こちらもページ跨ぎの場合はdataにデータを追加しない様、制御処理を追加しておいたほうがいいかもしれません

Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    If FormatCount = 1 Then
        data = data & Left(Me!薬品名 & String(12, "・"), 12) & Format(Me.Page, "@@@") & vbCrLf
    End If
End Sub
9
norinori 2021/05/11 (火) 18:16:39

hirotonさん、感動です! やりたかったことが出来てます!! 改めて、いくら自分で本を読んだりネットで調べてもダメだったと痛感しました。教えて頂いたコードを読み解いて勉強してみます。解決できない時はまたご指導ください。取り急ぎご報告まで。

10
norinori 2021/05/13 (木) 08:20:33

hirotonさん、早くも質問です。小出し小出しで申し訳ない内容です。
索引を印刷したところ、本文の薬品ページと索引で示すページが異なっている一部薬品があります。ページが変わるタイミングの薬品で、レポートで薬品を剤型→薬効分類とグループ化しているのですが、薬効分類がページが切り替わる時、例えば、1ページ目に薬効分類が入っていると薬品が2ページ目なのに索引には1ページと表記される といった状態です。2点目は、以前
ご指摘の通り、薬品にはカタカナ、漢字、数字が混在しています。印刷をしてみると、やはり五十音順にならんでいた方が見やすいかなと思い、ご指導を頂けないでしょうか?
今更ですが、レポートと薬品集テーブルのスクリーンショットを添付しました。宜しくお願い致します。画像1
画像2

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関数は省略
12
hiroton 2021/05/13 (木) 14:04:00 d3c7a@f966d

五十音での並び替えについて

とりあえず無理やり的な方法で(修正箇所だけ)

'詳細_Format内
    keepIndexString = Me!薬品名のフリガナ & "<split>" & Left(Me!薬品名 & String(12, "・"), 12) & Format(Me.Page, "@@@") & vbCrLf

'レポートフッター_Format内
            Me(colName) = Me(colName) & Mid(s, InStr(s, "<split>") + 7) & vbCrLf

例えば

名称かな
茨城県いばらき
栃木県とちぎ
群馬県ぐんま
埼玉県さいたま
千葉県ちば
東京都とうきょう
神奈川県かながわ

のようなデータがあった場合、

出力データ
いばらき<split>茨城県
とちぎ<split>栃木県
ぐんま<split>群馬県
さいたま<split>埼玉県
ちば<split>千葉県
とうきょう<split>東京都
かながわ<split>神奈川県

のようにひとかたまりの文字列のデータにして並び替えた後、分割用の文字から後ろを抜き出せば「かな順」で並び替えができるというものです
「<split>」は誤動作しないよう「かな」に含まれない文字列なら何でも構いません


内容が複雑化してきて、簡素化した記述が足かせになって余計な苦労をしてるような気がしてきました。データのボリュームが増えてきているのでコード内でもしっかりデータを管理できるような仕組みを導入したほうがよさそうです

13
hiroton 2021/05/13 (木) 14:46:46 修正 d3c7a@f966d

というわけで、ちゃんと使いやすいデータにして対応する例
Dictionary オブジェクトを使って目次データを整理するようにします

Option Compare Database
Option Explicit

Dim dicIndex As Object

Private Sub Report_Open(Cancel As Integer)
    Set dicIndex = CreateObject("Scripting.Dictionary")
End Sub

Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    Dim indexString As String
    indexString = Left(Me!薬品名 & String(12, "・"), 12) & Format(Me.Page, "@@@")

    With dicIndex
        If .Exists(Me!薬品名のフリガナ.Value) Then
            .Item(Me!薬品名のフリガナ.Value) = indexString
        Else
            .Add Me!薬品名のフリガナ.Value, indexString
        End If
    End With
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
    
        '並び替え用配列の準備
        arr = dicIndex.Keys
        '並び替え用配列を出力順に並び替え
        Call ArrayListSort(arr)
    
        '出力順にデータを取り出して段組みに振り分ける
        CNT = 0
        For Each s In arr
            colName = "txt目次" & CNT \ rowCount Mod colCount
            Me(colName) = Me(colName) & dicIndex.Item(s) & vbCrLf
            CNT = CNT + 1
        Next

        isExecuted = True
    End If
End Sub

Dictionary オブジェクトを使うには事前準備が必要なのでレポートの開く時イベントに処理を追加しています。

Dictionary オブジェクトの仕様上「薬品名のフリガナ」に重複データがあると最後の「薬品名」のみ目次に反映されます

14
norinori 2021/05/14 (金) 08:27:55

hirotonさん、本当に有難うござます。自分がやろうとしていたことが、素人には絶対無理だったと痛感しました。ご指導頂いた資料で今後じっくり勉強することにして・・・ とりあえず、このままコピペしてみました。添付しましたファイルの様なコメントが出ました。完全なコピペはダメだったでしょうか?画像1

17

エラーメッセージの通りだと思います
画像1

新しく追加したプロシージャはReport_Openなので開く時プロパティに[イベント プロシージャ]を設定してください
ArrayListSort関数も省略しているので適当な場所に入れておいてください(汎用的に使える関数なので標準モジュールに入れてしまってもいいと思います)


[イベント プロシージャ]は各イベントのプロパティのプルダウンから常に選べるようになっているプロパティですが、これを指定すると、それぞれで専用のプロシージャを呼び出しなさいという指定になります(レポートの開く時ならReport_Openとか)

[イベント プロシージャ]を選んで[...]をクリックすると、対応するプロシージャが自動で生成されますが、コードをコピペしても[イベント プロシージャ]は自動で設定はされないので、この部分は自分でやる必要があります。

18

適当にエラーが出るプロパティを設定してみたら同じエラーメッセージ出ませんでした。多分原因は

ArrayListSort関数も省略しているので適当な場所に入れておいてください

こっちのほうですね。

完全なコピペ

で必要な関数を消してしまったんでしょう。開く時(Report_Open)ではArrayListSort()使ってないのでエラーメッセージが残念な感じですがよくあることなので・・・

19

先週金曜日から何とかご指摘を克服しようと努力はしましたが、今の知識では難しくお知恵を頂こうと思っていました。
13の完コピに、1のSub ArrayListSort以下を合体させたところ”薬品名のフリガナフィールドが見つかりません”とのメッセージに変わりました(前進ですか?)。レポートに「薬品名のフリガナ」がないのは気になっていたのですが、この点は如何でしょうか? 

画像1
Sub ArrayListSort(ary As Variant)
    Dim aryList As Object
    Dim s

    '// .NET FrameworkのArrayListクラスを利用する
    Set aryList = CreateObject("System.Collections.ArrayList")

    For Each s In ary
        Call aryList.Add(s)
    Next
    Call aryList.Sort
    ary = aryList.ToArray
End Sub

20

レポート上にテキストボックスを配置し、名前を「薬品名のフリガナ」、コントロールソースも「薬品名のフリガナ」とします。

印刷するデータではないので可視プロパティは「いいえ」にします。


五十音で並び替えたいということなので五十音のデータが必要です。薬品名から自動で五十音を作るのは現実的ではないので並び替え用に五十音のデータを用意します。>> 10の画像から使えそうなフィールド「薬品名のフリガナ」を用いていますが、見る限り五十音だけでないようなので必要であれば専用のフィールドを追加で用意してください

印刷しないデータなのでレコードセットから直接取れればいいんですが、レポートだとレコードセットを直接参照することができないのでレポート上にデータを読み込んであげる必要があります。そのため、テキストボックスを配置しコントロールを参照します

コントロールの名前プロパティとコントロールソースプロパティ(フィールド名)が同じ場合は意識する必要はないですが、別々にしている場合は注意してください

21

hirotonさん、有難うございます。上記の様に設定したところ、漢字、カナ、数字の区別なく五十音順に並び替えることが出来ました。ただ、ページ跨ぎになっている薬剤のページはやはりずれていますが、私としては大満足です。大変な知識不足でお手数をお掛けして申し訳ありませんでした。こういったコードを沢山見ることが向上に繋がるでしょうか?

22

実践あるのみですね。目的を立てて「できた!」までこぎつけてほんのちょっとレベルアップしたかもって思う感じです。
読み物としていろいろ見ておくと「自分のやろうとしてることくらいすでに誰かやっているんじゃないか?」とか「これめんどくさいな。もっと簡単な方法があるんじゃないか?」とかそういう考え方はできるようになるかもしれませんが、これが実力が付いたと言えるかというと微妙なところです。現にhirotonの回答は次々と問題が出てきて穴だらけですし


ページ跨ぎになっている薬剤のページはやはりずれています

限定条件はあるもののその条件下なら今の回答でうまくいくと思っているんですが、うまくいかない部分があるということですか?それともこの条件だと目的のレポートにならないということですか?

24

今後継続して使用していく目的としてはとても便利で、思っていた以上のレポートです。
現にhirotonの回答は次々と問題が出てきて穴だらけですし
→ 私が条件を全て表示していなかったからです。感謝しかないです。

15

このスレッドの流れを細かく読んではいませんので、外しているかも知れませんが、
ちょっと思ったことを書いてみます。

レポートの最後に索引を追加したいということですよね。

  • 一つのレポートで出力する。
  • 索引は複数ページにわたる可能性がある。
  • 索引は段組みレイアウトにしたい。

ということだと、かなり難易度が高いと思います。

一つのレポートで索引も出力するというのはあきらめて、
まずは、索引なしの医薬品集レポートを出力する。
その後、索引を出力する。
というようにレポートを2つに分けたらどうでしょう。

索引用のテーブルを作成しておいて、それから索引レポートを作成しておきます。

医薬品集レポートを出力するときに、フォーマット時イベントで索引用テーブルに索引用データを出力していく。

こうすれば、並べ替えも、段組みもレポートの機能で簡単にできます。

処理の流れは下記のようなイメージです。

フォームにコマンドボタンを2つ配置。
「医薬品集レポート印刷」
「医薬品集索引印刷」

「医薬品集レポート印刷」ボタンのクリック
索引テーブル の全データを削除 → 医薬品集レポートの印刷

医薬品集レポートの詳細(またはグループヘッダー)のフォーマット時イベントで索引データを索引テーブルに追加。

上記印刷後、「医薬品集索引印刷」をクリックで索引レポートを印刷。

16

今の問題点は「詳細_Formatで正確なページ数が取得できない」なので「取得後の目次データの取り扱いをどうするか」は問題の解決にならないです

一応いろいろ眺めていたら解決案は出てきました(公開する段階にないですが)


レポートの最後に索引を追加したいということですよね。

一つのレポートで出力する。
索引は複数ページにわたる可能性がある。
索引は段組みレイアウトにしたい。
ということだと、かなり難易度が高いと思います。

これ自体は>> 7で出来てます。いろいろ議論の余地もあるかと思いますが、現時点で索引表示のためにワークテーブルを使う必要性は感じないです

23
hiroton 2021/05/18 (火) 14:32:23 f7e14@f966d

エラーが出なくなったようなので続きですが、

  • 詳細セクションの同一ページ印刷プロパティは「はい/いいえ」どちらですか?
  • 詳細セクションに印刷時拡張の設定はありますか?

今後の方針について

単独で1ページを超えるような出力に対応する

データに依存する仕組みじゃ使いにくいですね。対策します

同一ページ印刷プロパティ「いいえ」に対応する

一応、対策案はあります。今の想定ではそれなりにコードが複雑になるので同一ページ印刷が「はい」なら対策コードは入れなくていいかなと思っています

詳細セクションの印刷時拡張の設定

今回の手法(『目次(索引)ページを自動作成』)では詳細_formatからページ数を取得するのことがかなり難しいことがわかりました。で、本当に今更な確認ですが、詳細セクションで印刷時拡張の設定が無ければ出力ページ数自体が元データから作れるのでは?と、ふと思ってしまいました。(謎の先入観で印刷時拡張「はい」があるものと思っていたようです)
今の手法も形になりそうなのでhirotonが別手法を挙げることはないですが、一応ここで確認事項としてあげておきます

25

•詳細セクションの同一ページ印刷プロパティは「はい/いいえ」どちらですか?→ はい
•詳細セクションに印刷時拡張の設定はありますか? → はい
       となっています。

26
norinori 2021/05/19 (水) 08:22:04

hiroton さん、索引に印字されているページが本文のページと一致しているかもです。ページに跨ぎになっている薬剤を全て確認し、また報告をさせて頂きます。

27

条件を付けている通りで特別なデータ(用法・容量がすごく長くてその薬品一つだけで1ページを超えるようなデータ)があるとうまくページを取得できません

そんなデータあるわけない!なら多分うまくページが取れてると思います。適当に用法・容量が1ページを超えるようなデータを作って試してみてください。ダメな例がわかると思います

「データ」は今は良くても、今後、誰がどのように登録するかわからないなので

データに依存する仕組みじゃ使いにくいですね。対策します

という方針を示しています。今後についても「そんなデータあるわけない!」なら今のコードで完成でもいいかなぁとは思います


追加の対策を考える場合、ちょっとテストしていたらグループヘッダーのセクション繰り返しの設定で動作を変えないといけないようでした。このプロパティの設定も教えてください。

28
norinori 2021/05/19 (水) 10:24:52

hiroton さん、確認しましたが、やはり索引に印字されているページが本文のページと一致していました。完璧です。
『用法・容量がすごく長くてその薬品一つだけで1ページを超えるようなデータ』はない為、ダメな例を勉強してみます。
グループヘッダーのセクション繰り返しの設定 → 画像を添付しました。画像1

索引の印刷プレビュー画面も添付しました。3段組、30行、文字数も制限しいている為、見栄えがよくありません。現在の薬品集が薬品名(文字数は制限なし)・・・ページ数となっている為、そのようにしてみようと思っています。自分で変えてみようと思いますが、無理だったらまた質問をさせて頂きます。
索引にページ数が入るのは仕方がないことですか?
画像2

29
hiroton 2021/05/19 (水) 11:20:16 db65e@f966d

『用法・容量がすごく長くてその薬品一つだけで1ページを超えるようなデータ』はない為、ダメな例を勉強してみます。

今のコードも突っ込みどころはいろいろあるんですが、いったん完成ということにしてしまいますか。ダメな場合があるということだけは覚えておいてください。

見栄えがよくありません。

元々見栄え自体はあまり気にしなくてもいい方法のようですから。見栄えを気にするならhatenaさん指摘のように、索引専用のレポートを作ることも検討してみましょう
ちなみに「薬品名(文字数は制限なし)」とすると発生する問題があります。どんな問題が出るのか確かめて、どうしたいか考えてみてください


索引にページ数が入るのは仕方がないことですか?

ページフッターのページ数表示ですよね?索引のページ(レポートフッター)だったら非表示にすればいいと思ったんですが意外とめんどうでした

Private Sub レポートヘッダー_Format(Cancel As Integer, FormatCount As Integer)
    Me!ページ数表示.Visible = True
End Sub

Private Sub レポートフッター_Format(Cancel As Integer, FormatCount As Integer)
    If FormatCount = 1 Then Me!ページ数表示.Visible = False

(後略)

※ページ数表示は実際のコントロール名に合わせてください

30
norinori 2021/05/20 (木) 08:28:37

hiroton さん、↑の通りやってみたところ、索引にページがのらなくなりましたが、本文のページ数に索引ページ分をカウントしているようです。画像1
全体のページは必要ないので、 =[Page] & " ページ" としてみました。
ちなみに本文最後のページだけページ数が入らないのは何故でしょうか?

31
hiroton 2021/05/20 (木) 09:49:00 3cacd@f966d

レポートフッターの改ページプロパティを「カレント セクションの前」にしてください

今の表示は同一ページ印刷「はい」の設定で、「本文の最後のページに収まらないから次のページから開始」という処理になってると思います。この場合だと本文最後のページでレポートフッター_Formatが呼び出されます

同一ページ印刷プロパティで制御

表示内容がないだけで、本文最後のページと索引最初のページ(レポートフッター)が同じページになっている
→本文の最後のページからページ数表示が非表示

改ページプロパティで制御

本文のページと索引のページは明確に分かれる
→索引だけページ数表示が非表示

32

もしくは改ページプロパティは弄らずに

    If FormatCount = 1 Then Me!ページ数表示.Visible = False
↓
    If FormatCount = 2 Then Me!ページ数表示.Visible = False

    If FormatCount = 2 Then Me!ページ数表示.Visible = False

にするとか

33

hirotonさん、どちらの方法も本文最後にページが入りました。
完璧です!! 

34
norinori 2023/05/06 (土) 13:17:37

2年程前、医薬品集の索引作成で大変お世話になりました。今回、この医薬品集に大分類(薬効87分類)、中分類(拡張薬効分類)を設けてレポートも作成し直した為、分類ごと(薬効87分類)の索引も欲しいと思い、hateneさんが提示されていた『目次(索引)ページを自動作成』を元にコピペしてみたのですが、テキストボックスに何もはきださない現象となっています。分からないなりに試行錯誤しましたが、どこが間違っているのかさっぱり分かりません。ご教示お願い致します。
Option Compare Database
Option Explicit
Private Sub グループヘッダー1_Format(Cancel As Integer, FormatCount As Integer)
    If Me.Pages = 0 Then
        Me.txt索引 = Me.txt索引 & Left(薬効87分類 & String(12, "・"), 12) & Format(Me.Page, "@@@") & vbCrLf
    End If画像1
画像2

End Sub

Private Sub レポートヘッダー_Format(Cancel As Integer, FormatCount As Integer)
    Me.Page = 0
End Sub

35
norinori 2023/05/06 (土) 13:19:32

↑すみません投稿し直します。

36
norinori 2023/05/06 (土) 13:21:38

2年程前、医薬品集の索引作成で大変お世話になりました。今回、この医薬品集に大分類(薬効87分類)、中分類(拡張薬効分類)を設けてレポートも作成し直した為、分類ごと(薬効87分類)の索引も欲しいと思い、hateneさんが提示されていた『目次(索引)ページを自動作成』を元にコピペしてみたのですが、テキストボックスに何もはきださない現象となっています。分からないなりに試行錯誤しましたが、どこが間違っているのかさっぱり分かりません。ご教示お願い致します。
Option Compare Database
Option Explicit

Private Sub グループヘッダー1_Format(Cancel As Integer, FormatCount As Integer)
    If Me.Pages = 0 Then
        Me.txt索引 = Me.txt索引 & Left(薬効87分類 & String(12, "・"), 12) & Format(Me.Page, "@@@") & vbCrLf
    End If
End Sub
Private Sub レポートヘッダー_Format(Cancel As Integer, FormatCount As Integer)
    Me.Page = 0
End Sub
画像1
画像2

37
hiroton 2023/05/08 (月) 10:43:42 8b032@f966d

なにやら見覚えのあるタイトルが、と覗いてみたら懐かしい記憶が少しだけよみがえりました(ほとんど忘れてます)


今までの(薬品名を五十音ソートした)索引とはどういう関係ですか?
・削除して新たに分類ごとの索引を配置
・残したまま新たに分類ごとの索引を配置(→配置位置は?既存の索引の前? or 後 or その他)
・複合した索引を設置、薬品名は分類のグループごとに分割
・その他

38
norinori 2023/05/08 (月) 16:10:57

hirotonさんの目にとまり良かったです。薬品名を五十音順とした索引はそのままで、分類とその
ページの索引を新たに追加したいです。五十音順の索引コードに何かあっては困るので、分類索引のコードは別で作成していました。配置は五十音順索引の前にしたいです。宜しくお願い致します。

39

独立した内容で新たに追加したいということであれば、改めて質問を立てたほうがいいかもしれません。既存環境に追加したいということでこの質問のURL(https://zawazawa.jp/ms-access/topic/564
を記載するといいと思います


今ちょっと腰を据えて手を付けられそうにないので確認と方針を挙げておきます

ひとまず分類のみの索引が出力されるか試してみる
→レポートを複製して、コードをいったん全て削除して、分類用索引のコードのみでテストする

分類の索引は出力順でいいですか?
→出力順を弄らないならコードを弄るところもほぼないと思います。(コントロール名くらい)
レポートの最初(レポートヘッダー)に出力するか最後(レポートフッター)に出力するかでコードが変わってくるので使うコードをよく見てください。また、これに合わせてコントロール(テキストボックス)の配置場所も重要かもしれません

コントロール名が正しく指定できているか?
→コントロール名
×:コントロールソースプロパティ
〇:名前プロパティ
です。
また、掲示板上のやり取りがやりやすいように具体的な名前を付けておくといいと思います
既存のコードがこの質問のコピペなら「txt目次N(N=0,1,2)」となっていると思います。(改めて見直したらソートしてるので「目次」じゃないですね)
分かりやすいように既存のテキストボックスはtxt目次Ntxt薬品名索引Nとして、今回追加する様のはtxt分類索引とするなど
分類索引も段組みにしたいのなら、その情報も必要ですね

分類だけで索引がうまく作成出来たら元のレポートと組み合わせます
既存の索引の前にということなので、レポートフッターの先頭に「txt分類索引テキストボックス」と「改ページコントロール」を挿入すればいいのでは?と思っていますがテストできていません