Microsoft Access 掲示板

views
4 フォロー
6,282 件中 1,721 から 1,760 までを表示しています。
3
あん 2023/06/09 (金) 15:22:39 927ea@06086

hiroton様、hatena様
ご回答ありがとうございます。

hiroton様の「コードの一括処理は余計なバグを生む」
hatena様の「纏められるものはなるべつ纏める」
勉強させていただきました。

今回、自分で試行錯誤しながら、VBAでVBAをコントロールするコードの記述ができました。

新規フォームに「実行」ボタン、「対象文字列」テキストボックス、「置換文字列」テキストボックスを配置し、
実行ボタンをクリックすると、全モジュールに対し、対象文字列を置換文字列に置き換える処理を行います。

5

hirotonさん すごく分かり易い表現でして頂きありがとうございます。お手数かけました。
中々すごい式ですね。VBAでする場合はどう記述したらいいでしょうか? サブフォームで2つ目以降の商品をコンボで選んだ時に警告が出てキャンセルが理想的です。そうすると色々と認識しやすいので。
宜しくお願いします。

2
すぬぅ 2023/06/09 (金) 13:25:12 863dd@6f7d6

はい,私もWindows10+Access2013では使うことはできていました。使っていたプログラムを,Windows11+Access2021のパソコンに移行して,壁にぶつかってしまった次第です。これも,IEのサポート終了の影響なのでしょうか・・・。
どなたか,Windows11+Access2021で使われている方はいらっしゃいませんでしょうか?

4
hiroton 2023/06/09 (金) 11:48:13 b43ba@f966d

関数は「機能をひとまとめにしたもの」なので、そこだけ抜き出せば何らかの値に置き換わります。複雑な計算式はメモ帳などで整形してみると理解しやすくなります

┌=IIf(
│ ┌DCount("*"
│ │,"取引明細テーブル"
│ │,"取引ID=" & [取引ID]
│ └)<=1
│,[商品ID]
│,┌DLookUp("商品ID"
│ │,"商品テーブル"
│ │,"区分け='" & 
│ │ ┌DLookUp("区分け"
│ │ │,"商品テーブル"
│ │ │,"商品ID=" & 
│ │ │ ┌DLookUp("商品ID"
│ │ │ │,"取引明細テーブル"
│ │ │ │,"取引ID=" & [取引ID] & " AND 明細ID <> " & [明細ID]
│ │ │ └)
│ │ └) & "' AND 商品ID=" & [商品ID]
│ └)
└)

※区分け取得部分のDLookup関数を調整

サブフォームに一番最初に区分けAの商品を選んだ場合、BやC(つまりA以外)が選べない様にしたい

これをプログラミング的な思考に置き換えていきます

本手法は入力規則を使うことにしたので、「入力可能な商品IDかどうかを判定し、入力可能であればその商品IDを入力規則の値にする」様な計算式を作成します

まず、「サブフォームに一番最初に区分けAの商品を選んだ」の時点で「最初の入力」の場合と「2回目以降の入力」で別な処理を行う必要が出ます。つまり、「何の制限もない初回入力」と「制限のかかる2回目以降」を作る必要があります

'//サブフォームのデータ単位で最初の入力と2回目以降の入力を切り分ける処理
┌=IIf(
│ ┌DCount("*"
│ │,"取引明細テーブル"
│ │,"取引ID=" & [取引ID]
│ └)<=1
│,(最初の入力)
│,(2回目以降の入力)
└)

「(最初の入力)」はどんな商品IDでも入力できる必要があるので、入力規則としては「どんな商品IDが指定されても同じ商品IDになるような式」とします。つまり自分自身を設定すれば解決です

「(2回目以降の入力)」は、「自身の区分け」と「入力済みデータの区分け」が同じかどうかを判定し、処理を分岐(そのまま入力、または、入力規則のエラーとしてメッセージ表示)させます
ただ、入力規則を使う関係上、「同じかどうか」だけでなく、「同じ場合は自身の商品ID」という結果が必要になります。そこで、DLookup関数を使って商品テーブルから「(入力済みデータの区分け)+自身の商品ID」のレコードの商品IDを求めています
これで、自身が同じ区分内の商品かチェックされるという仕組みです

