テキストボックスの文字を縦位置の中央に表示する

 レポートのテキストボックスの文字配置には縦中央(上下中央)というのがなく、通常は文字が上端に表示されます。
 それでも中央に表示したい場合、通常は上余白プロパティを適当な値に設定すればそれらしくなります(簡単ですので通常はこちらをおすすめします)が、文字列が長いと全体的に下に片寄って表示されますので見栄えが良くありません。
 そこで、実験的な内容になりますが、正確に縦位置の中央に表示する例を以下で試してみます。ただし、この方法ではレコードソースとなるテーブル(クエリ)に、レコードを一意に識別できる値(通常は主キー)が存在することが必要となりますのでご注意ください。

手順

f:id:accs2014:20180809231336p:plain:right:w600

 サンプルとなるテーブル「会員テーブル」です。「会員番号」の値でレコードを一意に識別できます。
 このテーブルに基づくレポートを作り、「コメント」をテキストボックスの縦位置の中央に表示させます。


f:id:accs2014:20180811085220p:plain:right:w600

 レポートのデザインビューです。まずはレコードソースを「会員テーブル」とします。
 そして「会員番号」でグループ化し、グループヘッダーを設けます。当然ですがこの場合1つのグループには1つのレコードしか含まれません。名前は特に設定する必要もありませんが「会員番号ヘッダー」とします。
 そしてこのグループヘッダーの中にテキストボックスを設けます。コントロールソースは「=[コメント]」(あるいは単に「コメント」)、名前は「txtコメントダミー」とし、印刷時拡張を「はい」とします。高さはテキスト1行分だけにします(重要)。ただしグループヘッダーは結果的に表示されませんので、ヘッダー自体の高さは適当に決めて構いません。
 そして詳細セクションに同じ幅のテキストボックスを設けます。コントロールソースは同じく「=[コメント]」(あるいは単に「コメント」)、名前は「txtコメント」とし、印刷時拡張を「いいえ」とします。高さは実際に表示させたい高さに合わせます。最終的に表示されるテキストボックスはこちらです。


f:id:accs2014:20180809234321p:plain:right:w650

 あとはレポートモジュールに以下のコードを記します。



Option Compare Database

'変数宣言 ダミーのテキストボックス(txtコメントダミー)の高さ,テキストボックス(txtコメント)の上余白
Dim dummy_height As Integer, comment_top_margin As Integer

Private Sub 会員番号ヘッダー_Print(Cancel As Integer, PrintCount As Integer)

dummy_height = Me.txtコメントダミー.Height
'ヘッダー描画しない
Me.PrintSection = False
'描画開始位置を進めない
Me.MoveLayout = False

End Sub

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

comment_top_margin = IIf((Me.txtコメント.Height - dummy_height) / 2 < 0, 0, (Me.txtコメント.Height - dummy_height) / 2)
Me.txtコメント.TopMargin = comment_top_margin

End Sub

 簡単に補足しますと、グループヘッダーに一旦ダミーのテキストボックスを描画して、高さ(これは文字列そのものの高さになります)を記録してからヘッダーそのものをなかったことにします。詳細セクションではその高さに基づき必要な余白の計算をした上で改めてテキストボックスを描画します。PrintイベントとFormatイベントを間違えるとうまくいきませんので注意してください。

f:id:accs2014:20180809231327p:plain:right:w400

 印刷プレビューです。


f:id:accs2014:20180809231324p:plain:right:w400

 ちなみに上余白は0未満にはなりませんので、文字が溢れる場合は末尾が見切れます。
 ダミーのテキストボックスの高さが高い場合にtxtコメント.Heightを書き換えればちょうど収まるようにすることも可能です。


備考

 「="ダミー"」みたいなダミーのヘッダーでも行けるかと思いましたが、やっぱり並び順になるフィールドがないとうまくいかないようです。
 あとアプローチとしてはサブレポートA(先に描画される方)からサブレポートB(後に描画される方)にダミーのテキストボックスの高さを渡す方法や、NextRecord = False を利用することで詳細セクションを2回ずつ描画して先から後に値を渡す方法が考えられます。ともにレコードを一意に識別できる値を必要としないのがメリットですが、前者はオブジェクトが増えて厄介なのと、後者はNextRecord = FalseとMoveLayout = Falseが併用できないらしいので挫けました;-o-)

 ちなみにラベルの場合は以下のような簡便法がありますので参考まで。

www.accessdbstudy.net