2017-05-11 58 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年作爲免費插件提供。 –

相關問題