0

我希望SELECT在 Excel 中的单个单元格内执行 SQL 语句,使用其他单元格作为SELECT语句的输入。经过一番搜索,我发现该sql.request功能完全符合我的要求。但是,该功能在 2002 年之后被弃用,我在这里运行 Excel 2007 和 2010。引文

我试图创建一个做同样事情的宏/VBA 脚本,但还没有走得很远。我所有的编程都是在 LabVIEW、Mathematica 和 SQL 中完成的;我不知道 VBA 中发生了什么。这是我设法想出的:

Sub Test2()

' Declare the QueryTable object. I'm not actually sure why this line is here...
Dim qt As QueryTable

' Set up the SQL Statement
sqlstring = "SELECT `Substrate ID` FROM temp_table WHERE `id`=" & Range("A1").Value

' Set up the connection string, reference an ODBC connection
connstring = "ODBC;DSN=OWT_x64;"

' Now implement the connection, run the query, and add
' the results to the spreadsheet
With ActiveSheet.QueryTables.Add(Connection:=connstring, Destination:=Range("A22"), Sql:=sqlstring)
    .Refresh BackgroundQuery:=False
End With

End Sub

上述代码存在三个主要问题:

  1. 此代码在单元格 A22 中返回列 ID(“Substrate ID”),在单元格 A23 中返回 SQL 查询的结果。我只想要结果,我只想要它在单元格 A22 中。所有查询都被强制只返回 1 行和 1 列。
  2. 我不知道如何使输出单元格 A22 成为脚本运行时处于活动状态的任何单元格。此外,输入单元格 A1 应该是直接位于活动单元格左侧(第 1 列)的单元格。
  3. 我不知道如何把它变成一个 Excel 函数

    =sql.request(connection_string,[output_ref],[driver_prompt],[query_text],[col_names_logical])

    这是我的最终目标。这样,我可以将此代码提供给我公司的其他人,他们可以轻松使用它。

该连接是与 MySQL 5.6 数据库的 ODBC 连接。查询非常简单,大致如下:

SELECT column FROM table WHERE id=excel_cell_value

正如您从我拥有的 VBA 代码中看到的那样。

目前,我在另一个 Excel 工作表中运行查询,该工作表返回“id”和“Substrate ID”列的所有行,然后运行VLOOKUP以查找感兴趣的项目。这开始成为一个问题,因为我们的数据库大小正在快速增长。

所以,我问:

  1. 如何摆脱结果中的列 ID?
  2. 我怎样才能把它变成一个自定义的 excel 函数?我查看了Office.com,它似乎并不太难,但我首先需要一个工作脚本。
  3. -或者- 是否有人已经制作了他们愿意分享的自定义功能?

谢谢!

编辑:由于蒂姆的链接,设法使某些东西起作用。

Function SQLQuery(sqlString As String, connString As String, Optional TimeOut As Integer) As String

SQLQuery = Error 'Assume an error happened

Dim conn As ADODB.Connection
Dim record As ADODB.Recordset

Set conn = New ADODB.Connection
conn.ConnectionString = connString
conn.Open
Set record = New ADODB.Recordset

If TimeOut > 0 Then
    conn.CommandTimeout = TimeOut
End If

record.Open sqlString, conn

Dim cols As Long
Dim i As Long

cols = record.Fields.Count   'Count how many columns were returned
If Not record.EOF Then   'Put results into comma-delimited string
    record.MoveFirst
    s = ""
    If Not record.EOF Then
        For i = 0 To cols - 1
            s = s & IIf(i > 0, ",", "") & record(i)
        Next i
    End If
End If

SQLQuery = s

End Function

但是,它很慢。关于如何加快速度的任何想法?

4

1 回答 1

1

这是缓存连接的快速测试。在具有 100 次查找的测试工作表上,它将计算时间从大约 18 秒减少到大约 0.5 秒

请记住,尽管它会保持连接打开,直到您关闭 Excel(或 VB 环境被重置)。

如果你想在你的环境中测试差异,你可以注释掉标记的行(不要忘记在VBE中也按下“停止”按钮来清除静态变量)。

Function SQLQuery(sqlString As String, connString As String, _
                                  Optional TimeOut As Integer) As String

    Static cs As String
    Static conn As ADODB.Connection

    SQLQuery = Error 'Assume an error happened
    Dim s

    If conn Is Nothing Or connString <> cs Then
        Set conn = New ADODB.Connection
        conn.ConnectionString = connString
        conn.Open
        If TimeOut > 0 Then conn.CommandTimeout = TimeOut
        cs = connString '###comment this out to disable caching effect
    End If

    Dim record As New ADODB.Recordset

    record.Open sqlString, conn

    Dim cols As Long
    Dim i As Long

    cols = record.Fields.Count   'Count how many columns were returned
    If Not record.EOF Then   'Put results into comma-delimited string
        record.MoveFirst
        s = ""
        If Not record.EOF Then
            For i = 0 To cols - 1
                s = s & IIf(i > 0, ",", "") & record(i)
            Next i
        End If
    End If

    SQLQuery = s

End Function
于 2012-05-04T20:27:15.440 回答