AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 01.02.2005, 14:07   #1  
lexa_q is offline
lexa_q
Участник
 
12 / 10 (1) +
Регистрация: 02.02.2005
Адрес: Спб
Приветствую всех!

Я сейчас буду задавать много глупый вопрос. Цель моя - выгружать отчеты во внешнее хранилище. Нужно все - и само содержимое отчета (в формате HTML/PDF) и "распарсенная" информация - значение полей отчета.

Вопрос #1.
Есть такая штука в отчетах "Опции/канал вывода". Было бы просто супер-круто добавить туда свой канал вывода "внешнее хранилище отчетов"! Возможно ли это? Есть такое чувство что да, куда копать?

Вопрос #2.
Как программно запустить отчет и указать канал вывода "файл". Тыкните в документацию или класс, пожалуйста!
Старый 01.02.2005, 14:21   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
1. Вроде да. Коламбус продает решение, где добавлен канал вывода в Excel (насколько я понял из разговоров с Коламбусами). Куда копать - не знаю.

2. Рыть в сторону класса SysPrintOptions, PrintJobSettings
__________________
полезное на axForum, github, vk, coub.
Старый 01.02.2005, 16:54   #3  
lexa_q is offline
lexa_q
Участник
 
12 / 10 (1) +
Регистрация: 02.02.2005
Адрес: Спб
Да, у коламбуса есть такой продукт...
Я тут нарыл класс ReportOutputUser, можно создать от него населедника и использовать в качестве print medium, как я понимаю это и есть канал вывода. Возникает закономерный вопрос - почему же до сих пор никто не сделал универсального наследника, выгружающего отчет в Excel? Это же будет работать с любым уже существующим отчетом - не надо писать дополнительного кода в отчете, в отличие от подхода, предлагаемого в MegadomReport. Где собака зарылась?
Старый 01.02.2005, 17:04   #4  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от lexa_q
Возникает закономерный вопрос - почему же до сих пор никто не сделал универсального наследника, выгружающего отчет в Excel?
Вы неправильно вопрос ставите.
Правильный вопрос: почему такую разработку еще никто не выложил в открытый доступ?

__________________
полезное на axForum, github, vk, coub.
Старый 01.02.2005, 17:47   #5  
lexa_q is offline
lexa_q
Участник
 
12 / 10 (1) +
Регистрация: 02.02.2005
Адрес: Спб
8)))
Ставлю правильный вопрос: есть ли в открытом доступе пример, как ВЫЗВАТЬ отчет так, чтобы формированием занимался мой наследник ReportOutputUser. Ковыряю xpo-шник системный, и че-то никак не врублюсь... Они там конечно круто все развели внутри:

