[ Вопрос дня ] Как заполнить объект ДанныеРасшифровки отчета на СКД с использованием набора данных типа Объект?

Курс Профессиональная разработка отчетов в 1С 8.3 на Системе Компоновки Данных (СКД) очень востребован у слушателей проекта. Владение механизмами СКД – основополагающие знания, без которых работать с современными типовыми конфигурациями просто невозможно.

Настоятельно рекомендуем досконально изучить тему Работа с системой компоновки данных средствами встроенного язык, это однозначно повысит эффективность и скорость вашей работы с решениями 1С.

Вопрос

Сделал отчет на СКД с использованием набора данных типа Объект (таблицы значений). В наборе есть поля типа ссылки на справочники и документы, но в отчете нет ни одной расшифровки.

Попробовал установить расшифровки с помощью макета СКД: оформление макета воспринимается, а расшифровка – нет.

В сети прочитал, что для наборов типа объект расшифровки нужно устанавливать в обработчике “ПриКомпоновкеРезультата“. Подскажите, пожалуйста, как это можно сделать?

Ответ

Для этого в процедуре ПриКомпоновкеРезультата нужно использовать объект ДанныеРасшифровки при создании макета компоновки и при инициализации процессора компоновки, например:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    НастройкиКомпоновки = КомпоновщикНастроек.ПолучитьНастройки();
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиКомпоновки, ДанныеРасшифровки);
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |   ТоварныеЗапасыОстатки.Товар,
        |   ТоварныеЗапасыОстатки.Склад,
        |   ТоварныеЗапасыОстатки.КоличествоОстаток КАК Остаток
        |ИЗ
        |   РегистрНакопления.ТоварныеЗапасы.Остатки КАК ТоварныеЗапасыОстатки";
    ТЗ = Запрос.Выполнить().Выгрузить();
    ВнешниеНаборы = Новый Структура("ТЗ", ТЗ);
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборы, ДанныеРасшифровки);
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);   
КонецПроцедуры

