报告连接到值的行和列名称(Microsoft Access)

时间:2013-04-05 20:42:47

标签: excel ms-access

由于我不使用数据库,所以我对这个问题的态度非常深刻。我希望通过在其他网站上帮助人们使用InDesign和Photoshop来向我们付出代价就足够了!

我可以使用Access或Excel进行操作。

我的数据看起来像:

year  President   Vice
1980  Reagan      Bush Sr.
1984  Reagan      Bush Sr.
1988  Bush Sr.    Quayle
1992  Clinton     Gore
1996  Clinton     Gore
2000  Bush Jr.    Cheney
2004  Bush Jr.    Cheney
2008  Obama       Biden
2012  Obama       Biden

我想要一份看起来像的报告:

Biden: Vice 2008, 2012
Bush Jr.: President 2000, 2004
Bush Sr.: President 1988; Vice 1980, 1984
Cheney: Vice 2000, 2004
Clinton: President 1992, 1996
Gore: Vice 1992, 1996
Obama: President 2008, 2012
Quayle: Vice 1988
Reagan: President 1980, 1984

我无法弄清楚如何识别可能出现在桌面上任何位置的常用名称,以及如何获取报告的行标签和列标签。

这是真实数据的简化版本,与政治家没有关系。实际上有十个列标签是相关的,而不仅仅是两个。 “老布什”举例说明一个人持有两个不同的办公室。

目前没有任何情况下同一行中的两个不同的列中出现相同的名称,但我不想排除这种可能性,除非允许这种情况变得非常复杂。

谢谢!

1 个答案:

答案 0 :(得分:2)

我们需要做的第一件事是通过UNION查询将数据从“少量行,多列”转换为“少量列,多行”。 (我将测试数据保存在名为[N_column_table]的表中。)

SELECT [year], "President" AS office, [President] AS person
FROM [N_column_table]
UNION ALL
SELECT [year], "Vice" AS office, [Vice] AS person
FROM [N_column_table]

如果您将该查询保存为“3_column_data”,那么您可以像在其他查询,报告等中使用它一样使用它。(在构建查询时,您将不得不添加约8个UNION ALL构造对于真实数据。)

所以现在我们的数据看起来像这样

year    office      person
1980    President   Reagan
1984    President   Reagan
1988    President   Bush Sr.
1992    President   Clinton
1996    President   Clinton
2000    President   Bush Jr.
2004    President   Bush Jr.
2008    President   Obama
2012    President   Obama
1980    Vice        Bush Sr.
1984    Vice        Bush Sr.
1988    Vice        Quayle
1992    Vice        Gore
1996    Vice        Gore
2000    Vice        Cheney
2004    Vice        Cheney
2008    Vice        Biden
2012    Vice        Biden

现在,至于“粘合”办公室和年份,我们需要使用一点VBA功能。在Access中创建一个模块,并粘贴以下代码

Public Function ListTerms(person As String) As String
Dim cdb As DAO.Database
Dim rstOffice As DAO.Recordset, rstYear As DAO.Recordset
Dim result As String, yearString As String

Const YearSeparator = ", "
Const OfficeSeparator = "; "

Set cdb = CurrentDb
result = ""

Set rstOffice = cdb.OpenRecordset( _
        "SELECT DISTINCT office " & _
        "FROM 3_column_data " & _
        "WHERE person=""" & Replace(person, """", """""", 1, -1, vbBinaryCompare) & """ " & _
        "ORDER BY 1")
Do While Not rstOffice.EOF
    yearString = ""
    Set rstYear = cdb.OpenRecordset( _
            "SELECT DISTINCT [year] " & _
            "FROM 3_column_data " & _
            "WHERE person=""" & Replace(person, """", """""", 1, -1, vbBinaryCompare) & """ " & _
                "AND office=""" & Replace(rstOffice!Office, """", """""", 1, -1, vbBinaryCompare) & """ " & _
            "ORDER BY 1")
    Do While Not rstYear.EOF
        If Len(yearString) > 0 Then
            yearString = yearString & YearSeparator
        End If
        yearString = yearString & rstYear!Year
        rstYear.MoveNext
    Loop
    rstYear.Close
    Set rstYear = Nothing
    If Len(result) > 0 Then
        result = result & OfficeSeparator
    End If
    result = result & rstOffice!Office & " " & yearString
    rstOffice.MoveNext
Loop
rstOffice.Close
Set rstOffice = Nothing
Set cdb = Nothing
ListTerms = result
End Function

现在我们可以在查询中使用该功能列出每个人及其在办公室的条款

SELECT personlist.[person], ListTerms(personlist.[Person]) as terms
FROM (SELECT DISTINCT person FROM 3_column_data) personlist

返回

person      terms
Biden       Vice 2008, 2012
Bush Jr.    President 2000, 2004
Bush Sr.    President 1988; Vice 1980, 1984
Cheney      Vice 2000, 2004
Clinton     President 1992, 1996
Gore        Vice 1992, 1996
Obama       President 2008, 2012
Quayle      Vice 1988
Reagan      President 1980, 1984