2009-11-06 3 views
0

Я пытаюсь запросить таблицу .xls с помощью VBScript, но у меня возникла проблема при попытке создать поле.
Я подключаюсь к электронной таблице следующим образом.Поле поиска проблем при запросе электронной таблицы

Set objConnection = CreateObject("ADODB.Connection") 
objConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & DataSource & ";Extended Properties=""Excel 8.0;HDR=No;"";" 

Затем я пытаюсь запросить таблицу. Поле, которое меня интересует, содержит десятичные значения, но также может содержать символ * в качестве подстановочного знака. Так что я пытаюсь сделать, это указать поле в varchar, чтобы я мог проверить *.

Set objRecordset = CreateObject("ADODB.Recordset") 
StrQuery = "SELECT * FROM [Sheet1$] WHERE F1 >= 2.3456 OR CAST(F1 AS VARCHAR) = '*'" 
objRecordset.Open StrQuery, objConnection, adOpenDynamic, adLockOptimistic 

Это вызывает неуказанную ошибку 80004005. Что я здесь делаю неправильно?
ПРИМЕЧАНИЕ. Я также попробовал CONVERT, но получил ошибку Undefined Function.

ответ

0

Вы можете попробовать добавить IMEX=1; к расширенным свойствам. Это сообщает JET DB для чтения смешанных номеров, дат и строк в виде текста. Тогда вы должны быть в состоянии:

SELECT * FROM [F1$] 

То есть, если F1 это имя первого листа.

+0

Мне также нужно сравнить числовые значения в поле, поэтому их преобразование вызовет больше проблем. Скажем, у меня есть запрос вроде SELECT * FROM [Sheet1 $] WHERE F1> = 2.34 И CAST (F1 AS VARCHAR) = '*' – Tester101

+0

Прочитайте весь лист и выполните фильтрацию в vbscript? – Andomar

+0

Это то, чего я пытаюсь избежать, так как я думаю, что запрос будет работать намного быстрее, чем фильтр, который я бы написал. – Tester101

1

Я хотел бы изменить следующие ключи реестра на сервере (после того, как резервное копирование, конечно):

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel\ImportMixedTypes = Text 
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel\TypeGuessRows = 0 

Я также хотел бы изменить строку подключения к следующему:

Dim sConnectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("/PathTo/YourFile/" & Filename) & ";" 
If chkUploadFileColumnsFirstRow.Checked Then 
    sConnectionString &= "Extended Properties='Excel 8.0;HDR=YES;IMEX=1'" 
Else 
    sConnectionString &= "Extended Properties='Excel 8.0;IMEX=1'" 
End If 

, если он сбой после установки этих критериев, я бы почувствовал, что что-то не так с вашим именем листа или с самим запросом.

+0

Мне также нужно сравнить числовые значения в поле, поэтому их создание приведет к большим проблемам. Скажем, у меня есть запрос типа SELECT * FROM [Sheet1 $] WHERE F1> = 2.34 AND CAST (F1 AS VARCHAR) = '*' – Tester101

+0

Я использую класс SqlBulkCopy и читаю данные из электронной таблицы и импортирую его во временную таблицу, затем соответствует типам данных, которые вы хотите сравнить. Если вы читаете во всех строках, вы можете сделать предположения о типах данных во временной таблице. –

0

Проблема заключается в том, что двигатель Microsoft Jet 4.0 не поддерживает функцию CAST(), а также не имеет VARCHAR ключевое слово (ни VARCHAR типа данных, приходят к этому). Зачем вам нужно использовать это значение? Нужно ли обрабатывать значение NULL?

Говоря о типах данных:

F1 >= 2.3456 

Значение 2.3456 является буквальным типа DECIMAL будучи фиксированной десятичной точкой. Excel не имеет собственного фиксированного десятичного типа, поэтому вы, скорее всего, сравниваете значение с плавающей запятой с фиксированной точкой. Я надеюсь, вы оцените проблемы, которые это может вызвать!

+0

Спасибо, но единственная проблема, с которой я столкнулся, - это когда я ищу символ подстановки (*). Числовые значения сравниваются точно, я просто не могу заставить его возвращать записи, содержащие * в поле. – Tester101

0

Ваш предикат

F1 >= 2.3456 

предлагает F1 является числовым типом данных. Пожалуйста, объясните, как вы можете ввести числовое значение в VARCHAR и ожидать получить * в результате ...? Я не вижу, как это происходит!

Если столбец содержит числовые значения и * символы, то это будет смешанных типов и двигатель Jet 4.0 должен решить, следует ли выбрать FLOAT (в этом случае ваши * символы будут заменены на значение NULL) или тип NVARCHAR(255) (в этом случае ваши числовые значения могут быть преобразованы в научные обозначения).

Возможно, вы можете использовать значения реестра, чтобы влиять на результат, но не надейтесь сделать это в коде SQL, потому что тип данных уже выбран.

Подробнее см. Daily Dose of Excel: External Data - Mixed Data Types от так называемого эксперта :) В комментариях есть много хороших деталей.

+0

Есть ли способ получить записи, содержащие * в поле? Мне просто нужно вернуть записи, где это поле имеет значение NULL? – Tester101

0

Я думаю, что вам нужно:

  1. удалить CAST и VARCHAR ключевые слова из вашего запроса (они являются незаконными);
  2. изменить локальный реестр ключ TypeGuessRows = 0 (сила для сканирования сканирование всех строк должно определять столбец смешанных типов ...);
  3. обеспечить локальный реестр машин ключ ImportMixedTypes = Text (... до импорт смешанных типов в виде текста, являющийся значением по умолчанию). См. Предыдущие ответы.

После того, как ваши символы «*» появятся в столбце (т. Е. Больше не будет NULL). Однако ваши значения float будут принудительно применены к тексту. Вы можете использовать/принудительно возвращать значения float-as-text в числовые значения в SQL, но сначала вам нужно будет проверить значение NULL и числовое значение, например.

SELECT F1, 
     IIF(
      F1 IS NULL, 
      '{{Excel cell is blank}}', 
      IIF(
       F1 = '*', 
       '{{Excel cell is the ''*'' character}}', 
       IIF(
        ISNUMERIC(F1), 
        CDBL(F1), 
        '{{Excel cell is non-nmeric and not the ''*'' character}}' 
       ) 
      ) 
     ) AS result  
FROM [F1$]; 

Примечание я обычно предпочитаю SWITCH() над гнездом IIF(), но в этом случае она должна быть IIF(). Причина: IIF(), если перегружен для Access Database Engine SQL, и будет оценено условие TRUE или FALSE, но оба они оба. В VBA противоположное имеет место, т. Е. Оба условия всегда оцениваются. SWITCH() не работает, либо в Access Database Engine SQL или VBA.

Смежные вопросы