从宏查询(加入)外部工作簿
query (join) external wokbooks from a macro
我有 3 Excel 个工作簿:
- 宏(完成后将是一个插件)
- 上期数据列表
- 本期数据列表
两个列表都少于 1000 行。
我正在尝试在这些列表之间创建一个 SQL join
,但我无法让它工作。由于工作表名称中有点(如 "TB 03.18"),我使用了在 SO 某处找到的技巧来定义相应工作簿中的命名范围。
下面是代码,其中包含 2 个 SQL 有效和出错的代码。我搞不清楚了。
'set connection to 'current tb'
sConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & wbCurr.FullName & _
";Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
Set con = New ADODB.Connection
con.Open sConn
wbCurr.Names.Add Name:="cur", RefersTo:=shCurr.Range("A4").CurrentRegion 'to be made dynamic !!!
wbPrev.Names.Add Name:="pre", RefersTo:=shPrev.Range("A9").CurrentRegion 'to be made dynamic !!!
lastRow = shPrev.Range("a15000").End(xlUp).Row
shCurr.Range("F5:I15000").Clear
Dim xl12 As String: xl12 = "[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='HDR=YES';] "
'this works ------------------
'sSql = "select reference from cur " & vbCrLf & _
"where cur.reference like '1%'"
'this works ------------------
sSql = "select pre.reference " & vbCrLf & _
"from pre IN '" & wbPrev.FullName & "' " & xl12 & vbCrLf & _
"where pre.reference like '1%'"
'not working: syntax error in FROM clause
'sSql = "select cur.reference from cur " & vbCrLf & _
"inner join pre IN '" & wbPrev.FullName & "' " & xl12 & " on cur.reference = pre.reference " & vbCrLf & _
"where cur.reference like '1%'"
Debug.Print Now, sSql
Set rs = con.Execute(sSql)
使用 Jet/ACE SQL 引擎,您可以使用方括号或反引号转义标识符中的特殊字符。因此,句点应该不是问题,然后您可以在 SQL 查询中使用完整的 sheet 名称和 A1
范围符号来代替命名范围。
但是,您的特定 SQL 错误是由于在 INNER JOIN
子句中使用了 IN
。避免使用最适合一个 table 的 IN
并使用句点限定符语法将工作簿路径作为内联调用中的参数传递,其中甚至不需要 Provider:
FROM [Excel 12.0 Xml;HDR=Yes;Database=C:\Path\To\Workbook].[Worksheet$] AS w
总而言之,考虑以下没有命名范围的调整,这很难调试。下面显示了如何使用括号或反引号处理句号,以及如何使用 A1
符号范围引用内部和外部工作 sheet。
strSQL = "SELECT s1.[reference]" & _
" FROM [S.h.e.e.t1$A4:Z100] s1" & _
" INNER JOIN [Excel 12.0 Xml;HDR=Yes;Database=C:\Path\To\Workbook].`S.h.e.e.t.2$A9:Z100` s2
ON s1.[reference] = s2.[reference]" & _
" WHERE s1.reference LIKE '1%'"
rs.Open strSQL, con
我有 3 Excel 个工作簿:
- 宏(完成后将是一个插件)
- 上期数据列表
- 本期数据列表
两个列表都少于 1000 行。
我正在尝试在这些列表之间创建一个 SQL join
,但我无法让它工作。由于工作表名称中有点(如 "TB 03.18"),我使用了在 SO 某处找到的技巧来定义相应工作簿中的命名范围。
下面是代码,其中包含 2 个 SQL 有效和出错的代码。我搞不清楚了。
'set connection to 'current tb'
sConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & wbCurr.FullName & _
";Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
Set con = New ADODB.Connection
con.Open sConn
wbCurr.Names.Add Name:="cur", RefersTo:=shCurr.Range("A4").CurrentRegion 'to be made dynamic !!!
wbPrev.Names.Add Name:="pre", RefersTo:=shPrev.Range("A9").CurrentRegion 'to be made dynamic !!!
lastRow = shPrev.Range("a15000").End(xlUp).Row
shCurr.Range("F5:I15000").Clear
Dim xl12 As String: xl12 = "[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='HDR=YES';] "
'this works ------------------
'sSql = "select reference from cur " & vbCrLf & _
"where cur.reference like '1%'"
'this works ------------------
sSql = "select pre.reference " & vbCrLf & _
"from pre IN '" & wbPrev.FullName & "' " & xl12 & vbCrLf & _
"where pre.reference like '1%'"
'not working: syntax error in FROM clause
'sSql = "select cur.reference from cur " & vbCrLf & _
"inner join pre IN '" & wbPrev.FullName & "' " & xl12 & " on cur.reference = pre.reference " & vbCrLf & _
"where cur.reference like '1%'"
Debug.Print Now, sSql
Set rs = con.Execute(sSql)
使用 Jet/ACE SQL 引擎,您可以使用方括号或反引号转义标识符中的特殊字符。因此,句点应该不是问题,然后您可以在 SQL 查询中使用完整的 sheet 名称和 A1
范围符号来代替命名范围。
但是,您的特定 SQL 错误是由于在 INNER JOIN
子句中使用了 IN
。避免使用最适合一个 table 的 IN
并使用句点限定符语法将工作簿路径作为内联调用中的参数传递,其中甚至不需要 Provider:
FROM [Excel 12.0 Xml;HDR=Yes;Database=C:\Path\To\Workbook].[Worksheet$] AS w
总而言之,考虑以下没有命名范围的调整,这很难调试。下面显示了如何使用括号或反引号处理句号,以及如何使用 A1
符号范围引用内部和外部工作 sheet。
strSQL = "SELECT s1.[reference]" & _
" FROM [S.h.e.e.t1$A4:Z100] s1" & _
" INNER JOIN [Excel 12.0 Xml;HDR=Yes;Database=C:\Path\To\Workbook].`S.h.e.e.t.2$A9:Z100` s2
ON s1.[reference] = s2.[reference]" & _
" WHERE s1.reference LIKE '1%'"
rs.Open strSQL, con