我需要将行转换为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
答案 0 :(得分:1)
Access TRANSFORM不是非常直观且易于使用,我认为你不能这样使用它。每个结果行应该是您的表的聚合。我知道无法将以前的字段名称添加到新列中。
查看一个工作示例: TRANSFORM and PIVOT in Access 2013 SQL
您真正想要的只是对现有数据的新演示。
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
答案 1 :(得分:1)
这是一个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子句。
答案 2 :(得分:0)
数据总是与字段名称和年份相同吗?如果是这样,您可以使用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