Private Sub Form_Open(Cancel As Integer)
Dim dbs As DAO.Database
Dim tdf As DAO.TableDef
Set dbs = CurrentDb
For Each tdf In dbs.TableDefs
If tdf.Connect Like "*データーベース1.accdb*" Then
If tdf.Connect Like "*PWD=1234*" Then
Exit For
Else
tdf.Connect = _
"MS Access;PWD=1234;DATABASE=C:\test\データベース1.accdb"
tdf.RefreshLink
End If
End If
Next tdf
dbs.Close: Set dbs = Nothing
End Sub
'請求月数の分だけ、サブフォームにレコードを追加する
Dim i As Long, s As Long
With Me.T_月額マスタのサブフォーム1.Form.Recordset
'「ごとに請求」のコンボボックスで、以下の値が選択されている場合
If Me.入金月頻度 = "2ヶ月" Then
s = 2
ElseIf Me.入金月頻度 = "半年" Then
s = 6
ElseIf Me.入金月頻度 = "1年" Then
s = 12
End If
For i = 0 To 月数 Step s
.AddNew
![契約番号] = Me.txt契約番号
![月額] = Me.月額
![入金月] = DateAdd("m", i, 開始年月)
![税率] = Me.税率
![税の処理] = Me.税の処理
.Update
Next
End With
'請求月数の分だけ、サブフォームにレコードを追加する
Dim i As Long
With Me.T_月額マスタのサブフォーム1.Form.Recordset
For i = 0 To 月数
.AddNew
Me.T_月額マスタのサブフォーム1.Form![契約番号サブ] = Me.txt契約番号
Me.T_月額マスタのサブフォーム1.Form![月額サブ] = Me.月額
Me.T_月額マスタのサブフォーム1.Form![入金月サブ] = DateAdd("m", i, 開始年月)
Me.T_月額マスタのサブフォーム1.Form![税率サブ] = Me.税率
Me.T_月額マスタのサブフォーム1.Form![税の処理サブ] = Me.税の処理
'「ごとに請求」のコンボボックスで、以下の値が選択されている場合
If Me.入金月頻度 = "2ヶ月" Then
i = i + 1
ElseIf Me.入金月頻度 = "半年" Then
i = i + 5
ElseIf Me.入金月頻度 = "1年" Then
i = i + 11
End If
Next
End With
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
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関数は省略
ご回答ありがとうございます。基本的なやり方は間違えていないようです。
差し支えなければ、Hatena様の最後のコードについて説明いただけないでしょうか。
複数のテーブルをこのif~nextでリンクできるのでしょうか
下記サイトの回答コメントにあるのが、一般的な方法ではないでしょうか。
さらに、もっとも一般的な方法があれば、誰か補足をお願いします。
回答ありがとうございます。
実は事業所が離れており、私がネットワークはいることができていない中でエラーが出てしまったのです。
現地はランタイムで動いていて、前述のプログラムでリンクをくっつけなおしていたのですが、うまくいかないようで。
私がいなくても、永続的に事業所内のデータとリンクできるようにしなくてはならないのですが。
この質問は立て直します。ありがとうございました。
追記です。
メインフォームを新しく作り直したところ、消える現象はなくなりました!
プロパティの設定を新旧フォームで見比べてみたのですが、特に差異もなく…
原因を突き止めることができましたら、またご報告させていただきたいと思います。
>hatena様
ご回答とご指摘いただきありがとうございます!とても参考になりました!
Forループ内でカウンター変数を使用しない方が良いというのは知りませんでした…
例文をいくつか調べてみましたが、確かにカウンター変数を途中で変更されている方はおりませんでした。
ご法度というのは、For文にカウンター変数を変更する分岐を入れてしまうと、
煩雑になり可読性が落ちるからでしょうか?
また、コントロール名ではなく、フィールド名を指定するということですが、
こちらの理由をお伺いしてもよろしいでしょうか…?
個人的には、コードを見返した際に分かりやすく管理しやすいかな…
と思ってコントロール名を分かりやすい名前に変更し、指定していたのですが、
テーブルにデータを追加する場合などは、テーブルのフィールド名を指定しておかないと
後で問題になったりするのでしょうか?(見かける例文はコントロール名での指定が多い気がしたので…)
教えていただいたコードに変更しましたが、同じ症状が出てしまいます…
サブフォームをもう一度作り直してみましたが、結果は同じでした。
同じような症例がないか、もっと調べてみたいと思います。
(せっかくたくさんアドバイスいただいたのに解決できず申し訳ありません…)
適当にエラーが出るプロパティを設定してみたら同じエラーメッセージ出ませんでした。多分原因は
こっちのほうですね。
で必要な関数を消してしまったんでしょう。開く時(Report_Open)では
ArrayListSort()
使ってないのでエラーメッセージが残念な感じですがよくあることなので・・・フロントエンドを開いて、リンク情報がどうおかしくなっているかを確認するのは?
ありがとうございました!
>確認メッセージが出る出ないは、DoCmd.SetWarningsのコードがどこかにありませんか?
こちらを参考に、改めて確認したところ
自分の環境では確認メッセージを出さないように設定しており、
他の環境では設定してもらうか、マクロ、VBAでの制御が必要と知りました。
VBAで制御したところ、メッセージが出なくなりました。
大変助かりました。ありがとうございました。
同じ悩みの方のため、参考サイトのリンクを貼っておきます。
AccessVBAでクエリ実行時の確認メッセージを完全に非表示にする方法
ごめんなさい、Dsum動作比較のサイトを紹介しましたが、中身をよくわかっていませんでした。ちょうど使ってみて、使い勝手がいいじゃんと思ったんですけど、重くなりそうになったら要変更ですね。
下記、Hatenaさんの解説を読んで下さい、納得です。
りんごさんも回答されているようにテーブル→クエリ→フォーム→レポートがベストだと思います。
DSumは重くなります。
りんごさんが提示したリンク先
■T'sWare Access Labo #28 ~明細データテーブルの集計を考える~
には、
というような解説がありますが、これはテスト方法が間違っている。あるいはテスト結果の解釈が間違っていると思います。
テスト法は、DAOでレコードセットを開く、最終レコードへ移動する、ということだけをしています。
実際に使用する場合、集計結果を利用するはずです。集計結果を取得せずに最終レコード移動だけするという無意味な処理で速度を比較しても無意味だと思います。
具体的には下記のような処理にかかる時間を計測しています。
これでは上記で説明したように無意味なテストです。
下記のように各レコードにアクセスして集計結果を取得する処理を計測すべきでしょう。
これだとDSumが一番遅くなるはずです。レポートに出力する場合も、集計結果を出力することになるのでDSumが一番遅くなるはずです。
また、上記リンク先には下記のような解説もあります。
実際にクエリを開くと時間がかかるといっています。
レコードセットとして扱うと速いといってますが、OpenRecordset と MoveLast だけでは速いのは間違いではないですが、実際問題、OpenRecordset と MoveLast だけの処理というのはありえません。
T'sWareさんのサイトは有用な情報が多いのですが、たまにこのように外してい情報があるので注意が必要だと思います。
私の経験上、下記のような動作だと推測しています。
集計クエリでは、OpenRecordsetした時点で集計をしている。
サブクエリを利用した集計では、OpenRecordsetした時点では集計はしていない。レコード移動するときに集計する。
DSumでは、OpenRecordsetした時点では集計しない、レコード移動しただけも集計しない、集計結果にアクセスするときにはじめて集計する。
DSumでの「他のクエリーに比べて非常に画面表示に時間がかかる(1行ずつダラダラと表示されていく) 」という動作からもそう推測できます。表示するとき(集計結果にアクセスするとき)にはじめて集計されるということだと思います。
テーブル→クエリ→フォーム→レポートでいいと思う。
Dsum動作比較は、下記、サイトがありました。
ググっていたら、時間の計算に使えるかもしれないサイトがありました。
私の方からは、これくらいですね。頑張って👍
他の人は、旧バージョンを開いているとか?
とりあえず「●●●件のレコードが更新されます」を試しに実行して、テーブルの中身を確認しましょう。全件削除実行からの一連の流れなので、何か問題が起きれば、手動全件削除で元に戻せますよね。
前回のデータが残っているなら、全件削除のコードを比較。ループデータが残っているなら、For 〜Nextの中で、datasやrs(j)をdebug.printを比較。
確認メッセージが出る出ないは、DoCmd.SetWarningsのコードがどこかにありませんか?
確認した結果を教えてくれると、嬉しいな。
りんごさんへ
式の詳細ありがとうございす。
明日試してみます。
現在使ってるのが下の画像のようなものを使っております。
テーブル(外部データリンク)→クエリ→フォーム(サブフォームも)という流れでリアルタイムで更新できる仕組みを作ってます。
作業終了時間というフィールドを新たに追加したく今回質問させていただきました。
ただ作業生産性という少し専門的な分野の計算式が必要になってきますのでアクセスの質問掲示板を利用してもいいのか?という疑問は今もあります。
生産性と時間帯の人数(シフト)は基本的に固定で決まってますので、その部分は入力する予定です。
極端な話ですが一か月分入力することも可能です。
シフトのイレギュラーさえなければ一か月に一回のメンテでできればと考えております。
私のイメージとしてはクエリの部分で計算式を入れて作業終了時間を出せればと考えております。
そんな式が存在するのか?処理はできるのか?疑問は多々あります。
私の知識、技術不足のせいでうまく伝わっていないのかもしれませんので再度理想の形を説明させていただきました。
Excelで作るのが正解ではないでしょうか?
具体的にはわかりませんがExcelも必要であれば使うのは問題ありません。
更新すれば自動で作業終了時間がでる仕組みであれば他のこだわりは一切ありません。
いろいろと考えていただきありがとうございます。
「フォームを使わない、テーブルとクエリだけで作る。」という方針であれば、新たに未完了のテーブルと持ち時間のテーブルを追加する必要はないです。
新たにテーブルを作ります。追加するフィールドは、店舗名,チーム名,未完了,持ち時間、そして、下記の計算フィールドです。
・最大出荷数:[生産性]×[人数]×持ち時間
・出荷数:IIf([最大出荷数]>[未完了],[未完了],[最大出荷数])
・出荷時間:[出荷数]÷([生産性]×[人数])
・未完了残り:[未完了]-[出荷数]
・持ち時間残り:[持ち時間]-[出荷時間]
計算フィールドの結果に応じて、店舗名、チーム名、未完了、持ち時間を自分で探して入力します。フォームを作ると、探す手間が少しだけ楽になるでしょう。テーブルとクエリだけで作るならば、たぶん、Excelで作るのが正解ではないでしょうか?
クエリを頑張れば、ある程度、自動化出来るけれど、完成出来ずに重くなっただけ、なんてことも。
ありがとうございます。
コードを見直すということですが、1つ気になっているのが、自分の環境だと全くエラーが出ないのに、他の環境だとエラーが出ることです。
他の部分でも同じようなことが起こらないかと危惧しています。
これはどういった原因が考えられるでしょうか?
りんごへ
フォームに関してよく分かってない部分があり、テーブルとクエリで作成する感じでもよろしいでしょうか?
理解しにくい部分があるのですいません。
私の情報を整理します。
まず外部データのリンクのテーブルがあります。
とりあえずテーブルAにします。
[取引先CD] [取引先名]
[予定] [未完了]
[進捗]
上記のフィールドをテーブルAからクエリで抽出してます。
とりあえずクエリAにします。
どう言えばいいのかわかりませんが常に最新の情報に更新されます(手動)。
前回クエリAに追加したのが下記です。
現在時刻: Time()
残り時間: (([未完了]/([生産性]10))60)/1440
終了時間: [現在時刻]+[残り時間] [生産性]:テーブルを新たに作って追加しました。
ここまでが前回までです。
新たに未完了テーブルと持ち時間テーブルを追加する感じでよろしいでしょうか?
まったく見当違いのことを言ってたらすいません。
未完了テーブルの取引先名と未完了はクエリAにあるのですが必要でしょうか?
追加するフィールドについてですが、
チーム名:持ち時間テーブル
持ち時間:持ち時間テーブル
最大出荷数
出荷数
出荷時間
未完了残り
持ち時間残り
最大出荷数、出荷数、出荷時間、未完了残り、持ち時間残りの式を教えてもらえたら助かります。
終了時間に関してはまた別の機会に質問します。
大量に書き込んでいただいたのに方向性を変えて申し訳ありません。
AddDataのコードには、レコードを追加したら、(追加を確定する為に)更新すると書いてあるので、
確認メッセージ「●件のレコードが更新されます」が出るのは、正常に見えます。
2件のレコードを編集する流れで、●●●件、つまり、3桁のレコードを変更する確認メッセージが出るならば、異常と考えて、例えば、For〜Next処理をdebug.printしてみるか、上記以外のコードを見直す感じでしょうか。
ごめんなさい、質問の内容が理解できなかったため、本文を少し具体的に修正しました。
試していないので、あれですけど、例えば、
AddNew「10件のレコードを追加します。」
On Error Resume Next「1件」
Update「9件のレコードが更新されます」
という現象でしょうか?
それとも、
AddNew「10件のレコードを追加します。」
On Error Resume Next「1件」
Update「100件のレコードが更新されます」
という現象でしょうか?
失礼しました。おっしゃるとおり、以前ここで教えていただいたAddDataのコードがあります。本文に追記しました!
もしかして、AddDataのコードが、上記の他にありませんか?
例えば、
【うどん屋プロシージャの呼び出し】
Call うどん屋("きつねうどん", "400円")
【うどん屋プロシージャの記述】
……
エラーメッセージの通りだと思います
新しく追加したプロシージャは
Report_Open
なので開く時プロパティに[イベント プロシージャ]
を設定してくださいArrayListSort関数も省略しているので適当な場所に入れておいてください(汎用的に使える関数なので標準モジュールに入れてしまってもいいと思います)
[イベント プロシージャ]
は各イベントのプロパティのプルダウンから常に選べるようになっているプロパティですが、これを指定すると、それぞれで専用のプロシージャを呼び出しなさいという指定になります(レポートの開く時ならReport_Open
とか)[イベント プロシージャ]
を選んで[...]をクリックすると、対応するプロシージャが自動で生成されますが、コードをコピペしても[イベント プロシージャ]
は自動で設定はされないので、この部分は自分でやる必要があります。今の問題点は「
詳細_Format
で正確なページ数が取得できない」なので「取得後の目次データの取り扱いをどうするか」は問題の解決にならないです一応いろいろ眺めていたら解決案は出てきました(公開する段階にないですが)
これ自体は>> 7で出来てます。いろいろ議論の余地もあるかと思いますが、現時点で索引表示のためにワークテーブルを使う必要性は感じないです
以下、フォームのイメージです。
①開始時間を入力する。店舗を選ぶ。
・出荷時間のリストボックス
店舗A,30
店舗B,90
店舗C,…
・開始時間のテキストボックス:9:00
・終了時間のテキストボックス:
…,店舗名,開始時間,終了時間
1,
②終了時間を計算する。
・出荷時間のリストボックス
店舗A,30
店舗B,90
店舗C,…
・開始時間のテキストボックス:9:00
・終了時間のテキストボックス:9:30
…,店舗名,開始時間,終了時間
1,
③店舗名、開始時間、終了時間を計算。
・出荷時間のリストボックス
店舗A,30
店舗B,90
店舗C,……
・開始時間のテキストボックス:9:00
・終了時間のテキストボックス:9:30
…,店舗名,開始時間,終了時間
1,店舗A,9:00,9:30
④開始時間のテキストボックスに終了時間を入力
・出荷時間のリストボックス
店舗A,30
店舗B,90
店舗C,……
・開始時間のテキストボックス:9:30
・終了時間のテキストボックス:9:30
…,店舗名,開始時間,終了時間
1,店舗A,9:00,9:30
2,
終了時間は、開始時間に出荷時間を加える計算を考えてみました。
開始時間=9:00、終了時間=
開始時間=9:00、終了時間=9:30
開始時間=9:30、終了時間=9:30
開始時間=9:30、終了時間=11:00
まずは、先程のフォームの連結クエリをもとに、出荷時間のクエリを作ります。
店舗名,チーム名,出荷時間
店舗A,チーム9時 ,30
店舗B,チーム9時 ,30
店舗B,チーム10時,60
店舗C,チーム11時,……
店舗の終了時間を計算するときは、店舗名でグループ化、出荷時間の合計を集計しましょう。
りんごさんへ
たくさんのアドバイスありがとうございます。
難しそうですが、明日以降に試してみたいと思います。
このスレッドの流れを細かく読んではいませんので、外しているかも知れませんが、
ちょっと思ったことを書いてみます。
レポートの最後に索引を追加したいということですよね。
ということだと、かなり難易度が高いと思います。
一つのレポートで索引も出力するというのはあきらめて、
まずは、索引なしの医薬品集レポートを出力する。
その後、索引を出力する。
というようにレポートを2つに分けたらどうでしょう。
索引用のテーブルを作成しておいて、それから索引レポートを作成しておきます。
医薬品集レポートを出力するときに、フォーマット時イベントで索引用テーブルに索引用データを出力していく。
こうすれば、並べ替えも、段組みもレポートの機能で簡単にできます。
処理の流れは下記のようなイメージです。
フォームにコマンドボタンを2つ配置。
「医薬品集レポート印刷」
「医薬品集索引印刷」
「医薬品集レポート印刷」ボタンのクリック
索引テーブル の全データを削除 → 医薬品集レポートの印刷
医薬品集レポートの詳細(またはグループヘッダー)のフォーマット時イベントで索引データを索引テーブルに追加。
上記印刷後、「医薬品集索引印刷」をクリックで索引レポートを印刷。
まず、Forループ内でカウンター変数を変更するのはご法度です。Step を使いましょう。
データ追加は、サブフォームのレコードセットに対してAddNewで追加するようにします。
Withでサブフォームのレコードセットを参照するようしてますのて、
Me.T_月額マスタのサブフォーム1.Form
は不要です。![契約番号サブ] 等の[]内はコントロール名ではなく、フィールド名にしてください。
テーブルのフィールド名が「契約番号サブ」ならいいですが、「契約番号」なら、
![契約番号]
です。
あと、最後に .Update が必要です。
リンクフィールドの設定は問題ないと思います。
リンク親フィールド/子フィールドが設定されている箇所が分かりましたので、念のため追記いたします。
hirotonさん、本当に有難うござます。自分がやろうとしていたことが、素人には絶対無理だったと痛感しました。ご指導頂いた資料で今後じっくり勉強することにして・・・ とりあえず、このままコピペしてみました。添付しましたファイルの様なコメントが出ました。完全なコピペはダメだったでしょうか?
⑦リストボックスから、とりあえず泥臭く選んで登録する
未完了テーブルのリストボックス
1,店舗A,500
2,店舗B,1000
3,店舗A,0
持ち時間テーブルのリストボックス
1,チーム9時 ,60
2,チーム10時,60
3,チーム11時,60
4,チーム9時 ,30
…,店舗名,チーム名,未完了,持ち時間,最大出荷数,出荷数,出荷時間,未完了残り,持ち時間残り
1,店舗A,チーム9時 ,500 ,60,最大出荷数,500,30,0,30
2,店舗B,チーム9時 ,1000,30,
⑤店舗A,未完了残り0を登録
未完了テーブルのリストボックス
1,店舗A,500
2,店舗B,1000
3,店舗A,0
⑥チーム9時,持ち時間残り30を登録。
持ち時間テーブルのリストボックス
1,チーム9時 ,60
2,チーム10時,60
3,チーム11時,60
4.チーム9時 ,30
出荷時間のログ
…,店舗名,チーム名,未完了,持ち時間,最大出荷数,出荷数,出荷時間,未完了残り,持ち時間残り
1,店舗A,チーム9時 ,500 ,60,最大出荷数,500,30,0,30
未完了テーブルのリストボックス
1,店舗A,500
2,店舗B,1000
持ち時間テーブルのリストボックス
1,チーム9時 ,60
2,チーム10時,60
3,チーム11時,60
④リストボックスから、店舗A、チーム9時、未完了500、持ち時間60を選んで登録。
以下、フォームの連結クエリのイメージです。
…,店舗名,チーム名,未完了,持ち時間,最大出荷数,出荷数,出荷時間,未完了残り,持ち時間残り
1,店舗A,チーム9時 ,500 ,60,以降、計算で導出。
未完了のログと持ち時間のログを考えてみました。持ち時間は、9:00~10:00ならば、60とします。
以下、フォームのイメージです。
① 出荷日を選ぶ。
② 店舗名を選んで登録。
未完了テーブルのリストボックス
1,店舗A,500
2,店舗B,1000
③ チームを選んで登録。
持ち時間テーブルのリストボックス
1,チーム9時 ,60
2,チーム10時,60
3,チーム11時,60
情報が足りずに申し訳ありません…
サブフォームのリンク
親フィールド:「T_契約マスタ」の「契約番号」
子フィールド:「T_月額マスタ」の「契約番号」
(リレーションシップで結ばれている関係をリンクフィールドと解釈しているのですか、相違ありませんでしょうか…?)
サブフォーム上で手入力した場合は問題なく入力できました。
以上、どうぞよろしくお願いいたします。
というわけで、ちゃんと使いやすいデータにして対応する例
Dictionary オブジェクトを使って目次データを整理するようにします
Dictionary オブジェクトを使うには事前準備が必要なのでレポートの開く時イベントに処理を追加しています。
Dictionary オブジェクトの仕様上「薬品名のフリガナ」に重複データがあると最後の「薬品名」のみ目次に反映されます
五十音での並び替えについて
とりあえず無理やり的な方法で(修正箇所だけ)
例えば
のようなデータがあった場合、
のようにひとかたまりの文字列のデータにして並び替えた後、分割用の文字から後ろを抜き出せば「かな順」で並び替えができるというものです
「<split>」は誤動作しないよう「かな」に含まれない文字列なら何でも構いません
内容が複雑化してきて、簡素化した記述が足かせになって余計な苦労をしてるような気がしてきました。データのボリュームが増えてきているのでコード内でもしっかりデータを管理できるような仕組みを導入したほうがよさそうです
適当なデータを作って試してみたら確かにうまくいかないですね
レポートのイベントの発生メカニズムの研究(hatena chipsさん)
ページ跨ぎが発生した場合に目次データが重複しないよう
と制御を入れたんですが、
FormatCount = 1
だけだとうまく目的のデータにならないようです。画像を見てわかる通り、目次データの取得は「実際の描画があったら目次データを作成する(ページ番号を取得する)」とする必要がありそうです。hirotonはうまい方法を知りません目次データを取得している詳細_Formatイベントは描画前の処理なので、このタイミングで「描画があったかどうか?」は知りようがありません。やるとすれば、印刷しようとしている余白に印刷できる高さがあるかどうかを計算するという方法になると思います。現在の印刷位置情報や、印刷領域の残り高さが必要になるのでかなり大変です
条件を限定すれば、いくらか簡単な方法でチェックすることもできそうです
・同一ページ印刷プロパティ「はい」
・単独で1ページを超えるような出力がない(上図の例なら詳細は最大でも9行(1ページで収まる)場合)
であれば、「
FormatCount = 2
があれば、それが描画ページ」とすることができます。ただ、FormatCount = 1
のときはFormatCount = 2
があるかどうかわからないので、「仮データを置いて、次の明細に移動したら仮データの確定処理をする」様にします下記の情報を提示してもらえますか。
「ごとに請求」ボタンのクリック時イベントのVBAコード。
サブフォームコントロールの「リンク親フィールド」「リンク子フィールド」の設定。
サブフォームで手入力で入力したときは問題なく入力できるかどうか。