ReportOutputUser createViewer(...)
{
.....
switch (outputType)
{
case ReportOutputUserType::HTML:
{
ret = new WebReportHTML(jobsCursor, pagesCursor, report);
return ret;
}
....

Ну а как в эту маханику внедрить мой класс? Тем более что Axapta не дает расширить enum ReportOutputUserType и тем более перекрыть ClassFactory::createViewer. Я так мыслю что надо копать в сторону ReportRun - видимо, он вызывает createViewer(), но раскопки стали ходить по кругу уже...
Старый 01.02.2005, 18:09   #6  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
lexa_q, спокойнее.
Пользуйтесь перекрестными ссылками.

Леко найти, что в первом топике я неполностью указал класс.
Параметрами отчета заведует класс PrintJobSettings.

Далее смотрите, на метод viewerType этого класса. Смотрите что в системном перечислении ReportOutputUserType есть два зарезервированных пункта Viewer4. Viewer5.

Далее посмотрите на перечисление PrintMedium и обратите внимание на зарезервированное слово ViewerClass. Обратите внимание, что этот ViewerClass трактуется в форме печати SysPrintForm как файл...

Далее поищите на течнете и поройтесь в перекрестных ссылках.

В общем, в панику впадать не стоит. Все достаточно логично. Нужно только время, чтобы разобраться...
__________________
полезное на axForum, github, vk, coub.
Старый 01.02.2005, 18:14   #7  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от lexa_q
Ну а как в эту маханику внедрить мой класс? Тем более что Axapta не дает расширить enum ReportOutputUserType и тем более перекрыть ClassFactory::createViewer.
Посмотрел туда.
С чего это вы не можете его перекрыть?
Кроме того, в этом методе есть чудесный класс SysDummyPrintViewer

<div class='XPPtop'>X++</div><div class='XPP'>ReportOutputUser createViewer(PrintJobHeader jobsCursor, PrintJobPages pagesCursor, ReportOutputUserType outputType, ReportRun report=NULL)
{
   ReportOutputUser ret;

   [color=:blue]switch[/color] (outputType)
   {
       [color=:blue]case[/color] ReportOutputUserType::HTML:
       {
           ret = [color=:blue]new[/color] WebReportHTML(jobsCursor, pagesCursor, report);
           [color=:blue]return[/color] ret;
       }
       [color=:blue]case[/color] ReportOutputUserType::Viewer5:
       {
           ret = [color=:blue]new[/color] WebReportGraph(jobsCursor, pagesCursor, report);
           [color=:blue]return[/color] ret;
       }
       [color=:blue]case[/color] ReportOutputUserType::PDF:
       {
           [color=:blue]return[/color] [color=:blue]new[/color] PDFViewer(jobsCursor, pagesCursor);
       }

       [color=:blue]case[/color] ReportOutputUserType::[color=:blue]Default[/color]:
       [color=:blue]case[/color] ReportOutputUserType::Viewer4:
       {
           [color=:blue]return[/color] [color=:blue]new[/color] SysDummyPrintViewer(jobsCursor, pagesCursor);
       }

   }
   [color=:blue]return[/color] NULL;
}</div>
__________________
полезное на axForum, github, vk, coub.
Старый 01.02.2005, 18:20   #8  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
В общем, замечательная такая иерархия выстраивается...
Ее и используйте.
Изображения
 
__________________
полезное на axForum, github, vk, coub.
Старый 03.02.2005, 13:27   #9  
lexa_q is offline
lexa_q
Участник
 
12 / 10 (1) +
Регистрация: 02.02.2005
Адрес: Спб
В общем, как я понял, подход такой:
I. Модифицируем форму SysPrintForm, чтобы она предлагала новый канал вывода - наш. В методе initSendTo() добавляем пункт в список
II. В SysPrintForm.closeOK() надо задать параметры генерации, хранимые в clientSysPrintOptions. 2 параметра:
1) clientSysPrintOptions.parmTarget(PrintMedium::ViewerClass)
это прводит к тому, что ReportRun() вызывает ClassFactory::createViewer().
2) clientSysPrintOptions.parmViewerType( *XXX*)
*XXX* передатся в createViewer как параметр outputType.
III. Модифицируем метод
<div class='XPPtop'>X++</div><div class='XPP'>ClassFactory::createViewer(PrintJobHeader jobsCursor, PrintJobPages pagesCursor, ReportOutputUserType outputType, ReportRun report=NULL)
{
   ...
   [color=:blue]case[/color] *XXX*: [color=:blue]return[/color] [color=:blue]new[/color] MyViewer();
}</div>

Внимание, вопрос! 8)
Перечисление ReportOutputUserType не расширяемо - в него не добавить свое значение *XXX* ! Там есть неиспользуемое значение Viewer4, но не хотелось бы на него завязываться. Я попробовал в качестве *XXX* передавать просто число 100, и ловить в createViewer() тоже 100. Работает. Но пахнет это плохо! Как быть? Верен ли описанный подход?
Тут народ в http://www.axforum.ru/forums/showthread.ph...32267#post32267 тоже делал свой канал, они наверняка в курсе. Но при попытке написать им письмо сайт просит обратиться к админу, т.е. к mazzy. Обращаюсь! Mazzy, ка им написать?
Старый 03.02.2005, 14:04   #10  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Ёпть! Вот же оно! Блин. Если бы я в своё время докопался до этого, то был бы уже такой отчёт в общем доступе! Пришлось извращатся через MegadomeReport...

