Sql server 用VBA控制数据库表单Excel
我正在尝试创建一个excel加载项,它具有一组从数据库中提取值的函数(我使用MS SQL Server)。因此,我的查询将只返回一个记录集。我在vba代码中使用了如下内容 但问题是,如果我在100个单元格中有我的自定义函数,宏每次都会连接到数据库并从数据库中检索数据Sql server 用VBA控制数据库表单Excel,sql-server,excel,vba,Sql Server,Excel,Vba,我正在尝试创建一个excel加载项,它具有一组从数据库中提取值的函数(我使用MS SQL Server)。因此,我的查询将只返回一个记录集。我在vba代码中使用了如下内容 但问题是,如果我在100个单元格中有我的自定义函数,宏每次都会连接到数据库并从数据库中检索数据 是否有一种方法可以建立一个连接并使用该连接编写任意多的查询?简单,运行所有100个函数/循环来访问数据库。完成一个,然后关闭连接。看看下面修改过的代码 Option Explicit Sub ConnectSqlServer()
是否有一种方法可以建立一个连接并使用该连接编写任意多的查询?简单,运行所有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个循环,并在数据库连接关闭之前运行它。
希望它有用。简单,运行所有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个循环,并在数据库连接关闭之前运行它。
希望它有用。在这种情况下,不要在循环中执行db操作。这很耗时,而且使用不当。相反,在循环中创建select、insert或其他语句,然后完成循环操作和计算,然后只打开一次连接,向db发送请求(创建的sql脚本),从db获得响应,然后关闭连接。就这些。数据库操作必须与日常操作和递归操作分开。(反模式)敬请注意。在这种情况下,不要在循环中执行数据库操作。这很耗时,而且使用不当。相反,在循环中创建select、insert或其他语句,然后完成循环操作和计算,然后只打开一次连接,向db发送请求(创建的sql脚本),从db获得响应,然后关闭连接。就这些。db操作必须避免日常操作和递归操作。(反模式)致以最诚挚的问候。免责声明:虽然这不是本文所述问题的直接解决方案,但我想添加此方法,作为所述问题的更快、更简单的解决方案 步骤1:创建一个(可能隐藏的)工作表,从中提取此Excel文件中所需的所有SQL数据。将数据拉入一个包含所有必要列/维度的表中,以便随后从此表中获取数据 这就是我的意思。假设您在这个Excel文件中需要SQL server上的表
Users
中的一些数据,以及服务器上的StockMarket
表中的一些信息。从表Users
中,您需要用户名、名字、姓氏和职务。从表StockMarket
中,您需要股票市场ID和该特定股票的价格。由于这些价格是按日期计算的,因此您还需要该价格的报价日期
现在,由于您希望将所有数据都放在一个表中,因此必须想出一种聪明的方法将所有这些数据合并到一个表中。一种方法可以是:
之后,您可以使用如下查找函数从上表中获取所有数据:
=INDEX(SQLdata,MATCH(1,(SQLdata[Table]="Users")*(SQLdata[UserID]=25),0),4)
请注意,我将表命名为SQLdata,以便于查看和理解公式。此外,像这样,您可以轻松地扫描Excel文件以查找对此表的任何引用
另一种方法可以是以下方法,以使表格更加简洁:
请注意,这一次我将字符串
与数字
以及字符串
与日期
s混合在一起(这是非常糟糕的设计,对于这里的一些人来说甚至不可能想到)。此外,列标题现在不那么具有描述性。然而,这也起作用:
=INDEX(SQLrev,MATCH(1,(SQLrev[Table]="Users")*(SQLrev[Dimension1]=25),0),5)
注意,这次我调用了表SQLrev
这两种解决方案还允许您聚合表中的数据。因此,如果你想要(例如)2017年苹果的平均价格,那么你可以使用以下公式将今年的报价相加,然后除以3:
=SUM(IF("StockMarket"=SQLrev[Table];1;0)*IF("AAPL"=SQLrev[Dimension1];1;0)*SQLdata[Price])/3
这种方法最显著的优点是,您只需更新整个Excel文件中的一个表,这意味着只有一个来自服务器的SQL pull
最显著的缺点(除了编写可能变得非常复杂的SQL select)是您需要知道需要驻留在该表中的所有数据。如果未将数据拉入此表,则上述公式都无法检索这些值
虽然这种方法肯定有其缺点,但它比您想要的Excel插件更容易实现
以上所有公式都是数组公式,必须按Ctrl+
Shift
+Enter
输入。有关数组公式的更多信息,请阅读以下内容:免责声明:虽然这不是本文中描述的问题的直接解决方案,但我想将此方法添加为描述的问题的更快更简单的解决方案
步骤1:创建一个(可能隐藏的)工作表,从中提取此Excel文件中所需的所有SQL数据。将数据拉入一个包含所有必要列/维度的表中,以便随后从此表中获取数据
这就是我的意思。假设您在这个Excel文件中需要SQL server上的表Users
中的一些数据,以及服务器上的StockMarket
表中的一些信息。从表Users
中,您需要用户名、名字、姓氏和职务。从表StockMarket
中,您需要股票市场ID和该特定股票的价格。由于这些价格是按日期计算的,因此您还需要该价格的报价日期
现在,由于您希望将所有数据都放在一个表中,因此必须想出一种聪明的方法将所有这些数据合并到一个表中。一种方法可以是:
之后你可以得到所有的