Excel VBA - 搜索范围和连接的 SQL ADODB 记录集以在列中匹配写入结果集
Posted
技术标签:
【中文标题】Excel VBA - 搜索范围和连接的 SQL ADODB 记录集以在列中匹配写入结果集【英文标题】:Excel VBA - search range and connected SQL ADODB recordsets for match write Resultset in column 【发布时间】:2017-04-13 20:02:13 【问题描述】:我有一个包含两个数据源的 Excel (2010) 表:
-
访问 2010 数据库
SQL Server 2008 R2
我在 Access DB 的 A:I 列中有数据。在 A 列中,我有记录的 ID,此 ID 对应于我的 SQL DB 表中的 ID 列。
我正在尝试搜索 A 列中的 ID,如果它与 SQL DB 中的 ID 匹配,我想在 J 列的 SQL 表中显示“coOverview”列中的数据。
简而言之,“如果ID = coID,则将coOverView写入J列”
我已经成功地能够连接和检索所需的记录集并复制/填写 J 列,所以我知道我能够成功地连接和读取我的 SQL 表中的数据。现在,只有当 ID 与 A 列中的 ID 匹配时,我才需要从我的 SQL 表中复制 coOverview 中的数据。
Sub RetrieveOverview()
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim ConnectionString As String
Dim query As String
Set cn = New ADODB.Connection
ConnectionString = "Provider=SQLOLEDB;Password=***;Persist Security Info=True;User ID=*****;Data Source=***;Initial Catalog=**"
cn.Open ConnectionString
cn.CommandTimeout = 900
query = "SELECT coOverview FROM SQLTable"
rs.Open StrQuery, cn
Sheets(1).Range("J2").CopyFromRecordset rs
End Sub
我不知道我应该是SQL语句中的条件还是循环中的条件。
【问题讨论】:
明确地说,您将两个数据集都拉入并将它们存储在 Excel 的单元格中?如果是这样,我会将两个范围都拉入数组并编写一个简单的比较循环。如果您有合理的数据量,应该很快。 Kyle,不,我没有将两个数据集都存储在单元格中。我将一个数据集存储在一个范围 (A:I) 中,并且我想使用 A 列中的 ID 并将其与我在 SQL 语句中连接到的 SQL DB 中的表中的 ID 匹配。找到匹配的 ID 后,我想复制 SQL 表中“coOverview”列中的相应数据并将其写入 Excel 电子表格的 J 列。 您遇到的具体问题是什么?您说您已成功连接和检索所需的记录集并复制/填写 J 列。除此之外您还想做什么? 你需要更改sql查询。 @sshel207,您似乎确实将这两个查询都放在了工作簿的单元格中。代码行Sheets(1).Range("J2").CopyFromRecordset rs
将您的记录集复制到列 J。有关非数组循环解决方案,请参阅下面的答案。否则,我建议将您的查询结果(在将 ID 添加到查询后)放在不同的位置,并构建一个数组循环器来组合数据集。
【参考方案1】:
这会通过 A 列并将唯一值添加到变量 str
。完成后,str
将类似于 (138,353,....)
。然后,您可以在 SQL 语句中将 than 插入到 WHERE
子句中,以仅返回 ID 匹配的结果。请注意,如果您的 ID 是 SQL DB 中的字符串,则需要在构建字符串时将它们用单引号括起来。如果 ID 在 A 列中已经是唯一的,则可以剪切 If instr(1,str,c.Value) <> 0 Then
部分。此外,如果 A 列中的 ID 是唯一的,您可以对它们进行排序,然后将查询重新排序,并将记录集放在 J 列中,所有内容都应该对齐。
Sub RetrieveOverview()
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim ConnectionString As String, Ids as String
Dim query As String
Dim rng as Range, c as Range
Dim lrow as long
With Thisworkbook.Sheets("your sheet name")
lrow = .Range("A" & .Rows.Count).End(xlUp).Row
End With
Set rng = Thisworkbook.Sheets("your sheet name").Range("A1:A" & lrow)
For Each c in rng
If instr(1,str,c.Value) <> 0 Then
If str <> "" Then
str = str & "," & c.Value
Else
str = "(" & c.Value
End If
End If
Next c
str = str & ")"
Set cn = New ADODB.Connection
ConnectionString = "Provider=SQLOLEDB;Password=***;Persist Security Info=True;User ID=*****;Data Source=***;Initial Catalog=**"
cn.Open ConnectionString
cn.CommandTimeout = 900
query = "SELECT ID, coOverview FROM SQLTable WHERE ID in " & str
rs.Open StrQuery, cn
Sheets(1).Range("J2").CopyFromRecordset rs
End Sub
【讨论】:
【参考方案2】:sql 语句应该是这样的,您可以将tblSQLServer
和tblAccess
更改为您的表的实际名称。
sSQL = "SELECT tblSQLServer.coOverView, " & _
"FROM (tblSQLServer " & _
"INNER JOIN tblAccess " & _
"ON tblSQLServer.CoID = tblAccess.ID)"
【讨论】:
【参考方案3】:考虑一个 SQL Server 分布式查询,使用其OPENDATASOURCE
方法通过匹配 ID 字段将 Access 数据库表与 SQL Server 表连接起来。在 ADO 记录集调用中传递此查询:
SELECT mssql.[ID], acc.[Category], acc.[Name], acc.[Days], acc.[Costs], mssql.[coOverview]
FROM
OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0','Data Source=C:\Path\To\Access\Database.accdb')...myAccTable acc
INNER JOIN
mysqlTable mssql
ON acc.ID = mssql.ID
【讨论】:
以上是关于Excel VBA - 搜索范围和连接的 SQL ADODB 记录集以在列中匹配写入结果集的主要内容,如果未能解决你的问题,请参考以下文章
vbscript VBA Excel交叉连接多个范围而不重复