Цитата:
Это же будет работать с любым уже существующим отчетом - не надо писать дополнительного кода в отчете, в отличие от подхода, предлагаемого в MegadomReport.
Есть только одно но - это секционность отчётов. С ней надо разобраться, ибо она делает бесполезной выгрузку в Excel.
Старый 03.02.2005, 14:22   #11  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Цитата:
Я попробовал в качестве *XXX* передавать просто число 100, и ловить в createViewer() тоже 100. Работает. Но пахнет это плохо!
Да как бы это ни пахло, других способов "неограниченно" расширять reportViewer-ы похоже нет.
Старый 03.02.2005, 15:01   #12  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Размышления по поводу и без.
Экспорт отчётов в эксель очень просто сделать например вот таким способом:
1. экспортируем отчёт в txt файл
2. импортируем этот файл в эксель
...неудобно, но зато работает и сразу даёт понять что экспорт всех отчётов в эксель задача не такая уж и прямолинейная - добавление нового канала вывода, поддерживающего все методы startPage, startSection... и т.п. выльется в совершенно бесполезную работу, по той причине, что данные в эксель экспортируются не для распечатки, а для анализа.
Табличного анализа. Т.е. все данные должны быть подбиты в строгие строки и колонки, чтобы по ним можно было суммировать, сортировать и т.п.

Тут возникает множество проблем стандартного дизайна отчётов.
Во первых - как правило отчёты состоят из секций, а секции как известно стоят одна под одной, нарушая табличный порядок, плюс еще у подсекций могут выводится подолнительные заголовки. Плюс к тому возникает вопрос - разумно ли в excel выводить подитоги, если он сам это умеет делать. Плюс еще у каждой страницы может быть начало и конец, плюс еще куча мелочей, в результате если посмотреть то что получается при выводе достаточно сложного отчёта в txt наглядно видно почему придётся изрядно поломать голову за написанием универсального канала вывода для всех уже существующих отчётов в Excel.
Старый 03.02.2005, 15:19   #13  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от lexa_q
Тут народ в http://www.axforum.ru/forums/showthread.ph...32267#post32267 тоже делал свой канал, они наверняка в курсе. Но при попытке написать им письмо сайт просит обратиться к админу, т.е. к mazzy. Обращаюсь! Mazzy, ка им написать?
Адреса участников не раздаем.
Я написал участникам обсуждения на ахфоруме.
Если они захотят - ответят.
__________________
полезное на axForum, github, vk, coub.
Старый 03.02.2005, 15:21   #14  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от =A=L=X=
Размышления по поводу и без.
Экспорт отчётов в эксель очень просто сделать например вот таким способом:
1. экспортируем отчёт в txt файл
2. импортируем этот файл в эксель
...неудобно, но зато работает и сразу даёт понять что экспорт всех отчётов в эксель задача не такая уж и прямолинейная
Согласен.
Но все равно было бы красиво, если бы кто-нибудь (а еще лучше разработчики Аксапты) таки сделали бы такой канал.
__________________
полезное на axForum, github, vk, coub.
Старый 03.02.2005, 15:48   #15  
lugachy is offline
lugachy
Участник
 
82 / 11 (1) +
Регистрация: 15.03.2004
Цитата:
Сообщение от lexa_q
Внимание, вопрос! 8)
Перечисление ReportOutputUserType не расширяемо - в него не добавить свое значение *XXX* ! Там есть неиспользуемое значение Viewer4, но не хотелось бы на него завязываться. Я попробовал в качестве *XXX* передавать просто число 100, и ловить в createViewer() тоже 100. Работает. Но пахнет это плохо! Как быть? Верен ли описанный подход?
Могу порекомендовать почитать описание класса ReportOutputUser, там есть пример как создавать пользовательский канал вывода. Они, как ни странно, используют ReportOutputUserType:efault.
Пользовательский канал определяется там так:

printJobSettings.setTarget(PrintMedium::viewerClass);
printJobSettings.viewerType(ReportOutputUserType:efault);

и к классу reportOutputUser навешивается наследник для управления выводом.
Старый 03.02.2005, 18:04   #16  
lexa_q is offline
lexa_q
Участник
 
12 / 10 (1) +
Регистрация: 02.02.2005
Адрес: Спб
Да, точно! У ReportOutputUser есть описание! Слона-то и не заметил!
Mazzy, спасибо!
lugachy, спасибо!
В описании они предлагают перекрывать prompt() отчета для установки printJobSettings.setTarget/setViewerType. Это не гуд так как придется добавлять этот код во все отчеты.

