Ответы с форумов MSDN

OleDB вставка числа в Excel

Date: 15.03.2019 3:27:36

OLE DB ориентирован на работу с реляционными БД, где каждый столбец таблицы имеет определенный тип. Однако, документы Excel не являются реляционными БД; ячейки в столбце могут иметь смешанные типы, а формат отображения является вообще отдельным атрибутом, не имеющим отношение к данным. Когда вы подключаетесь к Excel-документу через OLE DB с параметром IMEX=0, драйвер БД пытается угадать тип столбца, анализируя некоторое количество начальных строк и выбирая тот, который встречается чаще. Если же IMEX=1, то драйвер должен воспринимать все как текст (но из-за бага в Jet это в действительности не работает, пока не установить определенные ключи в реестре). Способа принудительно воспринимать все как число нет.

Словом, если вам нужен продвинутый контроль над типами данных, OLE DB - неподходящее средство. Используйте вместо него:

Office Automation - для клиентских приложений, запускаемых на компьютерах с установленным Office

Open XML SDK - для серверных приложений, или для приложений, запускаемых на компьютерах без Office

Message 283

Date: 15.03.2019 5:12:08

Насколько я помню, да, но я не уверен, распространяется это только на XLS или также и на XLSX. Вы можете проверить это сами, создав таблицу, в которой первые ~20 строк заняты числами, а далее идут текстовые значения, и попытавшись считать ее. При IMEX=1 все значения должны считаться как текст. Если числа считаются как числа, а текст - как NULL, это тот же баг, что и в Jet.

Message 282

Date: 15.03.2019 14:12:01

Если вы файл заполняете с нуля, можно попробовать создавать таблицы SQL-запросом с явным указанием типов, а не использовать то, что создано самим Excel. Как-то так:

CREATE TABLE [Table] ([Column1] TEXT, [Column2] FLOAT)

Message 281

Date: 15.03.2019 17:01:45

Ага, увидел. Сейчас попробовал сам, у меня вроде отображает как число

 
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.OleDb;

namespace ConsoleTest
{  
    class Program
    {   
        static void Main(string[] args)
        {
            OleDbConnection conn = new OleDbConnection();            
            conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source = \"D:\\Test\\book.xlsx\"; Extended Properties=Excel 12.0 Xml";
            conn.Open();

            OleDbCommand cmd = new OleDbCommand("Create table [Test](A TEXT,B FLOAT)", conn);
            var res = cmd.ExecuteNonQuery();
            Console.WriteLine("Create table " + res.ToString());

            cmd = new OleDbCommand("Insert into [Test] (A,B) Values ('hello',1.1)", conn);
            res = cmd.ExecuteNonQuery();
            Console.WriteLine("Insert " + res.ToString());

            Console.ReadKey();
        }
    }


}

Результат:

1,1 выровнено по правому краю, как число.


Message 280

Date: 15.03.2019 18:11:29

Если в DataTable при заполнении через адаптер где-то генерируется тип string вместо правильного типа, скорее всего, придется кое-что переписать. Либо заполнять DataTable вручную, явно задавая правильный тип для столбцов, либо менять InsertCommand у адаптера, вставляя преобразование в нужный тип. 

Message 279

Date: 16.03.2019 7:50:16

Точно, есть такой подводный камень. Так как Jet/ACE - это файл-серверный движок, он использует промежуточные буферы и окончательное обновление данных в целевом файле может происходить только после закрытия соединения. Для обычной работы с файлами есть Flush, а для OLE DB его аналога я не нашел.

Автор: VadimTagil

Главная страница - Список тем - Репозиторий на GitHub