'//(2回目以降の入力)部分
│,┌DLookUp("商品ID"
│ │,"商品テーブル"
│ │,"区分け='" & 
│ │ (入力済みデータの区分け)
│ │  & "' AND 商品ID=" & [商品ID]
│ └)

「(入力済みデータの区分け)」の取得方法はそのまま関数が何をやっているのか考えてみてください。


取引明細テーブルに区分けデータも記録しているのであれば、区分け判定部分の計算式はもう少し単純にできそうですね


実装方法はいくつか考えられますが、「入力規則に計算式を一つ入れればいい」が謳い文句として簡単そうに見えたのでそれで実現しています。(VBA使ったほうがすっきりする回答になるんですけどね)

1
hiroton 2023/06/09 (金) 10:23:32 b43ba@f966d

ネット検索する限りIEはなくてもWebBrowserコントロールはそのまま動くように見えますね
こちら、Windows10ですがファイルは読み込めました

ひとつひとつ問題の切り分けをして試してみてはどうでしょう?

3

構成は下記です。
1.ユーザーテーブル:●ユーザーID(主キー) ●ユーザー名
2.商品テーブル:●商品ID(主キー) ●商品名 ●区分け
3.取引メインテーブル:●取引ID(主キー) ●日付 ●ユーザー選択(コンボにて)
4.取引明細テーブル(サブ):●明細ID(主キー) ●商品選択(コンボにて) 他数量等 ●取引ID
この3と4を使い(取引IDを1対多でリレーション)して親子フォームを作成しています。
フォームのページというのは私が勝手に認識してました。取引ID毎の親子フォームになっているもので。
取引入力時にその時のサブフォームで一番最初に選択した商品区分け以外の区分けを選ぼうとした場合に警告を出しキャンセルさせたいのです。少し前からこのフォームで処理していたのですが事情がかわり取引毎に同一区分け商品だけが紐付けしなくてはいけなくなったので(過去に入力されたものはいいのですが、今後で)

hiroton さん早速ありがとうございます。関数単体の意味はわかるのですが全体の処理はどういう動きでしょうか?(長い関数式が慣れてなくて、すみません)

宜しくお願いします。

2
hiroton 2023/06/09 (金) 09:32:37 b43ba@f966d

何をもって簡単と言うかわかりませんが
コンボボックスの入力規則に以下を設定します

=IIf(DCount("*","サブテーブル","リンクフィールド=" & [リンクフィールド])<=1,[商品],DLookUp("商品","商品テーブル","区分け='" & DLookUp("区分け","商品テーブル","商品=" & DLookUp("商品","サブテーブル","リンクフィールド=" & [リンクフィールド])) & "' AND 商品=" & [商品]))

※各項目は実際のフォームの内容に合わせる必要があります

1
りんご 2023/06/09 (金) 07:56:00 935bc@0e907

リレーションシップも定義済みです。
スクリーンショットを提示できますか?難しければ、主キーとリレーションシップを書いた方が、回答が増えるでしょう。
他に確認すべきところありますでしょうか。
タブを使わずに、メインフォームとサブフォームで該当部分を試しに組んでみるとか?

2

同じようなコードの置換、追加が多数必要になるということは、同じような処理が多数あるということですよね。

Private Sub PI担当者ID_AfterUpdate()

ということから推測すると、多数のコントロール(テキストボックス等)があり、そのコントロールで更新が発生したら、PI測定日を現在の日付を入力してメッセージボックスを表示させたい、
ということがご希望のことかと思えますがどうでしょうか。

こういう場合、共通の処理は一つのプロシージャにまとめておくと修正があっても一か所ですみます。

例えば下記のようなに。

Sub Ctrl_Update()
    If Isnull(Me.ActiveControl) = False Then
        Me.PI測定日 = Date
        Msgbox "日付を代入しました。", vbokonly '追加
    End If
