17

您能否告诉我是否可以列出 MS Access 表中的所有字段名称?

4

14 回答 14

20

我在 ms 访问中工作太多了。

我知道这样做的唯一方法是使用 vba,并定义例如记录集,然后循环遍历字段。

例如:

Sub ListFields()

dim rst as new adodb.recordset
rst.open "SELECT * FROM SomeTable", CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly
' Note: adOpenForwardOnly and adLockReadOnly are the default values '
' for the CursorType and LockType arguments, so they are optional here '
' and are shown only for completeness '

dim ii as integer
dim ss as string
for ii = 0 to rst.fields.count - 1
    ss = ss & "," & rst.fields(ii).name
next ii

Debug.Print ss

End Sub

字符串变量ss将包含名为“SomeTable”的表中所有列名的逗号分隔列表。

通过对逻辑进行一些重新格式化,如果您愿意,您应该能够将此数据插入到另一个表中,然后将其查询出来。

这有帮助吗?

于 2012-07-18T23:27:06.617 回答
10

此版本易于运行,并将直接粘贴到 Access 中。将此函数添加到模块中,按 F5 运行,然后从输入框中复制结果:

Public Function FieldNames() As String

    Dim sTable As String
    Dim rs As DAO.Recordset
    Dim n As Long
    Dim sResult As String

    sTable = InputBox("Name of table?")
    If sTable = "" Then
        Exit Function
    End If

    Set rs = CurrentDb.OpenRecordset(sTable)

    With rs
        For n = 0 To .Fields.Count - 1
            sResult = sResult & .Fields(n).Name & vbCrLf
        Next 'n
        .Close
    End With

    Set rs = Nothing

    InputBox "Result:" & vbCrLf & vbCrLf _
            & "Copy this text (it looks jumbled, but it has one field on each line)", _
            "FieldNames()", sResult

End Function

替代输出:

用户 user1003916 提供了 InputBox 的替代方案来克服 1024 个字符的限制(我还没有测试过):

Sub CopyText(Text As String)

    'VBA Macro using late binding to copy text to clipboard.
    'By Justin Kay, 8/15/2014

    Dim MSForms_DataObject As Object
    Set MSForms_DataObject = CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")

    MSForms_DataObject.SetText Text
    MSForms_DataObject.PutInClipboard
    Set MSForms_DataObject = Nothing

End Sub
于 2015-06-15T18:47:07.570 回答
7

更新:要使用此 SQL 查询,您必须使用 DBEAVER 等工具。访问客户端将不允许您查询它的隐藏结构。

哎呀!IMO:我无法想象想要深入 VBA 的阴暗面

如何通过 SQL 获取访问表列

SELECT * FROM information_schema.columns 
    WHERE TABLE_NAME="YOUR_TABLE_NAME" 
       AND 
    TABLE_SCHEMA="PUBLIC" 

PS 我注意到 Access 将我的架构称为“公共”

上面使用了 Access 2016,并通过 ODBC 和 jdbc:ucanaccess 进行了测试,效果非常好。

示例输出

列名的屏幕截图

于 2016-12-19T13:04:35.903 回答
5

您可以简单地使用 Documenter 工具。转至Database Tools > Database Documenter,选择表格并按 OK。

于 2012-07-18T19:44:55.937 回答
2

一种快速而肮脏的方法涉及 Excel。请执行下列操作:

  1. 在数据表视图中打开表。
  2. 使用适用于您的 Access 版本的特定过程导出到 Excel 文件。
  3. 打开 Excel 文件(如果尚未打开)。
  4. 选择并复制包含标题的第一行。
  5. 将另一个工作表添加到工作簿(如果不存在)。
  6. 单击 A1。
  7. 选择性粘贴 > 转置

字段将粘贴在单个列中。要找出它们的字段索引号,请在单元格 B1 中键入“0”,然后将系列填写到字段号的最后一行。

此外,您可以按字母顺序对列进行排序,特别是对于涉及数十个字段的旧版平面文件。当我尝试将平面文件转换为关系模型时,这确实节省了很多时间。

于 2014-07-30T23:52:53.717 回答
1

这不是 SQL,但对于像我这样只需要列出查询所需的字段名称的人来说,这个问题是最重要的 Google 结果,因为 Access 不支持 "* except foo, bar" 以获得 99% 的桌子。

答案改编自 Patrick Wood 的 social.msdn.com 答案,访问 MVP https://social.msdn.microsoft.com/Forums/office/en-US/1fe5546b-db3f-4e17-9bf8-04f4dee233b7/how-to-列出指定表中的所有字段名称?forum=accessdev

将 tablename 更改为您在模块中的名称。这个函数应该在全局级别:

Function ListTdfFields()
    ' NOT doing DIMs, since then you must enable/attach ADODB or DAO
    ' Dim db As ADO.Database
    Set db = CurrentDb
    tablename = "tblProductLicense"  ' <=== YOUR TABLE NAME HERE
    Set tdf = db.TableDefs(tablename)
    For Each fld In tdf.Fields
        Debug.Print tablename; ".["; fld.Name; "]," ; 
        ' remove ending ; for 1 line per field
    Next
    Debug.Print ""
    Set tdf = Nothing
    Set db = Nothing
End Function

然后添加一个宏 RunCode ListTdfFields() 并运行它。输出将被发送到模块的 VBA 设计视图的即时窗口。

于 2017-11-13T19:51:10.847 回答
1

已经有一些很好的答案,但我决定添加我自己的转折。希望它们是不言自明的。

用法:

  • getFieldNames(TableName:="Table1",IncludeBrackets:=True,Delimiter:=vbNewLine,CopyToClipboard:=True)
  • getFieldNames(TableName:="Table1",IncludeBrackets:=True,CopyToClipboard:=True)
  • getFieldNames(TableName:="Table1",IncludeBrackets:=True)
  • getFieldNames(TableName:="Table1")

我用它来构建一个字段名称数组:

  • Chr(34) & getFieldNames(TableName:="Table1",IncludeBrackets:=False, 分隔符:= Chr(34) & "," & Chr(34)) & Chr(34)

Function getFieldNames(ByVal TableName As String, Optional ByVal IncludeBrackets As Boolean, Optional ByVal Delimiter As String = ", ", Optional ByVal CopyToClipboard As Boolean) As String
    Dim rs As DAO.Recordset

    On Error Resume Next
    Set rs = CurrentDb.OpenRecordset(TableName)
    On Error GoTo 0

    If rs Is Nothing Then Exit Function

    Dim results() As String
    ReDim results(rs.Fields.Count - 1)

    Dim n As Long
    For n = 0 To rs.Fields.Count - 1
        results(n) = rs.Fields(n).Name
    Next
    rs.Close

    Dim result As String
    If IncludeBrackets Then
        result = "[" & Join(results, "]" & Delimiter & "[") & "]"
    Else
        result = Join(results, Delimiter)
    End If


    If CopyToClipboard Then
        With CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
            .SetText result
            .PutInClipboard
        End With
    End If

    getFieldNames = result
End Function
于 2019-04-19T10:46:53.203 回答
1

此 SQL 在 Access 2016 中适用于查询,而不是表,但可能有用。

SELECT MSysObjects.Name AS QueryName, 
       IIf(IsNull([Name1]),
           Right([Expression],Len([Expression])-InStr(1,[Expression],".")),[name1])
           AS FieldName
  FROM MSysQueries INNER JOIN MSysObjects 
    ON MSysQueries.ObjectId = MSysObjects.Id
 WHERE MSysQueries.Attribute=6;
于 2019-12-20T17:09:05.990 回答
0

构建查询:

SELECT Table_Name.*
FROM Table_Name
WHERE False;

导出到 Excel 您将在没有任何数据的情况下将每个字段名称放在一行中。如果您选择行并复制,您可以粘贴特殊>转置并将它们全部放在一个列中。

于 2019-01-21T22:02:17.367 回答
0

我想分享这个 VBA 解决方案,我没有写,只是稍作修改(将 tableName 更改为使用'SourceTable')。运行后,您可以查询它创建的表。它利用了隐藏的系统表。

Sub GetField2Description()
'************************************************* *********
'Purpose: 1) Deletes and recreates a table (tblFields)
' 2) Queries table MSysObjects to return names of
' all tables in the database
' 3) Populates tblFields
'Coded by: raskew
'Inputs: From debug window:
' Call GetField2Description
'Output: See tblFields
'************************************************* *********
Dim db As DAO.Database, td As TableDef
Dim rs As Recordset, rs2 As Recordset
Dim Test As String, NameHold As String
Dim typehold As String, SizeHold As String
Dim fielddescription As String, tName As String
Dim n As Long, i As Long
Dim fld As Field, strSQL As String
n = 0
Set db = CurrentDb
' Trap for any errors.
On Error Resume Next
tName = "tblFields"
'Does table "tblFields" exist? If true, delete it;
DoCmd.SetWarnings False
DoCmd.DeleteObject acTable, "tblFields"
DoCmd.SetWarnings True
'End If
'Create new tblTable
    db.Execute     "CREATE TABLE tblFields(Object TEXT (55), FieldName TEXT (55),     FieldType TEXT (20), FieldSize Long, FieldAttributes Long, FldDescription TEXT (20));"
strSQL = "SELECT MSysObjects.Name, MSysObjects.Type From MsysObjects WHERE"
strSQL = strSQL + "((MSysObjects.Type)=1)"
strSQL = strSQL + "ORDER BY MSysObjects.Name;"
Set rs = db.OpenRecordset(strSQL)
If Not rs.BOF Then
' Get number of records in recordset
rs.MoveLast
n = rs.RecordCount
rs.MoveFirst
End If
Set rs2 = db.OpenRecordset("tblFields")
For i = 0 To n - 1
fielddescription = " "
Set td = db.TableDefs(i)
'Skip over any MSys objects
If Left(rs!Name, 4) <> "MSys" And Left(rs!Name, 1) <> "~" Then
NameHold = rs!Name
On Error Resume Next
For Each fld In td.Fields
tableName = fld.SourceTable

