Использование дат из ячейки или именованного диапазона в запросе 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") & "' [...]"

Вы также можете попробовать использовать параметризованный запрос.

Другие вопросы по тегам