我在Excel 2010 VBA中使用ADO 2.8查询Access 2010数据库。我不拥有数据库,也没有权力对其进行任何更改。我已经使用Excel VBA多年,但我的Access知识很粗略。
使用与数据库中的一个查询相同的SQL(从Access查询复制并粘贴到Excel VBA中),在某些字段中得到的结果与数据库中的查询得到的结果不同。
对于受影响的字段,我在Access中看到这些字段被定义为查找。以下是来自其中一个受影响字段的示例查找'行源属性:
SELECT [Signers].[SignerID], [Signers].[SignerName] FROM Signers ORDER BY [SignerID], [SignerName];
在Access数据库中,SQL语句引用该字段,查询返回SignerName。
但是在我的ADO代码中,同一个SQL语句引用该字段,查询返回SignerID,而不是SignerName。
我可以通过我的ADO代码从同一个SQL语句中获取SignerName而不是SignerID吗?或者我是否需要修改SQL语句?
谢谢,
格雷格
更新
在Access方面,我想我现在看到为什么只出现SignerName。在字段的“查找”选项卡上,“列宽”属性为:
0&#34 ;; 1.2605"
所以我猜SignerID在Access查询结果中,但列宽为0。
不幸的是,这对ADO方面没有帮助。有关在ADO查询结果中获取SignerName而不是SignerID的任何建议吗?
UPDATE2:
这是一个示例SQL语句,它根据Access或ADO中的不同字段返回不同的字段:
SELECT MasterAccount.[SignerKey1]
FROM MasterAccount ;
Per Preet的请求,这里是Excel VBA中的ADO代码:
strDatabasePath = rgDatabasePathCell.Value 'rgDatabasePathCell is a worksheet cell object.
strPWD = DATABASE_PASSWORD
Set cnn = New ADODB.Connection
cnn.Provider = "Microsoft.ACE.OLEDB.12.0"
cnn.ConnectionString = "Data Source='" & strDatabasePath & "';Jet OLEDB:Database Password='" & strPWD & "';"
cnn.Open
Set cmd = New ADODB.Command
cmd.ActiveConnection = cnn
cmd.CommandType = adCmdText
cmd.CommandText = strSQL
Set rst = New ADODB.Recordset
rst.Open cmd.Execute
shMA.Cells(2, 1).CopyFromRecordset rst 'shMA is a worksheet object.
更新3:
我突然想到,从我到目前为止所说的话,我可能会改变这一点:
SELECT MasterAccount.[SignerKey1]
FROM MasterAccount ;
到此:
SELECT [Signers].[SignerName]
FROM MasterAccount ;
但是有13个受影响的查找字段,所有字段都完全相同"行源"属性文本如上所示,并且每行返回不同的SignerName项。我不知道为什么他们每行都会返回不同的物品;我发现它们的定义方式没有任何区别。我的任务是在Excel中获得与Access查询相同的结果。
更新4:
VBlades - 谢谢,我找到了一个表单,其中包含13个SignerKey-n字段中每个字段的下拉列表。如果我右键单击该表单并选择“表单属性”,则RecordSource属性为:
SELECT MasterAccount.*, Bank.BankRating FROM Bank INNER JOIN MasterAccount ON Bank.BankID = MasterAccount.Bank;
但是,我不明白如何为13个SignerKey-n字段中的每一个选择不同的SignerName项,或者如何处理此信息以在ADO中获得与Access查询中相同的结果。有什么建议吗?
更新5:
我可能接近解决方法。如果我这样做,我会得到SignerKey1的SignerName字段:
SELECT Signers.SignerName
FROM Signers RIGHT JOIN MasterAccount ON Signers.SignerID = MasterAccount.SignerKey1.Value;
如果我这样做,我会为每一行的每个字段获得不同的SignerName项目:
SELECT Signers.SignerName, Signers_1.SignerName, Signers_2.SignerName
FROM Signers AS Signers_2 INNER JOIN (Signers AS Signers_1 INNER JOIN (Signers RIGHT JOIN MasterAccount ON Signers.SignerID = MasterAccount.SignerKey1.Value) ON Signers_1.SignerID = MasterAccount.SignerKey2.Value) ON Signers_2.SignerID = MasterAccount.SignerKey3;
这在Access查询和ADO中都有效。下一步,我将尝试将这些连接添加到主SQL语句中。
更新6:
好吧,当我尝试将这13个连接中的一个连接到主SQL语句时,它在Access查询中工作正常,但在ADO中我得到错误:
必须先释放行句柄才能获得新句柄。
所以我被卡住了。有什么建议吗?
我已经向数据库所有者提出了这个问题,但他们并不知道为什么受影响的字段会出现问题。行来源属性包括SignerID,所以我不确定这是否会有所帮助。
答案 0 :(得分:0)
您可以执行以下操作(最简单的方法)
从查询中排除[Signers].[SignerID]
SELECT [Signers].[SignerName] FROM Signers ORDER BY [SignerID], [SignerName];
或者,创建包含[SignerID]
,[SignerName]的复合字段,并使用您熟悉的VBA提取任何部分:
SELECT ([SignerID] & "_" & [SignerName]) As Composite FROM Signers ORDER BY [SignerID], [SignerName]
此致
答案 1 :(得分:0)
好的,我通过从Signers表中获取SignerID和SignerName字段的单独记录集来解决这个问题。
然后我循环遍历每个受影响字段的所有行,在第二个表中查找SignerID,并在原始表中交换SignerName作为SignerID。
我尝试在ADO中执行此操作,但收到错误“UPDATE或DELETE查询不能包含多值字段”。因此,我将记录集复制到Excel工作表后进行了交换。
我本来想知道如何在ADO中处理它,但这很有效。一切都很好。