Господа, есть соображения как вставить свой класс-перехватчик отчета без "хака" с передачей 100 (*XXX*) в createViewer? Есть ли еще место, куда можно внедриться типа SysPrintForm?

lugachy, как Вы сделали у себя?

=A=L=X=, вы совершенно правы насчет всех этих startSection/startPage. Оформление и отступы не нужны, нужны сухие данные. lugachy заставил Аксапту не бить отчет на страницы:
Цитата:
Решил проблему так:
В методе формы SysPrintForm.closeOk() для своего канала вывода (экселя)устанавливаю свойство viritualPageHeight в 0. После этого аксапта понимает что нет пределов по высоте и больше не пытается разбивать отчет на страницы.
А с подсекциями и промеж. итогами буду разбираться отдельно. Есть соображения ?

Если все удастся, не вижу причин не выложить в общий доступ скелет получившегося канала - без кода выгружки во внешнюю систему.
Старый 03.02.2005, 18:23   #17  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от lexa_q
Господа, есть соображения как вставить свой класс-перехватчик отчета без "хака" с передачей 100 (*XXX*) в createViewer? Есть ли еще место, куда можно внедриться типа SysPrintForm?
Есть старый полухакерский способ, который работал в 2.5
В 3.0 не проверял.

Будьте предельно внимательны и осторожны.
Ни в коем случае НЕ ВЫПОЛНЯЙТЕ этих действий на РАБОЧЕЙ БАЗЕ.
Я ничего не гарантирую, ниже только предположения.
  • Экспортируйте какой-нибудь BaseEnum
  • Измените текстовый xpo-файл так, как будто там находится PrintMedium (или другой системный объект).
  • Импортируйте
  • Выполните глобальную компиляцию
__________________
полезное на axForum, github, vk, coub.
Старый 04.02.2005, 10:02   #18  
lugachy is offline
lugachy
Участник
 
82 / 11 (1) +
Регистрация: 15.03.2004
Цитата:
Сообщение от lexa_q
В описании они предлагают перекрывать prompt() отчета для установки printJobSettings.setTarget/setViewerType. Это не гуд так как придется добавлять этот код во все отчеты.
Форма в которой выбирается канал вывода - она везде одна и та же - sysPrintForm.

Модифицируем методы::

buildSendToList(***)
{
***
***
//самый конец метода

formListItem = new FormListItem("Excel", imageListAppl_Print.image(#ImageExcel), PrintMedium::ViewerClass);
sendTo.addItem(formListItem);
}

changeTarget(***)
{
//В конец тала switch'a добавляем
case PrintMedium::ViewerClass :
element.setTargetSettings(#TAB_PRINTER, "Вывести отчет в Excel", PrintMedium::ViewerClass, true);
break;

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

В качестве примера по реализации Viewer-класса могу порекомендовать посмотреть классы WebReportHTML и WebReportBase.

Скажите, вы уже определились конкретно что вы хотите получить?? В каком виде вы хотите получать отчеты в Эксель? Если у вас задача получать в экселе красивые отчеты, да еще и для заказчика - бросайте это дело. Или по крайней мере определитесь сначала что и как вы хотите получить.

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

}
Старый 04.02.2005, 11:06   #19  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
О красоте речь скорее всего не идет, т.к. экспортировать в эксель чтобы потом это просто распечатать глупо.
Скорее всего желательно следующее поведение:
а) сообщить движку отчётов что весь отчет должен выводится в одну страницу (уже даже объяснили как)
б) прологи и эпилоги выводить без извратов - как получится
в) секции выводить не в подчинении друг к другу, а разворачивать их в плоскую таблицу, т.е.:
заголовок секции 1
секция1 (а)
заголовок секции 2
секция2 (а)
секция2 (б)
заголовок секции 1
секция1 (б)
заколовок секции 2
секция2 (в)

превратить в
заголовок секции 1 заголовок секции 2
секция1 (а) секция2 (а)
секция1 (а) секция2 (б)
секция1 (б) секция2 (в)

Чем больше думаю о том как такое реализовать, тем больше мыслей что придётся остановится на MegadomeReport.
Старый 04.02.2005, 11:49   #20  
lugachy is offline
lugachy
Участник
 
82 / 11 (1) +
Регистрация: 15.03.2004
Такое сделать вполне возможно.
 

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 17:44.