Microsoft Access 掲示板

views
4 フォロー
6,278 件中 921 から 960 までを表示しています。
7
hiroton 2024/01/10 (水) 17:43:00 429d8@f966d

その他

移動日/移動月については軽く触れていますが、そのほか、後の処理の(楽をしたい)都合で日付データとして各月の1日に統一したデータで扱っています
レポートの表示はテキストボックスの書式の設定(YYYY年MM月)で対応しています

「抽出の最小日以前から保管個数がある場合」は考慮していません

その他、細かいところは適当なので(代替の背景色が有効のせいで微妙に表示がおかしいとか)そういう調整は必要です


こういう案件の場合、ワークテーブルを用意してゴリゴリしてからそれをレポートにとかってなるんですかねぇ

Noの連番取るのにVBA使わないとダメなの何か方法あるんじゃない?って思わなくもないけど、保管用のデータ作るとこと考えるとそっちがめちゃくちゃ遠回りになりそうだしなぁとか
「とりあえずやってみたらそれっぽくできたので公開してるだけ」なのでこういう手法どうなの?とかあればください

5
hiroton 2024/01/10 (水) 16:58:05 429d8@f966d

3.「存在しない月のデータ」をどう補完するか

「新しいデータを読み込んだ時、古いデータとの比較で月が離れていたら、データを挿入する」方法を取ります
「データ」はレポートのクエリを基に詳細セクションで読み込まれるので、「『移動月』でグループ化し、グループヘッダーを設置すると、『新しいデータと古いデータの間』」になります

このグループヘッダーを出力しなかったり、出力したり、たくさん出力するようにすれば、存在しないデータの補完ができます

移動月ヘッダーで表示する「区分」も「保管」のみなので、区分はラベルコントロールです
その他のテキストボックスはそれぞれ

No_補完
コントロールソース:(非連結)

移動月補完
コントロールソース:(非連結)

保管個数表示補完
コントロールソース:(非連結)

保管手数料単価補完
コントロールソース:=[保管手数料単価]

保管手数料補完
コントロールソース:=[保管個数表示補完]*[保管手数料単価]

です。存在しない月データの補完用のセクションなので全部「補完」とつけてるだけです
新しいレコードに移って捨てられてしまうデータをVBAで保存しておいて必要に応じて(非連結の)テキストボックスに設定、セクションの出力(繰り返し出力)をするとかそんな流れになっています

4
hiroton 2024/01/10 (水) 16:32:59 429d8@f966d

1.「保管」の累計個数をどう計算するか

入庫を足して在庫を減らして、それを積み立てれば累計(残在庫)です。ACCESSレポートではテンプレート的な用法があるのでそのまま使います

画像1
詳細セクションに「累計」テキストボックスを配置します

コントロールソース|=Nz([入庫数],0)-Nz([出庫数],0)
集計実行     |全体

詳細セクションでデータを表示する必要はないので枠線だけ表示されるように調整しています。(非表示+枠線は別なコントロールでとかでもいいです)

「移動月」でグループ化して、フッターを配置し、「保管」行として使います
「保管」専用の行なので「区分」はラベルコントロールでそのまま「保管」を表示、その他必要なテキストボックスを配置します

保管個数表示
コントロールソース|=[累計]

保管手数料単価
コントロールソース|=DLookUp("手数料単価","T_区分マスター","区分ID=3")

保管手数料
コントロールソース|=[保管個数表示]*[保管手数料単価]

2.「No」の連番をどう取得するか

「保管」データの累計計算のためにセクションを跨いでしまったのでVBAで計算・設定します
非連結のテキストボックスに、データが出力されるたび+1してデータを設定するだけです。「データが出力されるたび」がどんな時かきちんと把握しておく必要があります
画像1

今回は適当に上から「No_補完」「No_入出庫」「No_保管」という名前にしました


出力のタイトルは「移動日」ですが、元データに「移動日」フィールドがあるので、データ段階では「移動月」の名前になっています。レポートに配置するラベルで「移動日」と表示すればいいと思います
この「移動月」でグループ化してヘッダー・フッターを設置します。デフォルトでは「グループヘッダー0」「グループフッター0」のような名前になっていますが、解説用にそれぞれ「移動月ヘッダー」「移動月フッター」と名前を変えています。

移動月ヘッダーの使い方は次での解説がメインですが、「No」表記が必要なのでここでの解説に「No_補完」が紛れ込んでいます


連番を付けるだけ、でいいのであればよくある手法があるんですが、その他の要求と組み合わせるとどうするといいのか悩みどころですね

3
hiroton 2024/01/10 (水) 15:51:28 429d8@f966d

適当に「2024年3月に400個出庫」のデータを加えたサンプル
画像1

hirotonは「簡単な手法」が思い浮かばなかったので覚悟してください
複雑な要件なので問題を分解します

1.「保管」の累計個数をどう計算するか
2.「No」の連番をどう取得するか
3.「存在しない月のデータ」をどう補完するか

回答としては一緒くたにやっていますが、どの問題を解決するためのものなのか考えながら見てください

レポートのレコードソースのクエリ

SELECT
    T_入出庫一覧.区分,
    [移動日] - Day([移動日]) + 1 AS 移動月,
    Sum(IIf(
            [区分ID] = 1,
            [合計]
        )) AS 入庫数,
    Sum(IIf(
            [区分ID] = 2,
            [合計]
        )) AS 出庫数,
    T_区分マスター.手数料単価,
    Sum([手数料単価] * [合計]) AS 手数料
    T_区分マスター.区分ID,
FROM
    T_入出庫一覧
    INNER JOIN
        T_区分マスター
    ON  T_入出庫一覧.区分 = T_区分マスター.区分
GROUP BY
    T_入出庫一覧.区分,
    [移動日] - Day([移動日]) + 1,
    T_区分マスター.手数料単価,
    T_区分マスター.区分ID
ORDER BY
    [移動日] - Day([移動日]) + 1,
    T_区分マスター.区分ID
;

上記クエリによるレポート出力用の基礎データ例
画像1

レポートのモジュール

Option Compare Database
Option Explicit

Dim No As Long
Dim 保管月 As Date
Dim 保管個数 As Long

Private Sub Report_Load()
    保管月 = DateAdd("M", -1, Me!移動月)
End Sub

Private Sub 移動月フッター_Format(Cancel As Integer, FormatCount As Integer)
    No出力 Me!No_保管
    
    '//補完用データ確保
    保管月 = Me!移動月
    保管個数 = Me!保管個数表示
End Sub

Private Sub 移動月ヘッダー_Format(Cancel As Integer, FormatCount As Integer)
    If Me!移動月 = DateAdd("M", 1, 保管月) Then
        Cancel = True
        Exit Sub
    End If
    
    '//前のレコードが2月以上前なのでデータ補完
    No出力 Me!No_補完
    
    保管月 = DateAdd("M", 1, 保管月)
    Me!移動月補完 = 保管月
    Me!保管個数表示補完 = 保管個数
    
    Me.NextRecord = False
End Sub

Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    No出力 Me!No_入出庫
End Sub

Private Sub No出力(ctl As TextBox)
    No = No + 1
    ctl = No
End Sub

レポートのデザイン
画像1画像1

2
My Car Bomber 2024/01/10 (水) 13:32:56 7fdfc@44ebd >> 1

両方あり得ます。
入庫・出庫が同一月に発生する場合、1行目入庫、2行目出庫、3行目保管になるようにしたいと考えています。

1
hiroton 2024/01/10 (水) 13:16:57 429d8@f966d

とりあえず確認

「入庫」「出庫」が同一月に発生することはありますか?その場合どのような表示になりますか?
「入庫」「出庫」が発生せず、「保管」だけが発生する月はありますか?

5

ありがとうございました。テキストボックス配置しましたら思い通りになりました。
ACCESSレポートは複雑でこんな方法は全く知りませんでした。
このグループだけレポートフッターに配置した他のデータから参照した値を含めた合計で表示したかったのです。
お世話になりました。

4
My Car Bomber 2024/01/10 (水) 10:43:13 7fdfc@44ebd >> 3

ありがとうございます!
非連結にすればよかったのですね。

回答頂けるまでにいろいろ試して、区分・商品1~4・合計・移動日・在庫移動日・発注日フィールドを持つtmpテーブルを作成し、こちらをレコードソースにしてフォーム作成しました!

3

結果が1件だけなら、いろいろ方法はありますが、
フォームの「在庫移動日」は非連結テキストボックスにしておきます。そうすれば入力可能になります。

レコードソースの集計クエリをもとに追加クエリを作成して、追加先は「T_入出庫状況」にします。
追加元と追加先の対応するフィールドを設定して、次に新規列に下記の設定をします。

フィールド在庫移動日: Forms!フォーム名!在庫移動日
テーブル集計クエリ名
レコードの追加在庫移動日

SQLだと下記のようなになります。

INSERT INTO T_入出庫状況 (区分, 商品1, 商品2, 商品3, 商品4, 合計, 在庫移動日)
SELECT 区分, 商品1, 商品2, 商品3, 商品4, 合計, Forms!フォーム名!在庫移動日 AS 在庫移動日
FROM 集計クエリ;

フォーム上にコマンドボタンを配置して、そのクリック時にこの追加クエリを実行するようにすればいいでしょう。

4

グループフッターに大分類IDフィールドをテキストボックスとして配置してください。
大分類IDを表示したくない場合は「可視」を「いいえ」にします。

3

ありがとうございました。コードを下記で記述したのですが 『***大分類IDフィールドが見つかりません』のエラーが出ました。(大分類IDでグループ化してまして、それの3を非表示にしたい)
Private Sub グループフッター1_Format(Cancel As Integer, FormatCount As Integer)
  Cancel = [大分類ID] = 3
End Sub
コードの記述が間違ってますでしょうか?

2
My Car Bomber 2024/01/10 (水) 08:40:41 7fdfc@44ebd >> 1

"T_発注書取込"テーブルの構成は
取込ID(オートナンバー)主キー
No(数値)
社名(短いテキスト)
〒(短いテキスト)
住所(短いテキスト)
TEL(短いテキスト)
商品1(短いテキスト)
商品2(短いテキスト)
商品3(短いテキスト)
商品4(短いテキスト)
発注日(日付/時刻)

発注日が複数日に渡ることはないので、グループ化で結果は1件だけになります。

1

この集計クエリの結果は1件だけですか。それとも複数件になりますか。

複数件の場合は、「在庫移動日」はすべて共通でいいのですか。それともレコード毎に異なるものを入力しますか。

それ以前に、現状のテーブルのフィールド構成はどうなってますか。
主キー設定も含めて提示してください。

9

この取得した日付をT_発注書取込の発注日フィールドに書き込む記述は、msgboxのところを書き換えればよいでしょうか?

はい、そうです。
とりあえず試してみてうまく行かない場合、質問してください。

2

フォーマット時イベントのCancel引数をTrueにすれば、そのセクションの出力を停止できます。

Private Sub グループフッター0_Format(Cancel As Integer, FormatCount As Integer)
    Cancel = Me!グループキー = "(非表示にするグループキー)"
End Sub
1
hiroton 2024/01/09 (火) 17:05:32 修正 429d8@f966d

そのグループフッターの可視プロパティをフォーマット時イベントで制御すればいいかな?

Private Sub グループフッター0_Format(Cancel As Integer, FormatCount As Integer)
    Me.Section("グループフッター0").Visible = Me!グループキー <> "(非表示にするグループキー)"
End Sub

※各名称は適切なモノに置き換えてください

27
亞紀姐 2024/01/09 (火) 15:46:02 6b68c@61731

また、

Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    Dim j As Integer
    Dim i As Integer

    For j = 51 To 57
        Me.DrawStyle = 0
        Me.Line (Me("L" & j).Left, 0)-(Me("L" & j).Left, 144000)
    Next
        
'     For i = 2 To 12
'        Me.DrawStyle = 2
'        Me.Line (Me("L" & i).Left, 0)-(Me("L" & i).Left, 144000)
'     Next

    WordWrapOff Me.NAS用, Me.txtFld1
    
Me.NAS用.FELineBreak = False
Me.txtFld1.FELineBreak = False

End Sub

とし、詳細セクションのフォーマットイベントにあった罫線スタイルの指定をなくしたところうまくいきました。
(前はここがダブってしまっていて、線がきれいに点線になっていませんでした。)

大変失礼しました。

以上にて無事に担当に提出することが出来ました。
本当に長々とありがとうございました。

26
亞紀姐 2024/01/09 (火) 15:45:47 6b68c@61731

以下の様に修正しました。

Private Sub Report_Page()
On Error GoTo Err_Report_Page

Dim LineTop As Long, LineLeft As Long, LineWidth As Long, LineBottom As Long, SecHight As Long
Dim i As Integer

    With Me
        LineTop = .ページヘッダーセクション.Height + .グループヘッダー0.Height
        LineLeft = .直線355.Left
        LineWidth = .直線372.Width
        LineBottom = 21 * 567 - Me.Printer.BottomMargin - Me.Section(acPageFooter).Height
        SecHight = Me.詳細.Height

        '縦罫線 内側
        For i = 2 To 19
            If i = 8 Then .DrawStyle = 2
            If i = 19 Then .DrawStyle = 0
           Me.Line (Me("lbl" & i).Left, LineTop)-(Me("lbl" & i).Left, ((21 - 0.5 - 3.998) * 567) - 90)
        Next

        '太線 の太さをここで指定
        .DrawWidth = 12
        
        '外枠
         Me.Line (LineLeft, LineTop - .直線355.Height)-(LineLeft + LineWidth - 10, ((21 - 0.5 - 3.998) * 567) - 90), , B
         Me.Line (LineLeft, ((21 - 0.5 - 3.998) * 567) - 95)-(LineLeft + LineWidth - 10, ((21 - 0.5 - 0.5) * 567) - 300 - .直線385.Height), , B

    End With

Exit Sub
Exit_Report_Page:
    Exit Sub

Err_Report_Page:
Select Case Err.Number
Case 2501
MsgBox "印刷するデータは有りません。", vbOKOnly
Resume Exit_Report_Page

Case Else
MsgBox Err.Number & " : " & Err.Discription
Resume Exit_Report_Page

End Select
End Sub
25
亞紀姐 2024/01/09 (火) 15:45:35 6b68c@61731

通貨型、無事にできました!
ありがとうございます!!

縦罫線に関しては前の質問でもページフォーマット時(Report_Page)でやればいいのでは?と回答してますが、うまくいかなかったんでしょうか?

失礼しました。
何かで作業途中になっていました…

24
hiroton 2024/01/09 (火) 13:53:59 429d8@f966d

不思議な現象ですねぇってことで書式「通貨」に設定したテキストボックスでテストをしてみました

Dim s As String
s = Format(Me!テキスト3, Me!テキスト3.Format)
Debug.Print s; Asc(s); AscW(s); Me!テキスト3.Format

s = "\30"
Debug.Print s; Asc(s); AscW(s)

結果

\30 92  165 Currency
\30 92  92 

書式「通貨(Currency)」で使われる円記号はUnicodeのA5のようです。PrintメソッドがUnicodeに対応していないので文字化けするとかじゃないですかねぇ

文字コードの変換を入れてあげると円記号が表示できます

s = Format(.Value, .Format) 'テキストボックスの書式プロパティで書式化
s = StrConv(s, vbNarrow) 'Printメソッドでの描画用に変換

縦罫線に関しては前の質問でもページフォーマット時(Report_Page)でやればいいのでは?と回答してますが、うまくいかなかったんでしょうか?

23
亞紀姐 2024/01/09 (火) 11:59:56 修正 6b68c@61731

ありがとうございます。

1.数字を桁区切り+¥がついた通貨型で表示したい

テキストボックスは非表示にして、Printメソッドで表示してますので、そちらの方を修正する必要があります。

1.の通貨型なのですが画像1
のような設定なのですが(日本円設定です)
画像2
になってしまいます。
他に設定しなくてはいけない部分があるのでしょうか?

2.指定した場所から左揃えではなく右揃えで表示したい

2.の右揃えは出来ました。
ありがとうございます。

3.同じような書式設定にしたいものが複数あるが、同じコードを繰り返す以外のやり方はないのか?

3.のこちらも出来ました。
ありがとうございます。

