2012-04-11 75 views
1

我已經創建了一張工作表,用於從Microsoft SQL數據庫中提取數據以生成日期爲StartDateEndDate之間的客戶報告。使用單元格中的日期或Sql查詢中的命名範圍

我一直在玩一些東西,但一直沒有成功。我已經搜查過,但一直未能找到任何我曾經或能夠理解的東西。

我相信的問題是我在Excel中使用的日期的數據類型,並試圖將它傳遞給SQL查詢。我知道我需要以某種方式轉換它,以使其成爲可能並且正確。

如果我手動輸入日期到查詢它工作正常。但不適合客戶使用 我沒有這方面的經驗,我只是!扼殺我的方式通過它。如果有人會對我如此友善,這將是非常感激。

下面是我想使用

Sub DataExtract() 
' 
DataExtract Macro 
' 

' Create a connection object. 
Dim cni96X As ADODB.Connection 
Set cni96X = New ADODB.Connection 

' Set Database Range 

' Provide the connection string. 
Dim strConn As String 
Dim Lan As Integer 
Dim OS As Integer 
Dim PointID As String 


' Set Variables 
Lan = Range("Lan").Value 
OS = Range("OS").Value 
PointID = Range("PointID").Value 
StartDate = Range("StartDate").Value 
EndDate = Range("EndDate").Value 


'Use the SQL Server OLE DB Provider. 
strConn = "PROVIDER=SQLOLEDB;" 

'Connect to 963 database on the local server. 
strConn = strConn & "DATA SOURCE=(local);INITIAL CATALOG=i96X;" 

'Use an integrated login. 
strConn = strConn & " INTEGRATED SECURITY=sspi;" 

'Now open the connection. 
cni96X.Open strConn 

' Create a recordset object. 
Dim rsi96X As ADODB.Recordset 
Dim rsi96X1 As ADODB.Recordset 
Set rsi96X = New ADODB.Recordset 
Set rsi96X1 = New ADODB.Recordset 

With rsi96X 
    ' Assign the Connection object. 
    .ActiveConnection = cni96X 
    ' Extract the required records1. 
    .Open "SELECT ModuleLabel, originalAlarmTime FROM LastAlarmDetailsByTime WHERE (os = " & OS & " And theModule = N'" & PointID & "'AND AlarmCode = N'DI=1' And lan = " & Lan & " And originalAlarmTime BETWEEN N'" & StartDate & "' AND N'" & EndDate & "') ORDER BY originalAlarmTime DESC" 
    ' Copy the records into sheet. 
    Range("PointLabel, TimeCallInitiated").CopyFromRecordset rsi96X 


With rsi96X1 
    .ActiveConnection = cni96X 
    ' Assign the Connection object. 
    .Open "SELECT originalAlarmTime FROM LastAlarmDetailsByTime WHERE (os = " & OS & " And theModule = N'" & PointID & "'AND AlarmCode = N'CDI1' And lan = " & Lan & " And originalAlarmTime BETWEEN N'" & StartDate & "' AND N'" & EndDate & "')ORDER BY originalAlarmTime DESC" 
    ' Copy the records into sheet. 
    Sheet1.Range("TimeCallEnded").CopyFromRecordset rsi96X1 
    ' Tidy up 
    .Close 

我希望這是有道理的代碼。

+0

您必須格式化您的日期,例如:'StartDate = Formta(Range(「StartDate」)。Value,[Format])'Where'[Format]'是'YYYYMMDD'或'YYYY-MM-DD' – 2016-05-02 16:09:26

回答

0

試着改變你的SQL語句的日期部分:

"[...] originalAlarmTime BETWEEN '" & Format$(StartDate, "yyyy-mm-dd") & "' AND '" & Format$(EndDate, "yyyy-mm-dd") & "' [...]" 

您也可以嘗試使用parameterized query

+0

Kylenz,非常感謝你的工作。 – twaters88 2012-04-16 03:44:42

+0

