テーブル保守
業務システムを開発する際は様々なリンクテーブル(マスタ)が必要になります。
その際、その情報一つ一つのテーブル用にフォームを作成すると結構な数のオブジェクトになります。
そうなるとAccessファイルサイズが大きくなり動作スピード等にも影響が出てくるのでテーブルの保守は直接テーブルを開いてデータの更新/追加/削除等を行う方法が一番手間はないのですが、これをエンドユーザーに行わせる場合、扱いかたによってはデータベースファイル自体が壊れる場合があります。(原因ははっきりわかりませんが、経験上わりとあります。)
その為極力安全な方法をとる必要があります。既定ではデータの変更は出来ないようにする事。テーブルのデータ変更はそのテーブルを使っていない時に極力行う。
以上2点を考慮しテーブル保守共通のフォームを作成します。
テーブルを表示するサブフォームはテーブルの構造に会わせて都度フォームの変数や名前を割り当てる方法をとる事でフォームの共通化が可能です。
この手法は集計クエリーの表示でも利用されます。(テーブルのフィールド数が可変の場合のテーブル表示)
図1のフォームをデザインフォームにしたものが図2です。フォームの左側にあるテーブルをダブルクリックするとそのテーブルの要素を図2のサブフォームに割当表示するものです。テキストラベルとボックスは100個用意してあります。(テーブルのフィールド数が最大100個と想定)
①のサブフォームのテーブルのレコードセレクタをダブルクリックした時のイベントプロシージャは以下の通りです。
このフォームを開いた時の既定のフォームはブランクのフォームを表示させ、テーブルを選択した時に図2のフォームに変更します。
例:
Forms![W750_関連マスタメンテナンス_FM]![W750_関連マスタメンテナンス_FM_SUBF02].SourceObject = "W750_関連マスタメンテナンス_FM_SUBF02"
※ワンポイントアドバイス
Parentプロパティは便利
親オブジェクトの参照を取得するプロパティです。
例:
Forms![W750_関連マスタメンテナンス_FM]!列並び順 = TBL2![見出し名]
Parent!列並び順 = TBL2![見出し名]
上記は同じ動作をします。
下記はサブフォーム内のダブルクリック時のイベントプロシージャです。
Option Compare Database
Option Explicit
Dim MDB1 As Database, TBL1 As Recordset, TBL2 As Recordset, MySQL As String, MyQry As QueryDef
Private Sub Form_DblClick(Cancel As Integer)
Dim Msg As Integer, II As Long, RstCnt As Long
Dim frm1 As Form 'フォームオブジェクト変数
'フォームオブジェクトの有無のチェック
Set MDB1 = CurrentDb
Set TBL1 = MDB1.OpenRecordset("W750_Tableオブジェクト_表示qey", dbOpenDynaset, dbSeeChanges)
TBL1.MoveLast
TBL1.FindFirst "Name = " & "'" & テーブル名 & "'"
If TBL1.NoMatch Then
MsgBox "存在しないテーブルオブジェクトです。「一覧編集」で正しいテーブルオブジェクトを設定してください。"
TBL1.Close
Set TBL1 = Nothing
Set MDB1 = Nothing
Exit Sub
End If
Set TBL1 = Nothing
Set MDB1 = Nothing
With Forms![W750_関連マスタメンテナンス_FM]![W750_関連マスタメンテナンス_FM_SUBF02]
.Visible = False
.SourceObject = "W750_関連マスタメンテナンス_FM_SUBF02" '一旦元のサブフォームに戻す
.SourceObject = "W750_関連マスタメンテナンス_FM_SUBF02_Template"
Set frm1 = Forms![W750_関連マスタメンテナンス_FM]![W750_関連マスタメンテナンス_FM_SUBF02].Form
'初期状態に戻す
For II = 0 To 100
frm1("fld" & II).ControlSource = ""
frm1("ラベルfld" & II).Caption = "fld" & II
frm1("fld" & II).ColumnHidden = False
Next II
MySQL = "SELECT " & テーブル名 & ".* FROM " & テーブル名 & ";"
frm1.RecordSource = MySQL
'テーブルの要素をフォームのティールドに割り当てる
Set MDB1 = CurrentDb
Set TBL1 = MDB1.OpenRecordset(テーブル名, dbOpenDynaset, dbSeeChanges)
RstCnt = TBL1.Fields.Count
For II = 0 To 100
If II < RstCnt Then
frm1("fld" & II).ColumnHidden = False
frm1("fld" & II).TextAlign = 1 '.TextAlign 左配置:1 中央配置:2 右配置:3 均等割り付け:4
If TBL1.Fields(II).Type = dbLong Then frm1("fld" & II).TextAlign = 3
If TBL1.Fields(II).Type = dbSingle Then frm1("fld" & II).TextAlign = 3
If InStr(TBL1.Fields(II).Name, "登録") > 0 And InStr(TBL1.Fields(II).Name, "ID") = 0 Then frm1("fld" & II).TextAlign = 2
frm1("fld" & II).ControlSource = TBL1.Fields(II).Name
frm1("ラベルfld" & II).Caption = TBL1.Fields(II).Name
Else
frm1("fld" & II).ColumnHidden = True
End If
Next II
共通処理:
'入出力パス・ファイル名等
With Forms![W750_関連マスタメンテナンス_FM]
.マスタ内訳 = マスタ内訳
.テーブル名 = テーブル名
.出力Path = 出力パス名
.出力File = 出力ファイル名
.入力Path = 出力パス名
.入力File = 出力ファイル名
.入力_シート名 = 入力シート名
.出力_シート名 = 出力シート名
.列並び順 = Null
End With
Forms![W750_関連マスタメンテナンス_FM]![W750_関連マスタメンテナンス_FM_SUBF01].Requery
列幅自動整列
Forms![W750_関連マスタメンテナンス_FM]!一覧更新2.SetFocus
Forms![W750_関連マスタメンテナンス_FM]!列並び順 = Null
.Visible = True
.Form.Filter = ""
.Form.OrderBy = ""
End With
'並び順の検索
MySQL = "SELECT DISTINCT [◆テーブル_見出しマスタ].見出し名, [◆テーブル_見出しマスタ].FM記号 " & _
"From ◆テーブル_見出しマスタ " & _
"WHERE ((([◆テーブル_見出しマスタ].見出し名) Like '" & "*羽賀*" & "' Or ([◆テーブル_見出しマスタ].見出し名) Like '共用*') AND " & _
"(([◆テーブル_見出しマスタ].[テーブル名])= '" & Parent!テーブル名 & " ') AND (([◆テーブル_見出しマスタ].FM記号) = '" & Parent!Form_Name & "'));"
Set MDB1 = CurrentDb
Set MyQry = MDB1.CreateQueryDef("", MySQL)
Set TBL2 = MyQry.OpenRecordset(dbOpenDynaset, dbSeeChanges)
If TBL2.EOF And TBL2.BOF Then
TBL2.Close
Set TBL2 = Nothing
Set MDB1 = Nothing
Exit Sub
End If
TBL2.MoveFirst
Parent!列並び順 = TBL2![見出し名]
Parent.表示イメージ列順適用
TBL2.Close
Set TBL2 = Nothing
Set MDB1 = Nothing
End Sub
サブフォーム内にフォームを作り親子リンクを設定すると展開インジケーターが表示され「+」をクリックすると展開「-」をクリックすると畳みます。
展開/畳むは展開インジケーターで各々できますが、一括で展開/畳むは下記のイベントプロシージャで実行します。
展開されているサブフォーム内のフォームはデータシートにすると横に並ぶだけの為、単票フォームで作成しています。
Public Sub 全て展開する()
If Forms![W750_関連マスタメンテナンス_FM]![W750_関連マスタメンテナンス_FM_SUBF01].Form.Recordset.RecordCount = 0 Then Exit Sub
Forms![W750_関連マスタメンテナンス_FM]![W750_関連マスタメンテナンス_FM_SUBF01].SetFocus
Forms![W750_関連マスタメンテナンス_FM]![W750_関連マスタメンテナンス_FM_SUBF01]![テーブル名].SetFocus
'すべて展開コマンドを実行
DoCmd.RunCommand acCmdSubdatasheetExpandAll
End Sub
Private Sub 全て畳む_Click()
全て折り畳む
End Sub
Public Sub 全て折り畳む()
If Forms![W750_関連マスタメンテナンス_FM]![W750_関連マスタメンテナンス_FM_SUBF01].Form.Recordset.RecordCount = 0 Then Exit Sub
Forms![W750_関連マスタメンテナンス_FM]![W750_関連マスタメンテナンス_FM_SUBF01].SetFocus
Forms![W750_関連マスタメンテナンス_FM]![W750_関連マスタメンテナンス_FM_SUBF01]![テーブル名].SetFocus
'すべて折りたたみコマンドを実行
DoCmd.RunCommand acCmdSubdatasheetCollapseAll
End Sub