我创建了一张表格来从 Microsoft SQL 数据库中提取数据,以在 2 日期 StartDate
之间生成客户报告和 EndDate
.
我一直在玩一些东西,但无论如何都没有成功。我已经搜索过,但找不到任何我想要或能够理解的东西。
我认为的问题是我在 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
我希望这是有道理的。
最佳答案
您不能指定数据类型,Access 数据库引擎(以前称为 Jet)必须猜测。您可以通过更改某些注册表设置(例如 MaxScanRows
)并包括 IMEX=1
来影响其猜测。在连接字符串中。更多详情,请参阅 this knowledge base article .
这是我多年前就这个主题写的一些东西(如果你用谷歌搜索“ONEDAYWHEN=0”,你会发现它已被广泛阅读,尽管可能不够仔细!):
相关的注册表项(用于 Jet 4.0)位于:
Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/ImportMixedTypes
注册表项总是被读取(无论是
荣誉将在后面讨论)。您可以通过将 key 更改为ImportMixedTypes=OneDayWhen
并尝试使用 ISAM:你得到了
错误,“引擎部分的 Excel 键中的设置无效
Windows 注册表。”唯一有效的值是:
ImportMixedTypes=Text
ImportMixedTypes=Majority Type
数据类型是逐列确定的。 “多数类型”是指
扫描每列中的一定数量的行(稍后会详细介绍)
并计算数据类型。单元格的值和格式都是
用于确定数据类型。多数数据类型(即具有
最多行)决定整个列的整体数据类型。
如果出现平局,则存在偏向于 os numeric 的偏见。来自的行
发现的任何少数数据类型无法转换为多数数据
type 将返回一个空值。
对于
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
值(value)得到尊重。 IMEX
指“导入导出模式”。有三种可能的值。
IMEX=0
和 IMEX=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
以这种方式从不做任何事情情况。换句话说,is 和 put 的效果一样
ONEDAYWHEN=0
在扩展属性中,没有(甚至不是错误!)同样适用于
ImportMixedTypes
即不能用于覆盖注册表设置的连接字符串。
总之,使用
TypeGuessRows
让 Jet 检测是否有“混合类型的情况存在或使用它来“欺骗”Jet 检测到
某些数据类型是多数类型。如果发生
检测到“混合类型”的情况,使用
ImportMixedTypes
告诉Jet 使用多数类型或将所有值强制为
Text
(最多 255 个字符)。
关于sql - 在 Sql 查询中使用单元格中的日期或命名范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10100724/