Пример использования внешнего источника данных в скд. Наборы данных Скд набор данных объект таблица значений

В своей прошлой статье я уже писал, что 1С это парадоксальная платформа. Система компановки данных относится к таким парадоксам. СКД предназначена для конструирования сложных отчетов и предполагает замену "ручного" программирования отчетов конструированием в многофункциональном инструментарии. Возможность использования СКД появилась в восьмой версии, но потребовалось долгое время что бы появилась версия 8.2 дабы 1С смогла использовать ее в своих типовых продуктах. С одной стороны, СКД это многофункциональный инструментарий, используя который можно составить очень сложные отчеты без единой строчки кода. Однако у СКД довольно высокий порог вхождения, изучить и начать полноценно пользоваться ею "с наскока" очень тяжело, ибо интерфейс не совсем интуитивно понятный, а наиболее полные руководства использования имеются только в виде платной литературы.

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

Запрос = Новый Запрос(
"ВЫБРАТЬ
| Таблица.Номенклатура,
| Таблица.Склад
|ИЗ
| &ТЗ КАК Таблица");
Запрос.УстановитьПараметр("ТЗ", ТЗ);

Но с СКД не все так просто. Увы, операцию описанную выше проделать в системе компановки данных невозможно. Тем не менее возможность подгрузки внешних таблиц значений в системе реализована.

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

Детализируем задачу до некоторого примера. Имеется типовой отчет Расчетные ведомости организации конфигурации ЗиК 8. Необходимо что бы виды расчетов в отчете группировались по некоторым группам. Соответствия ВидРасчета-Группа хранятся во внешней таблице значений. Для подгрузки ее в основную схему компановки данных создаем "набор данных объект" с именем "Группы" (рисунок 2). Связь производим с "набором данных запрос" - "Начисления" по виду расчета (рисунок 3). В "наборе данных запрос" - "Начисления" значится информация по группам, удаляем все вхождения. После, на вкладке "Настройки" мы можем использовать поле "Группа", знаечние которого подгружается из внешнего источника данных (рисунок 4). В функции формирования отчета дополняем подгрузку внешних данных.

Функция СформироватьОтчет(Результат = Неопределено, ДанныеРасшифровки = Неопределено, ВыводВФормуОтчета = Истина) Экспорт

//получение или формирование искомой таблицы значений "Группы" и ее запись в одноименную переменную

ВнешниеДанные = Новый Структура();//создаем и заполняем структуру внешних данных
ВнешниеДанные.Вставить(Группы);

ЗначениеПанелипользователя = ТиповыеОтчеты.ПолучитьЗначенияНастроекПанелиПользователяОбъекта(ЭтотОбъект);
НастрокаПоУмолчанию = КомпоновщикНастроек.ПолучитьНастройки();
ТиповыеОтчеты.ПолучитьПримененуюНастройку(ЭтотОбъект);
ТиповыеОтчеты.СформироватьТиповойОтчет(ЭтотОбъект, Результат, ДанныеРасшифровки, ВыводВФормуОтчета, ВнешниеДанные);
КомпоновщикНастроек.ЗагрузитьНастройки(НастрокаПоУмолчанию);
Возврат Результат;

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

В случае, если бы мы делали отчет "с нуля", то код запуска формирования отчета выглядел бы следующим образом:

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

Прочитано 9660 раз

41
Делал недавно отчет с неопределенным количеством колонок. Возиться с кодом было неохота, решил сделать на СКД. С этим проблема не возникла, необходимо было натянуть результат на произвольный макет (свой заголовок +... 27
Несмотря на то, изучающие СКД встречаются с этим на первый или второй день, это должно быть в разделе FAQ. Простой пример программного вывода отчета на компоновке, использующий настройки по умолчанию. //Получаем схему из... 18
При формировании отчетов на СКД по умолчанию все группировки развернуты, но бывает что необходимо сразу после формирования показать отчет со свернутыми группировками! Данный код в модуле отчета позволяет свернуть... 10
На этой закладке можно указать, какие осуществляются связи между двумя и более наборами дан-ных, по каким параметрам и условиям..png 1. «Источник связи» - указывается первый набор данных, от... 9
Что при разработке отчетов требуется чтобы у пользователя с ограниченными правами, отчет формировался полностью без проверки прав! Особенно если настроен RLS Есть несколько способов как это сделать: 1. Установить...

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

Схема компоновки данных, реализованная в 1С, поддерживает три типа источника данных (Рис.1)

Источники данных

Наиболее очевидным и часто используемым разработчиками источником данных является «Запрос».

Конструктор запросов, реализованный в 8 версии 1С очень удобен, и, в большинстве случаев, связать между собой несколько таблиц, сделать необходимые группировки и отборы можно прямо в нем.

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

Третий источник данных «Объединение». Фактически, этот источник можно рассматривать как один из видов связи. Он объединяет (сводит в одну несколько таблиц), не сопоставляя, однако совпадение тех или иных полей. То есть, если в двух объединяемых таблицах 3 и 4 строки соответственно, то в результирующем источнике данных, будет 7 строк.

Постановка задачи

В качестве полигона для испытаний мы выберем базу УПП, версии 1.3.92.3, работающую в режиме обычного приложения.

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

Таким образом, мы должны:

  1. Взять табличную часть документа поступления;
  2. Загрузить файл в источник данных «Объект»;
  3. Связать эти два источника по определенному параметру (в нашем случае это будет код);
  4. Вывести результирующую таблицу.

Процесс выполнения

Пройдем все перечисленные шаги:

  • Создаем запрос к табличной части документа поступления (Рис.2)

Рис.2

  • Создаем набор данных объект (Рис.3);

Рис.3

Здесь важно обратить внимание на «Имя объекта, содержащего данные», именно это имя нам придется указать в коде модуля отчета.

  • Переходим в модуль отчета и создаем там процедуру «ПриКомпоновкеРезультата» (Рис.4);


Рис.4

Саму процедуру получения данных из внешнего файла мы описывать не будем, обратим внимание на ту часть кода, которая обязательно должна присутствовать в компоновке для того, чтобы мы могли получить данные для «Набора данных 2» (Рис.5).

Рис.5

Важно! При создании «Объекта» в коде процедуры при компоновке, значение параметра СтандартнаяОбработка должно быть Ложь.

Переходим на закладку «Связи наборов данных».

Связываем наборы

Заходим на соответствующую закладку схемы (Рис.6).

Мы видим табличную часть, которая очень похожа на табличную часть, которая есть в конструкторе запросов, за некоторым исключением. Для набора источника и набора приемника связи нельзя установить галочку «Все», зато добавлены несколько дополнительных колонок.

В связях наборов данных можно установить только связь, подобную внешнему левому соединению конструктора запроса.

Прежде, чем создать связь, давайте определимся с назначением колонок:

  1. Источник связи – первый набор данных, из которого возьмутся все имеющиеся значения;
  2. Приемник связи – набор данных, из которого выберутся значения, соответствующие нашему условию;
  3. Выражение источник – поле или выражение первого набора данных, по которому будет происходить сопоставление;
  4. Выражение приемник – поле или выражение зависимого набора;
  5. Параметр – если в этом поле указать имя параметра, то связь с набором – приемником будет осуществляться только по указанному в параметре значению;
  6. Список параметров – определяет возможность использования списка значений в качестве параметра;
  7. Условие связи – указав здесь выражение с использованием полей источника, можно создать условие, выполнение которого будет служить сигналом к установлению связи;
  8. Начальное значение – показывает начальное значение связи;
  9. Обязательная связь – определяет, задействованы ли поля, используемые в источнике (установлено ЛОЖЬ) или в приемнике (установлено ИСТИНА) и на основании этого добавляет связь в макет.

Таким образом:

  • В качестве источника связи будет выступать результат нашего запроса;
  • В качестве приемника будет выступать объект;
  • Выражение источник будет «НоменклатураКод»;
  • Выражение приемник «Номенклатура»;
  • Связь будет обязательной (Рис.7).

Если бы мы в качестве условия связи указали наименование какой-либо номенклатуры, или её вид воспроизводства или еще что-то, мы могли бы получить более точную выборку для нашей задачи. Результат наших действий можно увидеть на рис.8

Рис.8

Для двух нижних строк отчета в файле с ценами не нашлось соответствия.

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

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

Внутри этой процедуры будем собирать данные и формировать отчет.
В процедуре ПриКомпоновкеРезультата отключаем стандартную обработку. СтандартнаяОбработка = Ложь;
Затем формируем таблицу значений произвольным образом. Имена колонок таблицы значений должны совпадать с будущими полями набора данных в СКД.:


Для примера добавим три строки данных. Далее по шагам создаем вывод отчета.

  • Из схемы получаем настройки по умолчанию.

  • В соответствующую переменную отправляем данные о расшифровке.

  • Формируем макет с помощью компоновщика макета.

  • Передаём в макет компоновки схему, настройки и данные расшифровки.

  • Выполняем компоновку с помощью процессора компоновки. Для этого выполняем метод процессора компоновки данных Инициализировать(). В качестве параметров передаём макет компоновки данных, внешние наборы данных (тип: Структура, ключ структуры должен совпадать с именем объекта в схеме компоновки данных, значение - сформированная таблица значений), данные расшифровки.

  • Очищаем поле табличного документа.

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

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

Добавляем ресурсы, если это необходимо. По ним будут считаться итоги. В нашем случае это поля Количество и Сумма.

В закладке Настройки с помощью конструктора настроек формируем вариант отчета по умолчанию

Сохраняем наш отчет. Запускаем его в клиенте и формируем. Пример выполнения отчета СКД с использованием данных из таблицы значений приведен на картинке.


Вот и все. Достаточно просто, не правда ли?

Получившийся отчет для примера можно скачать

Привет!
Сегодня хочу описать тему, с которой без «акваланга» не разберешься:) ;)

