Форум » GUI » экспорт в Excel (тормоза) » Ответить

экспорт в Excel (тормоза)

gustow: Не пойму, в чем причина... Объясните, братцы, "тупому" :) ---- делаю экспорт в 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

gustow: Протестировал копипаст в Excel 2007 Вылетает (Error BASE/1004 Метод не экспортирован: SELECT) (Win XP, HMG Ext. 2.0.1) при попытке вставить в строку экселки с номером больше 65536 (64к). Т.ч. все работает в общем-то быстро (10'000 записей около 20 сек.) - но аппетиты по кол-ву вставляемых строк надо соразмерять :) Возможно, в 2010м Экселе этого ограничения нет?..

Andrey: gustow пишет: Протестировал копипаст в Excel 2007 Пример в студию... gustow пишет: Вылетает (Error BASE/1004 Метод не экспортирован: SELECT) (Win XP, HMG Ext. 2.0.1) при попытке вставить в строку экселки с номером больше 65536 (64к). Т.е. записи больше 65536 не попадут в таблицу ?

gustow: если надо кусок рабочего примера (криворукий, конечно, но работает :) ) - держи: [pre2] private gtim0 := seconds(), gtim1 // для тайминга use SPMESLPU codepage "RU866" new oSheet:Cells( 5, 1 ):Select() nRow00 := 5 // самая начальная строка, с которой вставляем nRow := 5 // текущая строка nRow0 := 5 // с какой строки вставлять очередной кусок do while .not.SPMESLPU->(EoF()) cClip := "" for j := 1 to 200 // чем больше буфер, тем быстрее // (НО! чем "шире" запись, тем легче упрёмся // в макс.длину строки = 65к... или неправ?) cClip := cClip + ; ltrim( str(SPMESLPU->LPU , 7, 0) ) + chr(9) + ; // еще бы (если десятичные точки есть) ltrim( str(SPMESLPU->MESBEG, 8, 0) ) + chr(9) + ; // заменять по ходу точки на запятые ltrim( str(SPMESLPU->MESEND, 8, 0) ) + chr(9) + ; // strtran( ... , ".", "," ) ltrim( dtoc(SPMESLPU->DBEG) ) + chr(9) + ; ltrim( dtoc(SPMESLPU->DEND) ) + chr(9) + ; ltrim( str(SPMESLPU->POCL , 2, 0) ) + chr(9) + ; ltrim( str(SPMESLPU->OTD , 4, 0) ) + chr(9) + ; ltrim( str(SPMESLPU->TYPEMS, 1, 0) ) skip nRow++ if SPMESLPU->(EoF()) exit endif if j < 200 cClip := cClip + chr(10) endif next j // копируем-вставляем CopyToClipboard( cClip ) // встаем на ту ячейку, начиная откуда надо вставлять oSheet:Cells( nRow0, 1 ):Select() // начиная с 1-й // вставляем из буфера обмена: oSheet:Paste() if .not.SPMESLPU->(EoF()) nRow0 := nRow endif enddo // выделяем весь диапазон вставленного oSel:=oSheet:Range( "A" + ltrim(str( nRow00, 0 )) + ":H" + ltrim(str( nRow-1, 0 )) ) oSel:VerticalAlignment := xlTop oSel:Rows:AutoFit() oSheet:Cells( 4, 1 ):Select() // ставим курсор (в этом листе) над шапкой gtim1 := seconds() close SPMESLPU MsgInfo("Тайминг: " + ltrim(str(gtim1-gtim0, 1)) + " сек." )[/pre2]


