On-line: гостей 3. Всего: 3 [подробнее..]
АвторСообщение
постоянный участник




Пост 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 тыс.строк "за раз"?

Заранее спасибо! "То ли лыжи погнулись... то ли я..." :)

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 32 , стр: 1 2 All [только новые]


постоянный участник




Пост N: 313
Зарегистрирован: 06.02.07
ссылка на сообщение  Отправлено: 03.05.12 11:38. Заголовок: Протестировал копипа..


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

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2195
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 03.05.12 12:00. Заголовок: gustow пишет: Проте..


gustow пишет:

 цитата:
Протестировал копипаст в Excel 2007


Пример в студию...

gustow пишет:

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


Т.е. записи больше 65536 не попадут в таблицу ?


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 314
Зарегистрирован: 06.02.07
ссылка на сообщение  Отправлено: 03.05.12 12:03. Заголовок: если надо кусок рабо..


если надо кусок рабочего примера (криворукий, конечно, но работает :) ) - держи:
  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)) + " сек." )


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 315
Зарегистрирован: 06.02.07
ссылка на сообщение  Отправлено: 03.05.12 12:08. Заголовок: Andrey пишет: Т.е. ..


Andrey пишет:

 цитата:
Т.е. записи больше 65536 не попадут в таблицу ?

В 2007м, получается, что нет :(( Может, я неправ?.. но пока так выходит....

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2196
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 03.05.12 13:08. Заголовок: А как к этой таблице..


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

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 316
Зарегистрирован: 06.02.07
ссылка на сообщение  Отправлено: 03.05.12 14:54. Заголовок: Ну что-то типа (корр..


Ну что-то типа (коррекция примера начиная с "enddo"):
  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
Или, наоборот, все дела про заголовки сделать ДО "do while ..." - а потом встал на ячейку, откуда начинать вставлять, и погнали наши городских... :)

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2197
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 03.05.12 15:00. Заголовок: gustow пишет: если..


gustow пишет:

 цитата:

если надо кусок рабочего примера


Спасибо БОЛЬШОЕ !

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 317
Зарегистрирован: 06.02.07
ссылка на сообщение  Отправлено: 03.05.12 15:02. Заголовок: шрифт у общего (надт..


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


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2198
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 03.05.12 17:15. Заголовок: gustow пишет: oShe..


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()
Просто нет в начале открытия ОЛЕ... Каждый по разному открывает...
Приведи пожалуйста кусок открытия ОЛЕ !

И как потом результат в файл сохранить ?

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 318
Зарегистрирован: 06.02.07
ссылка на сообщение  Отправлено: 04.05.12 06:48. Заголовок: Звиняйте, батьку :) ..


Звиняйте, батьку :) думал, понятно (потому как "стандартно").

В начале (открытие OLE) банально так:
  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()

и т.д.
И уже selection'ы диапазонов ячеек (называя указатель на выделенный диапазон как oSel) делаю (в данном случае) в этом конкретном текущем листе, который oSheet. Извиняй, может запутал ненамеренно... :)

Сохранение в файл в большинстве случаев я как раз не делаю - потому как просто Excel делаю видимым и показываю пользователю, ЧТО вывелось в пока еще безымянную экселку; а он потом, если надо, сам "сохранит как", распечатает и т.п. (зачем винчестер мусором загаживать - сперва "сохранив как"... а вдруг не надо было вообще?)

А если надо автоматом "сохранить в файл с предписанным именем и закрыться без вопросов", то так, например:
  ... 
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
что-то вроде этого...


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2199
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 04.05.12 07:34. Заголовок: gustow пишет: что-т..


gustow пишет:

 цитата:
что-то вроде этого...


Спасибо БОЛЬШОЕ !


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 319
Зарегистрирован: 06.02.07
ссылка на сообщение  Отправлено: 04.05.12 09:08. Заголовок: Во! :) А теперь на о..


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

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 32 , стр: 1 2 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 543
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет