![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Экспорт в Excel [D5, Access]
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".