gustow: Andrey пишет: Т.е. записи больше 65536 не попадут в таблицу ? В 2007м, получается, что нет :(( Может, я неправ?.. но пока так выходит....

Andrey: А как к этой таблице заголовки (на русском) приделать и название таблицы сделать (типа МОЯ ТАБЛИЦА - шрифт побольше) ?

gustow: Ну что-то типа (коррекция примера начиная с "enddo"): [pre2] enddo // выделяем весь диапазон вставленного oSel:=oSheet:Range( Diapazon( "A", nRow0, "H", nRow-1 ) ) oSel:VerticalAlignment := xlTop oSel:Rows:AutoFit() // выделяем ячейки во 2-й строке для заголовка над таблицей oSel:=oSheet:Range( "A2:H2" ) // объединяем ячейки oSel:Merge() // заголовок над таблицей oSheet:Cells( 2, 1 ):Value := "Список лицензированных МЭС для всех ЛПУ" // заголовки для колонок oSheet:Cells( 4, 1 ):Value := "Код ЛПУ" oSheet:Cells( 4, 2 ):Value := "Нач. код МЭС" oSheet:Cells( 4, 3 ):Value := "Кон. код МЭС" oSheet:Cells( 4, 4 ):Value := "Нач. дата" oSheet:Cells( 4, 5 ):Value := "Кон. дата" oSheet:Cells( 4, 6 ):Value := "Поколение" oSheet:Cells( 4, 7 ):Value := "Отделение" oSheet:Cells( 4, 8 ):Value := "Тип МС" // выделяем общий и колоночные заголовки oSel:=oSheet:Range( "A2:H4" ) oSel:VerticalAlignment := xlCenter oSel:HorizontalAlignment := xlCenter // заголовки полужирно oSel:Font:Bold := .T. oSel:Rows:AutoFit() oSheet:Cells( 4, 1 ):Select() // ставим курсор (в этом листе) над шапкой gtim1:=seconds() // тайминг close SPMESLPU[/pre2] Или, наоборот, все дела про заголовки сделать ДО "do while ..." - а потом встал на ячейку, откуда начинать вставлять, и погнали наши городских... :)

Andrey: gustow пишет: если надо кусок рабочего примера Спасибо БОЛЬШОЕ !

gustow: шрифт у общего (надтабличного) заголовка побольше: [pre2] // выделяем ячейки во 2-й строке для заголовка над таблицей oSel:=oSheet:Range( "A2:H2" ) // объединяем ячейки oSel:Merge() oSel:Font:Size := 14 // заголовок над таблицей oSheet:Cells( 2, 1 ):Value := "Список лицензированных МЭС для всех ЛПУ"[/pre2]

Andrey: gustow пишет: oSheet:Cells( 5, 1 ):Select() gustow пишет: // выделяем весь диапазон вставленного oSel:=oSheet:Range( "A" + ltrim(str( nRow00, 0 )) + ":H" + ltrim(str( nRow-1, 0 )) ) oSel:VerticalAlignment := xlTop oSel:Rows:AutoFit() Немного запутался... oSel: это oSel := oExcel:ActiveSheet() Просто нет в начале открытия ОЛЕ... Каждый по разному открывает... Приведи пожалуйста кусок открытия ОЛЕ ! И как потом результат в файл сохранить ?

gustow: Звиняйте, батьку :) думал, понятно (потому как "стандартно"). В начале (открытие OLE) банально так: [pre2] oExcel := TOleAuto():New( "Excel.Application" ) if Ole2TxtError() != 'S_OK' MsgStop('А у вас не установлен MS Excel !', "Ай-яй-яй! Низззяяяя..." ) Return Nil endif oExcel:Visible := .F. // невидимость Эксела при формировании // (хотя тут тестил БЕЗ невидимости - все равно быстро) //oExcel:ScreenUpdating := .F. // выключил прорисовку листа (ускоряет) // отменить автоматическую калькуляцию формул (ускоряет) //oExcel:Calculation := xlManual oExcel:WorkBooks:Add() oBook := oExcel:Get("ActiveWorkBook") oSheet := oExcel:Get( "ActiveSheet" ) ... oSheet:Cells( 5, 1 ):Select() и т.д.[/pre2] И уже selection'ы диапазонов ячеек (называя указатель на выделенный диапазон как oSel) делаю (в данном случае) в этом конкретном текущем листе, который oSheet. Извиняй, может запутал ненамеренно... :) Сохранение в файл в большинстве случаев я как раз не делаю - потому как просто Excel делаю видимым и показываю пользователю, ЧТО вывелось в пока еще безымянную экселку; а он потом, если надо, сам "сохранит как", распечатает и т.п. (зачем винчестер мусором загаживать - сперва "сохранив как"... а вдруг не надо было вообще?) А если надо автоматом "сохранить в файл с предписанным именем и закрыться без вопросов", то так, например: [pre2] ... oBook:SaveAs( fold + "\" +"Список МУ.xls", xlExcel8 ) // сохранить в формате "совместимый с Excel 97-2003" (xlExcel8 = 56) // если сохранить "в формате по умолчанию", параметр опускаем // "fold" - папка, куда сохраняем (например, где-то выше "fold:=GetCurrentFolder()" ) oBook:Close(0) // закрыть БЕЗ вопросов о сохранении oExcel:Quit() // закрываем сеанс OLE oSheet:=Nil // зачищаем следы антигосударственной деятельности oBook:=Nil // не думаю, что это уж так обязательно - но вдруг неправ? oExcel:=Nil [/pre2] что-то вроде этого...

Andrey: gustow пишет: что-то вроде этого... Спасибо БОЛЬШОЕ !

gustow: Во! :) А теперь на основе этого "ликбеза" надо, думаю, написать главку в Викикнигу про Харбор (назвав типа "Харбор и Эксел"). Кто б подмог из "техписо-способных"?



полная версия страницы