追加の質問で申し訳ないのですが
画像1
4.詳細セクションとグループフッターセクションのつなぎ目の部分で縦の罫線が微妙にずれます(画像の右縦線参照)
左位置は表示されている小数点第3位まで同じです。
しかし、設定上プロパティの左位置に数字を入力しても丸められているのか飛び飛びになるので実際にずれているのかもしれません。
これを画像の左縦線の様にまっすぐあわせるのは難しいのでしょうか?

5.画像の「6」が入力されている行が詳細セクションの(このページでの)最終行でその下がグループフッターセクションで作った空行なのですが、詳細セクションとグループフッターセクションの間に隙間ができてしまいます。
縦線の長さは全て一致して、セクションの高さも最小値(恐らく縦線の長さ+横下線の太さ分)になっていますがそれでも隙間が空きます。
また、縦線だけあえて少し長くしてみると
画像1
一番下の空白部分に線がはみ出します(当たり前)
一番下にはみ出さず、セクション間に隙間を作らない方法は何かありませんでしょうか?


尚、補足ですが詳細セクションとグループヘッダーセクションやグループフッターセクションページフッターセクションとの間には太線が引かれているため隙間があるのかもしれませんが隠れてしまい見た目上隙間は無いようになっています。

段々とずれてきてしまいすみません。
あと少しだと思うのですが、もう少しよろしくお願いします。

8
Anonymous 2024/01/09 (火) 10:58:42 修正 7fdfc@44ebd >> 6

エラーが出ていたためまだ実行結果を見ていませんでした。
もう一度コピペし直したところエラーは出なくなりました。

あと、読解が間違っていたようです。(2024.1.9)でもpos1=8、pos2=17なのでl=8で条件式に入りますね。

この取得した日付をT_発注書取込の発注日フィールドに書き込む記述は、msgboxのところを書き換えればよいでしょうか?

7

こちらのコードを試したところ、Beref引数の型が一致しませんとエラーが出るのですが、どうすればよろしいでしょうか?

そのエラーがでるのはどの行ですか。エラーのでる行を提示してください。

また、このコードの読解をしていたところ、8文字かそれ以上でなければ日付かどうか判定する条件式に入らないと思うのですが、ファイル名が発注書(2024.1.9).xlsxのように8桁ではない場合、どうすればよいでしょうか?

こちらで試してみましたが「発注書(2024.1.9).xlsx」でも問題なく 2024/01/09 という日付が返りますが。
実際に試してみましたか。

22
亞紀姐 2024/01/09 (火) 10:23:05 6b68c@61731 >> 17

ありがとうございます。

命名規則に抵触しているのだろうと探していたのですが「こういう風につけましょう」しか見つけられず、「ダメな理由」を見つけることが出来ずにいたのでとても助かりました。

今あるものを確認して修正します。

6
Anonymous 2024/01/09 (火) 09:36:38 修正 7fdfc@44ebd >> 1

こちらのコードを試したところ、Beref引数の型が一致しませんとエラーが出るのですが、どうすればよろしいでしょうか?
また、このコードの読解をしていたところ、8文字かそれ以上でなければ日付かどうか判定する条件式に入らないと思うのですが、ファイル名が発注書(2024.1.9).xlsxのように8桁ではない場合、どうすればよいでしょうか?

21

3.同じような書式設定にしたいものが複数あるが、同じコードを繰り返す以外のやり方はないのか?

テキストボックス名が、
txt_1月, txt_2月 ・・・・txt_12月
だとして、
Controlsで文字列のテキストボックス名でアクセスできますので、
それを利用してループ処理します。

    Dim i As Long
    For i = 1 to 12
        With Me.Controls("txt_" & i & "月")
            .Visible = False
            If Not IsNull(.Value) Then
                Me.FontSize = .FontSize
                Me.FontName = .FontName
                Me.CurrentX = .Left + 26 '//26は位置調整のための数字
                Me.CurrentY = (Me.Height / 2) - (Me.TextHeight(.Value) / 2)
                Me.Print .Value
            End If
       End With
    Next
20

1.数字を桁区切り+¥がついた通貨型で表示したい
2.指定した場所から左揃えではなく右揃えで表示したい

