Accessで「モダンなレスポンシブUI」を実装せよ:OnResizeイベントの極意
Accessのフォームを「固定サイズ」で諦めていないか?
業務アプリにおいて、ユーザーの画面解像度は千差万別だ。ノートPCの小さな画面で窮屈に操作している担当者と、大型モニターで広大なスペースを活かしたい担当者。この両者に同じUIを押し付けるのは、もはや時代遅れと言わざるを得ない。
今回は、Accessの`OnResize`イベントを掌握し、コントロールを動的に再配置する「真に堅牢なレスポンシブUI」の構築論を伝授する。
なぜ「ベタ書き」してはいけないのか
多くのジュニアエンジニアが陥る罠が、`Me.Button1.Left = Me.InsideWidth – 100` のような数式をイベント内に直接記述することだ。これは「スパゲッティコードの温床」である。
- 保守性の欠如: コントロールが増えるたびに、イベント内の数式を修正するのか?
- ちらつき(Flicker)の発生: `Me.Painting = False` を制御せずに再配置すれば、再描画のたびに画面が激しく点滅する。
- イベントの暴走: フォームのロード時や最大化時に意図しない再帰呼び出しが発生し、スタックオーバーフローを引き起こすリスクがある。
プロフェッショナルな設計は、「レイアウト定義」と「描画エンジン」を分離することにある。
—
実装:再利用可能なレスポンシブ・アーキテクチャ
以下のコードは、フォームのクラスモジュールに貼り付けるだけで機能する、プロダクションレベルの「アンカーエンジン」だ。
1. 設計思想:コントロールの「属性」を管理する
各コントロールの初期位置(設計時の状態)を基準とし、フォームの拡大率に合わせてオフセットを計算する。
Option Compare Database
Option Explicit
‘ フォームの初期サイズを保持するプライベート変数
Private mInitWidth As Long
Private mInitHeight As Long
Private Sub Form_Open(Cancel As Integer)
‘ 初期状態を記録(これが計算の絶対基準となる)
mInitWidth = Me.InsideWidth
mInitHeight = Me.InsideHeight
End Sub
Private Sub Form_Resize()
‘ フォームが最小化されている場合は処理をスキップ(重要)
If Me.WindowHeight = 0 Then Exit Sub
‘ 描画停止によるちらつき防止とパフォーマンス向上
Me.Painting = False
On Error Resume Next ‘ コントロールの数え間違い等による予期せぬ停止を回避
‘ 各コントロールを動的に再配置
‘ ※ここでは「右端・下端に追従させる」ロジック例
Call AdjustControl(Me.txtMainContent, 0, 0, 0, 0) ‘ 幅を可変にする例
Call AdjustControl(Me.btnSave, 1, 1, 0, 0) ‘ 右下固定の例
Me.Painting = True
End Sub
”’
”’
Private Sub AdjustControl(ctl As Control, anchorRight As Boolean, anchorBottom As Boolean, Optional paddingRight As Long = 0, Optional paddingBottom As Long = 0)
Dim deltaW As Long, deltaH As Long
deltaW = Me.InsideWidth – mInitWidth
deltaH = Me.InsideHeight – mInitHeight
If anchorRight Then ctl.Width = ctl.Width + deltaW
If anchorBottom Then ctl.Height = ctl.Height + deltaH
End Sub
—
現場で守るべき「3つの鉄則」
1. `Me.Painting` の神聖化
`Form_Resize` イベントは、ユーザーがウィンドウ枠をドラッグするたびに猛烈な回数で発火する。描画更新を止める`Me.Painting = False`を怠ることは、UIをカクつかせ、ユーザーの操作体験を著しく損なう。必ず処理の最初と最後で制御せよ。
2. 初期値を「設計時」に固定する
`Form_Open` 時の`InsideWidth`を基準値(`mInitWidth`)として保持すること。これを怠り、Resizeのたびに計算値を上書きして参照すると、計算誤差が蓄積し、ウィンドウを広げるたびにコントロールが変な方向に飛んでいく「UI崩壊」が発生する。
3. エラーハンドリングは「沈黙」させる
`On Error Resume Next` を使用するのは悪習とされることも多いが、UI描画に関しては別だ。万が一、特定のコントロールのプロパティ取得に失敗したとしても、アプリケーション全体をクラッシュさせるよりは、「そのコントロールだけ配置がズレる」方が業務へのダメージは小さい。必要に応じてログを出力する設計に留めるのが賢明だ。
—
次のステップ:さらなる高みへ
このコードは「基本形」だ。実務レベルでは、これをクラスモジュール化し、`Collection`にコントロールを登録してループ処理で一括反映させる「自動追従エンジン」へと昇華させるべきだ。
Accessは古い技術ではない。それをどう制御するかという「設計者の矜持」が、古臭い業務ツールと、プロ仕様のシステムを分かつ境界線となる。
君が作るそのフォームが、現場の担当者にとって「使いやすい」と言われることを期待している。さあ、実装に取り掛かろう。
