使用 VBA 在 Excel 单元格中运行 SQL 语句

Posted

技术标签:

【中文标题】使用 VBA 在 Excel 单元格中运行 SQL 语句【英文标题】:Run SQL-statement in Excel Cell with VBA 【发布时间】:2021-04-23 08:39:06 【问题描述】:

Excel 文件:

   |        A       |       B         |            C                |        D        |     E
---|----------------|-----------------|-----------------------------|-----------------|------------
1  |   sales_date   |   2020-01-15    |     =CONCATENATE(C2,C3)     |                 |
2  |                |                 |      SQL-Query Part 1*      |                 |
3  |                |                 |      SQL-Query Part 2*      |                 |
4  |                |                 |                             |                 |

VBA

Sub Get_Data_from_DWH()

    Dim conn As New ADODB.Connection
    Dim rs As New ADODB.Recordset
        
    Set conn = New ADODB.Connection
    conn.ConnectionString = "DRIVER=mysql ODBC 5.1 Driver; SERVER=XX.XXX.XXX.XX; DATABASE=bi; UID=testuser; PWD=test; OPTION=3"
    conn.Open
    
    strSQL = Sheet1.Range("C1")
                            
    Set rs = New ADODB.Recordset
    rs.Open strSQL, conn, adOpenStatic

    Sheet1.Range("D1").CopyFromRecordset rs
    
    rs.Close
    conn.Close
    
End Sub

SQL 查询:

SELECT
product, brand, sales_channel,
country, sales_manager, sales_date, return_date,
process_type, sale_quantity, return_quantity, sales_value, variable_costs, fixed_costs
FROM bi.sales
WHERE sales_date = '"&B1&" AND country IN ('DE', 'US', 'NL') 
ORDER BY FIELD (brand, 'brand_A', 'brand_B', 'brand_C');

我想用上面的VBA 运行上面的SQL-Query

问题是查询包含超过 255 个字符,因此它不适合一个 Excel 单元格。 因此,我将查询随机拆分为Cell C2Cell C3 中的两部分,并在Cell C1 中使用CONCATENATE(C2,C3) 将查询的两部分组合起来。

当我现在运行VBA 时,我得到runtime error '-2147217887 (80040e21)'


我猜VBA 无法处理Cell C1 中的CONCATENATE(C2,C3)。 因此,我想知道是否有其他方法可以解决此问题?


注意: 我知道我可以将 SQL 直接放入 VBA 代码中。但是,我的想法是拆分 SLQ 字符串和执行代码,因为我的原始 SQL 的字符比这个问题中的示例还要多,我想保持 VBA 的结构如this question 中所述。 p>

【问题讨论】:

(a) Excel 单元格没有 255 个字符的限制。 (b) 我强烈认为您的问题来自无效的 SQL 语句。 (c) 您的子句"&L1&" 看起来很可疑。 L1 应该是一个参数吗? (d) 我强烈建议使用ADODB-Parameter,例如***.com/a/60640185/7599798 (a) 有一个限制:***.com/questions/12386414/… (b) 如果我使用少于 255 个字符,SQL 语句就会运行,(c) 引用 L1 是上述问题中的错字。我将其固定为 B1,因为它应该引用此单元格 (d) 我将检查 ADODB 参数 链接的问题是关于 公式 的长度,而不是单元格的长度。 SQL 语句肯定没有 255 个字符的限制。将日期传递给查询始终是一个问题,如果您不使用 ADODB.Parameter,则需要完全按照数据库的预期格式化 SQL 语句 - 这对于不同的数据库非常不同 【参考方案1】:

您从哪里得知 Excel 单元格限制为 265 个字符?

Excel 365:这是 C1 中的 313 个字符:

这是单元格 A1 中的整个 SQL 查询:

【讨论】:

Excel 给了我这个错误,但即使有 313 个字符,仍然存在无法处理字符数超过字符限制的查询的关键问题。 那么字符限制是什么?告诉我们!【参考方案2】:

选项 1:

使用CONCATENATE 函数将查询拆分为多个部分可以删除正确运行查询所需的空格。 因此,根据查询而不是=CONCATENATE(C2,C3),您需要使用=CONCATENATE(C2," ",C3)


选项 2:

如果上述解决方案不起作用,您也可以通过变通方法解决问题,并将CONCATENATE 函数从Cell C1 复制并粘贴 到另一个单元格中作为值强>:

Sub Get_Data_from_DWH()

Sheet1.Range("C4").ClearContents
Sheet1.Range("C1").Copy
Sheet1.Range("C4").Cells.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False

    Dim conn As New ADODB.Connection
    Dim rs As New ADODB.Recordset
        
    Set conn = New ADODB.Connection
    conn.ConnectionString = "DRIVER=MySQL ODBC 5.1 Driver; SERVER=XX.XXX.XXX.XX; DATABASE=bi; UID=testuser; PWD=test; OPTION=3"
    conn.Open
    
    strSQL = Sheet1.Range("C4")
                            
    Set rs = New ADODB.Recordset
    rs.Open strSQL, conn, adOpenStatic

    Sheet1.Range("D1").CopyFromRecordset rs
    
    rs.Close
    conn.Close
    
End Sub

在 cmets 中讨论过 Excel 单元格没有限制。 对于简单的文本没有限制,但formula 的输入是有限的。 在问题的特定情况下,公式是必要的,因为Cell B1 中的条目应该是用户可以随时更改的变量。


因此,我认为唯一的办法是

a) 将 SQL 语句与正在执行的 VBA 代码分开 b) 使用超过 255 个字符的查询 c) 将 Excel 单元格中的条目作为变量应用

是上述解决方案之一。

【讨论】:

以上是关于使用 VBA 在 Excel 单元格中运行 SQL 语句的主要内容,如果未能解决你的问题,请参考以下文章

Excel 2010 VBA:使用单元格中的值保存文件以确定路径和文件名

Excel VBA 针对 SQL 表交叉引用 Excel 表

使用VBA在Excel填充单元格中插入多个图像,但保持宽高比

使用excel vba将特定文本行保留在单元格中以获取特定起始字母

vba如何读取excel中某单元格的行数或列数

使用 VBA for Excel 从大量单元格中删除“额外”空格(超过 1 个)的更快方法