首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >在ACCESS中导出所有数据表字段、外键关系。

在ACCESS中导出所有数据表字段、外键关系。

原创
作者头像
用户3597702
修改2025-08-16 09:00:03
修改2025-08-16 09:00:03
910
举报

在access数据库设计过程中可能会有导出数据表关系的需求,但是access自带的关系视图不支持导出功能,做成报表看起来也很杂乱。可以使用以下代码进行导出为excel文件:

代码语言:txt
复制
Option Compare Database
Option Explicit

' 将只在“引用方(子表)的字段”行显示它引用的“被引用方(父表.字段)”。
Public Sub ExportTableStructure_ChildFKsOnly()
    Dim db As DAO.Database
    Dim tdf As DAO.TableDef
    Dim fld As DAO.Field
    Dim rel As DAO.Relation
    Dim rf As DAO.Field
    Dim fkMap As Object
    Dim xlApp As Object, xlWB As Object, xlWS As Object
    Dim rowNum As Long
    Dim leftKey As String, rightKey As String
    Dim childKey As String, parentKey As String
    Dim leftIsPK As Boolean, rightIsPK As Boolean
    Dim debugMode As Boolean

    debugMode = False ' 如需调试改为 True(将在即时窗口输出判断信息)

    Set db = CurrentDb
    Set fkMap = CreateObject("Scripting.Dictionary")

    ' ==== 收集映射:只记录 子表字段 -> 父表字段 ====
    For Each rel In db.Relations
        If Left(rel.Name, 4) <> "MSys" Then
            For Each rf In rel.Fields
                leftKey = rel.Table & "." & rf.Name
                rightKey = rel.ForeignTable & "." & rf.ForeignName

                leftIsPK = IsFieldInPrimaryIndex(db, rel.Table, rf.Name)
                rightIsPK = IsFieldInPrimaryIndex(db, rel.ForeignTable, rf.ForeignName)

                ' 判断哪一侧更像“父表(主键)”,另一侧就是子表(外键)
                If rightIsPK And Not leftIsPK Then
                    childKey = leftKey: parentKey = rightKey
                ElseIf leftIsPK And Not rightIsPK Then
                    childKey = rightKey: parentKey = leftKey
                Else
                    ' 若两侧都不是/或两侧都是主键,回退到 DAO 的常见约定:把 rel.Table 视为“子表”
                    childKey = leftKey: parentKey = rightKey
                End If

                If debugMode Then
                    Debug.Print "Rel=" & rel.Name & " pair:" & leftKey & "<->" & rightKey & _
                                " leftIsPK=" & leftIsPK & " rightIsPK=" & rightIsPK & _
                                " -> child=" & childKey & " parent=" & parentKey
                End If

                If fkMap.Exists(childKey) Then
                    fkMap(childKey) = fkMap(childKey) & "; " & parentKey
                Else
                    fkMap.Add childKey, parentKey
                End If
            Next rf
        End If
    Next rel

    ' ==== 写入 Excel ====
    Set xlApp = CreateObject("Excel.Application")
    xlApp.Visible = True
    Set xlWB = xlApp.Workbooks.Add
    Set xlWS = xlWB.Sheets(1)
    On Error Resume Next
    xlWS.Name = "表结构"
    On Error GoTo 0
    xlWS.Range("A1:D1").Value = Array("表名", "字段名称", "数据类型", "外键关系")
    rowNum = 2

    For Each tdf In db.TableDefs
        If Left(tdf.Name, 4) <> "MSys" And Left(tdf.Name, 1) <> "~" Then
            For Each fld In tdf.Fields
                xlWS.Cells(rowNum, 1).Value = tdf.Name
                xlWS.Cells(rowNum, 2).Value = fld.Name
                xlWS.Cells(rowNum, 3).Value = FieldTypeName(fld.Type)
                If fkMap.Exists(tdf.Name & "." & fld.Name) Then
                    xlWS.Cells(rowNum, 4).Value = fkMap(tdf.Name & "." & fld.Name)
                Else
                    xlWS.Cells(rowNum, 4).Value = ""
                End If
                rowNum = rowNum + 1
            Next fld
        End If
    Next tdf

    MsgBox "导出完成!", vbInformation
End Sub

' 判断某表的某字段是否属于该表的主键索引(Primary Index)
Private Function IsFieldInPrimaryIndex(db As DAO.Database, tableName As String, fieldName As String) As Boolean
    On Error GoTo ErrHandle
    Dim tdf As DAO.TableDef
    Dim idx As DAO.Index
    Dim idxFld As DAO.Field
    Set tdf = db.TableDefs(tableName)
    For Each idx In tdf.Indexes
        If idx.Primary Then
            For Each idxFld In idx.Fields
                If idxFld.Name = fieldName Then
                    IsFieldInPrimaryIndex = True
                    Exit Function
                End If
            Next idxFld
        End If
    Next idx
    Exit Function
ErrHandle:
    ' 表不存在或无索引时视为 False
    IsFieldInPrimaryIndex = False
    Err.Clear
End Function

Private Function FieldTypeName(TypeCode As Integer) As String
    Select Case TypeCode
        Case dbBoolean: FieldTypeName = "Yes/No"
        Case dbByte: FieldTypeName = "Byte"
        Case dbInteger: FieldTypeName = "Integer"
        Case dbLong: FieldTypeName = "Long Integer"
        Case dbCurrency: FieldTypeName = "Currency"
        Case dbSingle: FieldTypeName = "Single"
        Case dbDouble: FieldTypeName = "Double"
        Case dbDate: FieldTypeName = "Date/Time"
        Case dbText: FieldTypeName = "Text"
        Case dbLongBinary: FieldTypeName = "OLE Object"
        Case dbMemo: FieldTypeName = "Memo"
        Case Else: FieldTypeName = "Other(" & TypeCode & ")"
    End Select
End Function

复制以上代码,在vba编辑器里创建一个模块,随便起一个名字,将代码粘贴进去,运行即可一键导出。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档