End Sub

Private Sub PI担当者ID_AfterUpdate()
     Ctrl_Update
End Sub

Private Sub 他のコントロール_AfterUpdate()
     Ctrl_Update
End Sub

さらに共通処理の部分をFunctionにしておけば、

Function Ctrl_Update()
    If Isnull(Me.ActiveControl) = False Then
        Me.PI測定日 = Date
        Msgbox "日付を代入しました。", vbokonly '追加
    End If
End Function

デザインビューでこの処理を適用したいコントロールを複数選択しておいて「更新後処理」に

=Ctrl_Update()

とすれば、コントロール_AfterUpdate() のコードをコントロール数分記述する必要もなくなります。

同じような処理を複数個所に繰り返し記述するはバグの原因になりかねませんので、纏められるものはなるべつ纏めるというのがプログラミングの鉄則で。

1
hiroton 2023/06/08 (木) 17:11:35 dd05a@f966d

標準のエディタには無い機能なので、それができるエディタを使うとか、[F3][END][CTRL+v]を繰り返すとか、それをマクロで作るとか

あとは改行の代わりに:を使ってマルチステートメント記述にするとか

まぁ、コードの一括処理は余計なバグを生むこともありオススメしませんが

3
nokonoko 2023/06/08 (木) 17:02:54 3e2e6@54883

今回はありがとうございました。
予定通りの作業ができるようになりました。

1

メインフォームのレコードソースはテーブルはユーザー情報を格納するもの。
サブフォームのレコードソースはそのユーザーが購入する商品データを入力するもの。
ということですか。

できれば、関係するテーブルのテーブル名とそのフィールド構成を提示してもらえますか。
少なくとも下記の3つのテーブルが必要なはずです。
ユーザー情報のテーブル
商品購入データのテーブル
商品情報のテーブル

データーベースはまずは、テーブル設計が重要でそれがまちがっていたら、使い物にならないので。

。フォームのページ毎に一つの商品区分け分商品しか選択出来ない様にしたいのです。

フォームにページという概念はないのですが、どのような意味が使っていますか。

2
nokonoko 2023/06/08 (木) 13:45:03 3e2e6@54883

回答ありがとうございます。
やりたいことができるようになりました。
しかし、このあたりのコードをまだいじっている途中なので、またこの続きに質問することがあるかもしれません。その時は、お時間がありましたら、よろしくお願いします

コードミスを見落としてました
openに対してcloseがないですね

ご指摘ありがとうございます。エラートラップのほうにまぎれて入っていました。

1
hiroton 2023/06/08 (木) 11:26:50 修正 dd05a@f966d

id名を取得しておいて、保存はExcel VBAでの記述をそのまま使えばいいですね

       Dim id名 As String
       For j = 0 To rs.Fields.Count - 1
           .cells(1, j + 1) = rs(j).Name
           If rs(j).Name = "id名" Then id名 = rs(j)
       Next j
       .cells(2, 1).copyfromrecordset rs
       .Visible = True

'// ここでできたエクセルを、名前を自動でつけて(id名でよい)、指定のパスに保存したい
  .ActiveWorkbook.SaveAs "(指定のフォルダパス)" & "\" & id名

コード全体に関しては
ループ内でやるべき(何度も繰り返す必要がある)処理か?
With ~ End With内の省略記述は正しくオブジェクトが指定できているか?
あたりを見つめてみるといいと思います


コードミスを見落としてました
openに対してcloseがないですね

   Set rs = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset)  '//これに対応するcloseがない

なくても動くといえば動くんですが(たいていエラーも起きないでしょう)だいぶ良くないので指摘しておきます

4

下記でどうでしょう。

