2017-05-11 62 views
1

我是一位自学的Excel VBA和SQL用户。在添加复杂性之前,我正在测试一些简单的查询。我必须在这里忽略一些非常明显的...EXCEL SQL SELECT将无法识别ThisWorkBook中的字段名称

我正在使用ADO连接在ActiveWorkbook(ThisWorkBook)中的表上运行SQL SELECT语句。 Excel表名为“tbl_QDB”,位于工作表“MyQDB”上。该表从单元格A1开始,因此表HeaderRowRange上方没有空白或已填充的单元格。

我已经建立了一个ADO连接到ThisWorkBook,这工作正常。下面的代码:

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$]" 

enter image description here

QID_1是在工作表 “MyQDB” 有效的字段。 如果我将QID_1放在()或[]或者`` 中,我甚至可以用构成字段来替换字段名称,例如,唐纳德杜克和我得到了同样的错误。

为什么SELECT语句在我使用“*”的情况下工作,但如果我使用表中的任何字段名称,则不会有效?这似乎非常基本,我觉得我一定错过了一个简单而重要的点。

如果有人能指出错误,我真的很感激!

+0

你为什么要从* Excel *里面查询Excel表?只需加载工作表并读取单元格 –

+0

'QID_1'不是字段名称。 Excel没有字段,它有* cells *。单元地址是例如'$ A $ 1'。错误本身意味着查询包含参数说明符,但没有传递参数值。很可能Excel会混淆意外的参数“QID_1”值 –

+0

为什么你称'QID_1'为一个字段? Excel具有行和列,而不是字段。您可以*命名特定范围,并将它们视为SQL查询中的表格。命名单元格仍然是一个范围,只有1行和1列。表格仍然是命名的范围。您的*查询*虽然是针对整个工作表,而不是特定的表。 –

回答

3

SQL应该工作 - 如果该字段存在。执行Select *并转储字段列表:

For i = 0 To rec2.Fields.Count - 1 
    Debug.Print rec2.Fields(i).Name 
Next i 
+0

谢谢大家的意见。 – englandexpects

0

谢谢大家的意见。 @FunThomas的建议让人大开眼界!结果是F1,F2,F3等,因此字段名称(或列名称,如果您愿意)未被识别。

这可以解释为什么在尝试与封闭的外部工作簿中的另一个表加入此表后,它无法工作。 SQL错误消息可能非常迟钝,并不是说它不能识别字段名称。

我现在已经修复了这个问题。以下是我可以告诉/警告其他人:

  1. 我开始使用标题上方行的此表。在上述两个单元 中,我记录了最后一次连接时间和状态到另一个 工作簿表。之前我意识到,这些额外的行在数据头上方的任意单元中填充了数据 ,这些数据导致了SQL的 问题。尽管Excel数据库中有我的数据,但Excel的SQL“引擎”会查看工作表,即存储数据的[MYQDB $] (尽管我知道您可以指定工作表和范围,但 不能使用实际的表名作为范围)。

  2. 在表格标题范围之上有空行是可以的。所以,我 删除了包含表格 headerrowrange以上数据的单元格。相反,我放置了一个文本框并使用了一个公式来查看另一个工作表,其中最后一次连接时间和状态为 现在存储为提供文本框的文本。

  3. 我现在可以看到即使是不占用单元格的文本框也会导致Excel SQL出现问题。

  4. 在发布我的问题之前,我制作了工作簿的副本,并删除了文本框和表格headerrowrange上方的行。我仍然有错误。我仍然有F1,F2,F3等字段名称(per @ FunThomas的建议)。

  5. 只有在删除这些行和文本框然后调整大小表(实际上,范围与以前相同)Excel SQL才能识别正确的字段名称。然后,我甚至可以(只是为了好奇)在表headerrowrange上插入一个空行,并且SQL仍然有效。

  6. 在我看来,Excel保留在内存中的旧表定义,只有通过删除表headerrowrange上的所有数据,然后调整表的大小,它刷新了。也许我以后应该不那么懒惰,并在sql:maybe中调用sheetname和range(表地址),这可能会忽略headerrowrange之上的单元格中的数据?

@PanagiotisKanavos:我本来试图比较两个表(实际的Excel表格,不仅范围,因此,他们有字段名),一个在的ThisWorkbook,另一个在一个封闭的Excel工作簿。 SQL是这样做的最好方法。无法在这些表之间获得左连接(并且此问题现在可能已经揭示了为什么这不起作用!)我决定将外部工作簿中的数据导入ThisWorkBook并在那里进行比较。然后,我要找出差异,存储在记录集(因此SQL),然后插入到外部工作簿。

感谢您的帮助!

+0

您可以使用PowerQuery从多个表和文件中选择数据,并加入并处理它们。 SQL是最好的方法,但它不是通过VBA使用的。旧的SQL数据功能已被Powerquery取代。 –

+0

我希望能够使用Power Query,但我的组织已锁定使用此类实用程序。这不是标准的桌面配置。我需要保持基本知识,以便可以将此工具推广给其他用户。 – englandexpects

+0

这不是一个实用程序。它是Excel 2013和2016中的一项内置功能。它*是替换以前版本中的数据连接工具的标准。它在2010年作为免费插件提供。 –

相关问题