テキストボックスは非表示にして、Printメソッドで表示してますので、そちらの方を修正する必要があります。

    Dim s As String
    With Me.請受金額月額
        .Visible = False
        Me.FontSize = .FontSize
        Me.FontName = .FontName
        s = Format(.Value, .Format) 'テキストボックスの書式プロパティで書式化
        Me.CurrentX = .Left + .Width - Me.TextWidth(s) '左寄せ
        Me.CurrentY = (Me.Height / 2) - (Me.TextHeight(.Value) / 2)
        Me.Print S
    End With
19

本題から遠いので個別に

『Me.1月』にするとエラーになってしまい

ニンゲンが記述するものはすべて「文字」なので、それが計算してほしいモノ(計算式)なのか、名前の指定なのかはそれだけでははっきりとしません
例えば「1 + 1」という名前のテキストボックスを作ったらそれを指定するときはどうしたらいいでしょうか?

ACCESSは開発を楽にするためにある程度自動認識でこれらの判別をしています
Me.1月という記述はその自動認識によって構文エラーとなるような記述ということですね

それがオブジェクトの名前による指定であると明記する場合には[]で囲みます。Me.[1月]とすれば正常に動作します


命名規則(の一部)というやつですが、どんな文字でもいいからと言って本当にどんな名前にしてもいいというわけではないということですね

可能な限り数字や記号から始まる名前を付けるのはやめましょう

18
hiroton 2024/01/06 (土) 08:52:08 b2999@f966d

適当にサンプルで作ったのはこんな感じですね
画像1

オブジェクトの表示にはいろんな「隙間」があるので影響あるものを見つけて適切に調整する必要はあると思います

17
亞紀姐 2024/01/05 (金) 21:53:41 6b68c@61731 >> 16

1.数字を桁区切り+¥がついた通貨型で表示したい
2.指定した場所から左揃えではなく右揃えで表示したい
3.同じような書式設定にしたいものが複数あるが、同じコードを繰り返す以外のやり方はないのか?

1に関しては
上記のコードだと下記の画像の様に桁区切りも¥もない数字になってしまい、以下を試しました。
.text → SetFocusがレポートの印刷プレビューではできない
.Value → 値を代入できないとエラーが出る
.Format = "Currency" → 何も変化なし
Me.請受金額月額 = Format(Me.請受金額月額, "\#,##0") → エラーで進まない
という感じで、結局希望する「協力会社1回金額」のような表示にはできませんでした。

2に関しては
上記コードだと左揃えだったので

        Me.CurrentX = .Left + (Me.Width / 2) - (Me.TextWidth(.Value) / 2)

としたらテキストボックスよりもだいぶ右の方に表示されました。

尚、よくわからずに

        Me.CurrentX = .Right

にしてみましたが、当然エラーでした。

3に関しては
まず、レコードによっては値がNullの場合があるため上記のコードにしています。

画像1

テキストを上下中央に配置したいテキストボックスは
テキストが1行のものが15(画像の請求回数・請受金額月額・協力会社1回金額・txt_1月~12月まで)、複数行の可能性があるものが2(協力会社名・作業内容)ありますが、複数行表示の可能性があるものは最悪このままでも、と思っていますが上記のようなコードをあと13書くのはコードがかなり冗長になるので避けたいと思いつつ、いい方法が見つけられませんでした。
(余談ですが、当初テキストボックスの名前が「1月」だったのですが、『Me.1月』にするとエラーになってしまい上記の様に『txt_1月』に変更しました。エラーの理由(規則?)を探しましたが見つけられませんでした)

1~3に関し、どうにかクリアしたいのですがもう少し教えていただけると助かります。(当初の質問とずれて来てすみません、問題があるようでしたら新たなスレッドを立てます)
よろしくお願いします。

16
亞紀姐 2024/01/05 (金) 21:51:05 修正 6b68c@61731

色々試したのですがhirotonさまのコード、短くてできればそれにしたかったのですが、真ん中にはなってくれず…
hatenaさまの以下の上下中央(レス番号12)コードを元に上下中央にしたいテキストボックス全てに書く方式になりそうです。
【参考コード】

Private Sub 詳細_Print(Cancel As Integer, PrintCount As Integer)
    
    With Me.テキストボックス1
        .Visible = False
        Me.FontSize = .FontSize
        Me.FontName = .FontName
        Me.CurrentX = .Left
        Me.CurrentY = (Me.Height / 2) - (Me.TextHeight(.Value) / 2)
        Me.Print .Value
    End With
    
