Вычисляемое поле в скд 1с 8.2. Функции языка выражений системы компоновки данных. Создаём новый отчёт

Доброго времени суток, уважаемые читатели нашего блога! Сегодня я хочу рассказать, на реальном примере, как
использовать функции СКД Массив (Array) и СоединитьСтроки (JoinStrings) . В статье об

немного упоминалось, как работать с
на закладке
, также уже объяснялось как
, используя закладку «Ресурсы». Сегодня мы ещё раз обратим внимание на эти
закладки в свете нашей темы.

Внешний вид примера отчета 1С с использованием двух функций СКД Массив и СоединитьСтроки следующий:

Постановка задачи для применения функций СКД Массив (Array) и СоединитьСтроки (JoinStrings)

Задача: Нужно все номера реализаций по одному товару вставить в одну ячейку.

Что-то вроде: номенклатура | кол-во | 001, 002, и т.д. |

Будем использовать запрос к регистру накопления «РеализацияТМЗ».

ВЫБРАТЬ
РеализацияТМЗ. Регистратор. Номер,
РеализацияТМЗ. Номенклатура,
РеализацияТМЗ. Регистратор,
РеализацияТМЗ. КоличествоОборот
ИЗ
РегистрНакопления. РеализацияТМЗ. Обороты
(, , Регистратор, ) КАК РеализацияТМЗ

Регистру накопления «РеализацияТМЗ» существует как в конфигурации Бухгалтерия, так и в конфигурации Управление торговым предприятием (УТП). Узнайте, как в конфигурации УТП в элементе справочника «Номенклатура». Поэтому, после скачивания, для проверки его работоспособности вы можете запускать этот отчёт в обеих конфигурациях.

Реализация поставленной задачи с применением функций СКД Массив и СоединитьСтроки


Такие же шаги, но с некоторыми дополнениями, были использованы при созданиии
.

Описание функции СоединитьСтроки (JoinStrings)

СоединитьСтроки (JoinStrings)

Используется для объединения строк в одну строку.

Синтаксис:

СоединитьСтроки (Значение, РазделительЭлементов, РазделителиКолонок)

Параметры:

  1. Значение — выражения, которые нужно объединить в одну строку.
    Если является Массивом, то в строку будут объединяться элементы массива.
    Если является ТаблицаЗначений, то в строку будут объединяться все колонки и строки таблицы;
  2. РазделительЭлементов — строка, содержащая текст, который нужно использовать в качестве
    разделителя между элементами массива и строками таблицы значений. По умолчанию – символ перевода строк;
  3. РазделителиКолонок -строка, содержащая текст, который нужно использовать в качестве разделителя
    между колонками таблицы значений. По умолчанию «;».

В данной небольшой заметке хочу показать, как можно произвести суммирование значений на различных уровнях группировки, в отчете с использованием системы компоновки данными.
Как показано на изображении, только на уровне группировки «Группы номенклатуры», рассчитывается ресурс «Заказать», в нем отображается, сколько нужно заказать по текущей группе номенклатуры исходя из определенных условий:


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

Соответственно, теперь необходимо рассчитать итоги, по выше находящимся группировкам («Склады», «ТипыСкладов») и общий итог.
Для этого используется функция ВычислитьВыражениеСГруппировкойМассив:
ВЫЧИСЛИТЬВЫРАЖЕНИЕСГРУППИРОВКОЙМАССИВ (EVALEXPRESSIONWITHGROUPARRAY)
Синтаксис:
ВычислитьВыражениеСГруппировкойМассив(,)
Описание:
Функция возвращает массив, каждый элемент которого содержит результат вычисления выражения для группировки по указанному полю.
Компоновщик макета при генерации макета преобразовывает параметры функции в термины полей макета компоновки данных. Например, поле Контрагент будет преобразовано в НаборДанных.Контрагент.
Компоновщик макета при генерации выражений для вывода пользовательского поля, в выражении которого присутствует только функцияВычислитьМассивСГруппировкойМассив(), генерирует выводимое выражение таким образом, чтобы выводимая информация была упорядочена. Например, для пользовательского поля с выражением:

