我正在尝试创建一个excel插件,它具有一组函数来从数据库中提取值(我使用的是MS SQL Server)。所以我的查询只返回一个记录集。我在我的vba代码中使用了类似下面的东西。
Using Excel VBA to run SQL query
但问题是如果我在100个单元格中有自定义函数,则宏每次都会连接到数据库并从数据库中检索数据。
有没有办法可以建立一个连接并使用该连接来编写任意数量的查询?
答案 0 :(得分:0)
简单,运行所有100个函数/循环来访问数据库。一个你完成然后关闭连接。看看下面的修改后的代码......
Option Explicit
Sub ConnectSqlServer()
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sConnString As String
' Create the connection string.
sConnString = "Provider=SQLOLEDB;Data Source=INSTANCE\SQLEXPRESS;" & _
"Initial Catalog=MyDatabaseName;" & _
"Integrated Security=SSPI;"
' Create the Connection and Recordset objects.
Set conn = New ADODB.Connection
Set rs = New ADODB.Recordset
' Open the connection and execute.
conn.Open sConnString
'>>>> run 100 loops
Dim i As Integer
For i = 1 To 100
Set rs = conn.Execute("SELECT * FROM Table" + 1 + ";")
' Check we have data.
If Not rs.EOF Then
' Transfer result.
' I assume that you've 100 Sheets
Sheets(i).Range("A1").CopyFromRecordset rs
' Close the recordset
rs.Close
Else
MsgBox "Error: No records returned.", vbCritical
End If
Next
' Clean up
If CBool(conn.State And adStateOpen) Then conn.Close
Set conn = Nothing
Set rs = Nothing
End Sub
我已添加100个循环并在关闭数据库连接之前运行它。 希望它有用。
答案 1 :(得分:0)
在这种情况下,不要在循环中执行db操作。这是耗时且不适当的用途。相反,在循环中创建select,insert或whatsoever语句然后编译循环操作和计算然后只打开连接一次并将请求(创建的sql脚本)发送到db并从db获取响应然后关闭连接。就这样。 db操作必须从dailiy和递归操作中提炼出来。(反模式)最好的问候。
答案 2 :(得分:0)
免责声明:虽然这不是该帖子中描述的问题的直接解决方案,但我想将此方法添加为更快更简单的解决方案。
步骤1:创建一个(可能隐藏的)工作表,在该工作表中提取此Excel文件中所需的所有SQL数据。将数据拉入 one 表,其中包含所有必需的列/维,以便从此表中获取数据。
这就是我的意思。假设您在此Excel文件中需要SQL Server上的表Users
中的一些数据以及服务器上StockMarket
表中的一些信息。从表Users
中,您需要UserID,名字,姓氏和职位。在表格StockMarket
中,您需要Stockmarket ID和此特定股票的价格。由于这些价格是按日期计算的,因此您还需要价格的报价日期。
现在,由于您希望所有人都在一个表中,因此您必须考虑将所有这些数据合并到一个表中的智能方法。一种方法可能如下:
之后,您可以使用以下查找函数从上表中获取所有数据:
=INDEX(SQLdata,MATCH(1,(SQLdata[Table]="Users")*(SQLdata[UserID]=25),0),4)
请注意,我将表SQLdata命名为在查看公式并理解它时更容易。此外,您可以轻松扫描Excel文件以获取对此表的任何引用。
注意,这次我将Strings
与Numbers
混合,Strings
与Date
混合(设计非常糟糕,对于某些人来说甚至不可能考虑到)。此外,列标题现在不太具描述性。然而,这也有效:
=INDEX(SQLrev,MATCH(1,(SQLrev[Table]="Users")*(SQLrev[Dimension1]=25),0),5)
注意,我这次调用了表SQLrev。
两种解决方案都允许您聚合表中的数据。因此,如果您想要(例如)2017年Apple的平均价格,那么您可以使用以下公式来总结今年的报价并将它们除以3:
=SUM(IF("StockMarket"=SQLrev[Table];1;0)*IF("AAPL"=SQLrev[Dimension1];1;0)*SQLdata[Price])/3
这种方法最显着的优点是您只需更新整个Excel文件中的一个表,这意味着服务器只有一个 SQL拉。
最值得注意的缺点(除了可能变得非常复杂的SQL选择之外)是您需要知道需要驻留在此表中的所有数据。如果未将数据提取到此表中,则上述公式都不能检索这些值。
虽然这种方法肯定有其缺点,但这比你想要的Excel AddIn更容易实现。
以上所有公式都是数组公式,必须按Ctrl
+ Shift
+ Enter
输入。有关数组公式的更多信息,请阅读以下内容:https://support.office.com/en-us/article/Guidelines-and-examples-of-array-formulas-7D94A64E-3FF3-4686-9372-ECFD5CAA57C7