Акваланг к тому, что погружение довольно глубокое. В литературе встречается мало ссылок на эту тему и пока не «приспичит» в ней не разберешься. Не возникнет даже посыла к такому действию;) Кстати, в документации об этом сказано очень плохо и непоследовательно, приходится обращаться к сторонней литературе.

К примеру, очень рекомендую «Разработка сложных отчетов в «1С:Предприятии 8.2″. Система компоновки данных», (если конкретнее, то смотрите стр. 224, 267 и 473)

В СКД существует 2 вида источников данных: Запрос, объект и объединение (эта штука не в счет, она не источник данных, а обработчик имеющихся). См рис 1:


Итак, если с источником (набором) данных типа «Запрос» нам более или менее понятно, как работать, то по поводу набора данных «Объект» есть трудности.

Для начала опишу, что мы хотим получить на выходе:

Отчет, пользователь нажал кнопку «Сформировать » и отобразился список номенклатуры (см. рис. 2):

Да, я допустил одну неточность, а именно: на снимке нет кнопки «Сформировать «, но есть кнопка «новое действе » (чуть позже объясню, почему так получилось;)

Да, да! Еще момент: весь этот список выводится из набора данных «Объект»:

Решение:

  1. Создаем внешний отчет;
  2. Добавляем макет СКД, назовем его «ОсновнаяСхемаКомпановкиДанных»;
  3. Добавляем в него набор данных «Объект», назначаем ему имя «СписокНоменклатуры» (должно быть так же, как и в рис. 3);
  4. В настройках отчета особо не экспериментируем, пусть будет все просто (см. рис. 4)