Private Sub 抽出ボタン_Click()
    Dim sFilter As String
    
    '日付入力値チェック
    If Not IsNull(Me!開始) And Not IsDate(Me!開始) Then
        Me!開始.SetFocus
        MsgBox "正しい日付を入力してください。", vbCritical + vbOKOnly, "日付入力不備"
        Exit Sub
    End If
    If Not IsNull(Me!終了) And Not IsDate(Me!終了) Then
        Me!終了.SetFocus
        MsgBox "正しい日付を入力してください。", vbCritical + vbOKOnly, "日付入力不備"
        Exit Sub
    End If
    '期間指定チェック
    If IsDate(Me!開始) And IsDate(Me!終了) Then
        If Me!開始 > Me!終了 Then
            MsgBox "期間指定が不適切です。再入力してください。", vbCritical + vbOKOnly, "期間指定不備"
            Exit Sub
        End If
    End If
    
    '抽出条件式生成
    If IsDate(Me!開始) Then
        sFilter = " AND 日付 >= #" & Me!開始 & "#"
    End If
    If IsDate(Me!終了) Then
        sFilter = sFilter & " AND 日付 <= #" & Me!終了 & "#"
    End If
    If Me!キーワード <> "" Then
        sFilter = sFilter & " AND [A] & ';' & [B] & ';' & [C] Like '*" & Me!キーワード & "*'"
    End If
    sFilter = Mid(sFilter, 6) '先頭の" AND "を削除
    
    If sFilter = "" Then
        Me.FilterOn = False
    Else
        Me.filter = sFilter
        Me.FilterOn = True
    End If
End Sub

A, B, Cの各フィールドに対して部分一致(あいまい検索)になってます。
例えば、Aフィールド 「あいう」、キーワード「う」でも一致とみなします。

もし、各フィールドに対して完全一致の条件にしたいなら、キーワードの条件式のコードを下記に修正してください。

        sFilter = sFilter & " AND ';' & [A] & ';' & [B] & ';' & [C] & ";" Like '*;" & Me!キーワード & ";*'"

フィールドの区切り記号として';'(セミコロン)を使用してますが、フィールド値にセミコロンが含まれる可能性がある場合は、含まれる可能性がない文字にしてください。

22

クエリが原因で改ページされることはありえません。
レポートの設定に原因があるのでしょう。

とりあえず思いつくのは、下記ぐらいです。
詳細セクションの「改ページ」プロパティが「しない」以外に設定されている。

上記について確認してみてください。

3
メイクーン 2023/06/07 (水) 21:14:15

【UP1の続き】
If Me!キーワード <> "" Then   
    If filter = "" Then
        filter = "A like '" & Me!キーワード & "'"
    Else
        filter = filter & " and A like '" & Me!キーワード & "'"  
    End If
End If
    If Me!キーワード <> "" Then
        If filter = "" Then
            filter = "B like '" & Me!キーワード & "'"
    Else
        filter = filter & " and B like '" & Me!キーワード & "'"          
    End If     
End If
If Me!C = True Then   
    If filter = "" Then
            filter = "C like '" & Me!キーワード & "'"
    Else
        filter = filter & " and C like '" & Me!キーワード & "'"
    End If
End If
If filter = "" Then
    Me.FilterOn = False
Else
    Debug.Print filter
    Me.filter = filter
    Me.FilterOn = True
    Me.OrderBy = "対応日 ASC"
    Me.OrderByOn = True
End If
End Sub

フィールドをABCの3つにしていますが実際は5つになります。宜しくお願い致します。

2
メイクーン 2023/06/07 (水) 21:11:39

大変遅くなり申し訳ございません。
現状のVBAは以下になります。
【UP1】
Private Sub 抽出ボタン_Click()
Dim filter As String
    filter = ""
If Me!開始 <> "" And Me!終了 <> "" Then
    If Me!開始 > Me!終了 Then
        MsgBox "期間指定が不適切です。再入力してください。", vbCritical + vbOKOnly, "期間指定不備"
        Exit Sub
    End If
End If
If Me!開始 <> "" Then
       If Me!開始 <> "" Then
        filter = "日付 >= #" & Me!開始 & "# and 日付 <= #" & Me!終了 & "#"
    Else      
        filter = "日付 >= #" & Me!開始 & "#"      
    End If      
