【実務・中級編】フォームの「OnResize」イベントでコントロールの配置を動的に最適化するレスポンシブUIの基礎 – Access VBA解析バイブル

スポンサーリンク

アクセスで「モダンなレスポンシブUI」を実現する:`OnResize`イベントを極めるアーキテクチャ

業務システムのUI設計において、Accessは長年「古い」「融通が利かない」と揶揄されてきた。ウィンドウを最大化しても、中のテキストボックスやリストボックスはポツンと左上に小さく取り残され、無駄なグレーの余白が広がる――。そんな情けない画面を作ってはいないだろうか。

「Accessだから仕方ない」と諦めるのは、VBAのオブジェクトモデルとイベントのライフサイクルに対する理解が浅いからに他ならない。

チーフアーキテクトである私から言わせれば、Accessフォームであっても、`OnResize`イベントを正しく掌握し、コントロールの座標とサイズを動的に計算するロジックさえ組み込めば、Webアプリケーション顔負けのモダンで堅牢なレスポンシブUIを構築することは容易だ。

今回は、実務の現場で即座に採用できる、バグ知らずの動的レイアウト制御の極意を伝授しよう。

1. なぜ「固定レイアウト」の業務システムは現場で嫌われるのか?

開発現場でよく見かける間違いは、デザインビューで固定サイズのフォームを作り込み、ユーザーがウィンドウサイズを変更する可能性を完全に無視しているケースだ。

  • 視認性の悪さ: 大画面モニターを使っているのに、入力エリアが画面全体の20%しか使われていない。
  • 操作性の欠如: リストボックスの縦幅が固定なため、大量のレコードからスクロールして探す手間が発生する。
  • 不快なちらつき(Flicker): 素人が書いたコードは、リサイズ時にコントロールを一つずつ移動・変形させるため、画面が激しくちらつき、処理も重い。

これを解決するには、「ウィンドウの拡大縮小率(あるいは差分)を算出し、一括して幾何学的な再計算(リフロー)を行う」というエンジニアリングの基本アプローチが必要となる。

2. 設計思想:`OnResize` と ウィンドウサイズの取得

Accessフォームには、ウィンドウのサイズが変更された瞬間に発火する `OnResize` イベントが用意されている。ここで重要になるのが、「フォーム自体のサイズ(InsideWidth / InsideHeight)」の監視だ。

ここで初心者によくあるミスが、`Me.Width` や `Me.Height` をそのまま使ってしまうこと。これらはフォームのデザイン上の外枠サイズであり、ウィンドウ自体のサイズ変更を正確に捉えられない場合がある。クライアント領域のサイズを表す `InsideWidth``InsideHeight` を使うのが鉄則だ。

また、リサイズイベントはマウスドラッグ中などにミリ秒単位で連続発生(バースト)する。このイベント内で重い処理を走らせると、Accessがフリーズしたような挙動を示すため、コードは極限まで軽量化しなければならない。

3. 【プロダクションコード】コピペで動く堅牢なレスポンシブ実装

以下のコードは、私が実際の基幹系リプレイス案件で標準採用しているテンプレートの抜粋だ。

このコードでは、以下の要件を満たしている。
1. フォーム初期化時(`Form_Load`)のサイズを基準(ベースライン)として保持。
2. ウィンドウが拡大・縮小した差分を、配置されているコントロール(リストボックス、テキストエリア、配置ボタン)に比例配分して適用。
3. コントロールの重なりやはみ出しを防ぐための最小サイズ(MinSize)ガードを実装。

フォームモジュールへの記述

Option Compare Database
Option Explicit

‘ =========================================================================
‘ フォーム名: frmResponsiveSample
‘ 概要: ウィンドウのサイズ変更に追従する動的レイアウト制御クラス
‘ =========================================================================

‘ デザイン時の基準サイズ(Load時に自動取得)
Private m_BaseWidth As Long
Private m_BaseHeight As Long

‘ 初期化フラグ(ロード中の無駄なイベント発火を防ぐ)
Private m_IsInitialized As Boolean

Private Sub Form_Load()
On Error GoTo ErrorHandler

m_IsInitialized = False

‘ 1. 基準となるフォームのクライアント領域サイズを保存
m_BaseWidth = Me.InsideWidth
m_BaseHeight = Me.InsideHeight

‘ 2. 各コントロールの「基準位置・サイズ」をTagプロパティに埋め込む
‘ (※後述の初期設定ロジック)
Call InitializeControlTags

m_IsInitialized = True
Exit Sub

ErrorHandler:
MsgBox “フォームの初期化に失敗しました: ” & Err.Description, vbCritical
End Sub

