![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
советы по оптимизации експорта в Excel [D6, WinME, Win2k, WinXP]
zorik © (2006-01-18 11:45:00)Моя програма генерирует отчеты в Excel. Примерно такого вида:
предприятие 1
цех 1
бригада 1
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
-------------------
всего по бригаде 1
бригада 2
* * * * * * * * * *
* * * * * * * * * *
-------------------
всего по бригаде 2
всего по цеху 1
цех 2
бригада 1
* * * * * * * * * *
* * * * * * * * * *
-------------------
всего по бригаде 1
бригада 2
* * * * * * * * * *
-------------------
всего по бригаде 2
всего по цеху 2
всего по предприятию 1
... и т.д.
То что выделено * -- это числа. Они оформляются в виде масива и целым куском експортируются. Потом для этой выделеной области рисуется левая, правая, нижняя и верхняя граници.
Названия предприятий, цехов, бригад просто записываются в определенные ячейки, которые потом объеденяются, выделяются жирным и центрируются. Тормоза проявляются больше всего здесь и при рисовании границ.
Подскажите советы для увеличения скорости експорта
evvcom (2006-01-18 17:01:00) [1]
> 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, ты просто с ним работать не умеешь.
> Может быть и одна строчка.
Если вообще всего одна строчка, то лишнюю удали.
zorik (2006-01-18 15:35:00) [2]Опишу детально весь процес
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;
zorik (2006-01-18 15:02:00) [3]
Границы нарисовать удастся. Достаточно всего 2 строки. Потом вычисляешь, сколько нужно строк и вставляешь необходимое между ними. Все форматирование Excel сам сделает.
Может быть и одна строчка. К тому же они разъеденены. Например
------------------
| ЦЕХ 1 | <<- построчное присваивание с форматированием
------------------
| Бригада 1 | <<- построчное присваивание с форматированием
------------------
| | | | | | | | <<-
------------------
| | | | | | | | <<- массив
------------------
| | | | | | | | <<-
------------------
| Бригада 2 |
------------------
| | | | | | | |
------------------
| | | | | | | |
------------------
evvcom (2006-01-18 14:25:00) [4]
> Граници нарисовать в шаблоне сразу не удастся, т.к. неизвестно
> количество строк
Границы нарисовать удастся. Достаточно всего 2 строки. Потом вычисляешь, сколько нужно строк и вставляешь необходимое между ними. Все форматирование Excel сам сделает.
P.S. Я так уже делал когда-то... Везде где можно, избегай поклеточного/построчного редактирования, делай групповое, например, копированием шаблонов пусть даже областей.
umbra (2006-01-18 12:34:00) [5]
> где взять полный пречень свойств ExcelApplication
в справке по Excel Visual Basic, которая есть в каждой инсталляции оффиса.
zorik (2006-01-18 12:24:00) [6]Не сильно помогло :-( Не подскажите где взять полный пречень свойств ExcelApplication?
zorik (2006-01-18 11:59:00) [7]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; спасибо, сейчас попробую
umbra (2006-01-18 11:49:00) [8]сделать файл-шаблон, в котором уже все покрашено и есть все границы, а при экспорте создавать файл по этому шаблону примерно так
XLApp.Workbooks.Add('шаблон.xls');
DSKalugin (2006-01-18 11:49:00) [9]отключить реакцию на события и сделать невидимым на время отрисовки
ExcelApp := CreateOleObject('Excel.Application');
ExcelApp.Visible := False;
ExcelApp.Application.EnableEvents := False;
*****выполнить все действия**********
ExcelApp.Visible := True;