ElseIf Me!終了 <> "" Then
    filter = "日付 <= #" & Me!終了 & "#"     
End If

行の関係上、続きは別途UPします。

21
アクセス初心者 2023/06/07 (水) 18:14:40 fe6cd@15915

確認しましたところ、
全てのVBA・改ページコントロールを削除したところ、
1ページ1行で表示されました。この場合、そもそものクエリに原因があるのでしょうか。

7

カスタムリボンというか単純にメインタブに追加して使用しています。

つまりテーブル[USysRibbons]をまだ作成していない、ということでしょうか。

カスタムリボンはタブは作れたものの、必要なコマンドのxmlがわからないので使えてません。

ある組み込みコントロールを任意のカスタムリボンに追加しようとしているが、
idMso属性に渡すべき具体的なコントロールIDが判らない、という意味で
おっしゃっているのであれば、とりあえず以下のリンク先のドキュメントを
参照してください。
AccessにおけるコントロールIDの一覧は accesscontrols.xlsx に掲載されています。

Microsoft Download Center: Office 2013 Help Files: Office Fluent User Interface Control Identifiers

[USysRibbons]のフィールド[RibbonXml]に格納するXMLの書き方自体が
判らない、ということなのであれば、とりあえず「必要なコマンド」が
何なのかについて具体的に明記されることをお奨めします。

25
ジュン 2023/06/07 (水) 16:31:55 ddfe5@d8b89

hiroton様 重ね重ねすみませんでした。
逆の発想でエラー時に処理するのも手ですね、これで上手く出来ました。
クエリの件は分かりました。また改めて具体的に投稿する様にします。
今回すごく勉強になりました。回答はどれも素晴らしいものばかりでした! もう一度hatena様へも感謝です。
本当にありがとうございました。

24
hiroton 2023/06/07 (水) 15:29:23 9c71f@f966d

質問に合わせて抜粋や改変してますけど、もともと全部hatenaさんの研究から読み取れることですねぇ
質問のやり取り中だったので控えてましたが、改めてhatenaさんの研究と情報公開に感謝します。ありがとうございます


追加の件
DCount("売上日付", "Q_ 請求書一覧用レコードソース")はきちんと0になってますか?

または、DoCmd.OpenReportはエラーでもいいんじゃない?という方法もあります
印刷データが無いとき印刷を中止する方法(cbcnetさん)


クエリの件は一概に言えるものでもないと思います。問題にすると結構大きくなると思うので、具体的にこういうデータでこういうクエリを作るときという形で改めて質問を立てたほうがいいと思います

23
ジュン 2023/06/07 (水) 14:47:56 ddfe5@d8b89

度々申しわけありません、このレポートを印刷用として顧客・対象年・対象月のコンボを配置したフォームを作ってまして、コマンドボタンでプレビューの形です。レポートにデータがない場合 エラーとなるのでレポートの空データ時イベントに「 MsgBox "データはありません"
  Cancel = True 」とするとMsgBox表示後にエラーとなります。デバック見ると DoCmd.OpenReport "R_請求書一覧", acViewPreview, ,抽出条件 のところで止まってました。それでフォームのコマンドボタンに 「If DCount("売上日付", "Q_ 請求書一覧用レコードソース") = 0 Then MsgBox "データはありません" Exit Sub」としたのですがやはりMsgBox表示後エラーとなり、デバック見ると レポートフッターに記述の Me.[tx月合計] = Me.[tx税込金額の累計] のところで止まっていました。
どこにキャンセルの命令を入れたらいいのか分からないのです。 何度もすみません。

22
ジュン 2023/06/07 (水) 13:34:01 ddfe5@d8b89

hiroton様 とても丁寧な説明ありがとうございました。レポートは複雑な動きがあるのですね。(今まで知りませんでした)
[pages]を配置することによって強制的に動作させるのですね。(思いもよらない発想です!)
自分の力ではとても解決出来ませんでした。本当にありがとうございました。hatena様にも感謝です。

