需要澄清
当我第一次想出这个答案时,我使用了约翰在他聪明的 Excel 答案中使用的相同方法,即使用每列最小行数的总和来产生排名。这会在问题中产生样本结果,但请考虑以下修改后的测试数据:
F1 F2 F3 F4 RowNum
--- --- --- --- ------
XXX bar baz bat 1
foo XXX baz bat 2
YYY bar XXX bat 3
foo YYY baz bat 4
foo bar YYY bat 5
foo bar baz YYY 6
foo bar baz bat 7
foo bar baz bat 8
foo bar baz bat 9
foo bar baz XXX 10
XXX 出现在第 1、2、3 和 10 行,因此总和为 16。YYY 出现在第 3、4、5 和 6 行,因此总和为 18。按总和排名将宣布 XXX 获胜,即使如果您从第 1 行开始扫描 XXX,则必须一直到第 10 行才能到达最后一个 XXX,而如果您从第 1 行开始扫描 YYY,则只需向下到第 6 行即可到达最后一个年年。
在这种情况下,YYY真的应该是赢家吗?
(原答案)
以下代码将 Excel 数据导入 Access 并添加 [RowNum] 列
Sub ImportExcelData()
On Error Resume Next '' in case it doesn't already exist
DoCmd.DeleteObject acTable, "ExcelData"
On Error GoTo 0
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, "ExcelData", "C:\Users\Gord\Documents\ExcelData.xlsx", False
CurrentDb.Execute "ALTER TABLE ExcelData ADD COLUMN RowNum AUTOINCREMENT(1,1)", dbFailOnError
End Sub
所以现在我们在 Access 中有一个像这样的 [ExcelData] 表
F1 F2 F3 F4 RowNum
--- --- --- --- ------
abc bcd abc def 1
cde fgh def bcd 2
def def bcd abc 3
bcd hji xyz lmn 4
让我们创建一个名为ExcelItems
Access 的已保存查询,以将条目串在一个长“列表”中......
SELECT F1 AS Item, RowNum, 1 AS ColNum FROM ExcelData
UNION ALL
SELECT F2 AS Item, RowNum, 2 AS ColNum FROM ExcelData
UNION ALL
SELECT F3 AS Item, RowNum, 3 AS ColNum FROM ExcelData
UNION ALL
SELECT F4 AS Item, RowNum, 4 AS ColNum FROM ExcelData
……归来……
Item RowNum ColNum
---- ------ ------
abc 1 1
cde 2 1
def 3 1
bcd 4 1
bcd 1 2
fgh 2 2
def 3 2
hji 4 2
abc 1 3
def 2 3
bcd 3 3
xyz 4 3
def 1 4
bcd 2 4
abc 3 4
lmn 4 4
现在我们可以找到为每个 ColNum 找到 Item 的最低 RowNum...
TRANSFORM Min(ExcelItems.[RowNum]) AS MinOfRowNum
SELECT ExcelItems.[Item]
FROM ExcelItems
GROUP BY ExcelItems.[Item]
PIVOT ExcelItems.[ColNum] In (1,2,3,4);
……归来……
Item 1 2 3 4
---- - - - -
abc 1 1 3
bcd 4 1 3 2
cde 2
def 3 3 2 1
fgh 2
hji 4
lmn 4
xyz 4
如果我们将该查询保存为,ExcelItems_Crosstab
那么我们可以使用它来对所有四列中出现的项目进行排名:
SELECT Item, [1]+[2]+[3]+[4] AS Rank
FROM ExcelItems_Crosstab
WHERE ([1]+[2]+[3]+[4]) IS NOT NULL
ORDER BY 2
……归来……
Item Rank
---- ----
def 9
bcd 10