End Sub

【現状のコード】

Private Sub 詳細_Print(Cancel As Integer, PrintCount As Integer)
    
    With Me.請受金額月額
        .Visible = False
        .Format = "Currency"
        Me.FontSize = .FontSize
        Me.FontName = .FontName
        Me.CurrentX = .Left 
        Me.CurrentY = (Me.Height / 2) - (Me.TextHeight(.Value) / 2)
        Me.Print .Value
    End With
     
    If IsNull(Me.txt_1月) = False Then
     If IsNull(Me.txt_1月) = True Then Me.txt_1月 = Me.txt_1月
       With Me.txt_1月
        .Visible = False
        Me.FontSize = .FontSize
        Me.FontName = .FontName
        Me.CurrentX = .Left + 26 '//26は位置調整のための数字
        Me.CurrentY = (Me.Height / 2) - (Me.TextHeight(.Value) / 2)
        Me.Print .Value
       End With
    End If

End Sub

ただ、以下のことが出来ずに半日悩んでいました。

2
Happy87 2024/01/05 (金) 17:57:31

hatenaさま

 早速なるアドバイスをいただき、ありがとうございました(深々お辞儀)。

 自分が想定していた内容、そのものズバリを解りやすく書いていただき、腑に落ちました。

 当人が何故「テーブルのコピー」→「リネーム」を洗い替えできていると認識しているのかは
 相変わらずナゾですが(しかも自称SE・・・)、

 とりあえず「データベースの最適化/修復」を定期的に行うように何とか説得をして、
 業務手順資料も修正してもらうように働きかけをしておきます。

  それにしても、自称って困りものですね。。。(何を言っても耳を貸さないので)
 

1

まず、データベースのデータの管理方法は、エクセルのブックなどのファイルの管理方法とは異なります。
ブックならディスクからメモリ上に読み込んで、更新後ディスクに上書きします。
つまりディスク上のデータ位置は連続しているし、データの順番も固定されています。

Accessの場合は、テーブルデータの更新、削除、追加した場合、データの連続性、データの並び順は保証されません。
更新した場合同じ位置に上書きされるとは限りません。
削除した場合、実際に削除されるわけではなく削除フラグを立てるだけです。
追加した場合、ファイルの最後に追加されるわけでもありません。
これは大量のデータを扱うデータベースに最適化された設計です。

つまり更新、削除、追加を繰り返すと、データの連続性はなくなり、データの並び順もごちゃごちゃになります。
このままではファイルサイズは肥大して、パフォーマンスも落ちます。
データ破損の危険性も高まります。

この非連続性を解消して、並び順もキーフィールドに合致するようにするのが「データベースの最適化/修復」という処理です。
Accessデータベースにおいて定期的な「データベースの最適化/修復」というのは必須といえます。

「テーブルのコピー」→「リネーム」で解決できる場合もあるかもしれませんが、それでは上記の非連続性は解消されませんので根本的な解決にはならないでしょう。
また、データペースにおいて、リレーションシップが設定されていれば、コピー→リネームの前にリレーションシップの削除、リネーム後にリレーションシップの再設定という作業も必要になり煩雑になります。設定ミスで破損なんてことにもなりかねません。

「データベースの最適化/修復」でやっていることは、元のデータベースファイルからデータをキーフィールドの並び順に読み込んで、新規データベースファイルに書き込むという処理をして、完了後に元のファイルを削除して新規ファイルをリネームするということをしています。つまり「洗い替え」をしているということだと思います。

経験上「データベースの最適化/修復」を定期的にやっていればめったに破損することはないです。
ただ、絶対破損しないということはないし、「データベースの最適化/修復」で修復できない場合もないとは言えないので、定期的にデータベースファイルのバックアップを取るという運用も必須でしょう。

15

Printイベントでは多くのプロパティが変更できません
そんな中でも余白のプロパティは変更できるようです

高さのプロパティは変更できないので、印刷時拡張が設定されたテキストボックスと表形式のレイアウトを組んでおくことで高さが揃うようにします

おお!!素晴らしいアイデアですね。
印刷時でも余白は変更できるとは思いもよりませんでした。
表形式のレイアウトで高さを揃えるというのも思いつきませんでした。

