Проблема с использованием OleDbDataAdapter для извлечения данных из листа Excel - PullRequest
6 голосов
/ 29 сентября 2010

Во-первых, я хочу сказать, что я нахожусь в глубокой воде, поскольку я просто делаю некоторые изменения в коде, который написан кем-то еще в компании, используя OleDbDataAdapter, чтобы «общаться» с Excel, и яЯ не знаком с этим.Там есть одна ошибка, за которой я просто не могу проследить.

Я пытаюсь использовать OleDbDataAdapter для чтения в файле Excel с 450 строками.

В коде это делается так:

connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source='" + path + "';" + "Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1;\"");
connection.Open();
OleDbDataAdapter objAdapter = new OleDbDataAdapter(objCommand.CommandText, connection);
objAdapter.Fill(objDataSet, "Excel");

foreach (DataColumn dataColumn in objTable.Columns) {
  if (dataColumn.Ordinal > objDataSet.Tables[0].Columns.Count - 1) {
    objDataSet.Tables[0].Columns.Add();
  }
  objDataSet.Tables[0].Columns[dataColumn.Ordinal].ColumnName = dataColumn.ColumnName;
  objImport.Columns.Add(dataColumn.ColumnName);
}

foreach (DataRow dataRow in objDataSet.Tables[0].Rows) {
   ...
}

Кажется, все работает нормально, кроме одной вещи.Второй столбец заполнен в основном четырьмя цифрами, такими как 6739, 3920 и т. Д., Но строки fice имеют буквенно-цифровые значения, такие как 8201NO и 8205NO.Сообщается, что эти пять ячеек содержат пустое содержимое вместо их буквенно-цифрового содержимого.Я проверил в Excel, и все ячейки в этих столбцах помечены как текст.

Кстати, это xls-файл, а не xlsx.

Кто-нибудь знает, почемуэти ячейки отображаются пустыми в DataRow, но числовые отображаются нормально?Есть другие столбцы с буквенно-цифровым содержимым, которые отображаются просто отлично.

Ответы [ 3 ]

8 голосов
/ 29 сентября 2010

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

Проблема возникает, когда вы начинаете пытаться запросить эту таблицу с помощью jet.Когда он думает, что имеет дело с числовым столбцом и находит значение varchar, он спокойно ничего не возвращает.Даже загадочное сообщение об ошибке не исчезнет.

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

Взгляните на эту статью .Это более подробно обсуждается в этом вопросе.в нем также говорится о возможном обходе:

Однако, согласно документации JET, мы можем переопределить параметр реестра через строку подключения, если мы установим IMEX = 1 (как часть расширенных свойств).), JET установит для всех типов столбцов UNICODE VARCHAR или ADVARWCHAR независимо от значения ключа «ImportMixedTypes» .hey

1 голос
/ 29 сентября 2010

Я бы не советовал использовать провайдер данных OleDb для доступа к Excel, если вы можете помочь.У меня не было ничего, кроме проблем, именно по причинам, указанным другими.Производительность, как правило, также ужасна, когда вы работаете с большими таблицами.

Вы можете попробовать это решение с открытым исходным кодом: http://exceldatareader.codeplex.com/

1 голос
/ 29 сентября 2010

IMEX=1 означает «Считать смешанные данные как текст».

Однако есть некоторые ошибки. Jet будет использовать только несколько строк, чтобы определить, смешаны ли данные, и если это произойдет, все эти строки будут числовыми, вы получите такое поведение.

Подробнее см. connectionstrings.com :

Проверьте [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel] расположенный реестр REG_DWORD "TypeGuessRows". Это ключ к тому, чтобы Excel не использовал только первые 8 строк, чтобы угадать тип данных столбцов. Установите это значение в 0 для сканирования всех строк. Это может повредить производительности. Также обратите внимание, что добавление опции IMEX = 1 может привести к включению функции IMEX после 8 строк. Вместо этого используйте IMEX = 0, чтобы принудительно заставить реестр TypeGuessRows = 0 (сканировать все строки) работать.

...