あと今回の件とは関係ないのですが、私はまだまだ知識不足でクエリをよく作成してます。複雑になる場合はクエリを分割して作成しており、その結果クエリが大量に出来ています。こういうやり方はよくないでしょうか? その事がいつも疑問に思ってまして。

21
hiroton 2023/06/07 (水) 13:10:04 9c71f@f966d

[Pages]は必須です
基本的な使い方の、ページ番号表示のために設置済みであれば改めて配置する必要はありませんが、未使用場合は配置する必要があります。表示不要なら可視プロパティを「いいえ」にしましょう


簡単に説明すると、レポートは「データの整形format」→「描画print」をレコードの数だけ繰り返します。そして、「描画」したら描画内容が確定され、修正できなくなります。プレビュー画面で見てるとイメージが付きにくいですが、実際に印刷されることを考えればわかりやすいですね
つまり、レポートヘッダーとは通常、真っ先に印刷済みになってしまうのであとから累計を書き込みたいといっても無理なのです

ここで、[pages]ですが、これは総ページ数を表示する変数です。しかしながら、総ページ数は出力してみないとわからないので上記の単純な仕組みでは描画することができません
そこで、ACCESSは[pages]が含まれるレポートを印刷しようとすると
『全レコード分(「データの整形」)→全レコード分(「データの整形」→「描画」)』
のように、印刷の仮データを作るかのような動作します

この動作をイベントで追いかければ

(仮)レポートヘッダー→(仮)詳細[レコード数分]→(仮)レポートフッター→(本番)レポートヘッダー→(本番)詳細[レコード数分]→(本番)レポートフッター

となるので、全レコード分の情報を反映した内容をレポートヘッダーに書き込むことができるようになります

処理するイベントがヘッダーでもフッターでもいいというのは、正確には「(仮)レポートフッター」か、「(本番)レポートヘッダー」のどちらかであればいいということですね


次に、コードがMe.[tx月合計] = Me.[tx税込金額の累計]の場合はフッターでなければならないのはなぜ?となるのですが、これは参照するデータの問題です。つまり、Me.[tx税込金額の累計]はイベントのタイミングで内容が異なるからということですね
レポート上のコントロールなので、描画するレコードに合わせて内容は変わっていて当然というわけです

20
ジュン 2023/06/07 (水) 11:39:58 ddfe5@d8b89

hiroton様ありがとうございました。
レポートフッターにコード記述したら上手くいきました。イベントが上から順に発生するのでそうしないと正しくならないのですね(まだなんとなくしか理解してないのですが)。不思議なのは =Pages のテキストボックスがないとデータが表示されませんでした。これも必須なのですね?

1
あん 2023/06/07 (水) 11:31:02 927ea@06086

申し訳ありませんでした。
こちらの手違いでした。

原因はレコードがない状態だったので、エラーが出ていたようです。
解決しました。

19

そのコードであればレポートヘッダーではなくレポートフッターにコードを記述してみてください


レポートヘッダーを弄りたいのになぜレポートフッターで制御する(できる)のか?というのがhatenaさんの研究から学ぶことができます

同様に、hatenaさんの回答(>> 14)のように「レポートヘッダーで制御するように組む」のも解法の一つです

hirotonも横やり的に違う解法を出してしまっているので混乱させてしまっているところがあると思います。気になったところがあれば遠慮なく聞いてください

18
hiroton 2023/06/07 (水) 10:48:07 修正 9c71f@f966d >> 16

個人的にはレポートあまりごちゃごちゃさせたくないんでVBA優先しちゃいますけどね

Option Compare Database
Option Explicit

'レポート上に「コントロールソース:=[pages]」のテキストボックスを配置すること

Dim lastDay As Date
Dim daySum As Currency
Dim total As Currency

Private Sub レポートフッター_Format(Cancel As Integer, FormatCount As Integer)
    total = total + daySum * 1.1
    Me!月合計 = total
