Автор | Сообщение |
|
| постоянный участник
|
Пост N: 19
Зарегистрирован: 06.02.07
|
|
Отправлено: 10.10.07 03:43. Заголовок: экспорт в Excel (тормоза)
Не пойму, в чем причина... Объясните, братцы, "тупому" :) ---- делаю экспорт в Excel (база с лекарствами) .... oExcel := TOleAuto():New( "Excel.Application" ) oExcel:Visible := .F. oLibros := oExcel:Get( "WorkBooks" ) oLibro := oLibros:Add() oHoja := oExcel:Get( "ActiveSheet" ) oHoja:Cells:Font:Name := "Arial" oHoja:Cells:Font:Size := 10 row0:=3 pbi:=1 ... do while .not. AFTG_X->(eof()) // AFTG_X - база, из которой экспортирую (лекарства, цены...) // (aftg_fi - массив макросов для выводимых выражений) oHoja:Cells( row0+pbi, 1 ):Value := " " for iii:=1 to 20 do case case iii=9 // цена oHoja:Cells( row0+pbi, iii ):Value := strtran( str(&(aftg_fi[iii]), 11, 2), ".", ",") oHoja:Cells( row0+pbi, iii ):Set( "NumberFormat", "#######0,00" ) oHoja:Cells( row0+pbi, iii ):HorizontalAlignment := XL_RIGHT case iii=11 // сумма oHoja:Cells( row0+pbi, iii ):Value := strtran( &(aftg_fi[iii]), ".", ",") oHoja:Cells( row0+pbi, iii ):Set( "NumberFormat", "##########0,00" ) oHoja:Cells( row0+pbi, iii ):HorizontalAlignment := XL_RIGHT otherwise // все остальные - просто взять значение if valtype(&(aftg_fi[iii]))="C" // если это строка oHoja:Cells( row0+pbi, iii ):Value := trim(&(aftg_fi[iii])) else if iii=3 // "Код ЛС" oHoja:Cells( row0+pbi, iii ):Value := &(aftg_fi[iii]) oHoja:Cells( row0+pbi, iii ):HorizontalAlignment := XL_RIGHT else // другие oHoja:Cells( row0+pbi, iii ):Value := &(aftg_fi[iii]) endif endif endcase if valtype(&(aftg_fi[iii]))="N" // если это число - выравнять вправо oHoja:Cells( row0+pbi, iii ):HorizontalAlignment := XL_RIGHT endif next iii AFTG_X->(dbskip()) pbi++ enddo ... // формируем заголовок таблицы oHoja:Cells( 1, 1 ):Value := "Выборка из БД формуляров МУ" oHoja:Cells( 1, 1 ):Font:Size := 12 oHoja:Cells( 1, 1 ):Font:Bold := .T. oHoja:Range("A1:F1"):Merge() oHoja:Range("A1:F1"):HorizontalAlignment := XL_CENTER oHoja:Columns("A:"+ckmax):AutoFit() // ckmax - max.буква (самой правой из заполняемых граф) в Экселе for iii:=1 to 20 if at( str(iii,3), " 2 4 5 6 12 13 14 15" ) > 0 // устанавливаем ширину колонок: // ФТГ (наим.), МНН, Торг, Форма, ЛПУ, Терр., Основание, Цел.Прог. if oHoja:Columns(chr(asc("A")-1+iii)+":"+chr(asc("A")-1+iii)):ColumnWidth > 20 oHoja:Columns(chr(asc("A")-1+iii)+":"+chr(asc("A")-1+iii)):ColumnWidth := 20 endif endif next iii // центрируем данные по Ед.Изм. oHoja:Range("G"+ltrim(str(row0))+; ":G"+ltrim(str(row0+pbi-1))):HorizontalAlignment := XL_CENTER oHoja:Cells( 2, 1 ):Select() oExcel:Visible := .T. oHoja:End() oLibro:End() oLibros:End() oExcel:End() ..... и вроде всё... Непонятка в том, что на небольших выборках (100-200-400) всё отрабатывает "мухой", а при попытке выкинуть 25-30 тысяч - ОППАНЬКИ... и идём нервно курить минут на ..дцать. Комп шуршит там чего-то, трудится... а процесс "нескончаем" (во всяком случае, за "разумное" время - ну пусть ЕДИНИЦЫ минут! а это "рубилово" идет минут 20-30!!!). На всякий - операционная обстановка: Win98, Office-97 [увы -так НАДО!..], Athlon 2400, оперативки 512 [сам знаю, что мало! но на "обычное экселЕние" хватает выше головы] И - заодно уж - подскажите неразумному: не пойму, как пользовать (для того же форматирования в ячейках, к примеру) экселовские константы (xlRight, xlCenter и пр.)? Пишу, например: oHoja:Cells( row0+pbi, iii ):HorizontalAlignment := oExcel:Constants():xlRight (или что-то типа) - и, естественно, бываю послан... Пришлось вверху писать дифайны вроде #define XL_RIGHT -4152 (понимаю, что глупо ["всё уже украдено до нас!"] - но "с налету" не понял еще, как правильно сделать) TsBrowse'овский Excel2() не выходит использовать (по ряду причин) (хотя потестил - получил тот же "нервный перекур"...) Или это "напряги" Эксела?.. Не может переварить 30 тыс.строк "за раз"? Заранее спасибо! "То ли лыжи погнулись... то ли я..." :)
|
|
|
Ответов - 32
, стр:
1
2
All
[только новые]
|
|
|
| Администратор
|
Пост N: 596
Зарегистрирован: 23.05.05
|
|
Отправлено: 10.10.07 08:12. Заголовок: Re:
Наверное ничего с этим не поделаешь, Эксель так и работает Я когда-то пытался понять причину, и у меня возникло впечатление, что с каждой следующей Row работа идет медленнее. Т.е, чтобы выбрать строку с большим номером N, мелкософтовский продукт лопатит строки 1 .. N-1 Возможно в более поздних версиях это улучшено Но все рано код надо оптимизировать, введя промежуточные переменные вместо oHoja:Cells( row0+pbi, iii ):Value := strtran( str(&(aftg_fi[iii]), 11, 2), ".", ",") oHoja:Cells( row0+pbi, iii ):Set( "NumberFormat", "#######0,00" ) oHoja:Cells( row0+pbi, iii ):HorizontalAlignment := XL_RIGHT надо oCell := oHoja:Cells( row0+pbi, iii ) oCell:Value := strtran( str(&(aftg_fi[iii]), 11, 2), ".", ",") oCell:NumberFormat := "#######0,00" oCell:HorizontalAlignment := XL_RIGHT Метод Set лучше не использовать, с прямым обращением работает лучше
|
|
|
|
| |
Пост N: 46
Зарегистрирован: 29.07.05
|
|
Отправлено: 10.10.07 10:25. Заголовок: Re:
Эта тема уже здесь обсуждалась года два назад. Набери в поиске TOleAuto, почитай. Виноват не Excel, а механизм OLE. Тут ничего не поделаешь. Для себя я решил проблему так: 1. Вывод информации в HTML-файл с расширением .xls программой на основе TB2Html от Jovan Bulajic 2. Вызов Excel с параметром <имя файла>. Работает ГОРАЗДО быстрее чем OLE!
|
|
|
|
| постоянный участник
|
Пост N: 349
Зарегистрирован: 12.09.06
|
|
Отправлено: 10.10.07 22:44. Заголовок: Re:
les пишет: цитата: | 1. Вывод информации в HTML-файл с расширением .xls программой на основе TB2Html от Jovan Bulajic |
| А можно поподробнее в этом месте, с примером ? Заранее спасибо.
|
|
|
|
| |
Пост N: 47
Зарегистрирован: 29.07.05
|
|
Отправлено: 11.10.07 09:39. Заголовок: Re:
|
|
|
|
| постоянный участник
|
Пост N: 20
Зарегистрирован: 06.02.07
|
|
Отправлено: 13.10.07 03:12. Заголовок: Re:
Спасибо за помощь! Буду "копать"... А то начальство захотело непременно "экселить" выборки (ну привыкли они!). Кстати: писал сперва, что "затыкается" на 20-30 тыщах... фигвам! те же "тормоза", оказывается, уже после 1-1,5 тысяч. :((
|
|
|
|
| постоянный участник
|
Пост N: 22
Зарегистрирован: 06.02.07
|
|
Отправлено: 26.10.07 03:21. Заголовок: сыскал решение!
сыскал решение проблемы! гонит в Эксел "мухой"! в нижележащем примере (на 1000 строк): через OLE - 32 сек :(( ; через буфер обмена ~2 сек. ===================== /* from comp.lang.xharbour: Yes, cell by cell is still slow. I use the clipboard functions when I have more than a screen full of data. Run the code below and you will see the dramatic difference between cell update versus paste from clipboard method. */ #include "minigui.ch" #include "common.ch" FUNCTION MAIN() LOCAL oExcel, oSheet LOCAL nRow LOCAL nCounter, nStart, nSeconds, nSecOle, nSecClip // oExcel = CREATEOBJECT( "Excel.Application" ) oExcel := TOleAuto():New( "Excel.Application" ) oExcel:WorkBooks:Add() // oSheet := oExcel:ActiveSheet oSheet := oExcel:Get("ActiveSheet") // GAL oExcel:Visible := .T. // GAL (добавил - просто чтоб видеть процесс) nRow := 2 oSheet:Cells( nRow, 1 ):Value = "Counter" oSheet:Cells( nRow, 2 ):Value = "Date" oSheet:Cells( nRow, 3 ):Value = "Row" nCounter := 1 nStart := nCounter // ------------------ Start Cell by Cell method nSeconds := seconds() DO WHILE nCounter < 1000 oSheet:Cells( nCounter+nRow, 1 ):Value := nCounter oSheet:Cells( nCounter+nRow, 2 ):Value := date()-nCounter oSheet:Cells( nCounter+nRow, 3 ):Value := nCounter-1 nCounter++ ENDDO nSecOle := seconds()-nSeconds // ------------------ Stop Cell by Cell oSheet:Cells( 1, 5):Value := "OLE time, sec" oSheet:Cells( 1, 6):Value := nSecOle nRow += nCounter+2 oSheet:Cells( nRow, 1 ):Value := "Counter" oSheet:Cells( nRow, 2 ):Value := "Date" oSheet:Cells( nRow, 3 ):Value := "Row" // ------------------ Start Clipboard method nSeconds := seconds() nCounter := 1 nStart := nCounter cMemo := '' DO WHILE nCounter < 1000 // build record cMemo += ltrim( str( nCounter ) ) cMemo += chr(9)+dtoc( date()-nCounter ) cMemo += chr(9)+ltrim( str( nCounter+nRow-1 ) ) cMemo += chr(10) nCounter++ // update sheet every 1000 records or eof() *IF mod( nCounter, 1000 ) = 0 // .or. eof() IF mod( nCounter, 100 ) = 0 // .or. eof() /* почему-то выдает ошибку ("нет такой ф-и" - хотя RTL.LIB подключается) GTSetClipboard( cMemo ) заменил на CopyToClipboard( cMemo ) */ CopyToClipboard( cMemo ) oSheet:Cells( nRow+nStart, 1 ):Select() oSheet:paste() nStart := nCounter cMemo := '' ENDIF ENDDO nSecClip := seconds()-nSeconds // ------------------ Stop Clipboard method oSheet:Cells( 1, 8):Value := "CLIP time, sec" oSheet:Cells( 1, 9):Value := nSecClip oSheet:Cells( 1, 11):Value := "1000 rows" // ------------------ Results on Screen * ? 'Ole = '+ltrim(str(nSecOle)) * ? 'Clip = '+ltrim(str(nSecClip)) * wait * oSheet:Columns( "A:C" ):AutoFit() oSheet:Columns( "A:I" ):AutoFit() // чтобы форматировало и графы тайминга oSheet:Cells( 1, 1 ):Select() // GAL oExcel:Visible := .T. // добавил для закрытия (не было) oSheet:End() oExcel:End() RETURN( nil ) =====================
|
|
|
|
| постоянный участник
|
Пост N: 292
Зарегистрирован: 09.10.06
|
|
Отправлено: 26.10.07 09:53. Заголовок: Re:
gustow пишет: цитата: | сыскал решение проблемы! гонит в Эксел "мухой"! |
| В некоторых случаях такое решение может быть небезопасным. Есть еще вариант выгрузки в файл с разделителями ( например CHR(9) ) средствами [x]Harbour и импорт средствами Excel.
|
|
|
|
| Администратор
|
Пост N: 612
Зарегистрирован: 23.05.05
|
|
Отправлено: 26.10.07 10:34. Заголовок: Re:
gustow пишет: цитата: | И - заодно уж - подскажите неразумному: не пойму, как пользовать (для того же форматирования в ячейках, к примеру) экселовские константы (xlRight, xlCenter и пр.)? |
| Ай хэв файлы word.ch и excel.ch с определениями констант Не помню, откуда он у меня взялся, то ли сам делал, то ли скачал где-то. Давно это было Могу выслать
|
|
|
|
| постоянный участник
|
Пост N: 360
Зарегистрирован: 12.09.06
|
|
Отправлено: 26.10.07 16:44. Заголовок: Re:
Pasha пишет: цитата: | Ай хэв файлы word.ch и excel.ch с определениями констант |
| Очень надо ! 30195@mail.ru Заранее благодарен
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 27.10.07 09:45. Заголовок: Re:
Петр пишет: цитата: | В некоторых случаях такое решение может быть небезопасным. |
| В каких? А то я постоянно его ( клипборд) использую.. aDb_cr := Ra->( dbstruct() ) for nCol := 1 to len( aDb_cr ) aadd( aHd, aDb_cr[ nCol, 1 ] ) next aHd[1]:="Попа" oClip := TClipBoard():New() oExc := TExcels():New() oExc :Font("Arial Cyr") oExc :SetFont("Arial Cyr") m := 1 Ra->( dbgotop() ) do while !Ra->( eof() ) cStr := "" for n := 1 to len( aDb_cr ) cField := aDb_cr[ n, 1 ] cStr1 := Ra->&cField if aDb_cr[ n, 2 ] == "N" cStr1 := alltrim( str( cStr1 ) ) endif cStr += cStr1 + if( n # len( aDb_cr ), chr( 9 ), "" ) next if !empty( cStr ) oClip:SetText( cStr ) oExc:SetPos( "A" + alltrim( str( m ) ) ) oExc:Paste() oClip:Clear() m ++ endif Ra->( dbskip() ) enddo
|
|
|
|
| постоянный участник
|
Пост N: 293
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.10.07 10:26. Заголовок: Re:
ММК пишет: цитата: | В каких? А то я постоянно его ( клипборд) использую.. |
| И все работает прекрасно? Случай первый: пользователь запустил программу, которая экспортирует таким образом базу обьемом так в 1000000 записей. Поскольку он (пользователь) знает, что подобный процесс довольно длительный, а времени терять не хочется, он запускает Word и что-то там начинает делать с использованием очень распространенного метода Copy-Paste. Случай второй: у пользователя установлена какая-то ну уж очень нужная программа, которая висит в трее и все время проверяет, что там в буфере обмена происходит (переводчик, клавиатурный нинзя или шпион, что-то другое ) и производит какие-то операции над содержимым буфера. Случай третий: у клиента установлена не одна, а целых две ваших (или чужих) программы, которые постоянно его ( клипборд) используют и он их запустил на выполнение одновременно.. И так далее.
|
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 27.10.07 12:15. Заголовок: Re:
Петр пишет: цитата: | И все работает прекрасно? |
| Вот черт!! :))) Еслиб я сначало прочитал все , что ниже наверняка бы не работало:))) А может каждая прожка использует свой кусочек памяти для клипборда? Хотя не могу с Вами не согласится - если подумать , вроде так . А, буду ждать пока чё не случится. Ну не все же они сразу будут клипбордом пользоваться:)
|
|
|
|
| постоянный участник
|
Пост N: 294
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.10.07 14:49. Заголовок: Re:
ММК пишет: цитата: | А может каждая прожка использует свой кусочек памяти для клипборда? |
| Я не думаю, что мы должны теряться в догадках msdn довольно подробно все излагает. Еше предлагаю по этой ссылке посмотреть как не надо писать программы http://www.flounder.com/badprogram.htm
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 27.10.07 15:36. Заголовок: Re:
Петр пишет: цитата: | как не надо писать программы |
| :))) Наверное было бы здорово если бы мы прислушивались ко всем советчикам:)) Но не все советы ... Действительно ( и без всяких догадок) клипборд он и есть клипборд, это всем понятно. Но работа с ним дает хороший результат , а все остальное просто надо иметь в виду:))На всякий случай я не жду заполнения всей страницы, oClip:SetText( cStr ) oExc:SetPos( "A" + alltrim( str( m ) ) ) oExc:Paste() oClip:Clear() Никто от ворда не отказался? :)
|
|
|
|
| |
Пост N: 87
Зарегистрирован: 17.10.05
|
|
Отправлено: 28.10.07 10:59. Заголовок: METHOD TSBrowse:Excel2()
Посмотрите код вывода таблицы в Excel напрямую - может не стоит париться с Ole?
|
|
|
|
| постоянный участник
|
Пост N: 72
Зарегистрирован: 13.10.05
|
|
Отправлено: 29.10.07 08:49. Заголовок: Re:
В Делфи есть примеры (вроде не официальные ) по работе с Ехсел. Все аналогично по работе через буфер.Только там стоит еще процедура очистки и все ок. Сам пробовал, вопросов не было
|
|
|
|
| постоянный участник
|
Пост N: 2193
Зарегистрирован: 12.09.06
|
|
Отправлено: 03.05.12 00:14. Заголовок: Народ, а за время на..
Народ, а за время написания этой статьи не появились ли новые возможности БЫСТРОГО перегона DBF для EXCEL ? Появилась нужда 65 000 записей (25-30 столбцов/полей ) перегнать в простую таблицу EXCEL с простым заголовком. В какую сторону копать, чтобы не наткнутся на Статьи на форуме читал....
|
|
|
|
| постоянный участник
|
Пост N: 308
Зарегистрирован: 13.10.05
|
|
Отправлено: 03.05.12 09:40. Заголовок: А способ, который оп..
А способ, который описывает ММК не пробовал? Он должен быть достаточно быстрый (относительно)
|
|
|
|
| |
Пост N: 60
Зарегистрирован: 16.12.08
|
|
Отправлено: 03.05.12 10:18. Заголовок: Есть класс texcel ра..
|
|
|
|
| постоянный участник
|
Пост N: 2194
Зарегистрирован: 12.09.06
|
|
Отправлено: 03.05.12 11:31. Заголовок: santy пишет: Есть ..
santy пишет: цитата: | Есть класс texcel разработанный Marcelo Torres. |
| Что-то даже демка не работает ...
|
|
|
Ответов - 32
, стр:
1
2
All
[только новые]
|
|