Sql server 自动更新Excel SQL连接以生成多个仪表板
我正在制作我们产品子集的报告。每个产品都有一个A4页的详细信息,使用excel显示在仪表板中 我有许多存储过程,excel使用这些存储过程连接到我的数据库并返回数据。然后,仪表板会自动更新这些数据 我需要为100多种产品中的每一种产品制作这个仪表板,并将它们合并到一个文档中 但是,要更新数据,我当前必须进入每个存储过程连接并手动更新产品ID。这是一项缓慢的任务 有没有办法使用SQL、Excel或VBA来改进此过程 也许有一段VBA可以读取产品ID列表,依次更新每个存储过程,将仪表板表保存为PDF格式并重复Sql server 自动更新Excel SQL连接以生成多个仪表板,sql-server,vba,tsql,excel,Sql Server,Vba,Tsql,Excel,我正在制作我们产品子集的报告。每个产品都有一个A4页的详细信息,使用excel显示在仪表板中 我有许多存储过程,excel使用这些存储过程连接到我的数据库并返回数据。然后,仪表板会自动更新这些数据 我需要为100多种产品中的每一种产品制作这个仪表板,并将它们合并到一个文档中 但是,要更新数据,我当前必须进入每个存储过程连接并手动更新产品ID。这是一项缓慢的任务 有没有办法使用SQL、Excel或VBA来改进此过程 也许有一段VBA可以读取产品ID列表,依次更新每个存储过程,将仪表板表保存为PDF
编辑:Excel通过数据选项卡下的内置连接工具使用存储过程连接到数据。以下是存根,用于使用productId从头开始创建SQL查询:
sql = "SELECT * FROM Table1 WHERE PRODUCT_ID = " & productId
If IsMissing(trustedConnection) Then
sConn = "OLEDB;Provider=SQLOLEDB;Data Source=" & _
serverInstance & ";Initial Catalog=" & database & _
";User ID=" & userId & ";Password=" & password & ";"
Else
sConn = "OLEDB;Provider=SQLOLEDB;Data Source=" & _
serverInstance & ";Integrated Security=SSPI;Initial Catalog=" & _
database & ";"
End If
'Output worksheet
Set wks = Target.Parent
With qt
.CommandType = xlCmdSql
.CommandText = sql
.Name = sName
.RefreshStyle = xlOverwriteCells
.Refresh BackgroundQuery:=False 'Execute SQL
End With
Set qt = wks.QueryTables.Add(Connection:=sConn, Destination:=Target)
现在只需创建一个循环,并根据需要创建尽可能多的工作表和这些SQL查询。这将帮助您:
Sub SQL_Multi()
'
Dim RqSql As String, _
RqSql = RqSql_Part1 & DicArt(i) & RqSql_Part2
RqSql = RqSql_Part1 & DicArt(i) & RqSql_Part2
DicArt()
ReDim DicArt(0)
'create or get the article list here (you can use Add_Array_To_Dico described below)
DicArt = Add_Array_To_Dico(Array_Articles, DicArt, 1, True)
'Add a new connection
'Workbooks("base.xlsx").Connections.AddFromFile "D:\Documents\DEMO.odc"
'Set your query here
RqSql_Part1 = "Select * from DataBase where ID='"
RqSql_Part2 = "' and ...."
For i = LBound(DicArt) + 1 To UBound(DicArt)
'Here is where the query is made for each ID
RqSql = RqSql_Part1 & DicArt(i) & RqSql_Part2 '"article reference" : you can change here to place correctly the article
With ActiveWorkbook.Connections("DEMOtest").ODBCConnection
.BackgroundQuery = True
.CommandText = Array(RqSql)
.CommandType = xlCmdSql
.Connection = "ODBC;DSN=DEMO;UID=ID;PWD=PWD;APP=Microsoft Office 2013;WSID=CHA02KW;DATABASE=DEMO"
.RefreshOnFileOpen = False
.SavePassword = True
.SourceConnectionFile = ""
.SourceDataFile = ""
.ServerCredentialsMethod = xlCredentialsMethodIntegrated
.AlwaysUseConnectionFile = False
End With
'Refreshing connection
ActiveWorkbook.Connections("DEMOtest").Refresh
'Wait long enough for refreshing to be finished (5 secs here)
DoEvents
Application.Wait (Now + TimeValue("0:00:05"))
DoEvents
Sheets("Dashboard").Calculate
DoEvents
'Export to Pdf (correct Filename)
Sheets("Dashboard").ExportAsFixedFormat Type:=xlTypePDF, _
Filename:=ThisWorkbook.Path & "\All\Mains " & DicArt(i) & ".pdf", _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
Next i
End Sub
以及用于获取具有唯一事件的数组的自定义函数:
Public Function Add_Array_To_Dico(ByVal ArrayT As Variant, _
ByVal DicoArray As Variant, _
Optional ByVal ColIndex As Integer, _
Optional ByVal HasHeaders As Boolean) _
As Variant
Dim A()
ReDim A(0)
Dim IsInDico As Boolean
Dim CellCont As String
Dim StartRow As Integer
If IsMissing(HasHeaders) Then
'consider there is no headers
StartRow = 0
Else
If HasHeaders Then
StartRow = 1
Else
StartRow = 0
End If
End If
For i = StartRow To UBound(ArrayT, 1)
CellCont = ArrayT(i, ColIndex)
IsInDico = False
For k = LBound(DicoArray) To UBound(DicoArray)
If CellCont <> DicoArray(k) Then
Else
'Matched with dictionnary
IsInDico = True
Exit For
End If
Next k
If IsInDico <> False Then
'Already in Dictionnary
Else
'Add in Dictionnary
ReDim Preserve DicoArray(UBound(DicoArray) + 1)
DicoArray(UBound(DicoArray)) = CellCont
End If
Next i
Add_Array_To_Dico = DicoArray
End Function
存储过程位于数据库中,对吗?如何通过Excel访问它?在Excel 2013中使用宏?@EngJon:数据->连接。设置与SQL Server的连接,然后在“连接属性”的“定义”选项卡上将命令类型设置为SQL。然后将SQL粘贴到命令文本中。在这里,我假设DicArt是我的产品ID列表?在哪里访问/执行SQL查询?i、 e.是使用现有连接还是创建新连接并运行存储过程?您可能还记得,我对VBA很陌生。事实上,它是您的ID列表。您只需使用初始连接创建一个数组,并在Add_array_to_Dico函数的2个first参数中指定ID所在的列。如果不需要在代码中创建一个连接,那么它将使用您现有的连接,这样做是没有用的,查询将在这里升级:RqSql=RqSql\u Part1&DicArti&RqSql\u Part2,您只需在开始时将查询的各个部分放在Part1和Part2中。是否足够清楚?要做到这一点,我需要手动创建工作表并单独保存它们吗?不需要。您可以在产品中循环,并在上面包含此宏自动为查询创建新工作表。之后,您只需要使用RefreshAll命令刷新它们