我一直在做关于这一主题有点研究,我似乎无法找到一条可行的解决方案,或者一个解释不够好,我来实现。
如果你曾经创建在Access交叉表查询,大家都知道,在默认情况下访问按字母顺序排序的列。 您可以通过转到属性对话框并在您喜欢的顺序输入列标题更改此顺序。 这是一个真正的痛苦,但是,因为在其他网站上提到的一个回答者,“这只是一个痛一次 !”
嗯......如果你的列是动态的,这是不正确的。 就我而言,我有一个包含列标题,我想使用该字段进行排序表中第二列。 我想我可以追加我的排序列的细节,说明柱前端(已经提出的其他地方),但我不觉得这是解决问题的最优雅的方式。 这是特别的问题,因为这类信息系统数据和无用的交叉表的最终用户。
有谁知道一个解决这个问题的? 如果是这样,你能拼出一个交叉表查询的动态列排序的步骤是什么?
我认为这个问题是跨越处于共同使用(访问2003+),但以防万一它的确与众不同,我使用Access 2010的所有版本的Access持久。
UPDATE
下面是一些非常简单的,样本数据,帮助快递问题。 大约有我的生活场景包围的其他一些复杂性,但这个数据肯定是建立一个对获取点。
表#1这是标题从何而来。 该Key
是排序的列顺序和Descriptions
是在交叉表输出的标题。
+---------+---------------------------------------+
| Key | Descriptions |
+---------+---------------------------------------+
| Kfsg2E | Hey, this is accounting code X! |
+---------+---------------------------------------+
| abR3 | This is yet another accounting code! |
+---------+---------------------------------------+
| Gruu! | Yet another accounting code |
+---------+---------------------------------------+
表#2这是数据的商店P_Key + F_Key
是独特的,这两者是在表中的主键。
+---------+---------+-------+
| P_Key | F_Key | Value |
+---------+---------+-------+
| 1001 |Kfsg2E | 1.0 |
+---------+---------+-------+
| 1001 |abR3 | 1.1 |
+---------+---------+-------+
| 1001 |Gruu! | 1.2 |
+---------+---------+-------+
| 1002 |Kfsg2E | 2.0 |
+---------+---------+-------+
| 1002 |abR3 | 2.1 |
+---------+---------+-------+
| 1002 |Gruu! | 2.2 |
+---------+---------+-------+
| 2001 |Kfsg2E | 3.0 |
+---------+---------+-------+
| 2001 |abR3 | 3.1 |
+---------+---------+-------+
| 2001 |Gruu! | 3.2 |
+---------+---------+-------+
交叉结果这些被导出到Excel的用户更新。
+---------+---------------------------------+--------------------------------------+-----------------------------+
| P_Key | Hey, this is accounting code X! | This is yet another accounting code! | Yet another accounting code |
+---------+---------------------------------+--------------------------------------+-----------------------------+
| 1001 | 1.0 | 1.1 | 1.2 |
+---------+---------------------------------+--------------------------------------+-----------------------------+
| 1001 | 2.0 | 2.1 | 2.2 |
+---------+---------------------------------+--------------------------------------+-----------------------------+
| 1001 | 3.0 | 3.1 | 3.2 |
+---------+---------------------------------+--------------------------------------+-----------------------------+
这是Access如何排序这些列。 不过,我需要它看起来就像是下面的表格,这是在排序落键的Table #1
,而不是Description
。
+---------+--------------------------------------+-----------------------------+---------------------------------+
| P_Key | This is yet another accounting code! | Yet another accounting code | Hey, this is accounting code X! |
+---------+--------------------------------------+-----------------------------+---------------------------------+
| 1001 | 1.1 | 1.2 | 1.0 |
+---------+--------------------------------------+-----------------------------+---------------------------------+
| 1001 | 2.1 | 2.2 | 2.0 |
+---------+--------------------------------------+-----------------------------+---------------------------------+
| 1001 | 3.1 | 3.2 | 3.0 |
+---------+--------------------------------------+-----------------------------+---------------------------------+
已经遇到了同样的情况不同的时间,我准备了一个可重复的方式,以一个在列表中添加到PIVOT子句结尾。 这样做将在透视字段在列表中元素的顺序在交叉表查询的列进行排序。 此结构的文档可以从MSDN 。 该解决方案是需要由一个或另一种形式的事件上的命令按钮来触发的过程。 请参阅下面的子屏幕截图。
Public Sub SortPivotColumns(querynameSource As String, queryname As String, SortName As String, SortColumnNameField As String, SortIndexName As String, NonPivotFieldCount As Integer, ParamArray ParamArr() As Variant)
' This sub goes through several steps to effectively adds an In list that sorts the 'Columns' of a crosstab query in MS Access
' 13 November 2012
' E Easterly
'
' This technique uses several components.
' 1) The original unmodified cross tab query (querynameSource)
' 2) The resulting, columns-have-been-sorted query (query)
' 3) An index table which has two columns, a numeric index used for sorting and the column name
' 4) A table or query that can be joined on the column names of the cross tab query to update the index table
' The name of the table or query would be 'SortName'
' The field in 'SortName' that the crosstab query columns are joined against is the 'SortColumnNameField'
' The field in 'SortName' that has the desired order is the SortIndexName
' 5) A number which specifies the count of non-pivot/row heading columns (NonPivotFieldCount)
' 6) An optional array that contains any parameters needed for the query
'
'
' USE:
'
' SortPivotColumns "qryCrosstab_Initial", _
' "qryCrosstab_Sorted", _
' "tblKeyDescriptions", _
' "Descriptions", _
' "NumericIndexForSorting", _
' 1
'
'
'
'
Dim rs As DAO.Recordset
Dim db As Database
Dim fld As DAO.Field
Dim sql As String
Dim ColumnHeading As Variant
Dim qdf As QueryDef
Dim qdfSRC As QueryDef
Dim UpdateIndexSQL As Variant
DoCmd.SetWarnings False 'Turn off warnings
Set db = CurrentDb
Set qdfSRC = db.QueryDefs(querynameSource)
Set qdf = db.QueryDefs(queryname)
qdf.sql = qdfSRC.sql
If Not (IsEmpty(ParamArr)) Then
Dim i As Integer
For i = 0 To UBound(ParamArr)
qdf.Parameters(i) = ParamArr(i)
Next
End If
' First, get the list of fields from the query
Set rs = qdf.OpenRecordset
' Then, create a temporary indexing table
If Not IsNull(DLookup("Name", "MSysObjects", "Name='ttblSortCrosstabColumns' And Type In (1,4,6)")) Then
db.Execute "DROP TABLE ttblSortCrosstabColumns"
End If
db.Execute "CREATE TABLE ttblSortCrosstabColumns (FieldIndex INTEGER , ColumnName TEXT(250))"
' And populate it with the current index and column names from queryname
For Each fld In rs.Fields
If fld.OrdinalPosition > (NonPivotFieldCount - 1) Then
DoCmd.RunSQL "Insert into ttblSortCrosstabColumns VALUES(" & fld.OrdinalPosition & ", """ & fld.Name & """)"
End If
Next fld
Set fld = Nothing
rs.Close
Set rs = Nothing
' Now, the temporary table is joined with the sort table/query and the indexes are updated
UpdateIndexSQL = (" UPDATE ttblSortCrosstabColumns " & _
" INNER JOIN " & SortName & " ON ttblSortCrosstabColumns.ColumnName=" & SortName & "." & SortColumnNameField & _
" Set ttblSortCrosstabColumns.FieldIndex = [" & SortIndexName & "]")
DoCmd.RunSQL (UpdateIndexSQL)
' Then, the column headings are added to a string to prepare the In list
sql = "SELECT ttblSortCrosstabColumns.ColumnName FROM ttblSortCrosstabColumns ORDER BY ttblSortCrosstabColumns.FieldIndex"
Set rs = db.OpenRecordset(sql)
rs.MoveFirst
ColumnHeading = "'" & rs.Fields(0).Value & "'"
rs.MoveNext
Do While Not rs.EOF
ColumnHeading = ColumnHeading & ", '" & rs.Fields(0).Value & "'"
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
' db.Execute "DROP TABLE ttblSortCrosstabColumns"
Dim cs As Variant
' Set qdf = db.QueryDefs(queryname) ' may not need this
' The query is updated with the In list
cs = Left$(qdf.sql, Len(qdf.sql) - 3) & " In(" & ColumnHeading & ");"
qdf.sql = cs
' Take a look at the resulting query sql by uncommenting the below section
' Debug.Print cs
DoCmd.SetWarnings True 'Turn warnings back on
End Sub
在下面的屏幕截图,请注意tblKeyDescriptions和tblPFValues。 这些是问题。 qryCrosstab_Initial类似于上述问题所提供的查询。 该表格用来运行程序和之前和查询后打开。
因为子需要用于排序的列名的数字索引的整数字段(NumericIndexForSorting)加入到tblKeyDescriptions。
现在,检查在初始和分类查询的SQL视图中突出显示了在列表中。
这是所有需要为了在交叉表查询的列。 动态地生成在列表子的目的。
注:子需要每个查询运行时间运行,因此使用的事件,如一个命令按钮在Click事件绑在一起的顺序是有帮助的。
下面是使用了一些访问与Excel中的一个不完美的解决方案:
- 当进行交叉表,使用Table1.Key的列。
- 在一个新的标签(称之为“查找”?)Excel文件,使表#1
- 在Excel文件中的主选项卡(即其中数据集粘贴)的第一行,创建一批VLOOKUP()的公式来看待列#2和从您的查找表的正确描述拉。
- 粘贴数据集成列#2。 其结果将是下面的表格,其中第一行实际上是一堆Vlookups的是,在正确的列描述拉。
- 请用户忽略或删除列#2。
我不知道你的脚本是多么复杂,但是,如果这个数据被粘贴到通过自动化的Excel文件,那么你可以只隐藏列#2并跳过步骤6。
+---------+--------------------------------------+-----------------------------+---------------------------------+
| P_Key | This is yet another accounting code! | Yet another accounting code | Hey, this is accounting code X! |
+---------+--------------------------------------+-----------------------------+---------------------------------+
|PasteHere| abR3 | Gruu! | Kfsg2E |
+---------+--------------------------------------+-----------------------------+---------------------------------+
| 1001 | 1.1 | 1.2 | 1.0 |
+---------+--------------------------------------+-----------------------------+---------------------------------+
| 1001 | 2.1 | 2.2 | 2.0 |
+---------+--------------------------------------+-----------------------------+---------------------------------+
| 1001 | 3.1 | 3.2 | 3.0 |
+---------+--------------------------------------+-----------------------------+---------------------------------+
我只是解决了这个问题。 虽然提供的解决方案工程(按说明)另一种可能的解决方案是动态创建查询清晰度(像描述的解决方案),但不是改变查询的SQL,只需填写查询的列标题属性与列标题的动态生成的字符串。 OP已经提到的列标题的工作,但不是这似乎更容易实现,涉及到什么,但一些VBA枚举字符串的可能值,并设置属性
- 产生交叉的QueryDef
- 枚举列标题为字符串
- 设置性能
所以,我要试试这个,看看它是否工作/可能
好....原来的列标题是的QueryDef没有实际的属性,但它会自动放入SQL。
我想我有一个光辉的时刻;)
如果你知道你查询的预期成果和可以预测的列数,订购交叉表查询的结果,最简单的方法是在属性表中指定的列标题字段正确的顺序。
文章来源: How can I sort the columns in a crosstab query, when the column data is dynamic?