如何简化含分隔符字符串的SQL查询?(Excel VBA+ADO)
简化ADO SQL WHERE子句的两种方案
方案一:优化LIKE与内置函数组合(纯SQL写法)
针对你的筛选需求,可将多个条件通过OR合并,利用Jet/ACE引擎支持的CHAR(10)表示换行符,结合LIKE、InStr等函数简化WHERE子句:
SELECT [Art], [Count], [Comm], [w] FROM [Table] WHERE [W] IS NULL OR [W] = '104' OR [W] LIKE '104' || CHAR(10) || '%' -- 以'104'开头,后跟换行及其他内容 OR [W] LIKE '%' || CHAR(10) || '104' -- 以换行+'104'结尾 OR [W] LIKE '%' || CHAR(10) || '104' || CHAR(10) || '%' -- 中间包含换行+'104'+换行
若要进一步精简,可用InStr合并部分匹配逻辑:
SELECT [Art], [Count], [Comm], [w] FROM [Table] WHERE [W] IS NULL OR [W] = '104' OR InStr([W], CHAR(10) || '104' || CHAR(10)) > 0 OR Left([W], 4) = '104' || CHAR(10) OR Right([W], 4) = CHAR(10) || '104'
注:Jet/ACE引擎中字符串连接可用||或&,两种写法均生效。
方案二:VBA正则表达式辅助筛选(弥补LIKE不足)
如果SQL的LIKE无法满足复杂匹配需求,可先用ADO查询全量记录,再通过VBA的正则对象过滤:
步骤1:引用正则库
打开VBA编辑器 → 工具 → 引用 → 勾选「Microsoft VBScript Regular Expressions 5.5」
步骤2:VBA代码示例
Sub FilterWithRegex() Dim conn As Object Dim rs As Object Dim regex As New RegExp Dim filteredRs As Object Dim sql As String ' 建立ADO连接 Set conn = CreateObject("ADODB.Connection") conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0 Xml;HDR=YES;""" ' 查询所有目标字段 sql = "SELECT [Art], [Count], [Comm], [w] FROM [Table]" Set rs = conn.Execute(sql) ' 配置正则规则:覆盖所有匹配场景 regex.Pattern = "^104$|\n104\n|\n104$|^104\n" regex.IgnoreCase = False regex.Global = False ' 初始化空记录集存储筛选结果 Set filteredRs = CreateObject("ADODB.Recordset") filteredRs.CursorType = adOpenStatic filteredRs.Fields.Append "Art", rs.Fields("Art").Type filteredRs.Fields.Append "Count", rs.Fields("Count").Type filteredRs.Fields.Append "Comm", rs.Fields("Comm").Type filteredRs.Fields.Append "w", rs.Fields("w").Type filteredRs.Open ' 遍历原记录集筛选 Do While Not rs.EOF If IsNull(rs("w")) Then ' 直接保留NULL记录 filteredRs.AddNew filteredRs("Art") = rs("Art") filteredRs("Count") = rs("Count") filteredRs("Comm") = rs("Comm") filteredRs("w") = rs("w") filteredRs.Update Else ' 正则匹配非NULL的[W]字段 If regex.Test(rs("w")) Then filteredRs.AddNew filteredRs("Art") = rs("Art") filteredRs("Count") = rs("Count") filteredRs("Comm") = rs("Comm") filteredRs("w") = rs("w") filteredRs.Update End If End If rs.MoveNext Loop ' 将筛选结果输出到工作表(示例) Sheet2.Range("A1").CopyFromRecordset filteredRs ' 清理资源 rs.Close filteredRs.Close conn.Close Set rs = Nothing Set filteredRs = Nothing Set conn = Nothing Set regex = Nothing End Sub
正则规则说明:
^104$:匹配恰好为'104'的记录\n104\n:匹配被换行符包裹的'104'(中间包含场景)\n104$:匹配以换行+'104'结尾的记录^104\n:匹配以'104'+换行开头的记录
内容的提问来源于stack exchange,提问作者user23025019
相关产品推荐
相关产品推荐

