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

Вниз

Экспорт в Excel   Найти похожие ветки 

 
BBCHa ©   (2006-08-16 16:47) [0]

Всем привет! Есть три таблицы: два, 5 и 15 полей соттветственно. Эти таблицы выгружаются на три разных листа одного эксель файла. Делаю это так:
Excel:=CreateOleObject("Excel.Application");
Excel.Visible:=False;
Excel.Workbooks.Open(ExtractFilePath(Application.ExeName)+"f.xls");
Sheets:=Excel.Workbooks[1].Sheets[1];
k:=2;
frDM.ADOQuerySpisokClient.First;
While Not frDM.ADOQuerySpisokClient.EOF Do
 Begin
  Sheets.Cells[k,1]:=IntToStr(k-1);
  Sheets.Cells[k,3]:=frDM.ADOQuerySpisokClient.FieldByName("Name_Client").AsString ;
  frDM.ADOQuerySpisokClient.Next;
  Inc(k);
 end;
Sheets:=Excel.Workbooks[1].Sheets[2];
k:=5;
Query:=TADOQuery.Create(nil);
Query.Connection:=ADOConnection;
Query.SQL.Text:="SELECT * FROM Front_Contacts";
Query.Open;
Query.First;
While Not Query.EOF Do
 Begin
  Sheets.Cells[k,1]:=Query.FieldByName("Name_User").AsString;
  Sheets.Cells[k,2]:=Query.FieldByName("Name_Filial").AsString;
  If FormatDateTime("dd.mm.yyyy",Query.FieldByName("Date_Last").AsDateTime)<>"30.12.1 899"
   then
    Sheets.Cells[k,3]:=FormatDateTime("dd.mm.yyyy",Query.FieldByName("Date_Last").As DateTime);
  Sheets.Cells[k,7]:=Query.FieldByName("Name_Client").AsString;
  Sheets.Cells[k,9]:=Query.FieldByName("Name_Otrasl").AsString;
  Sheets.Cells[k,10]:=Query.FieldByName("Name_City").AsString;
  Sheets.Cells[k,11]:=Query.FieldByName("Adress").AsString;
  Sheets.Cells[k,12]:=Query.FieldByName("Name_Contact").AsString;
  Sheets.Cells[k,14]:=Query.FieldByName("Job_Title").AsString;
  Sheets.Cells[k,15]:=Query.FieldByName("Phone").AsString;
  Sheets.Cells[k,16]:=Query.FieldByName("EMail").AsString;
  Sheets.Cells[k,18]:=Query.FieldByName("Comment").AsString;
  Query.Next;
  Inc(k);
 end;
Sheets:=Excel.Workbooks[1].Sheets[3];
k:=5;
Query.Close;
Query.SQL.Text:="SELECT * FROM Front_Journal";
Query.Open;
Query.First;
While Not Query.EOF Do
 Begin
  Sheets.Cells[k,1]:=Query.FieldByName("Name_User").AsString;
  Sheets.Cells[k,2]:=Query.FieldByName("Name_Filial").AsString;
  Sheets.Cells[k,3]:=Query.FieldByName("Name_Client").AsString;
  Sheets.Cells[k,4]:=Query.FieldByName("Code_Product").AsString;
  Sheets.Cells[k,5]:=Query.FieldByName("Name_Product").AsString;
  Sheets.Cells[k,7]:=FloatToStr(StrToFloat(FloatToStrF(Query.FieldByName("Summa_Pl an").AsFloat,ffFixed,20,2)));
  Sheets.Cells[k,8]:=FormatDateTime("dd.mm.yyyy",Query.FieldByName("Date_Begin").A sDateTime);
  Sheets.Cells[k,9]:=FormatDateTime("dd.mm.yyyy",Query.FieldByName("Date_Reshen"). AsDateTime);
  Sheets.Cells[k,10]:=Query.FieldByName("Name_Status").AsString;
  Sheets.Cells[k,11]:=Query.FieldByName("Name_Otkaz").AsString;
  Sheets.Cells[k,12]:=FormatDateTime("dd.mm.yyyy",Query.FieldByName("Date_Prognoz_ Cast").AsDateTime);
  If Query.FieldByName("Costs").AsBoolean
   Then
    Sheets.Cells[k,13]:="&#238;&#239;&#235;";
  Sheets.Cells[k,17]:=Query.FieldByName("Comment").AsString;
  Query.Next;
  Inc(k);
 end;
Excel.Workbooks[1].Save;
Excel.Quit;


Делается все очень, просто крайне медлено и тормознуто. Т.е. фактически при количестве записей в таблицах 450, 1000 и 250 соответсвенно процедура отрабатывается за 5-6 часов.

