如何将冗长而复杂的SQL查询嵌入到Excel VBA代码中?

sat*_*sat 0 excel vba

我有下面的VBA代码,当我必须嵌入一个简单的查询(例如Select * from table1)时,可以成功地将数据从SQL数据库获取到Excel工作表中,但是该代码无法正常工作并显示

编译错误:未定义用户定义的类型。

当我有复杂而漫长的查询时:

 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=vrsqladhoc;" & _
                      "Initial Catalog=TACT_REV;" & _
                      "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
        Set rs = conn.Execute("select distinct column1 from table1;")

        ' Check we have data.
        If Not rs.EOF Then
            ' Transfer result.
            Sheets(2).Range("A2").CopyFromRecordset rs
        ' Close the recordset
            rs.Close
        Else
            MsgBox "Error: No records returned.", vbCritical
        End If

        End Sub
Run Code Online (Sandbox Code Playgroud)

我打算在VBA代码中嵌入的长查询看起来像这样:

 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=vrsqladhoc;" & _
                      "Initial Catalog=TACT_REV;" & _
                      "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
        Set rs = conn.Execute("select distinct column1 from table1;")

        ' Check we have data.
        If Not rs.EOF Then
            ' Transfer result.
            Sheets(2).Range("A2").CopyFromRecordset rs
        ' Close the recordset
            rs.Close
        Else
            MsgBox "Error: No records returned.", vbCritical
        End If

        End Sub
Run Code Online (Sandbox Code Playgroud)

请让我知道如何将长的SQL查询嵌入到VBA代码中而不会出现任何错误。

Mat*_*don 5

确切地说,您是如何建立连接字符串的:

    sConnString = "Provider=SQLOLEDB;Data Source=vrsqladhoc;" & _
                  "Initial Catalog=TACT_REV;" & _
                  "Integrated Security=SSPI;"
Run Code Online (Sandbox Code Playgroud)

通过串联字符串文字。

现在,使用如此长的查询会遇到的一个问题是,VBA不允许您编写逻辑行,这些行的代码跨度超过10-15条物理代码行。看到,上面的语句是一个逻辑代码行,但是它跨越了3条物理行,其中涉及2 行连续令牌。

因此,您只需执行以下操作:

Dim sql As String
sql = "SELECT Count(column1) as status_count, case when " & _
      " ..." & _
      " ..." & _
      " ..." & _
      "and so on"
Run Code Online (Sandbox Code Playgroud)

当编译器开始抱怨行延续太多时,您只需将其与自身连接起来即可:

sql = sql & " rest of the " & _
      " ...query"
Run Code Online (Sandbox Code Playgroud)

显然,这将变得非常难看,非常快。修复该查询中的错误将是一场噩梦。维持该查询将是一场噩梦。仅查看该查询将给您带来噩梦。

无论使用哪种语言,这种复杂的查询都不属于源代码。它们在视图存储过程中属于服务器。如果您无法在数据库上创建视图或存储过程,请将查询提供给可以的人。

如果绝对没有避免的方法,那么我强烈建议您使用a StringBuilder来进行字符串连接。结果至少比一排交错的行连续串联连接要干净得多,并且性能会更好。

Dim sql As String
With New StringBuilder
    .Append "SELECT ..."
    .Append "..."
    .Append "..."
    .Append "..."
    .Append "..."
    .Append "..."
    sql = .ToString
End With
Run Code Online (Sandbox Code Playgroud)

旁注:无论您做什么,都不要将用户输入连接到SQL查询中。参数化它。