Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Вставка диапазона значений


Автор: Fedia 19.10.2006, 07:00
Еще раз приветствую всех !

Сейчас почитал ветки форума по работе с Excel документами и не нашел примера вставки в таблицу диапазона значений. Я имею ввиду возможность одновременного заполнения сразу нескольких ячеек, входящих в диапазон ячеек, заданный двумя ячейками. Например, для занесения данных в диапазон ячеек с “A1” по “D4” в Delphi достаточно заполнить двухмерный массив типа OLEVariant, а затем выполнить: 
Код

ArrVar: OLEVariant;
//...
Excel.WorkBooks[1].WorkSheets[1].Range['A1', 'D4']:=ArrVar;

Можно ли подобное реализовать в C# ? Только без использования буфера обмена и, желательно, без применения метода select (т.е. без явного выделения ячеек в таблице, поскольку в этом случае при параллельном формировании нескольких таблиц Excel часто возникают сбои).

ЗЫ: надеюсь, что понятно описал, если что, постараюсь уточнить.

Автор: Fedia 24.10.2006, 07:25
Не мог я поверить, что в Delphi предусмотрена возможность заполнения диапазона значений при работе с документами Excel, а в C#, фактически, родном языке Microsoft-а -нет. В итоге разобрался с принципами реализации этой задачи С#:
Код

            Excel.Application app = new Excel.Application();
            try
            {    
                object optional = Missing.Value;
                app.DisplayAlerts = false;
                app.Visible = true;
                string AppWay = Path.GetDirectoryName(
                    Assembly.GetExecutingAssembly().GetModules(false)[0].FullyQualifiedName);
                Excel.Workbook workbook = app.Workbooks.Add(optional);

                Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets[1];

                DateTime Start = DateTime.Now;
                Excel.Range RangeE = worksheet.get_Range(worksheet.Cells[1,1],
                    worksheet.Cells[100,100]);
                object[,] ArE = new object[100, 100];
                for (int i=1; i<100; i++)
                    for (int n=1; n<100; n++)
                    {
                        ArE[i, n] = i*n;
                    }

                RangeE.Formula = ArE;
                TimeSpan ts = (DateTime.Now - Start);
                MessageBox.Show(ts.Minutes + ":" + ts.Seconds + ":" + ts.Milliseconds);
                workbook.SaveAs(@"C:\1.xls" + DateTime.Now.ToString("dd.MM.yyyy HH.mm") + ".xls", 
                    optional, optional, optional, optional,
                    optional, Excel.XlSaveAsAccessMode.xlShared, optional, optional, 
                    optional, optional, optional);
                app.Quit();    
            }
            catch
            {
                app.Quit();
                MessageBox.Show("Ошибка формирования документа Excel");
            }

Коротко о том, для чего такой способ заполнения таблиц Excel может понадобиться и для чего я создал данную ветку форума. Все дело в скорости формирования документа. Нередко перед разработчиком ставятся задачи формирования отчетов в виде документов Excel. Если отчет содержит несколько десятков строк, то скорость формирования такого отчета будет достаточна велика даже при поячеечном способе формирования. А если документ содержит пару десятков тысяч строк, то его формирование поячеечным способом может составить часы процессорного времени. Для ускорения процесса формирования документов (отчетов) такого размера и был разработан способ однооперационного заполнения диапазона ячеек.
Для сравнения скоростных характеристик формирования документов добавляю также пример формирования аналогичного по содержанию документа поячеечным способом: 
Код

            Excel.Application app = new Excel.Application();
            try
            {    
                object optional = Missing.Value;
                app.DisplayAlerts = false;
                app.Visible = true;
                string AppWay = Path.GetDirectoryName(
                    Assembly.GetExecutingAssembly().GetModules(false)[0].FullyQualifiedName);
                Excel.Workbook workbook = app.Workbooks.Add(optional);

                Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets[1];

                DateTime Start = DateTime.Now;
                for (int i=1; i<=100; i++)
                    for (int n=1; n<=100; n++)
                    {
                        worksheet.Cells[i, n] = i*n;
                    }

                TimeSpan ts = (DateTime.Now - Start);
                MessageBox.Show(ts.Minutes + ":" + ts.Seconds + ":" + ts.Milliseconds);
                workbook.SaveAs(@"C:\1.xls" + DateTime.Now.ToString("dd.MM.yyyy HH.mm") + ".xls", 
                    optional, optional, optional, optional,
                    optional, Excel.XlSaveAsAccessMode.xlShared, optional, optional, 
                    optional, optional, optional);
                app.Quit();    
            }
            catch
            {
                app.Quit();
                MessageBox.Show("Ошибка формирования документа Excel");
            }

У меня получилось следующее соотношение:
- поячеечное формирование: 0:55:0
- заполнение диапазона значений: 0:0:125. 
Итого, скорости формирования документа отличаются в 440 раз smile И это при заполнении только лишь 10 тысяч ячеек. Чем больше информации должен содержать итоговый документ, тем выгоднее применения описанного метода  smile 

Автор: Fedia 9.1.2007, 04:20
По просьбе одного из участников форума продолжаю тему.
Цитата
Прочитал твою тему  Вставка диапазона значений, в документ Excel(topic-117155.html). Это именно то что мне нужно....
Создается объект ArE. А как в этот объект "засунуть" данные из однго листа Экселя и перекинуть их в определенные ячейки другого листа. (С переключением листов вроде разобрался, а вот с процессом "эасовывания":) и как это сделат если данные не с А1 начинаються а к примеру с С20).


Код

//заполняем данные 1-го листа Excel
Excel.Range RangeE = worksheet.get_Range(worksheet.Cells[1,1],
    worksheet.Cells[100,100]);
object[,] ArE = new object[100, 100];
for (int i=1; i<100; i++)
    for (int n=1; n<100; n++)
    {
        ArE[i, n] = i*n;
    }

RangeE.Formula = ArE;
        
//Копируем часть данных, начиная с ячейки С20 в массив        
object[,] ArE1 = new object[50, 50];
RangeE = worksheet.get_Range(worksheet.Cells[20, 3],
    worksheet.Cells[69, 72]);
ArE1 = (object[,])RangeE.Formula;

//Вставляем эти данные во 2-й лист Excel
worksheet = (Excel.Worksheet)workbook.Worksheets[2];
RangeE = worksheet.get_Range(worksheet.Cells[20, 3],
    worksheet.Cells[69, 52]);
RangeE.Formula = ArE1;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)