VBAを使わなくても大丈夫で、クエリとサブレポート(サブフォーム)を使えば実現できます。
考え方は「商品ごとに1行だけの親レポート」+「その中に4つのサブレポートを商品コードで連動させる」という形です。
① 各テーブル(繰越在庫・仕入・売上・在庫)に共通の商品コード(商品IDなど)を持たせ、リレーションを張ります。
② 商品A・商品B…と並ぶ「商品一覧クエリ」または商品マスタテーブルを作り、それを親レポートのレコードソースにします。
③ 繰越在庫用、仕入用、売上用、在庫用と、それぞれ商品別の明細を出すクエリを4つ作ります。
④ 親レポートで商品コードごとにグループを作り、そのグループヘッダ内に4つのサブレポートを配置します。サブレポートの「リンク親フィールド/リンク子フィールド」に商品コードを指定します。
⑤ 「全テーブルにない商品は出力しない」にしたい場合は、親レポートのレコードソースとなるクエリで、4つのテーブル(またはいずれか必要なテーブル)を商品コードで内部結合にしておけば、該当データが1つも無い商品は元から出てきません。
このように、レイアウトはレポートとサブレポート、抽出条件はクエリ側で工夫すれば、VBAなしで作成できます。
追記
結論としては、「商品テーブルを軸に4つのテーブルを外部結合し、どれか1つでもレコードがある商品だけに絞り込むクエリ」を作るとよいです。繰越在庫が無い商品も、仕入や売上があればきちんと出力できます。
やり方の一例を、クエリデザインビューで説明します。
1. 新規クエリを作成して、商品テーブル・繰越在庫・仕入・売上・在庫の5つを追加します。
2. 商品テーブルの「商品コード」と、各テーブルの「商品コード」をそれぞれ結んでリレーションを作ります。
その結合線をダブルクリックし、結合の種類で
「商品テーブルの全レコードと、結合フィールドが等しい他方テーブルのレコードだけを含める」
を選んでください。
これを4つのテーブルすべてに対して行います。
(商品テーブルを親、他4つを子にする片側外部結合にします)
3. クエリの出力に使いたい項目(商品テーブルの「商品コード」「商品名」など)だけをフィールド行に置きます。
4. 条件用として、繰越在庫・仕入・売上・在庫の各テーブルから「商品コード」フィールドをクエリグリッドに追加します。
これらは「表示」のチェックを外して、画面には出さないようにします。
5. その4つの「商品コード」列の抽出条件に、「どれか1つでも Not Null」という条件を付けます。
具体的には次の感じです。
繰越在庫.商品コード列の「抽出条件」行に Is Not Null
仕入.商品コード列の「または」行に Is Not Null
売上.商品コード列のさらに下の「または」行に Is Not Null
在庫.商品コード列のその下の「または」行に Is Not Null
つまり、4列それぞれに Is Not Null を書きますが、同じ行ではなく「または」の行をずらして書き、論理的に「繰越在庫がある または 仕入がある または 売上がある または 在庫がある」という条件にします。
6. 必要であれば、クエリプロパティで「固有の値」をはいにして、商品ごとに1行だけ出るようにします。
このクエリを親レポートのレコードソースにすれば、「どの明細テーブルにも1件も無い商品」はそもそもレポートに出てこず、繰越在庫が無くても仕入や売上があれば商品が出てくるようになります。サブレポート側は今までどおり商品コードでリンクさせれば大丈夫です。
追記
結論としては、「データの無いサブレポートはラベルごと非表示にする」処理を入れる必要があり、その部分だけは簡単なVBAを書くのが現実的です。
流れは次のとおりです。
1 メインレポート上のコントロールに名前を付けます
例
ラベル lblKurikoshi サブレポート subKuriko
ラベル lblShiire サブレポート subShiire
ラベル lblUriage サブレポート subUriage
ラベル lblZaiko サブレポート subZaiko
2 これらが置いてあるセクションのプロパティで「縮小可能」をはいにします
3 メインレポートの該当セクションの「書式設定時」イベントに次のようなコードを書きます
(セクション名は実際のものに変えてください)
Private Sub 明細区分_Format(Cancel As Integer, FormatCount As Integer)
Me.lblKuriko.Visible = Me.subKuriko.Report.HasData
Me.subKuriko.Visible = Me.subKuriko.Report.HasData
Me.lblShiire.Visible = Me.subShiire.Report.HasData
Me.subShiire.Visible = Me.subShiire.Report.HasData
Me.lblUriage.Visible = Me.subUriage.Report.HasData
Me.subUriage.Visible = Me.subUriage.Report.HasData
Me.lblZaiko.Visible = Me.subZaiko.Report.HasData
Me.subZaiko.Visible = Me.subZaiko.Report.HasData
End Sub
HasData が False のときは、そのサブレポートとラベルの Visible を False にして表示させません。
セクションを縮小可能にしているので、その行ごと詰まり、会社で使っているレポートと同じように、繰越在庫等が無い項目は印刷されなくなります。