印刷時拡張後の高さは印刷時拡張プロパティを「はい」にしたコントロールから取得できます(詳細セクションの高さでは取得できませんでした)

これには関しては、Me.Height でカレントセクションの印刷時拡張時の高さを取得できます。

3

お二方とも、お返事ありがとうございます。

btn決定 → cbo選択肢_AfterUpdate → cbo選択肢_BeforeUpdate → Form_Close → Form_Load
みたいなのを見ると もやもや するわけですけど、
VBEの「モジュール全体を連続表示」では、
プロシージャが長い、多い状態になるとスクロールしてる場合じゃないですよね。
Word のナビゲーションウィンドウのようなものも無く。

私はひとり情シスですが、詳しいお二方のご意見を伺えてよかったです。
ありがとうございました。

14
hiroton 2024/01/05 (金) 14:35:20 05530@f966d

いろいろ試してみました
Formatイベント/Printイベントで出来ること/できないことできないことむずかしいですねぇ

「Ctl1月」テキストボックスは「自社用」テキストボックスと同時に選択してレイアウト→表形式にしておきます

Dim h As Long

Private Sub Report_Load()
    h = Me!Ctl1月.Height
End Sub

Private Sub 詳細_Print(Cancel As Integer, PrintCount As Integer)
    Me!Ctl1月.TopMargin = (Me!自社用.Height - h) / 2
End Sub

hは固定値なので直接記述してもいいかなとも思います
例)

Private Sub 詳細_Print(Cancel As Integer, PrintCount As Integer)
    Me!Ctl1月.TopMargin = (Me!自社用.Height - 270) / 2 '//270は元のMe!Ctl1月.height
End Sub

Printイベントでは多くのプロパティが変更できません
そんな中でも余白のプロパティは変更できるようです

高さのプロパティは変更できないので、印刷時拡張が設定されたテキストボックスと表形式のレイアウトを組んでおくことで高さが揃うようにします

印刷時拡張後の高さは印刷時拡張プロパティを「はい」にしたコントロールから取得できます(詳細セクションの高さでは取得できませんでした)

13

読み込み時のはエラーが出る原因の話だけですね、>> 11でhatenaさんにも補足していただいていますが

Private Sub Report_Load()
    ReDim h(1 To Me.件数) '配列のサイズをレコード数分に設定
End Sub

だけで済むので簡単です。(デフォルトでは存在しないレポートヘッダーの組み込みも不要です)

やりとりを軽く眺めていましたが、そもそも「フォーマット時Me.詳細.Heightがうまく取得できない問題」が問題なのに、hatenaさんのコードもフォーマット時Me.詳細.Heightを使っているのでうまくいかないんじゃないかなーって思ってたのでその通りになったなーって印象です

12
hatena 2024/01/05 (金) 11:49:50 修正

下記はテキストボックス1のテキストを上下中央に表示します。

Private Sub 詳細_Print(Cancel As Integer, PrintCount As Integer)
    
    With Me.テキストボックス1
        .Visible = False
        Me.FontSize = .FontSize
        Me.FontName = .FontName
        Me.CurrentX = .Left
        Me.CurrentY = (Me.Height / 2) - (Me.TextHeight(.Value) / 2)
        Me.Print .Value
    End With
    
End Sub
11
hatena 2024/01/05 (金) 11:31:03 修正

Report_Loadならレポートヘッダがなくても動作するのでそれがいいですね。

上下中央に配置するテキストが画像のように金額だったり、「〇」だけなら、
印刷時イベントでPrintメソッドで出力する方法がいいですね。
これなら配列に高さを格納するコードは不要です。

Report.Print メソッド (Access) | Microsoft Learn

印刷時拡張で2行以上になる場合とかは使えないですし、ユニコード非対応なのでS-Shiftにない文字があると文字化けするのでその場合は、使えませんが。

2

私もhirotonさんと同じですね。
「必要なモノを適切な名前で、適切なモジュール内に記述」
この一言で言いつくされていると思います。

大きなプロジェクトだとプロシージャだけで百をこえることは普通ですし、追加、修正のたびにどのような順が適切かなんて考えてないです。
いかに適切な名前をつけるかに集中ですね。