Комментарии / обсуждение (28):

  1. tolyanekb

    Подскажите в курсе есть тема где ДанныеРасшифровки заполняют программно? Никак не могу понять как создавать свою расшифровку ПриКомпоновке().

    • Василий Ханевич

      Добрый день!
      В курсе есть видеоуроки, демонстрирующие создание макета в схеме компоновки, в ячейках макета определяются расшифровки. При таких настройках ДанныеРасшифровки будут заполнены при компоновке отчета.
      Также рассматривается, как в форме отчета обработать расшифровку.

  2. Имя

    А если СКД используется во внешнем отчете БЕЗ использования предопределенной процедуры “ПриКомпоновкеРезультата” – по кнопке в диалоге, по которой вызывается процедура, среди параметров которых нету ДанныеРасшифровки (в которой собирается в ТЗ для набора данных – объекта) – и в результате формируется отчет, в котором обработка расшифровки напрочь не работает… как исправить?..

    • Василий Ханевич

      Добрый день!
      В таком случае можно создать строковый реквизит формы ДанныеРасшифровки (это будет адрес во временном хранилище, куда поместим данные расшифровки).
      При программной работе с компоновкой указываем параметр ДанныеРасшифровки:

          ДанныеРасшифровкиКомпоновки = Новый ДанныеРасшифровкиКомпоновкиДанных;
          МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиКомпоновки, ДанныеРасшифровкиКомпоновки);
          ВнешниеНаборы = Новый Структура("ТЗ", ТЗ);
          ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
          ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборы, ДанныеРасшифровкиКомпоновки);
          ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
          ПроцессорВывода.УстановитьДокумент(ИабличныйДокумент);
          ПроцессорВывода.Вывести(ПроцессорКомпоновки);

          ДанныеРасшифровки = ПоместитьВоВременноеХранилище(ДанныеРасшифровкиКомпоновки, УникальныйИдентификатор);

      Тогда при программной обработке расшифровки можно будет получить нужные данные из временного хранилища:

      ДанныеРасшифровкиКомпоновки = ПолучитьИзВременногоХранилища(ДанныеРасшифровки);
      ПоляРасшифровки = ДанныеРасшифровкиКомпоновки.Элементы.Получить(Расшифровка).ПолучитьПоля();
  3. DiMel

    Добрый день!
    Подскажите, а существуют ли примеры полностью программной работы с объектом “ДанныеРасшифровкиКомпоновкиДанных”?
    Т.е. допустим я выполняю компоновку данных в коллекцию значений через метод ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений, а потом использую эту коллекцию для программного вывода отчета. Могу ли я сам сгенерировать объект “ЭлементРасшифровкиКомпоновкиДанныхПоля” и установить ячейке значение Идентификатора этого объекта не используя процессор вывода в табличный документ?
    Т.е. можно конечно при выводе в табличный документ использовать структуру (или другой подобный объект) и записывать в свойства ячейки “Параметр расшифровки”, но данный подход сильно нагружает память на клиенте и необходимо хранить текущие настройки на сервере во временном хранилище.

    • Василий Ханевич

      Добрый день!
      Обратимся к Синтакс-помощнику. Для объекта встроенного языка ЭлементРасшифровкиКомпоновкиДанныхПоля не указан конструктор, значит, создать его отдельно от процесса компоновки не получится.

      • DiMel

        А через серилизацию XDTO? Т.е. если вручную собрать XML и поместить во временное хранилище, а адрес указать свойство формы “Данные расшифровки”? Фактически я интересуюсь возможностью самостоятельной реализации объекта аналогичного ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент, только не обязательно вывод должен осуществляться в поле табличного документа. А допустим в поле HTML…

        • DiMel

          Проверил сейчас, сделал простой отчет по выводу справочника с реквизитами и серилизовал в файл объект “Данные расшифровки”, поправил значения в созданном файле и выполнил подмену объекта из поправленного файла. Открытие и расшифровка выполнялись по измененным объектам. Т.е. программно можно создавать и корректировать “Данные расшифровки”. К сожалению конструктора для объекта “ИдентификаторРасшифровкиКомпоновкиДанных” тоже нет, но он также может быть создан через XDTO серилизацию из такой строки:
          2
          Т.е. программное создание своей расшифровки возможна при программном выводе. Вероятно ни кому не требовалось, поэтому до сих пор и не реализовывалось…

          • Василий Ханевич

            Спасибо, что поделились результатами экспериментов.
            Предполагаю, что действительно задача не распространенная. Потому что если нужно вывести результат компоновки в коллекцию значений, то расшифровка не требуется, а если нужно вывести результат компоновки в табличный документ, то в макете можно настроить расшифровки.

        • Василий Ханевич

          Затрудняюсь порекомендовать Вам что-то по этому поводу, потому что не пробовал делать таких экспериментов.
          Возможно, в таком случае нет смысла использовать существующие объекты встроенного языка, СКД использовать только для получения данных, на основании этих данных кодом формировать HTML-документ. А может, внешнюю компоненту разработать для ускорения процесса.

  4. German_IGOR

    Я сейчас передаю через пользовательские настройки,
    но мне это не нравится потому что настройки в этом случае не работают
    с другой стороны возможно отредактировать настройки через прочее
    вот и думаю как правильно сделать …..

      • Василий Ханевич

        Я бы в первую очередь попробовал сделать обработку заполнения объекта, в которой компоновать результат в таблице значений, загружать полученные данные в сам объект.

        • German_IGOR

          Я так и делаю, вопрос в том как корректно передать владелецформы.объект
          в ПриКомпоновкеРезультата?
          Пробовал через ВременноеХранилищеЗначений – не получилось

          • Василий Ханевич

            ПриКомпоновкеРезультата – это специфическая процедура, которая вызывается платформой, но не используется явно разработчиком.
            Поэтому “снаружи” в нее можно что-то передать через компоновщик настроек. Для этого можно использовать настройки компоновщика (например, параметры).
            Еще вариант – использовать ДополнительныеСвойства, которые есть у настроек компоновщика. Про них я писал в предыдущем сообщении.

            Я же предлагаю вариант не искать способ передавать значение в процедуру ПриКомпоновкеРезультата, а создать обработку заполнения объекта с типом команды ЗаполнениеФормы, в которой компоновать результат в таблице значений, загружать полученные данные в сам объект. Тем самым мы получаем заполнение данных формы без записи объекта в базу данных.

            Пример кода:

            Функция СведенияОВнешнейОбработке() Экспорт

                ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
                ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
                ПараметрыРегистрации.Версия = "1.0";
                ПараметрыРегистрации.Назначение.Добавить("Документ.ИмяДокумента");

                НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
                НоваяКоманда.Представление = НСтр("ru = 'Заполнить товары без записи объекта (заполнение формы)'");
                НоваяКоманда.Идентификатор = "ЗаполнитьТовары";
                НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыЗаполнениеФормы();
                Возврат ПараметрыРегистрации;

            КонецФункции

            Процедура ВыполнитьКоманду(ИмяКоманды, ОбъектыНазначения, ПараметрыВыполнения) Экспорт

               Если ИмяКоманды = "ЗаполнитьТовары" Тогда

                    ЭтаФорма = ПараметрыВыполнения.ЭтаФорма;//так доступна сама форма и все ее реквизиты
                    ЭтаФорма.Модифицированность = Истина;

                    //программно работаем с компоновкой, выводим результат в ТЗ
                //заполняем ЭтаФорма.Объект.Товары по данным из ТЗ

               КонецЕсли;

            КонецПроцедуры
            • German_IGOR

              Метод объекта не обнаружен (ВыполнитьКоманду)
              {ОбщийМодуль.ДополнительныеОтчетыИОбработки.Модуль(1979)}: ВнешнийОбъект.ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды);
              {ОбщийМодуль.ДополнительныеОтчетыИОбработки.Модуль(2065)}: ВыполнитьНазначаемуюКомандуДополнительногоОтчетаИлиОбработки(
              {ОбщийМодуль.ДополнительныеОтчетыИОбработки.Модуль(752)}: ВыполнитьКомандуВнешнегоОбъекта(ВнешнийОбъект, ВыполняемаяКоманда.Идентификатор, ПараметрыКоманды, Неопределено);
              {(1)}:ДополнительныеОтчетыИОбработки.ОбработчикКомандыЗаполнения(Параметры[0],Параметры[1])
              {ОбщийМодуль.ОбщегоНазначения.Модуль(4883)}: Выполнить ИмяМетода + “(” + ПараметрыСтрока + “)”;
              {ОбщийМодуль.ПодключаемыеКоманды.Модуль(159)}: ОбщегоНазначения.ВыполнитьМетодКонфигурации(Обработчик, ПараметрыЭкспортнойПроцедуры);
              {Документ.СчетНаОплатуПоставщика.Форма.ФормаДокумента.Форма(691)}: ПодключаемыеКоманды.ВыполнитьКоманду(ЭтотОбъект, Контекст, Объект, Результат);
              {ОбщийМодуль.ПодключаемыеКомандыКлиент.Модуль(171)}: Контекст.Форма.Подключаемый_ВыполнитьКомандуНаСервере(СерверныйКонтекст, Результат);
              {ОбщийМодуль.ПодключаемыеКомандыКлиент.Модуль(60)}: ПродолжитьВыполнениеКоманды(Контекст);
              {Документ.СчетНаОплатуПоставщика.Форма.ФормаДокумента.Форма(686)}: ПодключаемыеКомандыКлиент.ВыполнитьКоманду(ЭтотОбъект, Команда, Объект);

              • Василий Ханевич

                Прикрепил пример обработки с приведенным кодом – ЗаполнениеКомментария.zip.
                Это обычная обработка заполнения объекта для конфигураций на базе БСП. На УТ 11.4 работает.
                Сравните, пожалуйста, со своим кодом. Возможно, метод ВыполнитьКоманду не отмечен как экспортный.

                  • Василий Ханевич
                    • German_IGOR

                      Взял себя в руки и добил таки данный отчет
                      через дополнительные свойства
                      все работает – правда там какие то заморочки
                      с призаписи объекта
                      написал примерно так
                      КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Свойство(“ДОПсвойство”, ССЫЛКА1);
                      ДокОб = ДанныеФормыВЗначение(ссылка1,Тип(“ДокументОбъект.Счетнаоплатупоставщика”));
                      Для Каждого СтрокаМассива Из ТЗ Цикл

                      НоваяСтрока =ДокОб.Товары.Добавить();
                      // НоваяСтрока = ДокЗаказ.Товары.Добавить();
                      НоваяСтрока.Номенклатура = СтрокаМассива.Номенклатура;
                      НоваяСтрока.Количество = СтрокаМассива.Количество1;

                      КонецЦикла;

                      ДокОБ.Записать(РежимЗаписиДокумента.Запись);
                      СтатусПроведения = 2;

                    • Василий Ханевич

                      Ок. Отлично, что решили свою задачу.

                    • German_IGOR

                      Извините в продолжение темы
                      как программно завершить отчет если нужное условие было выполнено
                      т.е. отчет сформирован данные записаны – как мне его аккуратно закрыть
                      форму отчета

                    • Василий Ханевич

                      Добрый день!
                      Например, можно воспользоваться параметром Уникальность при открытии формы:

                          ИдентификаторОтчета = Новый УникальныйИдентификатор;
                          ОткрытьФорму("Отчет.Отчет1.Форма", , , ИдентификаторОтчета);

                      Затем получить форму с этим ключом уникальности и закрыть ее:

                          Форма = ПолучитьФорму("Отчет.Отчет1.Форма", , , ИдентификаторОтчета);
                          Форма.Закрыть();
                    • German_IGOR

                      сделал немного по другому в расширении
                      в ФормаОтчета

                      &НаКлиенте
                      &После(“ОтчетСкомпоноватьРезультат”)
                      Процедура СН_ОтчетСкомпоноватьРезультат(Команда)

                      Попытка
                      Регистратор = ложь;

                      Регистратор=Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных(“проба”)).ИдентификаторПользовательскойНастройки).Значение;

                      если Регистратор = истина тогда

                      этаформа.Закрыть();

                      конецесли;

                      Исключение
                      КонецПопытки;

                      КонецПроцедуры

                    • Василий Ханевич

                      Ок, отлично, что получилось реализовать.
                      Для надежности указанного кода можно добавить проверку на Неопределено, поскольку метод Найти может возвращать и такое значение, если элемент не найден.

  5. German_IGOR

    я не знаю куда поместить данный вопрос.
    есть форма документа – счет на оплату поставщика
    вызывается внешний отчет СКД

    сформированные данные надо записать в документ откуда вызывался отчет

    &НаСервере
    Функция ПолучитьПользовательскиеНастройки(ВнешнийОтчетОбработкаДляОткрытияСсылка);

    КомпоновщикНастроек=ДополнительныеОтчетыИОбработкиВызовСерве­ра.ОбъектВнешнейОбработки(ВнешнийОтчетОбработкаДляОткрытияСсылка).КомпоновщикНастроек;
    Настройки=КомпоновщикНастроек.ПолучитьНастройки();
    Настройки.ПараметрыДанных.УстановитьЗначениеПараметра(“НачалоПериода”,НачалоГода(ТекущаяДата()));
    Настройки.ПараметрыДанных.УстановитьЗначениеПараметра(“КонецПериода”,КонецДня(ТекущаяДата()));
    Настройки.ПараметрыДанных.УстановитьЗначениеПараметра(“Ссылка”,объект);

    КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
    Возврат КомпоновщикНастроек.ПользовательскиеНастройки;
    КонецФункции

    Скрыть

    в модуле объекта отчета

    Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)

    СтандартнаяОбработка = Ложь;

    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    ПараметрыДанных = Настройки.ПараметрыДанных;
    Регистратор = ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных(“Проба”)).Значение;
    ссылка = ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных(“ссылка”)).Значение;

    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки, , , Ложь);
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки,, ДанныеРасшифровки, Истина);
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);

    ПроцессорВывода.Вывести(ПроцессорКомпоновки);

    если Регистратор = Истина тогда

    ДокОб = ДанныеФормыВЗначение(ссылка,Тип(“ДокументОбъект.Счетнаоплатупоставщика”));

    ну и далее обработка..

    конецесли;

    Скрыть

    этот вариант работает но настройки недоступны потому что форма настроек не понимает
    что такое ссылка

    поэтому пытаюсь получить владельцаформы.объект
    в форме отчета

    &НаКлиенте
    Процедура СН_ПриОткрытииПосле(Отказ)

    Сообщить(ВладелецФормы.Объект);

    ПриОткрытииНаСервере(ВладелецФормы.Объект);

    КонецПроцедуры

    &НаСервере
    Процедура ПриОткрытииНаСервере(Знач Об1)
    ДокОб = ДанныеФормыВЗначение(Об1,Тип(“ДокументОбъект.Счетнаоплатупоставщика”));
    Сообщить(ДокОб);

    КонецПроцедуры

    Скрыть

    Вопрос каким образом передать владельцаформы.объект в процедуру ПриКомпоновкеРезультата????????

    • Василий Ханевич

      Добрый день!
      Для этого можно использовать ДополнительныеСвойства, которые есть у настроек компоновщика:

      Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Вставить("ИмяСвойства", Значение);

      В модуле отчета получаем значение из дополнительных свойств настроек компоновщика:

      Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
         
          НужноеЗначение = "";
          Если КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Свойство("ИмяСвойства", НужноеЗначение) Тогда
              ...
          КонецЕсли;

      КонецПроцедуры

      Рассмотрите также возможность использования внешней обработки заполнения для решения Вашей задачи. В таком случае будет доступен Объект, который нужно заполнить, в обработке нужно будет программно выполнить компоновку, затем загрузить получившиеся данные в ТЧ документа.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Вход на сайт

Зарегистрироваться

Подтверждение регистрации будет отправлено на указанный e-mail.

Я подтверждаю, что ознакомлен(а) с Пользовательским соглашением, принимаю его условия и даю свое согласие на обработку моих персональных данных.

Восстановить доступ

E-mail или логин

Ссылка на создание нового пароля будет отправлена на указанный e-mail.