繁体   English   中英

我想将行转置为ms-access中的列

[英]I want to transpose rows into columns in ms-access

我需要将行转换为MS Access数据库,VBA,SQL中的列,欢迎使用这两种代码。

    | Name | Ticker | ID | Innovation | Quality | Year |
    | XYZ  |  PQR   | 11 | 1          | 1       | 2009 | 
    | XYZ  |  PQR   | 11 | 0          | 1       | 2010 | 
    | XYZ  |  PQR   | 11 | 1          | 0       | 2011 | 
    | XYZ  |  PQR   | 11 | 1          | 1       | 2012 | 

所需表

    | Year        | 2009 | 2010 | 2011 | 2012 |
    | Name        | XYZ  | XYZ  |  XYZ |  XYZ |
    | Ticker      | PQR  | PQR  | PQR  | PQR  |
    | ID          | 11   | 11   | 11   | 11   |
    | Innovation  | 1    | 0    | 1    | 1    |
    | Quality     | 1    | 1    | 0    | 1    |

从所需的表中可以看到,我试图将Year行作为Column,并列出Year以外的所有列作为我的行。 我试过在MS Access中使用Tranform和Pivot函数,但它仅枢转一个变量。 让我知道您对此的想法。

以下代码未能转置所有变量。

    TRANSFORM Max([Quality])
    SELECT Ticker
    FROM Table
    Where Ticker = "XYZ"
    GROUP BY Ticker
    PIVOT Year;

另外,如果可能的话,我想将其发布为PDF文档。

在此先感谢RVG

Access TRANSFORM并不是很直观且易于使用,我不认为您可以那样使用它。 每个结果行都应该是表的汇总。 我不知道如何将以前的字段名称添加到新列中。

请参见工作示例: Access 2013 SQL中的TRANSFORM和PIVOT

您真正想要的只是对现有数据的新呈现。

Excel可能会有所帮助。

我从来没有从Access导出pdf,但是从Excel导出很容易。 这是一个例子:

Sub ExportPdf(path As String, Optional openAfter As Boolean)

''calculate best range for print area
Dim lastCol As Integer
Dim firstRow As Integer
Dim lastRow As Integer

lastCol = pt.TableRange2.Columns(pt.TableRange2.Columns.Count).Column
firstRow = pt.TableRange2.Rows(1).Row
lastRow = ms.Cells(pt.TableRange2.Rows.Count * 3, 1).End(xlUp).Row

Worksheets(ContextSheet).PageSetup.PrintArea = Range(Cells(firstRow, 1), Cells(lastRow, lastCol)).Address

Worksheets(ContextSheet).ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
    path & "\Area " & getPivotTablePageFilters(getPivotTable()) & ".pdf", Quality:= _
    xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, _
    OpenAfterPublish:=openAfter
End Sub

这是一个vb脚本,该脚本从TableSource获取数据并将其转置为TableTranspose。 第二个表必须设置一个名为FName的列以获取字段名称,并在源表中每年设置一列。

Function Transpose()
Set db = CurrentDb()
db.Execute ("delete * from TableTranspose")
Set RS = db.OpenRecordset("TableSource")
Set YrList = db.OpenRecordset("select distinct [Yr] from [TableSource] Group by [Yr]")

For Each F In RS.Fields
    FN = F.Name
    INS = "Insert Into TableTranspose (FName"
    SQL = "Select '" & FN & "'"
    YrList.MoveFirst
    Do While Not YrList.EOF
        YR = YrList.Fields("YR").Value
        INS = INS & ",[" & YR & "]"
        SQL = SQL & ",max(iif(YR=" & YR & ",[" & FN & "])) AS [" & YR & "]"
        YrList.MoveNext
        Loop
    SQL = SQL & " From TableSource"
    db.Execute (INS & ") " & SQL)

Next F
MsgBox ("Done")
End Function

这是通过一次处理一个字段以匹配所需输出的布局,并遍历TableSource的每一年以查找组成TableTranspose中的行的数据来实现的。 有多少个字段或它们的名字都没有关系。

它将在Year的输出中创建一行,这将是多余的-您可以将其删除,或者在必要时添加逻辑以跳过该字段。

这似乎可以处理样本中的4年数据,并且可以将其扩展到更多年。 如果数据中的年份太多,则可能会达到SQL命令长度的限制,但我认为不是。

如果要从TableSource过滤记录,则可以仅从底部附近的db.execute行中添加WHERE子句。

数据是否始终是同一组字段名称和年份? 如果是这样,您也许可以使用UNION查询,例如:

Select "Name" as [FName],  max(iif(year="2009",name))as [2009], max(iif(year="2010"
,name)) as [2010], max(iif(year="2011",name)) as [2011], max(iif(year="2012", name)) as [2012] from Table group by FName

Union all Select "Ticker",  max(iif(year="2009",ticker)), max(iif(year="2010"
,ticker)), max(iif(year="2011",ticker)), max(iif(year=-"2012",ticker)) from Table group by FName

Union all Select "ID",  max(iif(year="2009",id)), max(iif(year="2010"
,id)), max(iif(year="2011",is)), max(iif(year="2012",id)) from Table group by FName

Union all Select "Innovation",  max(iif(year="2009",innovation)), max(iif(year="2010"
,innovation)), max(iif(year="2011",innovation)), max(iif(year=-"2012",innovation)) from Table group by FName

 Union all Select "Quality",  max(iif(year="2009",quality)), max(iif(year="2010"
,quality)), max(iif(year="2011",quality)), max(iif(year=-"2012",quality)) from Table group by FName

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM