「Accessで顧客一覧フォームの行をクリックしたら、その顧客のデータが最初から表示された状態で詳細フォームを開きたい」「フォームを読み取り専用で開くか、編集可能で開くかをボタンで切り替えたい」——こうした要件を実現する仕組みがOpenArgs(オープンアーグス)引数です。
OpenArgsはAccessのフォーム起動時に文字列形式のパラメータを渡せる機能です。受け取った側のフォームはMe.OpenArgsプロパティでその値を読み取り、初期表示の条件・編集可否・フォーカス位置など「起動時の振る舞い」を動的に制御できます。マクロビルダーからも設定できるため、VBAが書けない方でも実装できます。
本記事では、OpenArgs引数の仕組みと構文、マクロとVBAそれぞれの設定手順、実務でよく使う3つのパターン(ドリルダウン表示・モード切替・複数値渡し)、注意点、MOS Access試験との関連まで体系的に解説します。
OpenArgs引数とは何か
OpenArgsは、DoCmd.OpenFormメソッド(またはマクロのOpenFormアクション)の第8引数で、フォームを開く際に任意の文字列を渡せるパラメータです。渡した値は、開かれたフォーム側でMe.OpenArgsプロパティとして参照でき、起動条件に応じた処理を組み込めます。
OpenArgsが登場する前は、フォーム間のデータ受け渡しにグローバル変数やテーブルへの一時書き込みが使われていました。OpenArgsを使うと、グローバル変数に依存せずにフォームを呼び出した側のコンテキストを伝達でき、コードの見通しが格段によくなります。
| 比較項目 | OpenArgsを使う場合 | グローバル変数を使う場合 |
|---|---|---|
| 依存関係 | フォーム間の直接受け渡し | 標準モジュールにグローバル変数が必要 |
| マクロ対応 | マクロのOpenFormアクションから設定可 | VBAのみ |
| テストのしやすさ | 呼び出し元とセットで確認しやすい | 変数の状態を別途管理する必要あり |
| 渡せる値の型 | 文字列のみ(数値も文字列に変換) | 任意のデータ型 |
DoCmd.OpenFormのOpenArgs引数の位置
VBAのDoCmd.OpenFormメソッドは次の構文を持ちます。
DoCmd.OpenForm FormName, View, FilterName, WhereCondition, DataMode, WindowMode, OpenArgs
| 引数名 | 位置 | 説明 | 省略時の値 |
|---|---|---|---|
| FormName | 第1 | 開くフォームの名前(必須) | ― |
| View | 第2 | 表示形式(acNormal・acDesign・acPreviewなど) | acNormal |
| FilterName | 第3 | 適用するクエリフィルタ名 | 省略可 |
| WhereCondition | 第4 | SQL WHERE句のような絞り込み条件 | 省略可 |
| DataMode | 第5 | データ入力モード(acAdd・acEdit・acReadOnly) | acEdit |
| WindowMode | 第6 | ウィンドウモード(acWindowNormal・acDialogなど) | acWindowNormal |
| OpenArgs | 第7 | 任意の文字列パラメータ(本記事の主題) | 省略可 |
多くの場合、第3・第4・第5・第6引数は省略するため、コードは次のように書きます。
DoCmd.OpenForm "顧客詳細", , , , , , "1001"
省略した引数の箇所はカンマだけ残し、OpenArgsに渡す文字列(ここでは "1001")を最後に指定します。acNormal や空文字 "" を省略してコンマだけ並べる書き方は慣れれば読みやすくなります。
マクロビルダーでOpenArgsを設定する手順
VBAを書かずにマクロビルダーだけでOpenArgsを設定する場合の手順を示します。
- 呼び出し元のフォームをデザインビューで開き、ボタンコントロールを選択する
- プロパティシートの「イベント」タブで「クリック時」の右側にある「…」ボタンをクリックする
- 「マクロビルダー」を選択してマクロ編集画面を開く
- 「アクションの追加」から「OpenForm」を選択する
- 「フォーム名」に開きたいフォーム名を入力する
- 一番下の「OpenArgs」フィールドに渡したい文字列(例:
Forms!顧客一覧!顧客ID)を入力する - マクロを保存してフォームを保存する
「OpenArgs」フィールドにはリテラルの文字列("新規" のように引用符で囲む)のほか、Forms!フォーム名!フィールド名 という式で現在フォームのフィールド値を動的に参照することもできます。式を使う場合は、引用符なしでそのまま入力してください。
VBAでOpenArgsを渡す手順
VBAでフォームのボタンクリックイベントからOpenArgsを渡す場合のコード例を示します。
Private Sub btn詳細表示_Click()
Dim strArg As String
strArg = CStr(Me!顧客ID) ' 現在レコードの顧客IDを文字列に変換
DoCmd.OpenForm "顧客詳細", , , , , , strArg
End Sub
数値型のフィールドをOpenArgsに渡す場合は CStr() で文字列に変換してください。OpenArgsは文字列型(String)しか受け付けないため、数値のまま渡そうとするとエラーになります。
受け取り側フォームでMe.OpenArgsを参照する
渡したOpenArgsは、開かれた側のフォームのフォームモジュールから Me.OpenArgs で参照します。フォームが開く直前に実行される「開く時(Open)」イベント、または開いた直後の「読み込み時(Load)」イベントで処理するのが一般的です。
Private Sub Form_Load()
If Not IsNull(Me.OpenArgs) And Me.OpenArgs <> "" Then
' 受け取ったパラメータを使った処理
Me.Filter = "顧客ID = " & Me.OpenArgs
Me.FilterOn = True
End If
End Sub
Me.OpenArgs はフォームをOpenArgs引数なしで開いた場合に Null(空文字ではなくNull)になります。IsNullチェックを省くと、引数なしで開いたときにエラーが発生することがあるため、必ず最初に IsNull(Me.OpenArgs) で確認してください。
実務パターン①:一覧から詳細フォームへのドリルダウン(想定例)
以下は、顧客管理データベースでの想定例です。「顧客一覧」フォームで選択した顧客のIDをOpenArgsで渡し、「顧客詳細」フォームでそのレコードを絞り込んで表示します。
呼び出し元(顧客一覧フォーム)のコード
Private Sub btn詳細_Click()
If IsNull(Me!顧客ID) Then
MsgBox "レコードを選択してください"
Exit Sub
End If
DoCmd.OpenForm "顧客詳細", , , , acEdit, acDialog, CStr(Me!顧客ID)
End Sub
受け取り側(顧客詳細フォーム)のコード
Private Sub Form_Load()
If Not IsNull(Me.OpenArgs) And Me.OpenArgs <> "" Then
Me.RecordSource = "SELECT * FROM 顧客 WHERE 顧客ID = " & Me.OpenArgs
End If
End Sub
このパターンでは acDialog を指定してモーダルウィンドウとして開いているため、詳細フォームを閉じるまで一覧フォームの操作がロックされます。「詳細を確認・編集してから一覧に戻る」という業務フローに適した実装です。
実務パターン②:読み取り専用と編集可能をOpenArgsで切り替える(想定例)
同じフォームを「閲覧用(読み取り専用)」と「編集用」の2モードで使い分けるパターンです。モードを示す文字列(例: "readonly")をOpenArgsで渡し、フォームのLoad時にAlowEditsプロパティを切り替えます。
呼び出し元:2つのボタンで開き方を分ける
' 閲覧ボタン
Private Sub btn閲覧_Click()
DoCmd.OpenForm "受注詳細", , , , , , "readonly"
End Sub
' 編集ボタン
Private Sub btn編集_Click()
DoCmd.OpenForm "受注詳細", , , , , , "edit"
End Sub
受け取り側:OpenArgsでAlowEditsを切り替える
Private Sub Form_Load()
Select Case Me.OpenArgs
Case "readonly"
Me.AllowEdits = False
Me.AllowDeletions = False
Me.AllowAdditions = False
Me.Caption = Me.Caption & "(閲覧専用)"
Case "edit"
Me.AllowEdits = True
Case Else
' 引数なしで開いた場合は編集可能とする
Me.AllowEdits = True
End Select
End Sub
このパターンにより、フォームを2枚作る必要がなくなります。閲覧専用フォームと編集フォームを別々に維持・更新する手間が省け、メンテナンスコストを削減できます。
実務パターン③:複数の値をセパレーターで区切って渡す(想定例)
OpenArgsは文字列型のため、複数の値を渡したい場合は区切り文字(パイプ |、カンマ ,、セミコロン ;など)でつないで一つの文字列にします。受け取り側でSplit関数を使って分解します。
' 呼び出し元:注文IDとモードを一緒に渡す
DoCmd.OpenForm "注文詳細", , , , , , CStr(Me!注文ID) & "|edit"
' 受け取り側:Split関数で分解する
Private Sub Form_Load()
Dim arrArgs() As String
If Not IsNull(Me.OpenArgs) And Me.OpenArgs <> "" Then
arrArgs = Split(Me.OpenArgs, "|")
' arrArgs(0) = 注文ID, arrArgs(1) = モード
Me.RecordSource = "SELECT * FROM 注文 WHERE 注文ID = " & arrArgs(0)
If arrArgs(1) = "edit" Then Me.AllowEdits = True
End If
End Sub
区切り文字は渡すデータ本体に含まれない文字を選んでください。一般的なID(数字のみ)やステータス文字列と衝突しにくい | がよく使われます。なお、区切り文字がデータに含まれる可能性がある場合は、URLパラメータ形式(key1=val1&key2=val2)にして解析する方法も有効です。
OpenArgsの制限と注意点
| 注意点 | 詳細 |
|---|---|
| 文字列型のみ受け取れる | 数値・日付を渡す場合はCStr()で変換する。受け取り側でCInt()・CDate()に戻す |
| IsNullチェックが必要 | OpenArgsなしで開いた場合はNullになる。チェックを省くと「型が一致しません」エラーが発生する |
| 直接フォームを開いた場合は空 | ナビゲーションウィンドウからダブルクリックで開くとOpenArgsはNull。デバッグ時は注意 |
| フォームが複数回開かれる場合 | 同一フォームが既に開いている場合はLoadイベントが再発火しない。OpenイベントはForm_Openを使うと確実 |
| 長さ制限 | OpenArgsに渡せる文字列の長さに制限はないが、数百文字を超える場合はテーブル経由の受け渡しを検討する |
LoadイベントとOpenイベントの使い分け:フォームが既に開いているときにOpenArgsを更新して再度DoCmd.OpenFormを呼ぶと、Form_Loadは再実行されませんが、Form_OpenはフォームのAcWindowModeによっては再実行されます。同一フォームを動的に切り替えたい場合はForm_Open内でMe.OpenArgsを参照してください。
MOS Access試験でのOpenArgs関連の出題ポイント
MOS Access 365試験の出題範囲には「フォームとマクロの管理」が含まれます。OpenArgsはDoCmd.OpenFormアクション(またはマクロのOpenFormアクション)の引数として扱われ、フォームを開く操作と連動して出題される可能性があります。
- マクロビルダーでOpenFormアクションを設定できる:「フォーム名」「データモード」「OpenArgs」の各フィールドを正しく入力できること
- DoCmd.OpenFormの引数の順序を理解している:第7引数がOpenArgsであることを把握し、省略引数をカンマで埋めて記述できること
- Me.OpenArgsの参照場所を把握している:フォームモジュールのLoadイベントまたはOpenイベントで参照すること
- IsNullによるガード条件の必要性:引数なしで開いた場合にNullになることを理解していること
MOS試験でOpenArgsが直接問われる頻度は限られますが、マクロビルダーのOpenFormアクションの操作は試験全体を通して重要なスキルです。OpenArgs設定を含めた実践的な操作を一度体験しておくことで、マクロ関連の設問への対応力が上がります。分野別の出題数・配点は公表されていません。
MOS試験 フォーム操作チェックリスト
| 確認ポイント | 操作内容 | 難易度 |
|---|---|---|
| マクロビルダーを開ける | ボタンのクリック時イベントから「マクロビルダー」を選択できる | ★☆☆ |
| OpenFormアクションを追加できる | マクロビルダーでOpenFormアクションを検索・追加し「フォーム名」を入力できる | ★☆☆ |
| OpenArgsフィールドに値を入力できる | リテラル文字列または式(Forms!フォーム名!フィールド名)を正しく入力できる | ★★☆ |
| VBAでDoCmd.OpenFormを記述できる | 引数の位置を理解し省略引数をカンマで並べてOpenArgsに値を渡せる | ★★☆ |
| Form_LoadでMe.OpenArgsを参照できる | IsNullチェックのうえで値を取り出し、フィルタやプロパティ変更に使える | ★★★ |
よくあるつまずきとQ&A
Q. Form_Loadが実行されているのにMe.OpenArgsがNullになる
一般的な原因は、DoCmd.OpenFormの第7引数を省略している、または""(空文字)を渡しているケースです。マクロビルダーの「OpenArgs」フィールドに値が入っているか確認してください。引数付きで開いたつもりでも、ナビゲーションウィンドウからフォームを直接開くとOpenArgsはNullになります。デバッグ中は必ずボタン経由で開くようにしてください。
Q. 「型が一致しません」エラーがForm_Load内で発生する
Me.OpenArgsがNullの状態で文字列操作(SplitやLenなど)を行うとエラーになります。If Not IsNull(Me.OpenArgs) And Me.OpenArgs <> "" Then で確実にガードを入れてください。
Q. 数値を渡したつもりなのに比較がうまくいかない
OpenArgsは文字列なので、数値比較には CLng(Me.OpenArgs) や CInt(Me.OpenArgs) で型変換してから使ってください。SQL WHERE句で使う場合は数値型フィールドであれば変換不要ですが、文字列型フィールドに使う場合はシングルクォートで囲む必要があります("顧客コード = '" & Me.OpenArgs & "'")。
Q. フォームが既に開いている場合に値が更新されない
同じフォームが既に開いている場合、DoCmd.OpenFormを呼んでもLoadイベントは再実行されません。この場合はForm_Openイベントを使うか、一度フォームを閉じてから再度開く設計にしてください。または、開いているフォームを Forms!フォーム名 で直接参照して値を設定する方法も有効です。
まとめ:OpenArgsでAccessフォームの設計品質を高める
本記事のポイントをまとめます。
- OpenArgsとは:DoCmd.OpenFormの第7引数。フォームを開く際に文字列パラメータを渡せる
- 渡す側:マクロビルダーのOpenArgsフィールド、またはVBAでDoCmd.OpenFormの第7引数に文字列を指定する
- 受け取る側:Form_LoadまたはForm_OpenイベントでMe.OpenArgsを参照。IsNullチェックを忘れない
- 実務パターン3選:①IDを渡してドリルダウン表示、②読み取り専用・編集モードの切り替え、③Split関数で複数値を分解
- 注意点:文字列型のみ対応・Nullガード必須・既に開いているフォームはLoadイベントが再実行されない
- MOS試験では:マクロビルダーのOpenFormアクション操作とDoCmd.OpenFormの引数順序を把握しておく
OpenArgsを使いこなすと、グローバル変数やテーブルへの一時書き込みに頼らずフォーム間の連携が設計でき、Accessアプリケーションの保守性が大幅に向上します。まずはシンプルなドリルダウン(想定例①)から実装し、慣れてきたらモード切り替えや複数値渡しへと応用範囲を広げていきましょう。
PR
MOS試験シリーズの定番対策書。Access・Excel・Wordを含むMicrosoft 365全体の試験対策に使える出題範囲の網羅的な解説と模擬問題を収録。フォーム操作・マクロ設定を含む実践的な演習で、試験合格に向けた実力が確実に身につきます。
PR
Microsoft Copilot for Microsoft 365活用大全
AccessをはじめとするMicrosoft 365スイート全体の業務効率化を体系的に解説。フォーム設計・データ連携・自動化ワークフローの考え方を深めることで、OpenArgsを活用した高品質なAccessアプリ開発力が自然に身につきます。
Access・MOS試験の学習でお悩みですか?
当サイト「Excel・MOS試験対策.com」では、MOS試験合格を目指す方に向けてExcel・Word・Access・PowerPointの操作解説記事を多数公開しています。実務ですぐ使えるテクニックを中心にまとめていますので、ぜひ他の記事もご覧ください。
