我是一名自学成才的Excel VBA和SQL用户。在添加复杂性之前,我正在测试一些简单的查询。我必须在这里错过一些令人眼花缭乱的东西...
我正在使用ADO连接在activeworkbook(ThisWorkBook)中的表上运行SQL SELECT语句。 Excel表名为“tbl_QDB”,位于工作表“MyQDB”上。该表从单元格A1开始,因此Table HeaderRowRange上方没有空白或填充的单元格。
我已经设置了与ThisWorkBook的ADO连接,这很好用。这是代码:
Sub ConnectionOpen2()
'### UNDER DEVELOPMENT
Dim sconnect As String
Const adUseClient = 3
Const adUseServer = 2
Const adLockOptimistic = 3
Const adOpenKeyset = 1
Const adOpenDynamic = 2
'used to connect to this workbook for SQL runs
On Error GoTo err_OpenConnection2
Set cn2 = CreateObject("ADODB.Connection")
Set rec2 = CreateObject("ADODB.Recordset")
rec2.CursorLocation = adUseClient
rec2.CursorType = adOpenStatic
rec2.LockType = adLockOptimistic
datasource = ThisWorkbook.FullName
sconnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & datasource & ";" & _
"Extended Properties=""Excel 12.0;HDR=YES;ReadOnly=False;Imex=0"";"
cn2.Open sconnect
'etc, etc...
End Sub
我可以运行这个最简单的基本SELECT查询:
SQLSTR="SELECT * FROM [MYQDB$]"
rec2.open SQLSTR, cn2
这可以产生10条记录,即rec2.recordcount = 10。
但是,如果我试试这个,就会出错:
SQLSTR="SELECT QID_1 FROM [MYQDB$]"
QID_1是工作表“MyQDB”表格中的有效字段。 如果我将QID_1包含在()或[]或``中,它不会改变错误 我甚至可以用一个组成的字段替换字段名称,例如DonaldDuck和我得到同样的错误。
如果我使用“*”,为什么SELECT语句会起作用,但如果我使用表中的任何字段名称,那么它是否有效?这看起来很基本,我觉得我一定错过了一个简单而关键的点。
如果有人可以指出错误,我真的很感激!
答案 0 :(得分:3)
SQL应该有效 - 如果该字段存在。执行Select *
并转储字段列表:
For i = 0 To rec2.Fields.Count - 1
Debug.Print rec2.Fields(i).Name
Next i
答案 1 :(得分:0)
谢谢大家的意见。 那个建议@FunThomas让人大开眼界!结果是F1,F2,F3等,因此无法识别字段名称(或者您喜欢的列名称)。
这可以解释为什么在几天试图将这个表与另一个表连接在一个封闭的外部工作簿中之后,它就无法工作了。 SQL错误消息可能非常钝,并没有说它无法识别字段名称。
我现在已经解决了这个问题。这是我可以告诉/警告其他人的事情:
我用标题上方的行开始此表。在其中2个细胞中 上面我记录了最后一次连接时间和状态 工作簿表。我之前意识到这些额外的行,有数据 填充在标题上方的任何单元格中,都会导致问题 SQL。尽管我的数据在Excel表中,但是SQL“引擎” Excel查看工作表,即存储数据的[MYQDB $] (虽然我知道您可以指定工作表和范围,但是 不能使用实际的表名作为范围)。
表headerrowrange上方有空行。所以我 删除了包含表格上方数据的单元格 headerrowrange。相反,我放置了一个文本框并使用了公式 查看最后一个连接时间和状态的另一个工作表 现在存储以提供文本框的文本。
我现在可以看到,即使这个不占用单元格的文本框也会导致Excel SQL出现问题。
在此处发布我的问题之前,我制作了工作簿的副本,并删除了文本框和表格headerrowrange上方的行。我还是有错误。我还有F1,F2,F3等字段名称(根据@ FunThomas的建议)。
只有删除了这些行和文本框,然后调整大小表(实际上,与之前的范围相同)才能识别正确的字段名称。然后,我甚至能够(只是为了好奇)在表头文件上方插入一个空行,而SQL仍然有用。
在我看来,Excel在内存中保留了旧的表定义,并且只删除了表headerrowrange之上的所有数据,然后调整表的大小,刷新了它。也许我以后应该不那么懒,并在sql中调用sheetname和range(表地址):也许会忽略headerrowrange之上的单元格中的数据?
@PanagiotisKanavos:我最初试图比较两个表(实际的Excel表,不仅仅是范围,因此它们有字段名称),一个在ThisWorkBook中,另一个在一个封闭的Excel工作簿中。 SQL是执行此操作的最佳方式。无法让左连接在这些表之间工作(这个问题现在可能已经揭示了为什么这不起作用!)我决定将外部工作簿中的数据带入ThisWorkBook并进行比较。然后我将找到差异,存储在记录集(因此SQL),然后INSERT INTO外部工作簿。
感谢您的帮助!