End Sub

Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    If Me.FormatCount = 1 Then
        If Me!日付 = lastDay Then
            daySum = daySum + Me!数
        Else
            total = total + daySum * 1.1
            daySum = Me!数
            lastDay = Me!日付
        End If
    End If
End Sub

んー、ここまでVBA任せにするとなんか難しそうに見えますね

レポート上のコントロールのプロパティによって結果が変わるモノを使いたくない(プロパティ確認が手間)ってのもあるんですが、コントロールを使えばプレビューでイメージを掴みやすいってメリットも有難いところではあります

この先は、慣れと雰囲気でお好きなものをって感じですかね

17
ジュン 2023/06/07 (水) 10:21:27 ddfe5@d8b89

hatena様・hiroton様 ありがとうございました。
日付グループフッターに税込み金額の累計は出来てます---[tx税込金額の累計]。そしてレポートヘッダーにコード記述しました。
Private Sub レポートヘッダー_Format(Cancel As Integer, FormatCount As Integer)
     Me.[tx月合計] = Me.[tx税込金額の累計]
End Sub
でも[tx月合計]は総累計ではなく先頭の累計分が表示されます。何が間違っているのでしょうか?(コードはこれだけでは不足?)
すみません、私の理解が悪くて・・・ 因みに請求書一覧は1ページに必ず収まる量です。
宜しくお願いします。

6
カンカン 2023/06/07 (水) 10:21:08 d8b37@cccb5 >> 3

上にも書きましたが、カスタムリボンというか単純にメインタブに追加して使用しています。
カスタムリボンはタブは作れたものの、必要なコマンドのxmlがわからないので使えてません。

5
カンカン 2023/06/07 (水) 10:17:29 d8b37@cccb5 >> 2

現状ではメインタブに新しいグループと新しいタブを追加して、必要なコマンドを追加し、すべてのメニューを表示するのチェックを外して使用しています。

4
カンカン 2023/06/07 (水) 10:15:15 d8b37@cccb5 >> 1

ありがとうございます。全部みましたが、決め手となる方法はありませんでした。

16

おお!これはいいですね。
集計実行で累計を計算させて、VBAでフッターのフォーマット時にヘッダーに代入。
シンプルですし、確実です。

=Pages のテキストボックスは必須ですね。
こちらでサンプルも作成して動作確認できました。

15
hiroton 2023/06/06 (火) 18:00:11 74852@f966d

いずれにせよ、様々な条件に合わせて手を入れる必要は出るでしょう
細かいこと無視するなら

Private Sub レポートフッター_Format(Cancel As Integer, FormatCount As Integer)
    Me!月合計 = Me![日付毎数合計*1.1の集計:全体]
End Sub

画像1
画像2

こんなんでも動きますね
レポートに計算用コントロールを配置するか、VBAで変数を用意するかはまぁ好みで

[日付毎数合計*1.1]は数値確認用です(いらない)
※([日付毎数合計*1.1]とか[日付毎数合計*1.1の集計:全体]とか、実際にはこんな名前つけてはいけませんよ)


レポートヘッダーはACCESSの中でも特に厄介な案件ですね。正直「レポートヘッダー?じゃあVBAね」と思います。たいてい、何とかしようとするよりよっぽど楽なので

あとはまぁ、ヘッダーフッターの誤表記とか、フッターによる検索汚染とか、いつも以上に意識しておかないと話がかみ合わなくなったりするのも厄介ですね

14

レポートヘッダーに =Sum([税込み日別合計]) とすると、全レコード分繰り返されて集計されてしまうので、ここは、DSum関数を使う必要があります。

=DSum("税込み日別合計","税込み日別合計を表示するクエリ")

hirotonさん提案のVBAで累計していく方法もレポートヘッダーに表示しようとなると、結構はまることになります。
レポートのイベントの発生メカニズムを理解しておく必要があります。

レポートのイベントの発生メカニズムの研究 - hatena chips

レポートのイベントの発生メカニズムの研究 その2 - hatena chips

