AXForum  
Вернуться   AXForum > Блоги > CRM, SharePoint и Черная Магия
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

Добро пожаловать в мой блог! Изначально он не задумывался как блог CRM разработчика, но жизнь сама внесла нужные коррективы. Тут я публикою все свои наблюдения относительно обозначенных в заголовке систем. Если Вы найдете в нем что-то интересное для Вас, как для заказчика, то буду рад сотрудничать с Вами! В моей компетенции 100% задач по MS CRM 3.0/4.0/2011:
  • Консалтинг
  • Проектирование
  • Разработка
  • Обучение


MVP 2010, 2011
Рейтинг: 5.00. Голосов: 2.

Встраивание отчета в панель мониторинга

Запись от Артем Enot Грунин размещена 12.09.2012 в 16:58
Теги dashboard, reports

При всей своей визуальной мощи (и той нагрузке на производительность, которую она несет), панели мониторинга CRM 2011 не имеют встроенной возможности отображать в себе отчеты Reporting Services. На мой взгляд это достаточно странно, так как в прошлых версиях мы создавали свои кастомные страницы-панели именно на этой технологии.

В каких случаях возникает эта задача? Очень просто: когда недостаточно примитивной агрегации существующих данных и нужны вычисления. В общем случае я бы постарался максимально уйти от этой задачи, так как отчеты вот уже много версий Reporting Services имеют ряд существенных визуальных огрехов. Наиболее значимые из них с точки зрения панелей мониторинга:
  1. Размеры отчета и элементов НЕВОЗМОЖНО задать в процентах или других относительных единицах - отчеты не масштабируются при растягивании страницы.
  2. Итоговая веб страница имеет запутанную веб структуру без возможности внедрить в нее код и какие бы то ни было элементы интерактивности.

Иными словами, внутри панели отчет будет выглядеть ущербно и инородно! Тем не менее, иногда от этого не уйти!

В сети приводятся два наиболее распространенных неподдерживаеммых примера реализации подобного функционала. Первый от разработчиков системы: Dashboard Reporting Control for Microsoft Dynamics CRM 2011 и второй - его незначительная модификация от develop1: Embedding CRM reports in IFrames using the CRM2011 Report Viewer (отличается только способом переадресации к CRMReportViewer.aspx).

К сожалению, у обоих решений есть навязанный реализацией огрех: CRMReportViewer.aspx не позволяет скрыть параметры отчета. Это обозначает, что вы увидите панель с кнопками перелистывания страниц, печати и экспорта в Excel и др. форматы.

Особенность Reporting Services заключается в том, что до этой панели очень тяжело добраться через DOM, так как идентификаторы элементов генерируются при запуске отчета. Тем не менее, мне удалось топорно выломать оттуда эту панель. Решение не блещет элегантностью, но это, похоже, единственный вариант:

X++:
<html>
<head>
    <title></title>
    <script src="ClientGlobalContext.js.aspx" type="text/jscript"></script>
    <script type="text/jscript">
        function RunReport() {
            var id = getReportId("data");

            if (id == null) {
                documenc.write("Идентификатор отчета задан некорректно");
                documenc.write("\n\nИдентификатор должен быть задан без фигурных скобок и других символов");
                return;
            }

            var reportUrl = GetGlobalContext().getServerUrl()
                + "/crmreports/viewer/viewer.aspx?action=run&id=%7b"
                + id
                + "%7d";

            var reportIFrame = document.getElementById("reportIFrame");
            reportIFrame.onreadystatechange = hideReportControls;
            reportIFrame.src = reportUrl;

            function hideReportControls() {
                if (reportIFrame.readyState == "complete") {
                    var doc = reportIFrame.contentWindow.document;

                    menuBar = doc.getElementById('mnuBar1');
                    if (menuBar != null) {
                        menuBar.style.display = "none";
                    }

                    editFilter = doc.getElementById('trEditFilter');
                    if (editFilter != null) {
                        editFilter.style.display = "none";
                    }

                    hideNavigationAndSetListeners();
                }
            }

            function hideNavigationAndSetListeners() {
                resultFrame = reportIFrame.contentWindow.document.getElementById('resultFrame');
                if (resultFrame != null) {
                    if (resultFrame.readyState == "complete") {
                        var reportViewerTable = resultFrame.contentWindow.document.getElementById('reportViewer_fixedTable');
                        if (reportViewerTable != null) {
                            row = reportViewerTable.rows(reportViewerTable.rows.length - 2);
                            row.style.display = "none";
                            reportViewerTable.onclick = openReportWindow;
                            reportViewerTable.style.cursor = "pointer";
                        }
                        else {
                            resultFrame.contentWindow.setTimeout(hideNavigationAndSetListeners, 100)
                        }
                    }
                    else {
                        resultFrame.onreadystatechange = hideNavigationAndSetListeners;
                    }
                }
                else {
                    setTimeout(hideNavigationAndSetListeners, 100)
                }
            }

            function openReportWindow() {
                window.open(reportUrl);
            }
        }

        

        function getReportId() {
            var reportId = null;
            var query = window.location.search.substring(1);
            var parms = query.split('&');
            for (var i = 0; i < parms.length; i++) {
                var pos = parms[i].indexOf('=');
                if (pos > 0 && parms[i].substring(0, pos) == "data") {
                    reportId = parms[i].substring(pos + 1);
                }
            }

            return isGuid(reportId) ? reportId : null;
        }

        function isGuid(guid) {
            if (guid != null) {
                var guidRegEx = /^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$/;
                return guidRegEx.test(guid);
            }
            return false;
        }
    </script>
</head>
<body onload="RunReport()" style="border-width: 0px; padding-left: 0px; padding-top: 0px; margin-left: 0px; margin-top: 0px; margin-bottom: 0px; margin-right: 0px">
    <iframe id="reportIFrame" src="" frameborder="0" height="100%" width="100%" scrolling="no"
        style="display: block; border-width: 0px; padding-left: 0px; padding-top: 0px; margin-left: 0px; margin-top: 0px; margin-bottom: 0px; margin-right: 0px"/>
</body>
</html>
Использование контрола осуществляется аналогично приведенным примерам:
  1. Необходимо развернуть и опубликовать решение (файл приложен к посту)
  2. Необходимо добавить на панель веб-ресурс fixrm_ReportControl
  3. В качестве параметра указать GUID отчета
Так же данная реализация содержит небольшой, но глупый бонус. Клик на отчете открывает его в отдельном окне. Как я уже говорил, размеры в отчете задаются в абсолютных единицах. Это значит, что в отдельном окне откроется все тот же крошечный отчет что и в панели. "Исправить" это поведение можно путем создания второго укрупненного отчета с передачей его идентификатора в качестве второго параметра для ресурса. До этого не дошли руки. Если кто-то реализует и поделится - буду признателен.
Вложения
Тип файла: zip FixRMReportControl_1_0_0_0.zip (8.9 Кб, 6543 просмотров)
Размещено в CRM
Просмотров 312921 Комментарии 1
Всего комментариев 1

Комментарии

  1. Старый комментарий
    Может кто переделывал данное расширение под 2013/15? Не устанавливается оно (((
    Запись от TankMan размещена 13.12.2015 в 14:26 TankMan is offline
 


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