1

我创建了一张表来从 Microsoft SQL 数据库中提取数据,以在 2 日期StartDateEndDate.

我一直在玩一些东西,但无论如何都没有成功。我已经搜索过,但找不到任何我想要或能够理解的东西。

我认为的问题是我在 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

我希望这是有道理的。

4

2 回答 2

3

您不能指定数据类型,Access 数据库引擎(以前称为 Jet)必须猜测。您可以通过更改某些注册表设置(例如MaxScanRows)并包括IMEX=1在连接字符串中来影响其猜测。有关更多详细信息,请参阅此知识库文章


这是我多年前就这个主题写的一些东西(如果你用谷歌搜索“ONEDAYWHEN=0”,你会发现它已被广泛阅读,尽管可能不够仔细!):

相关的注册表项(用于 Jet 4.0)位于:

Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/

注册表项总是被ImportMixedTypes读取(是否兑现将在后面讨论)。您可以通过将密钥更改为 ImportMixedTypes=OneDayWhen并尝试使用 ISAM 来对此进行测试:您会收到错误消息“Windows 注册表引擎部分的 Excel 密钥中的设置无效”。唯一有效的值为:

  • ImportMixedTypes=Text
  • ImportMixedTypes=Majority Type

数据类型是逐列确定的。“多数类型”是指扫描每列中一定数量的行(稍后会详细介绍)并计算数据类型。单元格的值和格式都用于确定数据类型。多数数据类型(即行数最多的数据类型)决定了整个列的整体数据类型。如果出现平局,则存在偏向于 os numeric 的偏见。发现的任何少数数据类型中无法转换为多数数据类型的行将返回空值。

对于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指“导入导出模式”。有三个可能的值。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' 

最后,虽然在 MSDN 文章中提到MAXSCANROWS 可以在连接字符串的扩展属性中使用来覆盖 TypeGuessRows 注册表项,但这似乎是一个谬论。以这种方式使用MAXSCANROWS=0在任何情况下都不会做任何事情。换句话说,与放入 ONEDAYWHEN=0扩展属性的效果相同,没有(甚至不是错误!)同样适用于ImportMixedTypesie 不能在连接字符串中使用来覆盖注册表设置。

总之,用于TypeGuessRows让 Jet 检测是否存在“混合类型”情况,或使用它来“欺骗”Jet 将某个数据类型检测为多数类型。在检测到“混合类型”的情况下,用于ImportMixedTypes告诉 Jet 使用多数类型或将所有值强制为Text (最多 255 个字符)。

于 2012-04-11T08:34:52.147 回答
0

尝试将 SQL 语句的日期部分更改为:

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

您也可以尝试使用参数化查询

于 2012-04-11T07:13:32.670 回答