Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / Для тех кто создает отчеты в Excel и юзает Pivot Table / 3 сообщений из 3, страница 1 из 1
27.11.2004, 03:01
    #32802368
dmitry_cmc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Для тех кто создает отчеты в Excel и юзает Pivot Table
Всем привет.

Я долго мучался над одной задачей, причем так и не смог найти в сети примеров как это надо делать. Тем не менее задачу саму я добил :) (ура), и поэтому хочу поделиться решением с народом.

Описание задачи:

Коротко:
Изменить средствами C#, DataSource в Excel-ом Pivot.

Более подробно:
Вообщем, задача создания отчетом для пользователей.
Допустим каждый пользователь относится к конкретному городу, соответственно одинаковый отчет должен быть представлен каждому клиенту отфильтрованным по его городу.
Как средство представления был выбран Excel (2000 если быть точнее, ибо на него была лицензия). Т.е. каждый пользователь должен был при нажатии на кнопочку "Сгенерить отчет" получить отчетик в виде сводной таблицы где содержится пивот с торговыми точками, которые относятся к конкретно взятому городу.

В начале создаем шаблон со сводной таблицей.
Далее алгоритм такой - шаблон копируется в темповый файл, у него меняется датасорс (добавляется условие where для вьюшки), рефрешится и подсовывается юзеру.

Ну так вот. Используется соответственно Excel Automatization (или как это называется), который как выяснялось очень криво работает особенно по сравнению с чудненькой и логичненькой .NET (короче уежище).
Кое как достучавшись до пивота в этой фиговой объектной модели Екселя и найдя там его сорс (SourceData), который мало того что представляет собой массив из строк, которые логически объединяются в одну (и нафиг спрашивается так? опять же естестсвенное предположение, что у каждой из них длина ограничена), так этот сорс также находится в другом свойстве PivotCache и в нескольких местах (офигеть).
Короче ни одного из этих свойств изменить не получилось.

Кстати, by the way, объясните мне, пожалуйста, следующию вещь. Возможно я что-то не понимаю в COM. Вот, когда я делаю так:

Код: plaintext
1.
string str = pivot.SourceData[ 3 ];
str += " where 0 = 0";

str изменяется, а pivot.SourceData[3] нет :/

Идем дальше.
Вообщем суть в том. что на любую попытку изменения непосредственно датасорса ексель генерировал ошибку.
(тоже поведение обнаружилось при попытке запуска аналогичного макроса под Ексель, который выполняет те же действия).

Вообщем, в итоге воспользовавшись такой рульной вещью как запись макросов и пройдя еще через немалое кол-во граблей и всевозможных приколов, у меня наконец получилось накропать работающий вариант для C# (для ASP.NET), который привожу ниже.

Кроме всего этого, если вы будете генерить ексельные отчеты, вам наверняка придется использовать след. вещи:
- имперсонификация под юзера у которого есть права (немалые)
- убийство екселя в памяти
- сжатие файла
- отправка файла через браузер

Все это используется, но что бы не раздувать пост, я не привожу описание самих функций. Если кому надо - запостю отдельно.


Код: 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.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
public void GetReportCustomers( )
{
	Impersonate();

	// убиваем ексели, которые живут больше  3 -х минут
	KillExcel();

	try
	{
		// путь для темпового файла
		string temppath = ConfigurationSettings.AppSettings["temp_directory"] +
			"\\" + "ReportCustomers_" + 
			Convert.ToString( CityID ) +
			".xls";

		// копируем файл
		File.Copy( ConfigurationSettings.AppSettings["report_Customers"],
			temppath, true );

		// создаем ексель
		Excel.Application ExcelApp = new Excel.Application();

		ExcelApp.Visible = true;
	
		// открываем файл
		ExcelApp.Workbooks.Open( temppath,
			Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,
			Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,
			Type.Missing,Type.Missing);

		Excel.Workbook workbook = ExcelApp.Workbooks[ 1 ];

		Excel.Worksheet worksheet;


		worksheet = (Excel.Worksheet)workbook.Worksheets[ 1 ];

		// самое интересное - замена датасорса
		worksheet.PivotTableWizard
		( 
			Excel.XlPivotTableSourceType.xlExternal, 
			new object[]
			{ 
				"SELECT ReportCustomers.CustomerName, ReportCustomers.CustomerAddres",
				"s, ReportCustomers.CustomerID\r\nFROM MyDataBase.dbo.ReportCustomers ReportCustomers",
				" where ReportCustomers.CityID = " + Convert.ToString( CityID )
			}, 

			Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,
			Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,
			Type.Missing,

			new object[]
			{ 
				new object[]
				{
					ConfigurationSettings.AppSettings["ODBCconnectionString"]
				}, 
				new object[]
				{ 
					ConfigurationSettings.AppSettings["SQLendpoint"]
				}
			}
		);


		// освобождаем ресурсы (хотя нам это всеравно не поможет)
		Marshal.ReleaseComObject( worksheet );
		worksheet = null;

		workbook.Save();
		Marshal.ReleaseComObject( workbook );
`		workbook = null;
		ExcelApp.Quit();
		Marshal.ReleaseComObject( ExcelApp );
		ExcelApp = null;
		GC.Collect();		
		GC.WaitForPendingFinalizers();
		GC.Collect();


		// в след.  3 -х строках мы сжимаем и отправляем файло юзеру на вывод через браузер
		string archivepath = 
			ConfigurationSettings.AppSettings["temp_directory"] + "\\" + "ReportCustomers_" +
			Convert.ToString( CityID ) +
			".rar";

		CompressFile( temppath, archivepath );

		SendFileToUser( archivepath, "ReportCustomers.rar" );
	}
	catch( Exception e )
	{
		throw e;
	}
	finally
	{
		undoImpersonation();
	}
}

А вот описания ключей:

Код: plaintext
1.
<add key="SQLendpoint" value="s=127.0.0.1,1433" />
<add key="ODBCconnectionString" value="ODBC;DSN=MyDataBase;UID=UserName;PWD=UserPass;APP=Microsoft® Query;WSID=BAKI;DATABASE=MyDataBase;Network=DBMSSOCN;Addres" 

Все!

Если будут какие вопросы - пишите.

Удачи!
...
Рейтинг: 0 / 0
27.11.2004, 22:12
    #32802665
Max Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Для тех кто создает отчеты в Excel и юзает Pivot Table
я чего-то так и не понял - ты вопрос спрашиваешь или сам же себе и ответил?
Max Pro
...
Рейтинг: 0 / 0
27.11.2004, 23:44
    #32802675
dmitry_cmc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Для тех кто создает отчеты в Excel и юзает Pivot Table
Нет. не вопрос.

Просто поделился работающим решением ибо долго с ним гемороился.

Но маленький вопросик (по поводу COM) в сообщении все таки содержится
...
Рейтинг: 0 / 0
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / Для тех кто создает отчеты в Excel и юзает Pivot Table / 3 сообщений из 3, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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