Ок, половину дела сделали;)

Теперь сгенерируем основную форму отчета (да, еще момент! Моя конфигурация работает на обычном интерфейсе, но думаю, на управляемых формах вы найдете решение;) Итак, форма:

Здесь и возникает проблема! Если нажать на кнопку «сформировать» (рис. 5.), то мы увидим ошибку!


Решению данной проблемы я и посвятил данную статью!

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

Вставлял в форме процедуру «Сформировать», но в нее нет заходов, пришлось переопределить действие кнопки «сформировать» перед открытием формы:


На рис. 8 помимо изменения действия формы приведен пример запроса, его обработки и передачи сгенерированных данных в СКД. Изучим его белее внимательно:

  1. Генерируем входные данные для СКД;
  2. Инициализируем СКД;
  3. Выводим результат НА ФОРМУ (обратите на это так же внимание!).

Вспомним схему взаимодействия объектов системы компоновки данных:

Схема компоновки данных во внешнем отчете дотупна как глобальный объект в методе формы СхемаКомпоновкиДанных. К ней так же можно обратиться по имени, передав его в метод ПолучитьМакет (см. Рис. 8)

Основной кусок кода приведен ниже:

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

Да! Вот еще приятный момент!!!

В данном примере, как видите (см. рис. 2), вывод осуществляется в форму, а не в табл. документ! И это очень хорошо, ведь мы можем работать с формой (программно перехватывать события элемента формы, делать всякие фишки с drag and drop и прочее;)

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

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

«Поле табличного документа представляет собой табличный документ, размещенный в форме. Наряду с многообразием оформительских возможностей табличного документа это позволяет организовывать обработку событий, возникающих при выборе ячеек, картинок, а также других элементов управления, размещенных в поле табличного документа.»

Ладно, как говорится, успехов в бою;)

Публикации по теме