[Access VBA] デザインビューのテーブル定義を表形式でエクスポートする関数を作成した
概要
この記事について
Accessの各々のテーブルの内容をエクスポートする方法として、
- ナビゲーションバーのテーブルの右クリックメニューからエクスポート -> Excel、テキスト等形式を選択して出力
- データベースツールタブのデータベース構造の解析 -> テーブル指定 -> 印刷、またはExcel、PDF等形式を選択して出力
の選択肢がある。
しかし、
前者は、フィールドの型や主キーの有無など、テーブルの詳細な情報はエクスポートできず、
後者は、詳細な情報をエクスポートできるが、各フィールドごとに単票形式でエクスポートデータが得られるため、デザインビューのように一覧としてテーブルの設定を把握することが難しい。
よって、既存の機能で対応できないため、
デザインビューのテーブル定義を表形式でエクスポートする関数を作成した。
2020-10-27 ※本記事の関数の内容をもとにツール化したものも作成しました。🔽🔽
[Access VBA] デザインビューのテーブル定義を表形式でエクスポートするAccessツールを作成した
作成環境
Microsoft Office 2019
機能
カレントプロジェクト(コードが貼り付けてあるAccessファイル)の
すべてのテーブルのテーブル定義を表形式でエクスポートする。
エクスポート先は新規エクセルブック。テーブルデータがシートごとに格納される。
関数概要
名前 | 種類 | 機能 |
---|---|---|
exportTableDefTablesMain | Subプロシージャ | テーブル定義情報表形式エクスポートのMain関数 |
getTableDefArray | Functionプロシージャ | テーブルの定義情報を取得 |
getFieldTypeString | Functionプロシージャ | 引数フィールドのデータ型文字列を取得 |
getPKs | Functionプロシージャ | テーブルの主キーであるフィールド名を辞書として取得 |
getFKs | Functionプロシージャ | テーブルの外部キーであるフィールド名を辞書として取得 |
setWSName | Functionプロシージャ | 引数で指定されたエクセルシートの名前をセット |
呼び出し関係
- exportTableDefTablesMain
- 呼出 -> getTableDefArray
- 呼出 -> getFieldTypeString
- 呼出 -> getPKs
- 呼出 -> getFKs
- 呼出 -> setWSName
- 呼出 -> getTableDefArray
コード
[exportTableDefTablesMain]
1'******************************************************************************************
2'*関数名 :exportTableDefTablesMain
3'*機能 :テーブル定義情報テーブルを作成
4'*引数(1) :
5'******************************************************************************************
6Public Sub exportTableDefTablesMain()
7
8 '定数
9 Const FUNC_NAME As String = "exportTableDefTablesMain"
10
11 '変数
12 Dim xlApp As Object
13 Dim wb As Object
14 Dim tdf As DAO.TableDef
15 Dim defArr As Variant
16 Dim fstWs As Object
17 Dim ws As Object
18
19 On Error GoTo ErrorHandler
20
21 'エクセルブック開始
22 Set xlApp = CreateObject("Excel.Application")
23 With xlApp
24 .Visible = False
25 .DisplayAlerts = False
26 .ScreenUpdating = False
27 End With
28 Set wb = xlApp.Workbooks.Add
29
30 '初期シート
31 Set fstWs = wb.Worksheets(1)
32
33 'テーブルごとに別シートにテーブル定義情報テーブルを作成
34 For Each tdf In CurrentDb.TableDefs
35 Do
36 'システムテーブル等出力の必要のないテーブルの場合はcontinue
37 If Left(tdf.Name, 4) = "Msys" Or Left(tdf.Name, 4) = "Usys" Or Left(tdf.Name, 1) = "~" Then Exit Do
38
39 'テーブルの定義情報配列を取得
40 defArr = getTableDefArray(tdf)
41 If IsNull(defArr) Then GoTo ExitHandler
42
43 'ブックで新規シートを作成
44 Set ws = wb.Worksheets.Add
45 If Not setWSName(ws, tdf.Name) Then Call Err.Raise(1000, "シート名指定エラー", "シート名指定の際にエラーが発生しました。")
46
47 '定義情報配列を記入し、列幅調整
48 With ws.Range(ws.cells(1, 1), ws.cells(UBound(defArr) - LBound(defArr) + 1, UBound(defArr, 2) - LBound(defArr, 2) + 1))
49 .Value = defArr
50 .EntireColumn.AutoFit
51 End With
52
53 Loop While False
54 Next tdf
55
56 '初期シートの削除
57 If wb.Worksheets.Count > 1 Then fstWs.Delete
58
59 'ブック保存
60 wb.saveas Application.CurrentProject.Path & _
61 "\" & _
62 Left( _
63 CurrentProject.Name, _
64 InStrRev(CurrentProject.Name, ".") - 1 _
65 ) & _
66 "_テーブル定義一覧.xlsx"
67
68 '完了
69 MsgBox "エクスポート完了", , "通知"
70
71
72ExitHandler:
73
74 'クローズ
75 If Not wb Is Nothing Then wb.Close: Set wb = Nothing
76 If Not xlApp Is Nothing Then xlApp.Quit: Set xlApp = Nothing
77
78 Set tdf = Nothing
79 Set ws = Nothing
80 Set fstWs = Nothing
81
82 Exit Sub
83
84ErrorHandler:
85
86 MsgBox "エラーが発生したため、マクロを終了します。" & _
87 vbLf & _
88 "関数名:" & FUNC_NAME & _
89 vbLf & _
90 "エラー番号:" & Err.Number & vbNewLine & _
91 Err.description, vbCritical, "エラー"
92
93 GoTo ExitHandler
94
95End Sub
新規インスタンスでエクセルを立ち上げる。
初期シートはデータの格納後削除される。
[getTableDefArray]
1'******************************************************************************************
2'*関数名 :getTableDefArray
3'*機能 :テーブルの定義情報を取得
4'* 項目:フィールド名
5'* データ型
6'* サイズ
7'* 必須項目かどうか
8'* 主キー(PK)
9'* 外部キー(FK)
10'* 説明
11'*
12'*引数(1) :テーブル定義
13'*戻り値 :定義情報配列
14'******************************************************************************************
15Public Function getTableDefArray( _
16 ByVal pTdf As DAO.TableDef _
17 ) As Variant
18
19 '定数
20 Const FUNC_NAME As String = "getTableDefArray"
21
22 '変数
23 Dim defArr() As Variant
24 Dim fld As DAO.Field
25 Dim i As Long
26 Dim dicPKs As Object
27 Dim dicFKs As Object
28 Dim description As String
29
30 On Error GoTo ErrorHandler
31
32 getTableDefArray = Null
33
34 '(テーブルのフィールド数 + 1)×7のサイズの配列
35 ReDim defArr(0 To pTdf.Fields.Count, 0 To 6)
36
37 'ヘッダ設定
38 defArr(0, 0) = "フィールド名"
39 defArr(0, 1) = "データ型"
40 defArr(0, 2) = "サイズ"
41 defArr(0, 3) = "必須"
42 defArr(0, 4) = "PK"
43 defArr(0, 5) = "FK"
44 defArr(0, 6) = "説明"
45
46 'テーブルのすべての主キーであるフィールド名を辞書として取得
47 Set dicPKs = getPKs(pTdf)
48 If dicPKs Is Nothing Then GoTo ExitHandler
49
50 'テーブルのすべての外部キーであるフィールド名を辞書として取得
51 Set dicFKs = getFKs(pTdf)
52 If dicFKs Is Nothing Then GoTo ExitHandler
53
54 'フィールドごとに探索
55 For i = 1 To pTdf.Fields.Count
56 Set fld = pTdf.Fields(i - 1)
57 'フィールド名
58 defArr(i, 0) = fld.Name
59 'データ型
60 defArr(i, 1) = getFieldTypeString(fld.Type)
61 'サイズ
62 If fld.Type = dbText Then
63 defArr(i, 2) = fld.Size
64 Else
65 defArr(i, 2) = "-"
66 End If
67 '必須項目かどうか
68 If fld.Required Then defArr(i, 3) = "○"
69 '主キー(PK)かどうか ◆note1
70 If dicPKs.Exists(fld.Name) Then defArr(i, 4) = "○"
71 '外部キー(FK)かどうか ◆note1
72 If dicFKs.Exists(fld.Name) Then defArr(i, 5) = "○"
73 '説明
74 On Error Resume Next
75 description = fld.Properties("Description")
76 On Error GoTo ErrorHandler
77 defArr(i, 6) = description
78 Next i
79
80
81 getTableDefArray = defArr
82
83ExitHandler:
84
85 Set fld = Nothing
86 Set dicFKs = Nothing
87 Set dicPKs = Nothing
88
89 Exit Function
90
91ErrorHandler:
92
93 MsgBox "エラーが発生したため、マクロを終了します。" & _
94 vbLf & _
95 "関数名:" & FUNC_NAME & _
96 vbLf & _
97 "エラー番号:" & Err.Number & vbNewLine & _
98 Err.description, vbCritical, "エラー"
99
100 GoTo ExitHandler
101
102End Function
(引数テーブルのフィールド数+1)×7の大きさの配列を戻り値とする。
◆note1 - テーブルの主キー及び外部キーの辞書配列を先に取得しておいて、
各フィールドがそれに含まれているかどうかをチェックする。
[getFieldTypeString]
1'******************************************************************************************
2'*関数名 :getFieldTypeString
3'*機能 :フィールドのデータ型文字列を取得
4'*引数(1) :フィールドタイプ
5'*戻り値 :フィールドのデータ型文字列
6'******************************************************************************************
7Public Function getFieldTypeString(ByVal pFldTyepNum As Long) As String
8
9 '定数
10 Const FUNC_NAME As String = "getFieldTypeString"
11
12 '変数
13 Dim strType As String
14
15 On Error GoTo ErrorHandler
16
17 strType = ""
18
19
20 Select Case pFldTyepNum
21 Case dbBoolean
22 strType = "ブール型"
23 Case dbByte
24 strType = "バイト型"
25 Case dbInteger
26 strType = "整数型"
27 Case dbLong
28 strType = "長整数型"
29 Case dbSingle
30 strType = "単精度浮動小数点型"
31 Case dbDouble
32 strType = "倍精度浮動小数点型"
33 Case dbCurrency
34 strType = "通貨型"
35 Case dbDate
36 strType = "日付/時刻型"
37 Case dbText
38 strType = "テキスト型"
39 Case dbLongBinary
40 strType = "OLEオブジェクト型"
41 Case dbMemo
42 strType = "メモ型"
43 End Select
44
45 getFieldTypeString = strType
46
47ExitHandler:
48
49 Exit Function
50
51ErrorHandler:
52
53 MsgBox "エラーが発生したため、マクロを終了します。" & _
54 vbLf & _
55 "関数名:" & FUNC_NAME & _
56 vbLf & _
57 "エラー番号:" & Err.Number & vbNewLine & _
58 Err.description, vbCritical, "エラー"
59
60 GoTo ExitHandler
61
62End Function
引数で与えられるDAO.FieldオブジェクトのTypeプロパティは数値であるため、
それを文字列に変換する。
[getPKs]
1'******************************************************************************************
2'*関数名 :getPKs
3'*機能 :テーブルの主キーであるフィールド名を辞書として取得
4'*引数(1) :フィールドタイプ
5'*戻り値 :辞書
6'******************************************************************************************
7Public Function getPKs(ByVal pTdf As DAO.TableDef) As Object
8
9 '定数
10 Const FUNC_NAME As String = "getPKs"
11
12 '変数
13 Dim idx As DAO.Index
14 Dim fld As DAO.Field
15 Dim dic As Object
16
17 On Error GoTo ErrorHandler
18
19 Set getPKs = Nothing
20 Set dic = CreateObject("Scripting.Dictionary")
21
22
23 'インデックスより探索
24 For Each idx In pTdf.Indexes
25 If idx.Primary = True Then
26 For Each fld In idx.Fields
27 dic.Add fld.Name, True
28 Next
29 End If
30 Next
31
32 'Return
33 Set getPKs = dic
34
35ExitHandler:
36
37 Set dic = Nothing
38
39 Exit Function
40
41ErrorHandler:
42
43 MsgBox "エラーが発生したため、マクロを終了します。" & _
44 vbLf & _
45 "関数名:" & FUNC_NAME & _
46 vbLf & _
47 "エラー番号:" & Err.Number & vbNewLine & _
48 Err.description, vbCritical, "エラー"
49
50 GoTo ExitHandler
51
52End Function
[getFKs]
1'******************************************************************************************
2'*関数名 :getFKs
3'*機能 :テーブルの外部キーであるフィールド名を辞書として取得
4'*引数(1) :
5'*戻り値 :辞書
6'******************************************************************************************
7Public Function getFKs(ByVal pTdf As DAO.TableDef) As Object
8
9 '定数
10 Const FUNC_NAME As String = "getFKs"
11
12 '変数
13 Dim rsRelation As DAO.Recordset
14 Dim dic As Object
15
16 On Error GoTo ErrorHandler
17
18 Set getFKs = Nothing
19 Set dic = CreateObject("Scripting.Dictionary")
20
21 'リレーションテーブルにアクセス
22 Set rsRelation = CurrentDb.OpenRecordset( _
23 "SELECT szColumn FROM MSysRelationships WHERE szObject =" & _
24 " " & _
25 "'" & _
26 pTdf.Name & _
27 "'" & _
28 ";" _
29 )
30
31 With rsRelation
32 If .EOF Then Set getFKs = dic: GoTo ExitHandler
33 .MoveFirst
34 Do Until .EOF
35 dic.Add .Fields("szColumn").Value, True
36 .MoveNext
37 Loop
38 End With
39
40 'Return
41 Set getFKs = dic
42
43ExitHandler:
44
45 If Not rsRelation Is Nothing Then rsRelation.Close: Set rsRelation = Nothing
46
47 Exit Function
48
49ErrorHandler:
50
51 MsgBox "エラーが発生したため、マクロを終了します。" & _
52 vbLf & _
53 "関数名:" & FUNC_NAME & _
54 vbLf & _
55 "エラー番号:" & Err.Number & vbNewLine & _
56 Err.description, vbCritical, "エラー"
57
58
59 GoTo ExitHandler
60
61End Function
テーブルの外部キー情報は
システムテーブルのMSysRelationshipsに格納されているため、
Recordsetを用いて情報を取得する。
[setWSName]
1'******************************************************************************************
2'*関数名 :setWSName
3'*機能 :エクセルシートの名前をセット
4'*引数(1) :エクセルシート
5'*引数(2) :代入する名前
6'*戻り値 :True > 正常終了、False > 異常終了
7'******************************************************************************************
8Public Function setWSName( _
9 ByVal ws As Object, _
10 ByVal newName As String _
11 ) As Boolean
12
13 '定数
14 Const FUNC_NAME As String = "setWSName"
15
16 '変数
17
18 On Error GoTo ErrorHandler
19
20 setWSName = False
21
22 ws.Name = newName
23
24 setWSName = True
25
26ExitHandler:
27
28 Exit Function
29
30ErrorHandler:
31
32 'シート名に使用できない文字であった場合
33 ws.Name = "テーブル_" & ws.Parent.Worksheets.Count & "_" & Format(Now, "yyyymmddhhnnss")
34
35 setWSName = True
36 GoTo ExitHandler
37
38End Function
シート名とするテーブル名に
シート名として禁止されている文字(*、?等)が含まれている場合、
シート名重複防止にシート名は「テーブル_全シート数_yyyymmddhhnnss」としている。
使用方法
抽出したいAccessファイルのモジュールのどこかに
上記関数群を記入し、
exportTableDefTablesMainを実行する。
イメージ
次のようにエクセルファイルが出力される。
デザインビュー表示に似せた様式で各情報が一覧できる。
関連記事
- [Access VBA] コントロールソースにユーザ定義関数を用いると列幅の自動調整が想定通りに機能しない問題の解決
- [Excel VBA] 見積書作成ツールを作成した
- 【Excel】非マクロのメール作成ツールを作成した
- Excelのツール開発:関数(非マクロ)ツールとVBA使用ツールの比較