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

Вниз

Экспорт в 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.057 c
15-1159356367
GanibalLector
2006-09-27 15:26
2006.10.22
Запрет запуска реестра(RegEdit)


2-1159778266
laok
2006-10-02 12:37
2006.10.22
Как узнать что пользователь не работает с программой уже...


4-1148999843
Kolan
2006-05-30 18:37
2006.10.22
Событие чтения из Com порта происходит когда в порте ничего нет


3-1156510745
PEAKTOP
2006-08-25 16:59
2006.10.22
EXECUTE BLOCK


15-1159540793
Ringo
2006-09-29 18:39
2006.10.22
Есть контакт!





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский