我正在拉另一个工作簿,其中包含一个包含像ItemCreationDate这样的列的表,以及大多数列(总共28个这样的列),这些列以" Global"在他们中。我想
我附上了一个Sample.xlsx文件,其中我已经展示了如何从数据表开始到达“输出”选项卡。此数据表实际上是我想要拉入记录集并吐出表格的输入,如输出表中所示。我不想创建Pivot表,因为它很麻烦且数据非常多,而且我想要一种替代的SQL方法,其中我可以快速聚合数据并将其一次性插入到表中。
我没有使用SQL Server,因此无法使用UNPIVOT命令或动态SQL循环遍历所有" Global"列。
基本上我想形成一个类似于......的正确SQL字符串。
Dim arrSQL as variant
......
......
RS.Filter="Like Global*"
......
arrSQL = JOIN(RS.Fields, vbCr)
strSQL = "SELECT [arrSQL], IIF(YEAR([ITEM CREATION DATE])>=YEAR(DATE())-1,""NEW"",""OLD"") AS [New/Old] from [Data$] GROUP BY...."
strSQL = strSQL & " UNION ALL " & vbcr & _
strSQL = strSQL & " ......
现在,在同一记录集上运行SQL以减少列并获得所需的数据格式.... 我知道上面的内容不太正确,但在这些行上有一些东西,以便我可以在输出选项卡中显示正确的输出。
任何人都可以快速帮忙吗?
编辑@a_horse_with_no_name:
查看示例文件的屏幕截图:
答案 0 :(得分:1)
实际上,您可以使用Jet/ACE SQL Engine(Windows .dll文件)在MS Excel中运行SQL查询,这是MS Access默认连接的数据存储。因此,所有PC上配备的这项技术不限于任何一个Office / Windows程序。
考虑以下Excel VBA宏(如果在PC上使用Excel)通过ADO连接到ACE,运行三个聚合SQL查询的联合( GLOBAL VIT / CALC , GLOBAL FLAVORS , GLOBAL FLAVOR GROUP )和有条件的新旧计数/百分比。后一个百分比列对需要子查询。
要进行正确设置,请执行以下操作:
确保Item Creation Date
处于MM-DD-YYYY(基于美国)或DD-MM-YYYY(非基于美国)的日期格式,而不是屏幕截图或文件的日期字段如何目前已格式化。
Sub FormatDates()
For i = 2 To 2083
Range("A" & i) = CDate(Range("A" & i))
Next i
End Sub
在与保存数据的工作簿不同的工作簿中运行宏。下面假设数据工作簿在名为Data
的工作表中保存源信息。
RESULTS
的空白工作表,其中将填充包含列标题的查询输出。VBA 脚本(两个连接可用的驱动程序(已注释掉)和提供商版本)
Option Explicit
Sub RunSQL()
Dim cols As Object, datawbk As Workbook, datawks As Worksheet
Dim lastcol As Integer, i As Integer, j As Variant, output As Variant
Set cols = CreateObject("Scripting.Dictionary")
Set datawbk = Workbooks.Open("C:\Path\To\Data\Workbook.xlsx;")
Set datawks = datawbk.Worksheets("Data")
lastcol = datawks.Cells(7, datawks.Columns.Count).End(xlToLeft).Column
For i = 2 To lastcol
cols.Add CStr(i - 1), datawks.Cells(1, i).Value
Next i
datawbk.Close False
Set datawks = Nothing
Set datawbk = Nothing
output = DataCapture(cols)
End Sub
Function DataCapture(datacols As Object)
On Error GoTo ErrHandle
Dim conn As Object, rst As Object
Dim strConnection As String
Dim classSQL As String, itemSQL As String, grpSQL As String, strSQL As String
Dim i As Integer, fld As Object, d As Variant, lastrow As Integer
Set conn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")
' Hard code database location and name '
' strConnection = "DRIVER={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};" _
' & "DBQ=C:\Path\To\Data\Workbook.xlsx;"
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" _
& "Data Source='C:\Path\To\Data\Workbook.xlsx;" _
& "Extended Properties=""Excel 12.0 XML;HDR=YES IMEX=1;"";"
' OPEN DB CONNECTION '
conn.Open strConnection
For Each d In datacols.keys
strSQL = " SELECT '" & datacols(d) & "' AS [COLUMN], [Data$].[" & datacols(d) & "] AS ITEMS," _
& " SUM(IIF(Year([Item Creation Date]) >= Year(Date()) - 1, 1, 0)) AS NEW," _
& " " _
& " SUM(IIF(Year([Item Creation Date]) < Year(Date()) - 1, 1, 0)) AS OLD," _
& " " _
& " ROUND(SUM(IIF(Year([Item Creation Date]) >= Year(Date()) - 1, 1, 0)) / " _
& " (SELECT Count(*) FROM [Data$] AS sub" _
& " WHERE Year(sub.[Item Creation Date]) >= Year(Date()) - 1),2) AS NEWPCT," _
& " " _
& " ROUND(SUM(IIF(Year([Item Creation Date]) < Year(Date()) - 1, 1, 0)) / " _
& " (SELECT Count(*) FROM [Data$] AS sub" _
& " WHERE Year(sub.[Item Creation Date]) < Year(Date()) - 1),2) AS OLDPCT" _
& " FROM [Data$]" _
& " GROUP BY [Data$].[" & datacols(d) & "]"
' OPEN RECORDSET '
rst.Open strSQL, conn
' COLUMN HEADERS '
If d = 1 Then
i = 0
Worksheets("RESULTS").Range("A1").Activate
For Each fld In rst.Fields
ActiveCell.Offset(0, i) = fld.Name
i = i + 1
Next fld
End If
' DATA ROWS '
lastrow = Worksheets("RESULTS").Cells(Worksheets("RESULTS").Rows.Count, "A").End(xlUp).Row
Worksheets("RESULTS").Range("A" & lastrow + 1).CopyFromRecordset rst
rst.Close
Next d
conn.Close
MsgBox "Successfully processed SQL query!", vbInformation
Exit Function
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical
Exit Function
End Function
输出