:: Visual Foxpro, Foxpro for DOS
Как ускорить вывод в Excel
Master.Ternopil
Автор

Сообщений: 50
Откуда: Тернополь
Дата регистрации: 03.10.2005
Я пишу в Excel по одной ячейке в цикле бегая по таблице, это очень долго при больших таблицах.
Вот вычитал на сайте по С++ (rxlib.ru)

Многие спрашивают - как ускорить вывод в Excel больших массивов данных,
слишком медленно все работает.
Наиболее идеальный вариант - воспользоваться компонентами XLSReadWrite2 или аналогичными.
Также, в проекте есть пример, как можно немного ускорить такой вывод,
для этого при выводе данных можно не выводить данные последовательно в каждую ячейку
в цикле, а лучше сформировать вариантный массив, и выполнить присвоение области (Range)
этого массива, только после этого делая Excel видимым.
Также более быстрая работа происходит при использовании библиотеки типов.



Подскажите, как что-либо подобное сделать на фоксе.
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel
Петров Андрей

Сообщений: 2506
Откуда: Химки (М.О.)
Дата регистрации: 17.04.2002
Тут формировать вариантный массив не надо Он и так такой. Так что

select * from table1 into array arr
.range('A1:B100').Value=GetArrPtr('arr')
Function GetArrPtr
Lpara arr_name
retu &@arr_name




------------------
PS Недочитал тему до конца...
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel
AleksM

Сообщений: 17881
Дата регистрации: 11.11.2003
1. Делаешь выборку в массив: SELECT ... FROM ... INTO ARRAY laExcel
Ограничение на выборку в массив - 65000 элементов (в 9-ке снято)

2. Пишешь ф-цию (метод) для получения указателя на массив
Function ArrayPointer
LPARAMETERS tcArrayName
RETURN @&tcArrayName
3. Ну и в коде пишешь:
loWorkSheet.Range("A2:"+loWorkSheet.Range("A2").Offset(lnRowsCount-1,lnColumnsCount-1).Address).Value = ArrayPointer("laExcel")
где lnRowCount - число строк массива;
lnColumnCount - число столбцов массива.
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
Master.Ternopil
Автор

Сообщений: 50
Откуда: Тернополь
Дата регистрации: 03.10.2005
Спасибо Вам всем за отклики.


loWorkSheet.Range("A2:"+loWorkSheet.Range("A2").Offset(lnRowsCount-1,lnColumnsCount-1).Address).Value = ArrayPointer("laExcel")

на входе в описанную вверху строчку получаю следующую ошибку:
OLE error code 0x800a03ec: Unknown COM status code.

Range пробывал и в ручном формате типа :
loWorkSheet.Range("A1:H1000").Value = ArrayPointer("laExcel")
Ошибка та же.
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
AleksM

Сообщений: 17881
Дата регистрации: 11.11.2003
Приведу ещё тройку строк, которые были опущены в надежде на то, что всё ясно по именам объектов:

Сначала идёт это:
loXls = CREATEOBJECT("Excel.Application")
loWorkbook = loXls.Workbooks.Add()
loWorkSheet = loWorkbook.Worksheets(1)

а потом всё остальное.
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
AlexSSS

Сообщений: 6113
Откуда: Tallinn, Estonia
Дата регистрации: 19.09.2005
Для совсем быстрого вывода в Эксель я использую следующий алгоритм
1. в VFP подготавливается курсор или несколько для экспорта
2. все подготовленные курсоры COPY TO ... XL5 AS 1251
3. Из фокса запускаю Эксель и открываю на новых закладках сэкспортированные файлы
4. либо средствами VFP, либо макросами экселя перегоняю данные с полученных листов туда, куда мне надо со всеми нужными форматированиями.
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
Master.Ternopil
Автор

Сообщений: 50
Откуда: Тернополь
Дата регистрации: 03.10.2005
С Вашим (AleksM) способом разобрался, получилось не то что быстрее, а просто моментально!
Попробую еще вариант от AlexSSS. Интересно.
Еще раз ВСЕМ спасибо. Тема закрыта.
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
AleksM

Сообщений: 17881
Дата регистрации: 11.11.2003
Ну-у-у, способ это не мой. Он не раз приводился на форуме. Поиск дал бы тебе несколько ссылок на него. ;)
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
AleksM

Сообщений: 17881
Дата регистрации: 11.11.2003
Второй способ, который привёл AlexSSS, тоже имеет право на жизнь. НО в нем, как минимум, формируется дополнительный файл, что не всегда нужно. Скорость - вот основной его козырь. При поячеечном заполнении, передаче через буфер обмена или через массив сохранение выведенной информации, обычно, отдаётся на откуп пользователя.
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
AlexSSS

Сообщений: 6113
Откуда: Tallinn, Estonia
Дата регистрации: 19.09.2005
> НО в нем, как минимум, формируется дополнительный файл, что не всегда нужно
файл делается в TEMP каталоге, после создания отчета стирается.

На больших отчетах ускорение в десятки раз

впрочем, способа с передачей ссылки на массив я раньше не знал. Этот способ наверняка сравним по скорости.

Еще для ускорения получения Экселешных отчетов я использую готовые экселешные заготовки-шаблоны. Делается экселешный отчет со всеми шапками и форматированиями. Если требуется, в этом шаблоне прописываются и необходимые макросы.
Этот шаблон открывается из VFP, в него заливаются данные, после чего он перезаписывается в TEMP папку пользователя.
Способ с шаблонами очень удобен при отчетах со сложным форматированием

Если в шаблоне используются макросы, то их можно вынести в отдельный XLA файл (экселевская библиотека)
В этом случае в конечном отчете нет никаких макросов
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
Петров Андрей

Сообщений: 2506
Откуда: Химки (М.О.)
Дата регистрации: 17.04.2002
2 AlexSSS

Надо еще упомянуть что при таком подходе все Memo херятся... и например если нужно перенести таблицу в другое место (например B5) надо все равно будет приложить усилия для открытия Excel. И невсегда нужны названия полей в заголовке.




------------------
PS Недочитал тему до конца...
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
AlexSSS

Сообщений: 6113
Откуда: Tallinn, Estonia
Дата регистрации: 19.09.2005
>Надо еще упомянуть что при таком подходе все Memo херятся
ваша правда ;o)

> И невсегда нужны названия полей в заголовке.
а я и не предлагаю использовать полученный лист
см. внимательнее "перегоняю данные с полученных листов туда, куда мне надо со всеми нужными форматированиями."

>надо все равно будет приложить усилия для открытия Excel.
а то-ж!

>PS Недочитал тему до конца...
похоже на то ;o)
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
Евгений Банщиков

Сообщений: 218
Откуда: Kurgan
Дата регистрации: 09.04.2004
To Петров Андрей
В варианте с массивом есть 2 ограничения
1. Это работает только с VFP 7
2. До VFP9 Размер массива ограничен 65000
Это очень мало и зачастую для отчетов требуется гораздо больше значений.
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
Петров Андрей

Сообщений: 2506
Откуда: Химки (М.О.)
Дата регистрации: 17.04.2002
2 Евгений Банщиков

Согласен. Нужна золотая середина (между массивом буфером обмена и напрямую). Просто плохо отношусь к действию Export потому что все равно придется дорабатывать эти данные...




------------------
PS Недочитал тему до конца...
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel
Borshenko

Сообщений: 1767
Откуда: Chernigiv
Дата регистрации: 11.08.2005
А я для этого использую только буффер. Тоже получается быстро. Не знаю, какое должно быть для этого ограничение, но пока работает без збоев с довольно большими объемами.

Цитата:
#DEFINE TAB CHR(9)
#DEFINE CRLF CHR(13)+CHR(10)

_cliptext=""
Формируется первая строка со спиком датчиков
for i=1 to count_channel
_cliptext=_cliptext+tab+'Датчик '+channels(i)
endfor
Дальше прохожу всю таблицу и загоняю ее в буффер
scan
_cliptext=_cliptext+dtoc(date)+' '+alltrim(time)
for i=3 to 34
field_name=FIELD(i)
field_value=&field_name
if field_value>0
_cliptext=_cliptext+tab+str(field_value,6)
else
_cliptext=_cliptext+tab
endif
endfor
_cliptext=_cliptext+crlf
endscan
Потом открываю Excel и вставляю туда из буффера.
oXLChart1 = GetObject('','excel.sheet')
oleApp=oxlchart1.application
oleApp.visible = .f.
oleApp.Workbooks.Add
oleApp.ActiveWindow.WindowState = -4137
oleApp.worksheets(1).cells().clear
oleApp.worksheets(1).cells(1,1).pastespecial
oleApp.visible = .t.
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel
AleksM

