如何使用SQL在Access中的表中列出字段名称

时间:2012-07-18 19:16:13

标签: sql ms-access

如果可以在MS Access表中列出所有字段名称,请告诉我吗?

14 个答案:

答案 0 :(得分:14)

我在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”的表中所有列名的逗号分隔列表。

稍微重新格式化逻辑,你应该能够将这些数据插入到另一个表中,然后查询它。

这有帮助吗?

答案 1 :(得分:7)

此版本易于运行,并将粘贴到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

答案 2 :(得分:3)

更新:使用这个SQL查询你必须使用像DBEAVER这样的工具。 访问客户端不会允许您查看隐藏的结构。

YIKES!国际海事组织:我无法想象想要潜入VBA的黑暗腹部

如何通过SQL获取访问表列

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

PS我注意到Access称为我的架构“PUBLIC”

上面使用了Access 2016,并通过ODBC和jdbc进行了测试:ucanaccess,就像魅力一样。

示例输出

Screen shot of column names

答案 3 :(得分:2)

您只需使用Documenter工具即可。转到Database Tools > Database Documenter,选择表格,然后按确定。

答案 4 :(得分:1)

这不是SQL,但对于像我这样只需要列出查询所需字段名称的人来说,这个问题是谷歌的最高结果,因为Access不支持“* foo,bar”以获得99表的百分比。

答案改编自社交网站www.msdn.com,答案是Patrick Wood,Access MVP https://social.msdn.microsoft.com/Forums/office/en-US/1fe5546b-db3f-4e17-9bf8-04f4dee233b7/how-to-list-all-the-field-names-in-a-specified-table?forum=accessdev

将表名更改为模块中的名称。该功能应该在全球范围内:

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设计视图的立即窗口。

答案 5 :(得分: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,Delimiter:= 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

答案 6 :(得分:0)

看起来这个任务在过去的日子里比较容易。可能这个答案高度依赖于版本。它适用于我对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

答案 7 :(得分:0)

快速而肮脏的方法涉及Excel。执行以下操作:

  1. 在数据表视图中打开表格。
  2. 使用Access版本的特定过程导出到Excel文件。
  3. 打开Excel文件(如果尚未打开)。
  4. 选择并复制包含标题的第一行。
  5. 将另一个工作表添加到工作簿(如果不存在)。
  6. 点击A1。
  7. Paste Special&gt;移调
  8. 字段将粘贴在一列中。要查找其字段索引号,请在单元格B1类型&#34; 0&#34;中,然后系列填充到字段编号的最后一行。

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

答案 8 :(得分:0)

放手一搏......

    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();
        }
    }

将数据库结构转储到字符串数组的Helper方法..

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();
    }
}

答案 9 :(得分: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

答案 10 :(得分:0)

构建查询:

SELECT Table_Name.*
FROM Table_Name
WHERE False;

导出到Excel 每个字段名称将排成一行,没有任何数据。如果选择该行并复制,则可以粘贴special> transpose,并将它们全部放在一个列中。

答案 11 :(得分:0)

此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;

答案 12 :(得分: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

答案 13 :(得分:-2)

从information_schema.columns中选择column_name,其中table_name =&#39; table&#39;