https://zawazawa.jp/ms-access/topic/995
で質問した表は無事方向性が決まりました。
その節はありがとうございました。
その表について、社内からタイトル通り、高さが可変のテキストボックスの上下中央に文字を配置してほしいと要望がありました。
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.自社用, Me.txtFld1
Me.自社用.FELineBreak = False
Me.txtFld1.FELineBreak = False
Me.Ctl1月.TopMargin = IIf(Me.自社用.Height = 1.376 567, ((1.376 - 0.23) / 2) 567, ((Me.自社用.Height) / 2) - 0.23 * 567)
End Sub
そこで、赤字の部分を足しました。
(0.23はFontsize11の文字の実高さ3.2mmより、実施の枠の高さとACCESS上の設定された高さを比較し、Fontsize11の設定上の高さを算出したものです)
(可変部分はテキストボックス「自社用」で、「ビル名2」は固定高です)
結果、可変に対応できず、では、と思って詳細セクションの高さで判断…と思ったのですが、印刷時拡張後の高さは、印刷時イベントでないと取得できないというものを見、
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10136666480
それでは、と詳細セクションの印刷時イベントで
Me.Ctl1月.TopMargin = IIf(Me.詳細.Height = 1.376 567, ((1.376 - 0.23) / 2) 567, ((Me.詳細.Height) / 2) - 0.23 * 567)
といれて見たのですが、どちらも上から固定の高さのところに表示されてしまいました。
助けていただけましたら助かります。
お手数おかけしますがどうぞよろしくお願い申し上げます。
フォーマット時イベントで関係する設定を計算してレイアウトを決定します。印刷時イベントでは、それを出力するだけですので、印刷時ではレイアウトは変更できません。
印刷時拡張後の高さは印刷時にしか取得できない、しかし、レイアウト変更は印刷時ではできない、レイアウトの設定には印刷時拡張後の高さが必要である、
ということで普通の方法では不可能な状態です。
そこで利用するのが、下記で紹介している総ページを取得するときのダミーのフォーマット時イベントです。
レポートのイベントの発生メカニズムの研究 その2 - hatena chips
総ページを取得するために最終レコードまでダミーのフォーマット時イベントを発生させる。
その後、先頭に戻って、本番のフォーマット時、印刷時イベントを発生させて実際に出力する。
という動作になってます。
これを利用して、下記のような処理にします。
ダミーのフォーマット時に配列に各行毎の印刷時拡張後の高さを格納しておく。
本番のフォーマット時に配列から印刷時拡張後の高さを取得してそれをもとにレイアウトを設定する。
レポート上のどこでもいいので、総ページ数を取得するためにコントロールソースが
=[Pages]
のテキストボックスを配置しておく。(すでに総ページ数を表示するためのテキストボックスがあるなら不要)下記のような感じでレイアウトを設定できます。
ありがとうございます。
レポート上には
「=Int(([番号]/6)+0.9) & "頁/" & Int((Count([ビル名])/6)+0.9) & "頁中"」
というテキストボックスがあるのですが、多分それだとうまく作動しないのでは、と思い
「=[Pages]」
という非可視のテキストボックスを作りました。
コードに関しては、現状のコードに追加する形で
Option Compare Database
Option Explicit
'Dim d As Object ' Dictionary オブジェクト用変数
Const A4Height As Long = 21 * 567 'A4用紙の高さ=29.7cm、横の場合=21.0cm、1cm=567twips
Dim PageHeight As Long
Dim h() As Long '印刷時拡張後の高さを格納する配列
'開くとき
Private Sub Report_Open(Cancel As Integer)
' Set d = CreateObject("Scripting.Dictionary")
'印刷可能領域下辺のページ上端からの高さを取得
On Error Resume Next
PageHeight = A4Height - Me.Printer.BottomMargin
PageHeight = PageHeight - Me.Section(acPageFooter).Height
ReDim h(1 To Me.Recordset.RecordCount) '配列のサイズをレコード数分に設定
End Sub
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
If Me.Pages = 0 Then 'ダミーのフォーマット時はPages=0
h(Me.CurrentRecord) = Me.詳細.Height
Else
Dim exHeight As Long
exHeight = h(Me.CurrentRecord)
'exHeightに拡張後の高さが格納されているのでそれを利用してレイアウトを設定
End If
End Sub
としました。(最後のEnd Ifは対応するIfがない、としてエラーになったため削りました)
しかし、「h(Me.CurrentRecord) = Me.詳細.Height」のところで「インデックスが有効範囲にない」と言われて見ることが出来ませんでした。
何か他に直さなくてはいけないところがあるのでしょうか?
よろしくお願いします。
削らないでください。必要です。
それでエラーになるなら、提示のコードが実際のものとは異なっていると思います。
実際のコードをコピーして貼り付けてください。
コードはマークダウンのコードブロックにいれてください。
詳細は下記を参照ください。
Microsoft Access 掲示板 の使い方 Microsoft Access 掲示板 - zawazawa
Me.Recordset.RecordCount
はレポートでは使えないようですので、下記に修正してください。まずレポートヘッダーかレポートフッターにテキストボックスを配置して下記のように設定してください。
名前 件数
コントロールソース =Count(*)
可視 いいえ
あと、下記の部分はそちらのレポートの設定にあわせて、ご希望のレイアウトになるようにコードを記述してください。こちらではそちらのレポートの設定は分かりませんので。
>> 1
じゃないっすかね?
あっ、間違えてますね。
hirotonさん、ご指摘ありがとうござます。
ありがとうございます。
返答が遅くなりすみません。
上記のように変更し、以下のコード(全部コピーしました)にしましたが、やはり同じところで止まってしまいます。
(>しかし、「h(Me.CurrentRecord) = Me.詳細.Height」のところで「インデックスが有効範囲にない」と言われて見ることが出来ませんでした。)
Me.CurrentRecord にマウスオーバーすると「1」と表示され
Me.詳細.Height にマウスオーバーすると「798」と表示され
h にマウスオーバーすると「h(Me.CurrentRecord) = <インデックスが有効範囲にありません>」と表示されます。
あと、
>あと、下記の部分はそちらのレポートの設定にあわせて、ご希望のレイアウトになるようにコードを記述してください。こちらではそちらのレポートの設定は分かりませんので。
の部分なのですが、すみません。意味がよくわからなかったので一旦そのままにしてあります。
まずは表示ができるようにと思い、エラーを消したいのですが
まだ誤っている部分があるかを教えていただけると助かります。
尋ねてばかりですみません。
よろしくお願いいたします。
Report_Open時では件数は取得できませんでした。
Report_Open内の下記のコードを削除して、
レポートヘッダーのフォーマット時のイベントプロシージャを下記のように記述してください。
印刷時拡張後のセクションを高さを取得する方法を回答してます。
取得した高さを利用して、ご希望のレイアウトに設定するコードは亞紀姐さんが自分で考えて書いてくださいということです。
やはり同じところで同じエラーが出ます。
何か提示し足りない情報があるということですよね…
コードはこれが全部なので足りないとなると、元になるクエリとかレポートの設定なのでしょうか…
それとももう諦めたほうが良いのでしょうか…
レポートヘッダーを使っていない、または、レポートヘッダーのフォーマット時に
[イベント プロシージャ]
が設定されていないとか?ちょっと試してみましたが
ReDim h(1 To Me.件数)
はレポートの読み込み時(Report_Load
)にやるのがオススメですかねありがとうございます!
コードは書かれていたのですが、まさに
>レポートヘッダーを使っていない、または、レポートヘッダーのフォーマット時に[イベント プロシージャ]が設定されていないとか?
これでした!
コードに書いたらそこに記載されると思い込んでいました。失礼しました…
これで無事表示できるようになりました。
しかし、やっぱり元々希望している
【行の高さに係わらず、上下中央にテキストを配置】
ができません…(画像参照)
なお、hirotonさまの仰る
>ちょっと試してみましたがReDim h(1 To Me.件数)はレポートの読み込み時(Report_Load)にやるのがオススメですかね
も、hatenaさまの仰るレポートヘッダーのフォーマット時もどちらも試しましたが結果は同じでした。
読み込み時のはエラーが出る原因の話だけですね、>> 11でhatenaさんにも補足していただいていますが
だけで済むので簡単です。(デフォルトでは存在しないレポートヘッダーの組み込みも不要です)
やりとりを軽く眺めていましたが、そもそも「フォーマット時に
Me.詳細.Height
がうまく取得できない問題」が問題なのに、hatenaさんのコードもフォーマット時でMe.詳細.Height
を使っているのでうまくいかないんじゃないかなーって思ってたのでその通りになったなーって印象ですReport_Loadならレポートヘッダがなくても動作するのでそれがいいですね。
上下中央に配置するテキストが画像のように金額だったり、「〇」だけなら、
印刷時イベントでPrintメソッドで出力する方法がいいですね。
これなら配列に高さを格納するコードは不要です。
Report.Print メソッド (Access) | Microsoft Learn
印刷時拡張で2行以上になる場合とかは使えないですし、ユニコード非対応なのでS-Shiftにない文字があると文字化けするのでその場合は、使えませんが。
下記はテキストボックス1のテキストを上下中央に表示します。
いろいろ試してみました
Format
イベント/Print
イベントで出来ること/できないことできないことむずかしいですねぇ「Ctl1月」テキストボックスは「自社用」テキストボックスと同時に選択してレイアウト→表形式にしておきます
h
は固定値なので直接記述してもいいかなとも思います例)
Print
イベントでは多くのプロパティが変更できませんそんな中でも余白のプロパティは変更できるようです
高さのプロパティは変更できないので、印刷時拡張が設定されたテキストボックスと表形式のレイアウトを組んでおくことで高さが揃うようにします
印刷時拡張後の高さは印刷時拡張プロパティを「はい」にしたコントロールから取得できます(詳細セクションの高さでは取得できませんでした)
おお!!素晴らしいアイデアですね。
印刷時でも余白は変更できるとは思いもよりませんでした。
表形式のレイアウトで高さを揃えるというのも思いつきませんでした。
これには関しては、
Me.Height
でカレントセクションの印刷時拡張時の高さを取得できます。色々試したのですがhirotonさまのコード、短くてできればそれにしたかったのですが、真ん中にはなってくれず…
hatenaさまの以下の上下中央(レス番号12)コードを元に上下中央にしたいテキストボックス全てに書く方式になりそうです。
【参考コード】
【現状のコード】
ただ、以下のことが出来ずに半日悩んでいました。
1.数字を桁区切り+¥がついた通貨型で表示したい
2.指定した場所から左揃えではなく右揃えで表示したい
3.同じような書式設定にしたいものが複数あるが、同じコードを繰り返す以外のやり方はないのか?
1に関しては
上記のコードだと下記の画像の様に桁区切りも¥もない数字になってしまい、以下を試しました。
.text → SetFocusがレポートの印刷プレビューではできない
.Value → 値を代入できないとエラーが出る
.Format = "Currency" → 何も変化なし
Me.請受金額月額 = Format(Me.請受金額月額, "\#,##0") → エラーで進まない
という感じで、結局希望する「協力会社1回金額」のような表示にはできませんでした。
2に関しては
上記コードだと左揃えだったので
としたらテキストボックスよりもだいぶ右の方に表示されました。
尚、よくわからずに
にしてみましたが、当然エラーでした。
3に関しては
まず、レコードによっては値がNullの場合があるため上記のコードにしています。
テキストを上下中央に配置したいテキストボックスは
テキストが1行のものが15(画像の請求回数・請受金額月額・協力会社1回金額・txt_1月~12月まで)、複数行の可能性があるものが2(協力会社名・作業内容)ありますが、複数行表示の可能性があるものは最悪このままでも、と思っていますが上記のようなコードをあと13書くのはコードがかなり冗長になるので避けたいと思いつつ、いい方法が見つけられませんでした。
(余談ですが、当初テキストボックスの名前が「1月」だったのですが、『Me.1月』にするとエラーになってしまい上記の様に『txt_1月』に変更しました。エラーの理由(規則?)を探しましたが見つけられませんでした)
1~3に関し、どうにかクリアしたいのですがもう少し教えていただけると助かります。(当初の質問とずれて来てすみません、問題があるようでしたら新たなスレッドを立てます)
よろしくお願いします。
本題から遠いので個別に
ニンゲンが記述するものはすべて「文字」なので、それが計算してほしいモノ(計算式)なのか、名前の指定なのかはそれだけでははっきりとしません
例えば「1 + 1」という名前のテキストボックスを作ったらそれを指定するときはどうしたらいいでしょうか?
ACCESSは開発を楽にするためにある程度自動認識でこれらの判別をしています
Me.1月
という記述はその自動認識によって構文エラーとなるような記述ということですねそれがオブジェクトの名前による指定であると明記する場合には
[]
で囲みます。Me.[1月]
とすれば正常に動作します命名規則(の一部)というやつですが、どんな文字でもいいからと言って本当にどんな名前にしてもいいというわけではないということですね
可能な限り数字や記号から始まる名前を付けるのはやめましょう
ありがとうございます。
命名規則に抵触しているのだろうと探していたのですが「こういう風につけましょう」しか見つけられず、「ダメな理由」を見つけることが出来ずにいたのでとても助かりました。
今あるものを確認して修正します。
適当にサンプルで作ったのはこんな感じですね
オブジェクトの表示にはいろんな「隙間」があるので影響あるものを見つけて適切に調整する必要はあると思います
テキストボックスは非表示にして、Printメソッドで表示してますので、そちらの方を修正する必要があります。
テキストボックス名が、
txt_1月, txt_2月 ・・・・txt_12月
だとして、
Controlsで文字列のテキストボックス名でアクセスできますので、
それを利用してループ処理します。
ありがとうございます。
1.の通貨型なのですが
のような設定なのですが(日本円設定です)
になってしまいます。
他に設定しなくてはいけない部分があるのでしょうか?
2.の右揃えは出来ました。
ありがとうございます。
3.のこちらも出来ました。
ありがとうございます。
追加の質問で申し訳ないのですが
4.詳細セクションとグループフッターセクションのつなぎ目の部分で縦の罫線が微妙にずれます(画像の右縦線参照)
左位置は表示されている小数点第3位まで同じです。
しかし、設定上プロパティの左位置に数字を入力しても丸められているのか飛び飛びになるので実際にずれているのかもしれません。
これを画像の左縦線の様にまっすぐあわせるのは難しいのでしょうか?
5.画像の「6」が入力されている行が詳細セクションの(このページでの)最終行でその下がグループフッターセクションで作った空行なのですが、詳細セクションとグループフッターセクションの間に隙間ができてしまいます。
縦線の長さは全て一致して、セクションの高さも最小値(恐らく縦線の長さ+横下線の太さ分)になっていますがそれでも隙間が空きます。
また、縦線だけあえて少し長くしてみると
一番下の空白部分に線がはみ出します(当たり前)
一番下にはみ出さず、セクション間に隙間を作らない方法は何かありませんでしょうか?
尚、補足ですが詳細セクションとグループヘッダーセクションやグループフッターセクションページフッターセクションとの間には太線が引かれているため隙間があるのかもしれませんが隠れてしまい見た目上隙間は無いようになっています。
段々とずれてきてしまいすみません。
あと少しだと思うのですが、もう少しよろしくお願いします。
不思議な現象ですねぇってことで書式「通貨」に設定したテキストボックスでテストをしてみました
結果
書式「通貨(Currency)」で使われる円記号はUnicodeのA5のようです。PrintメソッドがUnicodeに対応していないので文字化けするとかじゃないですかねぇ
文字コードの変換を入れてあげると円記号が表示できます
縦罫線に関しては前の質問でもページフォーマット時(Report_Page)でやればいいのでは?と回答してますが、うまくいかなかったんでしょうか?
通貨型、無事にできました!
ありがとうございます!!
失礼しました。
何かで作業途中になっていました…
以下の様に修正しました。
また、
とし、詳細セクションのフォーマットイベントにあった罫線スタイルの指定をなくしたところうまくいきました。
(前はここがダブってしまっていて、線がきれいに点線になっていませんでした。)
大変失礼しました。
以上にて無事に担当に提出することが出来ました。
本当に長々とありがとうございました。