Private Sub Form_Resize()
‘ 初期化完了前、または最小化時は処理をスキップ
If Not m_IsInitialized Then Exit Sub
If Me.InsideWidth = 0 Or Me.InsideHeight = 0 Then Exit Sub

On Error GoTo ErrorHandler

‘ 画面描画のちらつきを抑止するため、可能なら画面更新を一時停止
‘ (※Access標準では完全に止められないが、演算の最適化でカバーする)

Dim wRatio As Double
Dim hRatio As Double

‘ 拡大・縮小率を計算(現在のサイズ / 基準サイズ)
wRatio = Me.InsideWidth / m_BaseWidth
hRatio = Me.InsideHeight / m_BaseHeight

‘ 各コントロールのレイアウトを動的に再計算
‘ 【例1】右側に追従させたいボタン群(X座標を連動)
‘ cmdClose.Left = m_BaseCmdCloseLeft wRatio

‘ 【例2】リストボックス(幅と高さを同時に拡張)
With Me.lstResults
‘ 最小サイズの保証(これ以上小さくさせないガード)
If (m_BaseListWidth wRatio) > 3000 Then
.Width = m_BaseListWidth wRatio
End If
If (m_BaseListHeight hRatio) > 2000 Then
.Height = m_BaseListHeight hRatio
End If
End With

‘ 【例3】横長のテキストボックス(幅のみ追従)
With Me.txtAddress
.Width = m_BaseTxtAddressWidth wRatio
End With

Exit Sub

ErrorHandler:
‘ リサイズ中の予期せぬエラーでシステムが停止しないようログに留める
Debug.Print “Resize Error: ” & Err.Description
End Sub

‘ ————————————————————————-
‘ 内部変数保持用のプライベート変数(本来はUCD等で管理すべきだが簡略化のためモジュール変数へ)
‘ ————————————————————————-
Private m_BaseListWidth As Long
Private m_BaseListHeight As Long
Private m_BaseTxtAddressWidth As Long

Private Sub InitializeControlTags()
‘ コントロールの初期デザインサイズをメモリに保持
m_BaseListWidth = Me.lstResults.Width
m_BaseListHeight = Me.lstResults.Height
m_BaseTxtAddressWidth = Me.txtAddress.Width
End Sub

4. チーフアーキテクトが教える「現場の地雷」と回避策

上記のコードをベースに実装を進める際、実務担当者が必ず踏む地雷がいくつかある。ここを抑えておかないと、テスト工程で致命的なバグ報告を受けることになる。

地雷1: コントロールの「アンカープロパティ」との競合

最近のAccessのバージョンには、コントロールのプロパティに「アンカー(下部に合わせる、右側に伸ばすなど)」が存在する。
結論から言えば、VBAで動的制御を行うフォームでは、すべてのコントロールのアンカー設定を「なし(左上基準)」に統一しなさい。
Access標準のアンカー機能とVBAによる座標計算を併用すると、二重に数値が加算されてコントロールが画面外へ飛んでいく、あるいは無限に拡大するバグを引き起こす。

地雷2: 最小サイズ(Min/Max)の制限不足

ユーザーがウィンドウを極端に小さく縮めた場合、コントロール同士が重なり合い、最悪の場合クラッシュする。
必ずコード内に `If 許容値 Then` によるガード節を設け、デザインが崩壊する限界値(Min Width / Min Height)を下回らないように制御すること。

地雷3: データベースやファイル連携への影響

フォームがリサイズされたからといって、バックエンドのレコードソース(Table/Query)への負荷が上がるわけではない。しかし、リサイズに伴ってリストボックスの再描画(Requery)を安易に呼ぶと、ネットワーク越し(SQL Serverなど)の環境で致命的なパフォーマンス低下を招く。
「レイアウトの変更(UI)」と「データの再取得(Data)」は完全に分離せよ。 `OnResize` の中で `Requery` を実行する愚行は絶対に避けること。

5. まとめ:Accessの限界を超えるために

Accessは「古いデータベースツール」ではない。それをどう使いこなし、モダンなユーザー体験に昇華させるかは、設計者であるあなた個人の技術力と美意識に懸かっている。

今回紹介した `OnResize` を活用したレスポンシブUIの構築手法は、単なる見た目の改善に止まらず、ユーザーの入力ミスを防ぎ、業務効率を劇的に向上させるための強力な武器となる。

「たかがAccess、されどAccess」。
細部へのこだわりを捨てた瞬間にシステムの品質は堕ちる。妥協なき設計で、現場が唸る真のプロフェッショナルツールを構築してほしい。

タイトルとURLをコピーしました