ВычислитьВыражениеСГруппировкойМассив("Сумма(СуммаОборот)", "Контрагент")
Компоновщик макета сгенерирует для вывода следующее выражение:

СоединитьСтроки(Массив(Упорядочить(ВычислитьВыражениеСГруппировкойТаблицаЗначений("Представление(Сумма(НаборДанных.СуммаОборот)),Сумма(НаборДанных.СуммаОборот)","НаборДанных.Контрагент"),"2")))

Параметры:

Тип: Строка. Выражение, которое нужно вычислить. Строка, например, Сумма(СуммаОборот).

Тип: Строка. Выражения полей группировки – выражения полей группировки, перечисленные через запятую. Например, Контрагент, Партия.

Тип: Строка. Выражение, описывающее отбор, применяемый к детальным записям. В выражении не поддерживается использование агрегатных функций. Например,ПометкаУдаления = Ложь.

Тип: Строка. Выражение, описывающее отбор, применяемый к групповым записям. Например, Сумма(СуммаОборот) > &Параметр1.
Пример:

Максимум(ВычислитьВыражениеСГруппировкойМассив ("Сумма(СуммаОборот)", "Контрагент"));

Подробное описание синтаксиса функции можно найти по адресу http://its.1c.ru/db/v837doc#bookmark:dev:TI000000582
Теперь для расчета, продублируем поле «Заказать», с различными значениями «Рассчитывать по…», используя следующие выражения, обратите внимание, что в каждом выше стоящем уровне используются значения уровней ниже стоящих группировок.

В итоге получаем следующую конструкцию:

Грамотное использование схемы компоновки данных (СКД) позволяет:

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

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

Что такое вычисляемое поле

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

Дело в том, что СКД – это нечто большее, нежели просто отображение результата выполнения запроса и это прекрасно видно из формы создания схемы (Рис.1).

Вычисляемые поля позволяют выполнять определенные действия со сформированным набором данных:

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

Давайте по этому списку и пойдем.

Массив значений в одной ячейке

Смоделируем ситуацию, когда необходимо получить в отдельную ячейку все номера документов поступления по контрагенту:


таким образом, мы в нашей схеме создали дополнительное расчетное поле;


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

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

  1. РазделительЭлементов – указывает, какой символ будет отделять один элемент массива или одну строку таблицы значений от другого (в нашем случае мы опустили этот параметр и по умолчанию был назначен перенос строки);
  2. РазделительКолонок – символ, используемый для разделения колонок таблицы значений (по умолчанию используется точка с запятой).

Обращение к экспортным функциям общего модуля

В качестве источника данных для заполнения вычисляемого поля могут выступать функции общего модуля.

Несколько важных моментов:

  • Функция обязательно должна быть экспортной;
  • Если функция расположена в общем модуле с установленным признаком «Глобальный», её вызов осуществляется непосредственно по имени, в противном случае вызов функции должен происходить по схеме «Имя общего модуля». «Имя вызываемой функции».

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


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

Выражения языка компоновки

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

  1. Рассчитать среднюю стоимость номенклатуры;
  2. Всевозможные проценты;
  3. Расчеты среднего заработка и т.д.

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

Сделать это можно с помощью конструкции «Выбор Когда ….Тогда… Иначе… Конец».

В конце несколько слов о достаточно новой функции ВычислитьВыражение(). С её помощью, в частности можно вычислять отклонения в стоимости между текущей и предыдущей строкой, накопительный остаток и т.д.

Допустим, получить СуммуДокумента из предыдущей строки нашего запроса можно указав в поле «Выражение» значение ВычислитьВыражение(«СуммаДокумента», «ПредыдущаяСумма»).

У данного способа, как мне кажется, есть минус, но он работает, но минус большой. Рассмотрим на примере: имеется в конфигурации документ "Поступление товара" с табличной частью "Товары", необходимо вывести в отчет документы и наименования поступившего товара для каждого документа.

Создадим отчет, добавим основную схему компоновки данных, в СКД добавим набор данных типа "запрос" и сформируем простенький запрос (см. рисунок 1).

