Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Отчеты в Excel / 9 сообщений из 9, страница 1 из 1
09.02.2009, 11:01
    #35805143
Отчеты в Excel
Вывожу курсор в Excel. Предварительно сделал шаблон в Excel'е, но это достаточно медленно получается при кол-ве строк около 1000. Как бы ускорить процесс выгрузки, и еще подсчитать промежуточные итоги в отчете?
Кто как делает???
...
Рейтинг: 0 / 0
09.02.2009, 11:23
    #35805210
Galyamov Rinat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отчеты в Excel
Антон Павлович,

Общая суть такая: Сделать эксопрт в excel средствами фокса.
Скопировать первый лист полученной книги в шаблон средствами excel`я


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
sele my_table

LOCAL lcShablon, lcNameShablon, lcNameOut

lcNewDoc	= getenv("temp")+'\'+SUBSTR(SYS( 2015 ), 3 )+'.xls'
lcOut		= getenv("temp")+'\'+SUBSTR(SYS( 2015 ), 3 )+'.xls'

LOCAL lnNum

lnNum= 0 



EXPORT TO (lcOut);
	fields	n_dog, NUM,;
			naimen,;
			suma,;
			Zadanie,;
			Oplata,;
			Nedoplata,;
			sostoyanie,;
			Deb_Count_period;
	type XL5 


wait window "Идет передача данных в Exel. Ждите ..." nowait noclear

* Экспорт данных в Exel
LOCAL goExcel
goExcel = CREATEOBJECT("Excel.Application")

if vartype(goExcel) # "O"
	MessageBox("Excel не найден!!!", 0 ,'Внимание!!!')
	return
endif

LOCAL lcShablon, lcNameShablon, lcNameOut

lcShablon=App_VS.GetDefaDir()+'Shablon\Prikaz_194.xls'

if !file(lcShablon)
	MessageBox('Не найден файл шаблона. Отчет не будет оформлен!!!'+chr( 13 )+'Чтобы избежать этой ситуации в будущем создайте файл "'+lcShablon+'" и оформите шапку отчета', 0 ,'Внимание!!!')
	loShablon=goExcel.WorkBooks.Add()
Else
	loShablon=goExcel.WorkBooks.Open(lcShablon)
endif

goExcel.DisplayAlerts = .F.
loOut=goExcel.WorkBooks.Open(lcOut)
loNewDoc=goExcel.WorkBooks.add

loShablon.Sheets( 1 ).Copy(loNewDoc.Sheets( 1 ))
loShablon.Close

&& Удаляем остальные листы нового документа
for i=loNewDoc.Sheets.Count to  2  step - 1 
	loNewDoc.Sheets(i).delete
EndFor

loOut.Sheets( 1 ).Range("A2:I"+Transform(reccount()+ 1 )).Copy
loNewDoc.Sheets( 1 ).Range("A17").PasteSpecial(- 4163 ,- 4142 ,.F.,.F.)


loOut.Close
delete file (lcOut)

...
Рейтинг: 0 / 0
09.02.2009, 11:59
    #35805327
Отчеты в Excel
А как ускорить процесс, если у меня около десятка тысяч записей?
...
Рейтинг: 0 / 0
09.02.2009, 12:16
    #35805374
Fffffffffffff
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отчеты в Excel
Антон Павлович,
процесс выгрузки командой Export идет долю секунды.
...
Рейтинг: 0 / 0
09.02.2009, 12:20
    #35805385
Kruchinin Pahan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отчеты в Excel
Антон ПавловичА как ускорить процесс, если у меня около десятка тысяч записей?
До 65k записей этот способ работает быстро. После 65k записей у Excel наступает ограничение на количество строк (65536 - максимум).
...
Рейтинг: 0 / 0
09.02.2009, 12:31
    #35805415
Отчеты в Excel
Хорошо, а что делать с промежуточными вычислениями. Например, мне надо сделать общие итоги и подитоги по определенной колонке, по которой было упорядочивание???
...
Рейтинг: 0 / 0
09.02.2009, 12:44
    #35805448
Kruchinin Pahan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отчеты в Excel
Антон ПавловичХорошо, а что делать с промежуточными вычислениями. Например, мне надо сделать общие итоги и подитоги по определенной колонке, по которой было упорядочивание???
Я обычно расширяю исходный набор данных в курсоре (добавляю строки подитогов). Потом делаю SCAN по этому курсору и перебиваю итоги на листе на формулу (обычно "=SUBTOTAL(9,)"). Обычно это незначительно замедляет выгрузку.
...
Рейтинг: 0 / 0
09.02.2009, 13:44
    #35805639
Kruchinin Pahan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отчеты в Excel
Антон Павлович,

Давайте я до кучи, свой примерчик приведу. У меня он полностью отрабатывает за 8 секунд.
По методу Рината, кстати, можно добиться большей производительности.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
#DEFINE cnMAXInteger	0x7FFFFFFF
CLEAR
CLOSE TABLES ALL
CREATE CURSOR CurTestData (Kod1 I, Kod2 I, Kod3 I, Name1 C( 10 ), Name2 C( 10 ), Name3 C( 10 ))
lnSeconds = SECONDS()
FOR m.i =  1  TO  10 
	FOR m.j =  1  TO  3000 
		INSERT INTO CurTestData VALUES (m.i, m.j, FLOOR(RAND() *  100 ), SYS( 2015 ), SYS( 2015 ), SYS( 2015 ))
	NEXT m.j
NEXT m.i
?"Создали набор данных: ", SECONDS() - lnSeconds

*-* (IGEL) Добавим итогов, добавление строк в Excel дольше работает.
lnSeconds = SECONDS()
SELECT ;
	Kod1, Kod2, Kod3, Name1, Name2, Name3 ;
	FROM CurTestData ;
UNION ALL SELECT ;
	Kod1, MAX(cnMAXInteger), SUM(Kod3), MAX(Name1), MAX(Name2), MAX(Name3) ;
	FROM CurTestData ;
	GROUP BY  1  ;
	ORDER BY  1 ,  2  ;
	INTO CURSOR CurData NOFILTER READWRITE
?"Добавили итогов к набору: ", SECONDS() - lnSeconds

loExcel = CREATEOBJECT("Excel.Application")
loExcel.WorkBooks.Add()
loSheet = loExcel.WorkSheets( 1 )

lnOffSetX =  1 
lnOffSetY =  3 
*-* (IGEL) Я обычно сбрасываю вот таким вот странным способом. Мне так больше нравится. На скорость влияет незначительно.
lnSeconds = SECONDS()
StoreCursor(loSheet, "CurData", "Kod1, Kod2, Kod3, Name1, Name2, Name3", lnOffSetX, lnOffSetY)
?"Выплюнули данные в Excel: ", SECONDS() - lnSeconds
*-* (IGEL) Итоги просто форматируем. В случае необходимости, можно отключить автопересчет перед этой операцией.
lnSeconds = SECONDS()
lnStartOffSet = lnOffSetY 
SELECT CurData
SCAN FOR Kod2 = cnMAXInteger
	lnY = lnOffSetY + RECNO() -  1 
	WITH loSheet.Cells[lnY, lnOffSetX]
		.EntireRow.Font.Bold = .T.
		.Cells[ 1 ,  2 ].Value = "ИТОГО"
		lcFormula = TEXTMERGE("=SUBTOTAL(9, R[-1]C:R<<lnStartOffSet>>C)")
		.Cells[ 1 ,  3 ].FormulaR1C1 = lcFormula
		lnStartOffSet = lnY
	ENDWITH
ENDSCAN

WITH loSheet.Cells[lnOffSetY + RECCOUNT("CurData"), lnOffSetX]
	.EntireRow.Font.Bold = .T.
	.Cells[ 1 ,  2 ].Value = "ИТОГО ВСЕГО"
	lcFormula = TEXTMERGE("=SUBTOTAL(9, R[-1]C:R<<lnOffSetY>>C)")
	.Cells[ 1 ,  3 ].FormulaR1C1 = lcFormula
	lnStartOffSet = lnY
ENDWITH
?"Все подытожили: ", SECONDS() - lnSeconds
*-* (IGEL) Готово.
loExcel.Visible = .T.

PROCEDURE StoreCursor
	LPARAMETERS toSheet, tcCursor, tcFieldList, tnOffSetX, tnOffSetY
	LOCAL luRetVal, lcField, lnCol
	PRIVATE laStoreVal( 1 )
	luRetVal = .T.
	
	FOR lnCol =  1  TO GETWORDCOUNT(tcFieldList, ",")
		lcField = RTRIM(GETWORDNUM(tcFieldList, lnCol, ","))
		SELECT &lcField FROM (tcCursor) INTO ARRAY laStoreVal && Здесь надо усложнить маленько выборку...
		lnRows = _TALLY
		IF !EMPTY(lnRows)
			toSheet.Cells[tnOffSetY, tnOffSetX + lnCol -  1 ].Resize[lnRows,  1 ] = RetArray("laStoreVal")
		ENDIF
	NEXT lnCntr
		
	RETURN luRetVal
ENDPROC

FUNCTION RetArray
	PARAMETERS tcArrayName
	RETURN @&tcArrayName
ENDFUNC


...
Рейтинг: 0 / 0
09.02.2009, 14:37
    #35805812
Отчеты в Excel
Огромное спасибо за пример!!!
Respect
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Отчеты в Excel / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]