Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Экспорт в Excel [D5, Access]


Страницы:   1 2

BBCHa ©   (2006-08-16 16:47:00) 

Всем привет! Есть три таблицы: два, 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]:='îïë';
  Sheets.Cells[k,17]:=Query.FieldByName('Comment').AsString;
  Query.Next;
  Inc(k);
 end;
Excel.Workbooks[1].Save;
Excel.Quit;


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

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


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


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

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


Kinda   (2006-08-23 16:28:00) [2]

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

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


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

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

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


Kinda   (2006-08-23 16:24:00) [3]


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


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

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


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


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

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


Kinda   (2006-08-23 14:52:00) [5]


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

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


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

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

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



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

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


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

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


Anatoly Podgoretsky   (2006-08-23 13:29:00) [7]

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


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

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


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


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

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


Anatoly Podgoretsky   (2006-08-22 11:38:00) [10]

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

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


Kinda   (2006-08-22 10:08:00) [11]


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

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


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


> Lexiy   (18.08.06 18:22) [10]

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


Lexiy   (2006-08-18 18:22:00) [13]

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

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


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


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

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


umbra   (2006-08-17 18:08:00) [15]

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


BBCHa   (2006-08-17 17:17:00) [16]

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

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


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

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


Anatoly Podgoretsky   (2006-08-16 19:04:00) [18]

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

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


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

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


BBCHa   (2006-08-16 18:45:00) [20]

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо