Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.02.19;
Скачать: CL | DM;

Вниз

советы по оптимизации експорта в Excel   Найти похожие ветки 

 
zorik ©   (2006-01-18 11:45) [0]

Моя програма генерирует отчеты в Excel. Примерно такого вида:


 предприятие 1
 цех 1
 бригада 1
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
-------------------
всего по бригаде 1
 бригада 2
* * * * * * * * * *
* * * * * * * * * *
-------------------
всего по бригаде 2
всего по цеху 1
 цех 2
 бригада 1
* * * * * * * * * *
* * * * * * * * * *
-------------------
всего по бригаде 1
 бригада 2
* * * * * * * * * *
-------------------
всего по бригаде 2
всего по цеху 2
всего по предприятию 1

... и т.д.


То что выделено * -- это числа. Они оформляются в виде масива и целым куском експортируются. Потом для этой выделеной области рисуется левая, правая, нижняя и верхняя граници.

Названия предприятий, цехов, бригад просто записываются в определенные ячейки, которые потом объеденяются, выделяются жирным и центрируются. Тормоза проявляются больше всего здесь и при рисовании границ.

Подскажите советы для увеличения скорости експорта


 
umbra ©   (2006-01-18 11:49) [1]

сделать файл-шаблон, в котором уже все покрашено и есть все границы, а при экспорте создавать файл по этому шаблону примерно так

XLApp.Workbooks.Add("шаблон.xls");


 
DSKalugin ©   (2006-01-18 11:49) [2]

отключить реакцию на события и сделать невидимым на время отрисовки
ExcelApp := CreateOleObject("Excel.Application");
ExcelApp.Visible := False;
ExcelApp.Application.EnableEvents := False;
*****выполнить все действия**********
ExcelApp.Visible := True;


 
zorik ©   (2006-01-18 11:59) [3]

umbra ©   (18.01.06 11:49) [1]

файл-шаблон есть. В нем записано название и шапка таблицы. Граници нарисовать в шаблоне сразу не удастся, т.к. неизвестно количество строк, оно может быть разное. Для вичисления размера масива использую select count() from table

DSKalugin ©   (18.01.06 11:49) [2]

ExcelApp.Visible := False; -- задается в настройках. На скорость сильно не влияят, а за ExcelApp.Application.EnableEvents := False; спасибо, сейчас попробую


 
zorik ©   (2006-01-18 12:24) [4]

Не сильно помогло :-( Не подскажите где взять полный пречень свойств ExcelApplication?


 
umbra ©   (2006-01-18 12:34) [5]


> где взять полный пречень свойств ExcelApplication


в справке по Excel Visual Basic, которая есть в каждой инсталляции оффиса.


 
evvcom ©   (2006-01-18 14:25) [6]


> Граници нарисовать в шаблоне сразу не удастся, т.к. неизвестно
> количество строк

Границы нарисовать удастся. Достаточно всего 2 строки. Потом вычисляешь, сколько нужно строк и вставляешь необходимое между ними. Все форматирование Excel сам сделает.
P.S. Я так уже делал когда-то... Везде где можно, избегай поклеточного/построчного редактирования, делай групповое, например, копированием шаблонов пусть даже областей.


 
zorik ©   (2006-01-18 15:02) [7]


Границы нарисовать удастся. Достаточно всего 2 строки. Потом вычисляешь, сколько нужно строк и вставляешь необходимое между ними. Все форматирование Excel сам сделает.


Может быть и одна строчка. К тому же они разъеденены. Например


------------------
|       ЦЕХ 1        |  <<-  построчное присваивание с  форматированием
------------------
|    Бригада 1     |  <<-  построчное присваивание с  форматированием
------------------
|  |  |  |  |  |  |  |  <<-  
------------------
|  |  |  |  |  |  |  |  <<-  массив
------------------
|  |  |  |  |  |  |  |  <<-  
------------------
|    Бригада 2     |
------------------
|  |  |  |  |  |  |  |
------------------
|  |  |  |  |  |  |  |
------------------


 
zorik ©   (2006-01-18 15:35) [8]

Опишу детально весь процес

1. Создается объект ExcelApplication
2. Открывается файл-шаблон, где написано название отчета и шапка таблицы
3. Отключается видимость, события и т.д.

   V.ScreenUpdating := False;
   V.Visible := se;
   V.DisplayAlerts := False;
   V.Interactive := False;
   V.Application.EnableEvents := false;

4. Проход по самой внешней таблице (предприятий) и запись названия предприятия. Ниже текст процедуры

procedure JoinCells(Sheet: Variant; Top, Width: Integer; Text: String; Bold: Boolean; FontName: string = "");
var
 IR1, IR2: Variant;
begin
 IR1 := Sheet.Cells[Top, 1    ];
 IR2 := Sheet.Cells[Top, Width];
 Sheet.Range[IR1, IR2].MergeCells := True;
 Sheet.Range[IR1, IR2] := Text;
 Sheet.Range[IR1, IR2].Font.Bold := Bold;
 if FontName <> "" then
   Sheet.Range[IR1, IR2].Font.Name := FontName;
end;

5. Проход по таблице нижчего уровня (бригада). Короче повторения шага 4. Максимальная вложеность до 4-х.
6. Проход по самой нижней таблице (с данными). Сначала вычисляю количество строк select count() from table. Потом создаю массив соотвествующего размера, прохожусь по внутренной таблице и заношв массив данные. Присваиваю этот массив определенной области Excel

procedure DrawRangeArray(Sheet: Variant; Text: Variant; xl, yl, xr, yr: Integer);
var
 IR1, IR2: Variant;
begin
 IR1 := Sheet.Cells[yl, xl];
 IR2 := Sheet.Cells[yr, xr];
 Sheet.Range[IR1, IR2] := Text;
end;

7. Рисую границы

procedure DrawBorders(Sheet: Variant; xl, yl, xr, yr: Integer);
var
 IR1, IR2: Variant;
begin
 IR1 := Sheet.Cells[yl, xl];
 IR2 := Sheet.Cells[yr, xr];
 Sheet.Range[IR1, IR2].Borders.Item[1].LineStyle := 1;
 Sheet.Range[IR1, IR2].Borders.Item[2].LineStyle := 1;
 Sheet.Range[IR1, IR2].Borders.Item[3].LineStyle := 1;
 Sheet.Range[IR1, IR2].Borders.Item[4].LineStyle := 1;
end;

8. Вычисляю сумму по столбцах посредством sql для самой вложеной таблицы и к самой верхней. Записываю в Excel

procedure DrawSum(Sheet: Variant; q: TIBQuery; const k: Integer; const Text1: String);
var
 IR1, IR2: Variant;
begin
 with q do
 begin
   IR1 := Sheet.Cells[k, 1];
   IR2 := Sheet.Cells[k, 3];
   Sheet.Range[IR1, IR2].MergeCells := True;
   Sheet.Range[IR1, IR2].HorizontalAlignment := -4152;
   Sheet.Range[IR1, IR2] := Text1;

   Sheet.Cells[k, 4] := FieldByName("sdo").Value;
   Sheet.Cells[k, 5] := FieldByName("sdw").Value;
   Sheet.Cells[k, 6] := FieldByName("sdr").Value;
   Sheet.Cells[k, 7] := FieldByName("sdg").Value;

   Sheet.Cells[k, 8] := FieldByName("gf").Value;
   Sheet.Cells[k, 9] := FieldByName("b").Value;

   Sheet.Cells[k, 12] := FieldByName("o").Value;
   Sheet.Cells[k, 13] := FieldByName("w").Value;
   Sheet.Cells[k, 14] := FieldByName("r").Value;
   Sheet.Cells[k, 15] := FieldByName("g").Value;

   Sheet.Cells[k, 16] := FieldByName("days").Value;
   Sheet.Cells[k, 18] := FieldByName("gl").Value;

   Sheet.Cells[k + 1, 4] := FieldByName("so").Value;
   Sheet.Cells[k + 1, 5] := FieldByName("sw").Value;
   Sheet.Cells[k + 1, 6] := FieldByName("sr").Value;
   Sheet.Cells[k + 1, 7] := FieldByName("sg").Value;
 end;
end;

Вычислить сумму средствами Excel не удастся, т.к. там еще сложные средние значения расчитываются.
9. После всего добавляется снизу подпись типа "директор   _______________" используя ф-цию JoinCells (см. выше)
10. Сохраняю файл под другим именем в другом месте.
11. Включаю все контролы и показываю файл

     V.ScreenUpdating := True;
     V.Visible := True;
     V.Interactive := True;
     V.Application.EnableEvents := True;
     V := Unassigned;


 
evvcom ©   (2006-01-18 17:01) [9]


> zorik ©   (18.01.06 15:02) [7]

Делаешь шаблон:
------------------
|       ЦЕХ 1        |  <<-  построчное присваивание с  форматированием
------------------
|    Бригада 1     |  <<-  построчное присваивание с  форматированием
------------------
|  |  |  |  |  |  |  |  <<-  
------------------
|  |  |  |  |  |  |  |  <<-  массив с  форматированием
------------------
где ЦЕХ 1 - 1 строка, Бригада 1 - 2 строка, пустой массив на 2 строках.
Далее (копирую из VB, на паскаль сам переведешь), данные по всем бригадам и цехам пихаешь в один VarArray, но запоминаешь, меж какими строками надо будет вставить заголовки цехов и бригад. Допустим данных получилось всего 102 строки, 2 уже есть в шаблоне, еще 100 надо добавить. Вставляешь:
   Rows("4:103").Select
   Selection.Insert Shift:=xlDown

При этом вставленные 100 строк будут иметь формат заливки строки 3, а границы строки 4 (удивительно, но вроде все так).
Потом вставляешь сразу все данные из созданного массива. Причем результаты (суммы) можно тоже сюда добавить, чтобы одним махом все.
Потом начинаешь вставлять названия бригад и цехов. Легче вычислять, вставляя их с конца, имхо:
   Rows("2:2").Select
   Selection.Copy
   Rows("6:6").Select
   Selection.Insert Shift:=xlDown
   Application.CutCopyMode = False


> Вычислить сумму средствами Excel не удастся, т.к. там еще
> сложные средние значения расчитываются.

Можно и в Excel, ты просто с ним работать не умеешь.

> Может быть и одна строчка.

Если вообще всего одна строчка, то лишнюю удали.



Страницы: 1 вся ветка

Текущий архив: 2006.02.19;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.049 c
9-1125469441
UnReg_ToXic_Clone
2005-08-31 10:24
2006.02.19
Скелеты и вертексы


3-1135158279
yk
2005-12-21 12:44
2006.02.19
Проблемы с подключением udf


15-1138519418
SergP
2006-01-29 10:23
2006.02.19
HTML. Чем можно заменить <input type="submit" ... >?


2-1138703794
Юля
2006-01-31 13:36
2006.02.19
База данных. Отчет.


2-1138686124
Mike48
2006-01-31 08:42
2006.02.19
315-й вопрос про ehlib