Сообщений: 17881
Дата регистрации: 11.11.2003
У каждого метода есть свои (+) и (-). ;)
При работе через буфер можно войти в конфликт с другими приложениями использующими его (буфер).
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Hi Евгений!

Цитата:
1. Это работает только с VFP 7
Для 6-ки можно пойти "от обратного" - в Excel сделать макрос принимающий
массив - пример я делал для boba - он правда в каком-то другом разделе
форума висит
Цитата:
2. До VFP9 Размер массива ограничен 65000
Да, но данные можно копировать порциями Тем более что на один лист в
Excel всё равно не запихать более 65536*256 элементов - т.е. за MAX 260
порций можно заполнить лист целиком...
P.S. Всегда с недоверием относился к "большим отчётам" - можно подумать что
какой-то человек в состоянии прочитать 36000 страниц Единственное
оправдание - это какой-то последующий анализ в Excel - например сводные
таблицы, авто-фильтры (хотя это можно и в программе сделать) и т.п.




------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
Евгений Банщиков

Сообщений: 218
Откуда: Kurgan
Дата регистрации: 09.04.2004
To Igor Korolyov
Не слишком ли много проблем с массивами ?
Вот еще 4
1.Не обрезаются концевые пробелы у символьных строк
2.Наличие пустой даты вызывает ошибку Excell
3.Наличие = в начале строки приводит к ошибке Excel
4.Часть данных нетекстовых типов (например Date, и Currency) вставляется как текст



Отредактировано (27.10.05 11:24)


------------------
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Hi Евгений!

Цитата:
Не слишком ли много проблем с массивами
IMHO не больше чем для других способов
Цитата:
Не обрезаются концевые пробелы у символьных строк
Не понял - если ты в элемент массива загнал строку с кучей пробелов, то
почему это она должна обрезаться? Как раз наоборот - если бы она обрезалась,
то было бы неправильно - то что в массиве - то и на листе Excel - и это
правильно Если надо резать - то при помещении в массив и режь - причём
именно так как оно тебе надо - RTRIM() или ALLTRIM()
Цитата:
Наличие пустой даты вызывает ошибку Excell
1) Лечится элементарно - заменой EMPTY(laData(m.lnI, m.lnJ)) для типов D и T
на ""
2) Связано с тем, что в Excel нету понятия пустой даты - впрочем как и во
многих других СУБД и просто средах программирования. Я вообще не очень
представляю как выглядит пустая дата в формате Variant-а
Цитата:
Наличие = в начале строки приводит к ошибке Excel
1) Опять же лечится без проблем - все символьные поля предваряются одиночным
апострофом - '
2) Причина очевидна - Excel воспринимает такую строку как формулу - при этом
если ты реально напишешь правильную формулу, то никаких проблем не
возникнет!
Цитата:
Часть данных нетекстовых типов (например Date, и Currency)
вставляется как текст
Не знаю почему у тебя с этим проблемы. У меня в связке VFP9 с Excel 2003 и
тип Currency, и тип Date вставляется абсолютно корректно... Причём даже
сразу форматируется как положено - в дате не показывается часть со временем,
а в Currency сразу форматирует как тип валюты - т.е. дописывает "р."




------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как ускорить вывод в Excel - AleksM-у
Евгений Банщиков

Сообщений: 218
Откуда: Kurgan
Дата регистрации: 09.04.2004
Привет Igor

Все что ты пишешь верно , но если использовать способ обмена через таблицу (copy to type fox2x as 866),
то всех этих проблем просто не возникает.
Концевые пробелы отрезаются,пустая дата обрабатывается , знак = не воспринимается как начало формулы.

По поводу 4 проблемы :у меня vfp9 и оффис xp. Выглядит это примерно так -10 строк нормалбных значений , 3 текстовых и.т.д.,
возможно виноваты какие то настройки оффиса или OS. Постараюсь выложить небольшой тестовый пример .
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 36 (Гостей: 36)

© 2000-2024 Fox Club 
Яндекс.Метрика