Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.02.19;
Скачать: [xml.tar.bz2];

Вниз

советы по оптимизации експорта в 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.042 c
15-1138683623
begin...end
2006-01-31 08:00
2006.02.19
С Днём рождения! 31 января


15-1138525647
vidiv
2006-01-29 12:07
2006.02.19
Node.appendChild(...) обнуляет некторые значения формы в js&amp;ie


15-1138709234
Digitman
2006-01-31 15:07
2006.02.19
Разыскиваю человека. Москвичи, помогите в пределах возможного...


15-1138632090
Din
2006-01-30 17:41
2006.02.19
Как сделать чтобы Интернет Эксплороер не выкачивал флеш-ролики?


1-1137736871
Woland USSR
2006-01-20 09:01
2006.02.19
Сканер штрих-кодов и com-порт





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский