sql-server - 如何将数据从 Excel 发送到 SQL 临时表以使用 VBA 进行处理?

标签 sql-server vba excel

我的小组使用基于 Excel 宏的工具来进行一些严肃的数字运算。我想将数字运算位移动到 SQL,因为由于运行时使用 VBA 变得无法忍受。用户需要能够使用 Excel 作为界面,并且还需要能够同时运行他们的宏,因为 Excel 工作簿是自包含的。我一直在测试我的计划,即从 VBA 调用 SQL 存储过程,将 Excel 中的数据提取到 SQL 临时表中,对其进行处理,然后将其发送回 Excel。如果我在 SQL Management Studio 中运行我的 SP,我可以从 Excel 中提取数据。这是SP:

ALTER PROCEDURE sp_test_import
-- Add the parameters for the stored procedure here
@path varchar(1000)
AS
BEGIN
SET NOCOUNT ON;

declare  @SQL varchar(2500);
set @SQL = '
select *
from openrowset(''Microsoft.ACE.OLEDB.12.0'',
  ''Excel 12.0 Macro;
   Database='+@path+''',
   [Sheet1$]); '

create table [#test](
    col1 varchar(15),
    col2 varchar(15),
    col3 varchar(15),
    col4 varchar(15)
)

insert into #test
exec(@SQL)

select * from #mb_test
END

所以效果很好。然后我尝试从包含数据的 Excel 文件中调用此 SP。
Option Explicit

Sub ado_test()

Dim adoConnection As ADODB.Connection
Dim adoRecordset As ADODB.Recordset
Dim connectString As String
Dim strSQL As String
Dim sPath As String

Worksheets("Sheet1").Select
sPath = ThisWorkbook.FullName

'-Create a new ADO connection --
Set adoConnection = New ADODB.Connection
'-Create a new ADO recordset --
Set adoRecordset = New ADODB.Recordset

'-Build our connection string to use when we open the connection --

connectString = "DRIVER=SQL Server;SERVER=MyServer;Trusted_Connection=yes;DATABASE=testDB"
adoConnection.ConnectionTimeout = 20
adoConnection.CommandTimeout = 20

adoConnection.Open connectString
strSQL = "EXEC testDB.dbo.sp_test_import " & vbCr _
            & "@path = " & "'" & sPath & "'"

adoRecordset.Open strSQL, adoConnection

End Sub

代码卡在“adoRecordset.Open”调用上。如果我改为将路径传递给变量@path 中的单独Excel 文件,那么一切都会顺利进行。有没有一种简单的方法可以让我从同一个工作簿进行这个 SP 调用?我不担心安全性,因为 SQL db 将是用于拉入和处理临时数据的专用结构。我只需要用户能够随时运行他们的 Excel 工具,所以我不想在数据库中使用永久表,以防他们各自的输入混淆在一起。

我在网上找到的所有东西都与 ASP 或 ISS 相关,而我对 ASP 和 ISS 一无所知,这似乎不是解决我特定问题的正确方法。我可以让 VBA 将数据传递给外部文本文件,然后将这些文本文件的路径传递给 SQL SP,但是如果有更简洁的解决方案,那么我想知道它。提前致谢!

最佳答案

我想是因为你传入了strSQL , 一个 String数据类型,作为 .Open 的第一个参数方法,但 Open方法需要 Command对象(根据 MSDN )。

你要做的是声明一个 ADODB.Command对象并通过它。我已经修改了你的代码来做到这一点:

Option Explicit

Sub ado_test()

    Dim adoConnection As ADODB.Connection
    Dim adoRecordset As ADODB.Recordset
    Dim adoCommand As ADODB.Command
    Dim connectString As String
    Dim strSQL As String
    Dim sPath As String

    Worksheets("Sheet1").Select
    sPath = ThisWorkbook.FullName

    '-Create a new ADO connection --'
    Set adoConnection = New ADODB.Connection
    '-Create a new ADO recordset --'
    Set adoRecordset = New ADODB.Recordset

    '-Create a new ADO command --'
    Set adoCommand = New ADODB.Command

    '-Build our connection string to use when we open the connection --'

    connectString = "DRIVER=SQL Server;SERVER=MyServer;Trusted_Connection=yes;DATABASE=testDB"
    adoConnection.ConnectionTimeout = 20
    adoConnection.CommandTimeout = 20

    adoConnection.Open connectString
    strSQL = "sp_test_import"

    With adoCommand
        .ActiveConnection = adoConnection
        .CommandText = strSQL
        .CommandType = adCmdStoredProc
        .Parameters.Refresh
        .Parameters(1).Value = sPath
    End With

    Set adoRecordset = adoCommand.Execute

    If adoRecordset.EOF = False Then ThisWorkbook.Worksheets("YourSheetName").Cells(1, 1).CopyFromRecordset adoRecordset
    '--adoRecordset.Open adoCommand, adoConnection'

    '--Close the database connection'
    adoConnection.Close

End Sub

有关 Command 的更多信息目的。

我还添加了如何使用 CopyFromRecordset 从 SQL Server 获取值到 Excel 工作簿中。 method .

关于sql-server - 如何将数据从 Excel 发送到 SQL 临时表以使用 VBA 进行处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29611867/

相关文章:

vba - 尽管公式是正确的,但在单元格中写入公式会出现错误

excel - 检查文件是否下载以恢复代码

sql-server - 添加具有先前选择的默认值的列

php - 在 SQL Server 中将 Varchar 值转换为整数/小数值

sql-server - CRLF 序列作为存储过程中的默认参数值

vba - 使用无模式表单和用户定义的类处理自定义事件

sql - 使用 DatePart(ww, Date) 时 T-SQL 显示周结束数据

VBA 宏触发与工作簿打开不同的宏

Excel IF 语句返回 "FALSE"

add-in - C# : Excel 2007 Addin, 如何 Hook Windows 激活和停用事件