Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
 C# Array to Excel  [new]
vah
Member

Откуда:
Сообщений: 2609
Скажите пожалуйста,
возможно ли данные из DataTable писать в Excel не в цикле, а записать сразу целиком массив, указав левую верхнюю и правую нижнюю границу?

Заранее благодарен.
4 мар 19, 14:34    [21824425]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 20286
Каким образом ты взаимодействуешь с документом Эксель?
Если через Interop - по идее можешь тупо в Range вставить массив.
4 мар 19, 14:40    [21824437]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
vb_sub
Member

Откуда:
Сообщений: 495
vah,
чем цикл не устраивает?
4 мар 19, 17:51    [21824701]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
PinkCat
Member [заблокирован]

Откуда:
Сообщений: 2421
vah,

​Сериализуй таблицу в формате ехцел-документа.
Сам - не делал, обхожусь писанием заголовков и дампом ЦСВ.
4 мар 19, 20:31    [21824811]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
Antonariy
Member

Откуда: ☭
Сообщений: 72716
Range.Value = array, и нет вопросов.
Главное, чтобы размеры Range и array совпадали.
4 мар 19, 22:16    [21824868]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
Antonariy
Member

Откуда: ☭
Сообщений: 72716
vb_sub
vah,
чем цикл не устраивает?
тормозами
4 мар 19, 22:17    [21824869]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
skyANA
Member

Откуда: Зеленоград
Сообщений: 26466
Лень проверять, но...

Если поставить макрос на запись, выделить таблицу, вырезать, а потом также куда-то вставить, то не получим код, нужный ТС?

Вроде все уже должны знать, что следует использовать Range и если что не понятно, то записывай макрос и смотри.
4 мар 19, 23:48    [21824913]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 20286
skyANA
то не получим код, нужный ТС?
Нет. Получим код, который портит буфер обмена. ТС не это нужно
5 мар 19, 00:36    [21824944]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
Изопропил
Member

Откуда:
Сообщений: 31078
Ado recordset копируется в excel - CopyFromRecordset

datatable в adodb recordset перегнать ессно нужно
5 мар 19, 00:58    [21824957]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
skyANA
Member

Откуда: Зеленоград
Сообщений: 26466
Shocker.Pro
skyANA
то не получим код, нужный ТС?
Нет. Получим код, который портит буфер обмена. ТС не это нужно

То есть код вставки не получим, точно?
5 мар 19, 07:43    [21825006]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
skyANA
Member

Откуда: Зеленоград
Сообщений: 26466
Ладно, фиг с ним, stackoverflow:
https://stackoverflow.com/questions/536636/write-array-to-excel-range

        object[,] arr = new object[dt.Rows.Count, dt.Columns.Count];
        for (int r = 0; r < dt.Rows.Count; r++)
        {
            DataRow dr = dt.Rows[r];
            for (int c = 0; c < dt.Columns.Count; c++)
            {
                arr[r, c] = dr[c];
            }
        }

        Excel.Range c1 = (Excel.Range)wsh.Cells[topRow, 1];
        Excel.Range c2 = (Excel.Range)wsh.Cells[topRow + dt.Rows.Count - 1, dt.Columns.Count];
        Excel.Range range = wsh.get_Range(c1, c2);

        range.Value = arr;
dt - это DataTable

По ссылке и про CopyFromRecordset есть.
5 мар 19, 07:50    [21825010]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 20286
skyANA
То есть код вставки не получим, точно?
мы получим код вставки Range из буфера обмена. Код вставки массива из памяти мы не получим - это разные операции. Массив можно вставить напрямую, тащить его в буфер обмена совсем не требуется.
5 мар 19, 11:22    [21825170]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
PinkCat
Member [заблокирован]

Откуда:
Сообщений: 2421
Antonariy,

тормозами
-----
​Тормоза на экстрагировании данных из таблицы или тормоза на вставке в Ехцел?
Думаю - Ехцел - там медленные олешные вызовы.

Попробуй исключить навигацию по колонкам - у DataRow есть ItemArray - обычно этого достаточно для повышения производительности.


В примере приведенном skyANA ​ можно исключить второй цикл и вставлять построчно.
Плюс, итератор по строкам должен быть быстрее индексатора по целому - там не массив, а дерево.


Есть еще один хитро выпернытый способ.
В ВБА таблица представляется как полностью плоская. Т.е. доступно dt[i,k].
В этом случае не нужно писать свои циклы, а можно задать Range() и присвоить range.Value = dt;
Какие именно библиотеки надо цеплять - не помню, но в басиковских аппах можно поискать.


Да, кстати, а почему бы просто не унаследоваться от DataTable и не написать свой двумерный indexer?
Для ехцеловского импортера его должно хватить...
5 мар 19, 12:32    [21825241]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
Изопропил
Member

Откуда:
Сообщений: 31078
PinkCat
Думаю - Ехцел - там медленные олешные вызовы.

именно поэтому нужно не циклы крутить, а вставку одним вызовом делать
5 мар 19, 12:40    [21825265]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 38457
PinkCat
там медленные олешные вызовы.
сам по себе Ole server имеет насколько помню вставку пачкой.
Какой тип не помню, но вроде было а API.
5 мар 19, 12:47    [21825275]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
Vladimir Baskakov
Member

Откуда:
Сообщений: 1938
В цикле сильно быстрее, если отменить автопересчет книги и еще немного всего (по материалам хабра, код VBA). Потом все вернуть на место
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    ActiveSheet.DisplayPageBreaks = False
    Application.DisplayStatusBar = False
    Application.DisplayAlerts = False
5 мар 19, 12:55    [21825288]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
PinkCat
Member [заблокирован]

Откуда:
Сообщений: 2421
Изопропил,


именно поэтому нужно не циклы крутить, а вставку одним вызовом делать
-----
Вставку одним вызовом можно делать по-разному.
Все, что требуется в данном случае - дать Ехцелу что-то работающее как двумерный массив...
В смысле - не обязательно формировать сам массив...
5 мар 19, 13:18    [21825321]     Ответить | Цитировать Сообщить модератору
 Re: C# Array to Excel  [new]
PinkCat
Member [заблокирован]

Откуда:
Сообщений: 2421
skyANA
Ладно, фиг с ним, stackoverflow:
https://stackoverflow.com/questions/536636/write-array-to-excel-range

        object[,] arr = new object[dt.Rows.Count, dt.Columns.Count];
        for (int r = 0; r < dt.Rows.Count; r++)
        {
            DataRow dr = dt.Rows[r];
            for (int c = 0; c < dt.Columns.Count; c++)
            {
                arr[r, c] = dr[c];
            }
        }

        Excel.Range c1 = (Excel.Range)wsh.Cells[topRow, 1];
        Excel.Range c2 = (Excel.Range)wsh.Cells[topRow + dt.Rows.Count - 1, dt.Columns.Count];
        Excel.Range range = wsh.get_Range(c1, c2);

        range.Value = arr;


Да, пока не забыл...
Как-то натолкнулся у мелкомягких в их коде на конструкцию с запоминанием DataColumn.
Сначала не понял зачем такие сложности, потом потестил на предмет времени доступа.
Индексация DataRow посредством DataColumn оказалась самой быстрой.


Так что пример правильнее писать как:
       
        object[,] arr = new object[dt.Rows.Count, dt.Columns.Count];
        int r = 0, c = 0;
        foreach (DataRow dr in dt.Rows)
        {
            c = 0;
            foreach (DataColumn dc in dt.Columns)
            {
                arr[r, c++] = dr[dc];
            }
            ++r;
        }


Можно так же вспомнить, что двумерные массивы в шарпе двух типов и - [,] - является одной сплошной областью и избавится от одного индекса - ехцелу должно быть без разницы. Но тестить надо...
5 мар 19, 13:54    [21825364]     Ответить | Цитировать Сообщить модератору
Все форумы / WinForms, .Net Framework Ответить