fielddescription = fld.Name
typehold = FieldType(fld.Type)
SizeHold = fld.Size
rs2.AddNew
rs2!Object = tableName
rs2!FieldName = fielddescription
rs2!FieldType = typehold
rs2!FieldSize = SizeHold
rs2!FieldAttributes = fld.Attributes
rs2!FldDescription = fld.Properties("description")
rs2.Update
Next fld
Resume Next
End If
rs.MoveNext
Next i
rs.Close
rs2.Close
db.Close
End Sub
Function FieldType(intType As Integer) As String
Select Case intType
Case dbBoolean
FieldType = "dbBoolean" '1
Case dbByte
FieldType = "dbByte" '2
Case dbInteger
FieldType = "dbInteger" '3
Case dbLong
FieldType = "dbLong" '4
Case dbCurrency
FieldType = "dbCurrency" '5
Case dbSingle
FieldType = "dbSingle" '6
Case dbDouble
FieldType = "dbDouble" '7
Case dbDate
FieldType = "dbDate" '8
Case dbBinary
FieldType = "dbBinary" '9
Case dbText
FieldType = "dbText" '10
Case dbLongBinary
FieldType = "dbLongBinary" '11
Case dbMemo
FieldType = "dbMemo" '12
Case dbGUID
FieldType = "dbGUID" '15
End Select
End Function
于 2017-04-17T17:39:48.370 回答
0

我来这里是为了寻找同样的要求,在参考了这个帖子之后,为我的要求起草了下面的代码。源表中的字段名称将被添加到一个数组中,稍后字段名称将分配给第二个表。只是在这里分享,这可能会帮助以后的人..

Public Sub FieldName_Change()
Dim intNumberOfFields, intX As Integer
Dim txtTableName,txttmpTableName txtFieldName() As String

intNumberOfFields = GetFieldNames(txtTableName, txtFieldName())
For intX = 1 To intNumberOfFields
  CurrentDb.TableDefs(txttmpTableName).Fields("F" & intX).Name = txtFieldName(intX)
Next intX
End Sub


Public Function GetFieldNames(ByVal txtTableName As String, ByRef txtFiledName() As String) As Integer
Dim rs As DAO.Recordset
Dim n As Long
Dim sResult As String

Set rs = CurrentDb.OpenRecordset(txtTableName)
ReDim txtFiledName(rs.Fields.Count)
With rs
    For n = 0 To .Fields.Count - 1
        txtFiledName(n + 1) = .Fields(n).Name
    Next n
    .Close
    GetFieldNames = n
End With
Set rs = Nothing
End Function
于 2020-04-03T06:08:03.123 回答
-1

似乎这项任务在过去更容易。这个答案可能高度依赖于版本。它适用于我对 Access 2007 DB 的快速测试:

select 
Specs.SpecName AS TableName,
Columns.FieldName
from
MSysIMEXColumns Columns
inner join MSysIMEXSpecs Specs on Specs.SpecID = Columns.SpecID
order by
Specs.SpecName,
Columns.FieldName
于 2012-07-19T02:34:39.233 回答
-1

试试这个...

    private void Button_OldDDLDump_Click(object sender, EventArgs e)
    {
        string _cnstr = "connectionstringhere";
        OleDbConnection _cn = new OleDbConnection(_cnstr);
        try
        {
            _cn.Open();
            System.Data.DataTable _dt = null;            
            try
            {
                _dt = _cn.GetSchema("tables");
                m_msghelper.AppendArray( DataTableHelper.DataTableToString(_dt) );                               
            }
            catch (Exception _ex)
            {
                System.Diagnostics.Debug.WriteLine(_ex.ToString());
            }
            finally
            {
                _dt.Dispose();
            }
        }
        catch (Exception _ex)
        {
            System.Diagnostics.Debug.WriteLine(_ex.ToString());
        }
        finally
        {
            _cn.Close();
        }
    }

在此处将数据库结构转储到字符串数组的辅助方法..

public static class DataTableHelper
{
    public static string[] DataTableToString( System.Data.DataTable dt )
    {
        List<string> _retval = new List<string>();

        foreach (System.Data.DataRow row in dt.Rows)
        {
            foreach (System.Data.DataColumn col in dt.Columns)
            {
                _retval.Add( string.Format("{0} = {1}", col.ColumnName, row[col]) );
            }
            _retval.Add( "============================");
        }
        return _retval.ToArray();
    }
}
于 2016-03-16T23:06:32.500 回答
-2

从 information_schema.columns 中选择 column_name,其中 table_name='table'

于 2016-06-06T18:42:16.817 回答