方法としては、下記のような考え方になります。
=Pages と総ページ数を表示するテキストボックスを配置しておく。
すると、総ページ数を取得するために、先頭レコードから最終レコードまでFormatイベントのみが発生する。
これで総ページ数を取得できたら、改めて先頭レコードに戻って最終レコードまでFormatイベントとPrintイベントが発生して実際にレポートしてと出力します。

この最初のループの時にFormatイベントで合計を累計していきます。
2回目のループのレポートヘッダーのFormatイベントで累計した合計をテキストボックスに代入します。
1回目のループかどうかの判断は pages が0かどうかで判断できます。

Option Compare Database
Option Explicit

Dim 税込総合計 As Currency

Private Sub グループフッター1_Format(Cancel As Integer, FormatCount As Integer)
    If  Me.Pages = 0 And Me.FormatCount = 1 Then 税込総合計 = 税込総合計 + Me!日合計 * 1.1
End Sub

Private Sub レポートヘッダー_Format(Cancel As Integer, FormatCount As Integer)
    If  Me.Pages < 0 Then Me!請求額総計 = 税込総合計
End Sub

とりあえず上記のような感じですが、レポートの設定によってはいろいろ難しいことも発生しますので、実際に動作確認しながら、修正していく必要があるかもしれません。

13
ジュン 2023/06/06 (火) 16:39:14 ddfe5@d8b89

総合計金額が= Sum([税込み日別合計])だと重複してしまうのはレコードソースには同じ日付・同じ顧客で品目が複数の場合あるからどうしてもそうなってしまうのですね。1品目なら問題ないのですが。この解決は中々ないでしょうか?
レポートフッターには税込み金額の累計がいけてるので例えばそれを変数に入れてレポートヘッダーに表示させる事は無理でしょうか?(そんな事無理な気がしているのですが)・・・すみません知識不足で。

12
ジュン 2023/06/06 (火) 13:31:41 ddfe5@d8b89

その後、レポートヘッダーに表示された総合計金額を調べると二重に計算されている事が分かりました。
例えば売上日が4/1に1品目、4/15に2品目の場合 総合計は日付合計の2つのSum値が正しいのですが、3つの日付合計値のSum値となっています。何か構成が間違えているのでしょうか?

*hiroton様ありがとうございました。色々と試してみますね。まずここまで来たのでクエリ方式でまず進めてみます。

11
ジュン 2023/06/06 (火) 12:50:51 ddfe5@d8b89

hatena様ありがとうございました。
頂いたコメント通り別クエリを使って新たにクエリを作成して(リレーションもして)、それを請求書一覧のレコードソースにしました。そうするとエラーは出なくなりました。そして日付フッターに「税込み日別合計」を配置しレポートヘッダーにテキストボックスに作り =Sum([税込み日別合計]) としました。そうすると何故か総合計の計算が全く合いません。フッターの方は最終の合計値が表示されています。どこが間違っているのでしょうか? 度々すみません・・・新たなレコードソースのSQLは下記です。

SELECT Q納品書レポート用空行あり.売上日付, Q納品書レポート用空行あり.注文番号, Q納品書レポート用空行あり.納品書番号, Q納品書レポート用空行あり.税率, Q納品書レポート用空行あり.顧客ID, Q納品書レポート用空行あり.顧客社名, Q納品書レポート用空行あり.IF条件付き製品型番, Q納品書レポート用空行あり.出荷数量, Q納品書レポート用空行あり.単価, Q納品書レポート用空行あり.小計, [Q_ 請求書一覧用日付別合計金額].税込み日別合計, Q納品書レポート用空行あり.売上年, Q納品書レポート用空行あり.売上月, Q納品書レポート用空行あり.HP用支払い条件
FROM [Q_ 請求書一覧用日付別合計金額] INNER JOIN Q納品書レポート用空行あり ON [Q_ 請求書一覧用日付別合計金額].売上日付集計用 = Q納品書レポート用空行あり.売上日付
ORDER BY Q納品書レポート用空行あり.売上日付, Q納品書レポート用空行あり.注文番号;