Рисунок 1. Запрос набора данных
На вкладке "Вычисляемые поля" добавим вычисляемое поле под названием ТабличнаяЧасть и в колонке Выражение укажем пустую строку (см. рисунок 2).
Наше вычисляемое поле будет использоваться как ресурс, поэтому на вкладке "Ресурсы" задаем выражение группировки: СоединитьСтроки(Массив(Товары.Номенклатура),""). А так же указываем, что рассчитывать данный ресурс нужно по полю Ссылка (см. рисунок 3).
Результат работы отчета:
О минусе - это использование группировки, в нашем случае выполняется группировка по реквизиту Ссылка, иначе работать не будет. Наличие группировки накладывает некоторые ограничения по настройке вывода данных (см. рисунок 4).

2) Вызов собственной функции из общего модуля.

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

Создадим отчет, добавим основную схему компоновки данных, в СКД добавим набор данных типа "запрос" и сформируем простенький запрос (см. рисунок 6).


Рисунок 6. Запрос набора данных
Создадим общий модуль _ДемоРаботаСОтчетами и напишем экспортную функцию ПолучитьПереченьТоваровДляОтчета(). Программный код функции смотри ниже.
На вкладке "Вычисляемые поля" добавим вычисляемое поле под названием ТабличнаяЧасть и в колонке Выражение укажем вызов функции из общего модуля (см. рисунок 2):
_ДемоРаботаСОтчетами.ПолучитьПереченьТоваровДляОтчета(Ссылка)

Перейдем на вкладку "Настройки" и создадим настройку по выводу данных - это будет детальная запись (см. рисунок 8).
Результат работы отчета:

Скачать пример отчета

Что нужно знать при использовании данного способа:
1) Выражение механизма компоновки данных может содержать вызовы функций глобальных общих модулей конфигурации. Например:
СокращенноеНаименование(Ссылка, Дата, Номер)
2) При программном формировании отчета использование функций общих модулей разрешено только при указании соответствующего параметра процессора компоновки данных (4-ый параметр):
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ДанныеРасшифровки, Истина);
3) Функции общих модулей не могут быть использованы в выражениях пользовательских полей.
4) Если при формировании отчета вызывается исключение с указанием на функцию общего модуля, проверьте контекст выполнения модуля (см. рисунок 9).

Описание использованных функций

СоединитьСтроки (Значение, РазделительЭлементов, РазделителиКолонок) - предназначена для объединения строк в одну строку.
  • Значение - выражения, которые нужно объединить в одну строку. Если является Массивом, то в строку будут объединяться элементы массива. Если является ТаблицаЗначений, то в строку будут объединяться все колонки и строки таблицы;
  • РазделительЭлементов - строка, содержащая текст, который нужно использовать в качестве разделителя между элементами массива и строками таблицы значений. По умолчанию – символ перевода строк;
  • РазделителиКолонок -строка, содержащая текст, который нужно использовать в качестве разделителя между колонками таблицы значений. По умолчанию "; ".
Массив([Различные] Выражение) - в качестве параметра можно использовать таблицу значений. При этом результатом работы функции будет массив, содержащий значения первой колонки таблицы значений, переданной в качестве параметра. Если выражение содержит функцию Массив, то считается, что данное выражение является агрегатным. Если указано ключевое слово Различные, то получаемый массив не будет содержать дублирующихся значений.

ПолучитьПереченьТоваровДляОтчета(ДокументСсылка) - функция формирует строку с перечнем поступившего товара.
// Параметры:
// ДокументСсылка - ДокументСсылка.ПоступлениеТовара - Документ "Поступление товара".
// Возвращаемое значение:
// Строка - строка с перечнем товаров.
Функция ПолучитьПереченьТоваровДляОтчета(ДокументСсылка) Экспорт

ПереченьТоваров = "";

Для Каждого СтрокаТЧ Из ДокументСсылка.Товары Цикл
ПереченьТоваров = ПереченьТоваров + СтрокаТЧ.Номенклатура;
ПереченьТоваров = ПереченьТоваров + Символы.ПС;
КонецЦикла;

Возврат ПереченьТоваров;

КонецФункции // ПолучитьПереченьТоваровДляОтчета()