不用擔心。如果您對答案感到滿意,請接受它! – KyleNZ 2012-04-16 07:18:15

3

您不能指定數據類型,Access數據庫引擎(以前稱爲Jet)必須猜測。您可以通過在連接字符串中更改某些註冊表設置(例如MaxScanRows)和IMEX=1來影響其猜測工作。有關更多詳細信息,請參閱this knowledge base article


這裏的東西很多年前我關於這個問題寫了(如果你谷歌「ONEDAYWHEN = 0」就可以看到它雖然也許沒有足夠仔細得到廣泛的閱讀!):

相關注冊表鍵(Jet 4.0的)是:

HKEY_LOCAL_MACHINE/SOFTWARE /微軟/噴氣/ 4.0 /發動機/ EXCEL/

ImportMixedTypes註冊表項總是讀(無論是 榮幸稍後討論)。您可以通過將密鑰更改爲 ImportMixedTypes=OneDayWhen並嘗試使用ISAM來進行測試:出現 錯誤,「 Windows註冊表的引擎部分的Excel密鑰中的設置無效」。唯一有效的值是:

  • ImportMixedTypes=Text
  • ImportMixedTypes=Majority Type

數據類型由柱測定柱。 '多數類型'表示在每列中掃描 特定行數(稍後更多) 並對數據類型進行計數。單元格的值和格式都是 ,用於確定數據類型。大多數數據類型(即最大行數爲 )決定整個列的整體數據類型。 在平局的情況下,支持os數字有偏見。從 行中發現的任何少數數據類型都將無法投射,因爲大多數數據類型將以空值返回 。

對於ImportMixedTypes=Text,整個列的數據類型將是:

Jet (MS Access UI): 'Text' data type 
DDL: VARCHAR(255) 
ADO: adWChar ('a null-terminated Unicode character string') 

注意,這是不同於:

Jet (MS Access UI): 'Memo' data type 
DDL: MEMO 
ADO: adLongVarWChar ('a long null-terminated Unicode string value') 

ImportMixedTypes=Text將在255個字符削減文本作爲Memo是 鑄如Text。對於要識別爲Memo的列,必須檢測到大多數類型 ,這意味着大多數檢測到的行必須包含256個或更多字符的 。

但是,在決定 混合和/或多數類型是什麼之前,每列的掃描行數是多少?還有第二個註冊表 密鑰,TypeGuessRows。這可以是0-16(十進制)的值。值爲1到16的值 是要掃描的行數。值爲零 表示將掃描所有行。

有一個最後的轉折。 IMEX=1連接中的設置 字符串的擴展屬性確定是否符合ImportMixedTypes 值。 IMEX涉及'IMport EXport模式'。有三個 可能的值。 IMEX=0IMEX=2導致ImportMixedTypes被忽略,並且使用'多數類型'的默認值。 IMEX=1是 確保ImportMixedTypes=Text的唯一途徑是榮幸。得到的 連接字符串可能是這樣的:

Provider=Microsoft.Jet.OLEDB.4.0; 
Data Source=C:\ db.xls; 
Extended Properties='Excel 8.0;HDR=Yes;IMEX=1' 

最後,雖然在MAXSCANROWS 可以在連接字符串的擴展屬性可以用來 覆蓋的TypeGuessRows註冊表項MSDN文章中提到,這似乎成爲一個謬論。 以這種方式使用MAXSCANROWS=0在任何 的情況下都不會做任何事情。換言之,與將 ONEDAYWHEN=0置於擴展屬性中相同,即沒有(甚至不存在 錯誤!)同樣適用於ImportMixedTypes,即不能在 中使用連接字符串來覆蓋註冊表設置。

總之,使用TypeGuessRows獲得射流以檢測「混合 類型」的情況是否存在或用它來「特技」射流成檢測 特定的數據類型爲大多數類型。如果檢測到 「混合類型」情況,請使用ImportMixedTypes告知 Jet使用多數類型或強制所有值爲Text (最多255個字符)。