Использование дат из ячейки или именованного диапазона в запросе SQL
Я создал лист для извлечения данных из базы данных 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
Я надеюсь это имеет смысл.
2 ответа
Вы не можете указать типы данных, которые должен угадать механизм базы данных Access (ранее Jet). Вы можете повлиять на его догадки, изменив некоторые настройки реестра (например, MaxScanRows
) и в том числе IMEX=1
в строке подключения. Для получения дополнительной информации см. Эту статью базы знаний.
Вот кое-что, что я написал по этому вопросу много лет назад (если вы заглянете в Google для "ONEDAYWHEN=0", вы увидите, что оно было прочитано, хотя, возможно, недостаточно внимательно!):
Соответствующие ключи реестра (для Jet 4.0) находятся в:
HKEY_LOCAL_MACHINE /Software/Microsoft/Jet/4,0/ Двигатели /Excel/
ImportMixedTypes
ключ реестра всегда читается (соблюдается ли он, обсуждается позже). Вы можете проверить это, изменив ключ на ImportMixedTypes=OneDayWhen
и пытаясь использовать ISAM: вы получаете сообщение об ошибке "Неверная настройка в ключе Excel раздела" Механизмы "реестра Windows". Единственные допустимые значения:
ImportMixedTypes=Text
ImportMixedTypes=Majority 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
ценность заслуженная IMEX
относится к "IMport EXport mode". Есть три возможных значения. 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
таким образом, никогда ничего не делает ни при каких обстоятельствах. Другими словами, имеет тот же эффект, что и ONEDAYWHEN=0
в расширенных свойствах, не являющихся ничем (даже не ошибкой!) ImportMixedTypes
то есть не может использоваться в строке подключения для переопределения параметра реестра.
В итоге, используйте TypeGuessRows
заставить Jet определить, существует ли ситуация "смешанных типов", или использовать ее, чтобы "обмануть" Jet, чтобы он определил тип данных как тип большинства. В случае обнаружения ситуации "смешанных типов" используйте ImportMixedTypes
сказать Jet либо использовать тип большинства, либо привести все значения как Text
(максимум 255 символов).
Попробуйте изменить часть даты вашего оператора SQL на:
"[...] originalAlarmTime BETWEEN '" & Format$(StartDate, "yyyy-mm-dd") & "' AND '" & Format$(EndDate, "yyyy-mm-dd") & "' [...]"
Вы также можете попробовать использовать параметризованный запрос.