Подскажите, есть ли способ повысить быстродействие? Заранее спасибо.


 
Lexiy   (2006-08-16 17:29) [1]

мне не нравится момент вноса данных в яйчейки попробуй вот так ...

// Заполняем массив
  Querys.DisableControls;
  Querys.First;
  While Not Querys.eof Do
  Begin
      For J := 1 To Querys.FieldDefs.Count Do
      Begin
          ArrayData[Querys.RecNo, J] :=
           Querys.FieldbyName(Querys.FieldDefs.Items[j - 1].DisplayName).value;
      End;
      Querys.Next;
  End;

  Querys.EnableControls;

//     Левая верхняя ячейка области, в которую будем выводить данные
  Cell1 := WorkBook.WorkSheets[1].Cells[BeginRow, BeginCol];
// Правая нижняя ячейка области, в которую будем выводить данные
  Cell2 := WorkBook.WorkSheets[1].Cells[BeginRow + RowCount - 1,
   BeginCol + ColCount - 1];

// Область, в которую будем выводить данные
  Range := WorkBook.WorkSheets[1].Range[Cell1, Cell2];

// А вот и сам вывод данных
// Намного быстрее поячеечного присвоения
  Range.Value := ArrayData;


 
Lexiy   (2006-08-16 17:33) [2]

да arraydata это variant ... хотя это и так понятно ... момент с датой просто опиши отдельно на иф ... у меня была похожая задача в свое время


 
BBCHa ©   (2006-08-16 18:45) [3]

я извиняюсь, какого типа должен быть arraydata? когда делаешь его arraydata: Variant; ругается, что "Variant is not an array".


 
Lexiy   (2006-08-16 18:54) [4]

ArrayData := VarArrayCreate([1, RowCount, 1, ColCount], varVariant);


 
Anatoly Podgoretsky ©   (2006-08-16 19:04) [5]

Делается все очень, просто крайне медлено и тормознуто.

Ченр де ты хочешь, если ты работаешь с Cells - это самый медленный из медленных способов. Как сказали работать надо с VarArrayCreate, у меня самые большие отчеты формируются менее одной секунды, правда я не использую OLE работаю через СОМ но это не существенно, просто еще быстрее.


 
BBCHa ©   (2006-08-17 10:55) [6]

Большое спасибо всем. Все получилось.


 
BBCHa ©   (2006-08-17 17:17) [7]

Но возник другой вопрос, да простят меня все:)
Необходимо в один из столбцов добавлять формуу вида
=ЕСЛИ(C5="";"";МЕСЯЦ(C5))
При попытке записать это в Range.Value - ругается, что в общем то понятно, а вот почему ругается при попытке записи в Range.Formula - непонятно.

Друзья, подскажите плз.


 
umbra ©   (2006-08-17 18:08) [8]

Range.Formula - только для английских формул. Для руских, укр., албанских надо использовать Range.FormulaLocal


 
VadimSpb   (2006-08-17 19:04) [9]


> =ЕСЛИ(C5="";"";МЕСЯЦ(C5))

Можно сделать в англ. транскрипции, например: СУММ -> SUM и т.д.
Но есть грабли: для 2000 офиса все равно не пройдет.
Range.FormulaLocal не проверял, но похожее также возможно, обязательно надо протестировать. Особенно для "97!
Я пришел к выводу, что безошибочно будет делать вычисление в программе, а экспортировать только результат - надежнее получается. В том случае, если есть много "непредсказуемых" пользователей :-)))


 
Lexiy   (2006-08-18 18:22) [10]

+9 иногда бывает нужно что бы пользхователь имел возможность поменять некоторые данные ... что же ему еще и формулу переписывать ??? :)

сделай макрос создай формулу и посмотри что пишет vba ... и спокойно кидаешь то же самое в яйчейку работает проверено косяков нет


 
VadimSpb   (2006-08-18 23:39) [11]


> Lexiy   (18.08.06 18:22) [10]

К сожалению, может и не работать. И косяки есть. Блажен - кто верует.
Попробуй выполнить в цикле более 350-400 раз
Worksheets("Sheet1").Copy After:=Worksheets("Sheet3").
Это из справки Excel 2003. И не только в VBA не отработает.
Речь идет об использовании шаблона: типа копируем его в новую страницу в данной книге. Если делаешь как в справке - не работает. Что в VBA, что аналогично в приложении. Хватает только примерно на 250 стр, точно не помню. Нашел свое решение: копирую нужную страницу из шаблона в другую книгу - тогда работает "до потери памяти".
И не забывай ограничения - 65536 строк и 256 столбцов в странице и т.д. смотри справку "Технические характеристики и ограничения Microsoft Excel"
Это все актуально, если делаешь "серьезные" отчеты ;-)))


 
Kinda ©   (2006-08-22 10:08) [12]


> Worksheets("Sheet1").Copy After:=Worksheets("Sheet3").
> Это из справки Excel 2003. И не только в VBA не отработает.
>

В таких случаях я делаю так:
Sheets.Add After:=Sheets(Sheets.Count)
А потом специальной процедурой копирую данные с листа шалона и форматирую лист как в шаблоне.
В результате работает быстро и более 500 раз (у меня), но думаю что можно и больше.


 
Anatoly Podgoretsky ©   (2006-08-22 11:38) [13]

Lexiy   (18.08.06 18:22) [10]
+9 иногда бывает нужно что бы пользхователь имел возможность поменять некоторые данные ... что же ему еще и формулу переписывать ??? :)

А ты как думаешь, a3=A1+A2 и что бы при этом еще и данные поменять, то есть по формуле 5, а ты хочешь 4 написать, смешно.


 
VadimSpb   (2006-08-22 15:44) [14]


> В таких случаях я делаю так:
> Sheets.Add After:=Sheets(Sheets.Count)

Создает-то он страницы быстро, вот только новые, которые надо форматировать. А это занимает много времени.
Шаблон хорош тем, что любой из многих пользователей может подправить его "под себя".


 
Lexiy   (2006-08-23 09:35) [15]

13 Анатолий не понял мысли ?


 
Anatoly Podgoretsky ©   (2006-08-23 13:29) [16]

А мысль простая, значение расчитывает пользователь, и если формулу изменить значением, то легко сделать, что 2+2=5
Раз есть формулы, то меняться должны значения операндов.


 
Lexiy   (2006-08-23 14:01) [17]

16 ... хм собственно я так полагаю что мы говорим об одном и том же надо :) просто немного не допоняли друг друга :)


 
Kinda ©   (2006-08-23 14:52) [18]


> Создает-то он страницы быстро, вот только новые, которые
> надо форматировать.

Совершенно верно.


> А это занимает много времени.

Неправда, это гораздо быстрее чем

> Worksheets("Sheet1").Copy After:=Worksheets("Sheet3").



> Шаблон хорош тем, что любой из многих пользователей может
> подправить его "под себя".

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


 
VadimSpb   (2006-08-23 16:07) [19]


> а потом процедура на его основе отформатирует новые листы.

В чем суть данного форматирования?
Если программно рисовать колонки, устанавливать толщину линий, ширину колонок и т.д., то это верно только для простеших отчетов.Такое решение, напр., для сложных квитанций занимает примерно такое же время как и копирование из шаблона.
Так о форматировании каким способом идет речь?


 
Kinda ©   (2006-08-23 16:24) [20]


> Так о форматировании каким способом идет речь?


Незнаю какие у тебя сложные квитанции,
но налоговые накладные форматятся так
> рисовать колонки, устанавливать толщину линий, ширину колонок
> и т.д

VBA-шнім макросом и быстро.


 
Kinda ©   (2006-08-23 16:28) [21]

Хотя, конешно не буду спорить,
скорость не намного быстрее, но зато,
проходит более чем

> Попробуй выполнить в цикле более 350-400 раз


Кстати конструкция

> Worksheets("Sheet1").Copy After:=Worksheets("Sheet3").

У меня работала прекрасно в 2000 офисе, начиная с ХР перестала.


 
VadimSpb   (2006-08-23 16:52) [22]


> скорость не намного быстрее, но зато, проходит более чем

Это как, если скорость практически та-же? :-))
Я все это перебробовал (и макрос VBA) с точным таймером - шаблоном то-же время занимает про сложных конструкциях и с количеством проблем нет (см. 11).
> Worksheets("Sheet1").Copy After:=Worksheets("Sheet3") взята из примера 2003 офиса. Работает, но в последний раз споткнулась на 334 стр. :-))
Проблема экспорта носит комплексный и взаимный характер.
1. Совместимость с версиями.
2. Скорость вывода.



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

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

Наверх




Память: 0.53 MB
Время: 0.036 c
15-1159546902
Desdechado
2006-09-29 20:21
2006.10.22
Программа для включения задизабленных кнопок


2-1159875670
Samson
2006-10-03 15:41
2006.10.22
медиасервак.


4-1149959106
suharew
2006-06-10 21:05
2006.10.22
ComPort компонент


2-1160383341
aht
2006-10-09 12:42
2006.10.22
Access+ADO


15-1159897272
SergP
2006-10-03 21:41
2006.10.22
Очень срочно подскажите.....