1

我试图在我的 VBA 代码中将变量传递到 SQL 查询的命令文本中,但一直遇到“类型不匹配”错误。我在我的电子表格中编写了一个简单的等式,它重新创建了 IN 语句的语法,我只想将它放入查询中。

因此,单元格 A1 包含以下内容:

(1, 2, 3)

我的VBA的相关片段如下:

Dim x as String
x = Sheets("SheetName").Range("A1")

然后在重新创建我的查询命令文本(我通过“记录”功能创建)的一长串代码中,我试图注入如下变量:

"Where table.field in " & x & " and table2.field <> 0"

如果重要的话:

  • 表中的字段存储为(int,not null)。
  • 我已经使用 MsgBox(x) 来验证它是否正确存储了字符串
  • 字符串不超过 255 个字符的限制
  • 我尝试过使用标准“?” 使用 MSQuery 传递参数的功能,也没有运气

过去我已经得到了这种技巧,但只有一个变量。需要放入 IN 语句的列表会不断变化,所以我只是想避免必须明确地调用每一个,或者必须返回 100% 的数据,然后在事后将其过滤掉.

任何帮助,将不胜感激!对完成同一件事的其他方式持开放态度;只是希望这会起作用,因为它很容易,因为电子表格已经设置好了。

更新:

今天再次处理这个问题,我发现我过度简化了这个例子,我知道字符串字符限制没有被违反,所以我假设 IN 子句的长度是可以的。通常情况下,我不应该假设这一点。

我发现 IN 子句的长度是一个因素,即使在 255 限制下也是如此。当单元格 A1 的完整长度最多包含 210 个字符时,一切都会正常工作;再举一个例子:

(1, 2, 3, 4, 5, 6, 7, 8, 9 ,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 19000101, 20160101, 20160530, 20160704, 20160905, 20161124, 20161125, 20161223, 20161226, 20170102, 20170103456789123)

如果我在最后一个数字的末尾添加另一个值,以将字符数跳到 211,我将遇到“类型不匹配”错误。

我试图通过创建另一个变量来容纳字符串的其余部分来避免这种情况,但这也产生了同样的错误。如果我尝试将超过 210 的任何内容填充到代码的单个部分中,就会出现错误。

假设单元格 A1 现在包含 210 长度的版本,下面的代码将正常执行,如果 A1 包含超过 210 个字符,它会给我“类型不匹配”:

Dim x As String
x = Sheets("SheetName").Range("A1")

    With ActiveWorkbook.Connections("Query from Database"). _
        ODBCConnection
        .BackgroundQuery = False
        .CommandText = Array( _
        "USE Database" & Chr(13) & "" & Chr(10) & "SELECT var.UOM, var.UOMClass" & Chr(13) & "" & Chr(10) & "FROM dbo.Variance var" & Chr(13) & "" & Chr(10) & "WHERE var.UOMC" _
        , "lass in" & x & "and var.ModType <>0")
        .CommandType = xlCmdSql
        .Connection = _
        "ODBC;DSN=Database;UID=user01;Trusted_Connection=Yes;APP=Microsoft Office 2010;WSID=COM1077;DATABASE=Database"
        .RefreshOnFileOpen = False
        .SavePassword = False
        .SourceConnectionFile = ""
        .SourceDataFile = ""
        .ServerCredentialsMethod = xlCredentialsMethodIntegrated
        .AlwaysUseConnectionFile = False
    End With
    With ActiveWorkbook.Connections("Query from Database")
        .Name = "Query from Database"
        .Description = ""
    End With
    ActiveWorkbook.Connections("Query from Database").Refresh

目前我刚刚将 ~230 长度的 IN 语句硬编码到实际的命令文本中,并且查询运行得很好,但是由于这个列表不仅会改变而且会增长,我仍然很好奇是否存在解决方案。

4

1 回答 1

0

CommandText 数组的每个元素的最大长度限制为 255 个字符,因此您需要确保不超过该长度。一种方法是将您的 SQL 构建为单个字符串,然后将其传递给一个函数,该函数将返回一个部分数组,每个部分都在限制范围内。

请参见下面的示例 -SplitMeUp将返回一个最大长度为 200 个字符的字符串数组

Sub Tester()
    Dim s As String, arr, n, sep
    For n = 1 To 200
        s = s & sep & n
        sep = "-"
    Next n

    arr = SplitMeUp(s)

    Debug.Print Join(arr, vbLf)

End Sub



Function SplitMeUp(strIn As String)
    Const MAX_LEN As Long = 200
    Dim rv(), n, i
    n = Application.Ceiling(Len(strIn) / MAX_LEN, 1)
    ReDim rv(0 To n - 1)
    For i = 1 To n
        rv(i - 1) = Mid(strIn, 1 + ((i - 1) * MAX_LEN), MAX_LEN)
    Next i
    SplitMeUp = rv
End Function

在您的用例中:

.CommandText = SplitMeUp( _
    "USE Database " & vbCrLf & "SELECT var.UOM, var.UOMClass" & _
     vbCrLf & " FROM dbo.Variance var WHERE var.UOMClass in" & _
     x & " and var.ModType<>0")
于 2015-12-08T22:06:11.660 回答