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

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

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


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