При разработке отчетов в системе компоновки данных (СКД) часто возникает необходимость не просто вывести данные из регистров, но и произвести их дополнительную обработку, например, пересчитать суммы в другую валюту на дату совершения операции. В типовых конфигурациях, таких как 1С:Управление торговлей 11.3, для этого часто используются функции общих модулей. Однако основной сложностью становится передача корректной даты документа в параметры этой функции, особенно когда поле Регистратор имеет составной тип данных. Рассмотрим подробно, как решить эту задачу несколькими способами.
Самый простой и производительный способ получить дату документа в отчете по регистру накопления — это использование стандартного поля Период. В большинстве виртуальных таблиц (Обороты, ОстаткиИОбороты), если в настройках запроса или параметрах виртуальной таблицы указана периодичность Регистратор, поле Период автоматически принимает значение даты и времени документа, сформировавшего движение.
Проанализируем преимущества этого метода:
Период является индексированным. Обращение к нему происходит быстрее, чем обращение к реквизитам через точку.ПоступлениеТоваровУслуг или СписаниеБезналичныхДенежныхСредств), так как дата операции уже выведена в отдельное поле.В вычисляемом поле СКД выражение для пересчета будет выглядеть следующим образом:
РаботаСКурсамиВалют.ПересчитатьВВалюту(Сумма, ВалютаИсточник, ВалютаРезультат, Период)
Если по каким-то причинам поле Период использовать неудобно (например, используется сложный запрос с объединениями), мы можем явно получить дату документа в тексте запроса. Многие начинающие разработчики совершают ошибку, пытаясь перебрать все возможные типы документов через конструкцию ВЫБОР КОГДА. На самом деле, платформа 1С поддерживает полиморфизм для стандартных реквизитов.
Рассмотрим, как правильно прописать выбор даты в конструкторе запроса СКД:
ВЫБРАТЬ
ТаблицаРасчетов.Регистратор КАК Регистратор,
ТаблицаРасчетов.Регистратор.Дата КАК ДатаДокумента,
ТаблицаРасчетов.СуммаУвеличение КАК ДолгУвеличение,
ТаблицаРасчетов.Валюта КАК ВалютаВзаиморасчетов
ИЗ
РегистрНакопления.РасчетыСПоставщиками.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Авто, , ) КАК ТаблицаРасчетов
Важный нюанс: Несмотря на то что Регистратор — это составной тип, конструкция Регистратор.Дата обратится к полю Дата любого документа, входящего в этот тип. Чтобы гарантировать корректную передачу типа данных в функцию, рекомендуется использовать типизацию:
ВЫРАЗИТЬ(ТаблицаРасчетов.Регистратор.Дата КАК ДАТА) КАК ДатаДокумента
Теперь в закладке «Вычисляемые поля» вы сможете обращаться к полю ДатаДокумента по его псевдониму.
Иногда возникают ситуации, когда СКД отказывается принимать Регистратор.Дата напрямую в параметрах функции из-за особенностей компоновки. В этом случае можно воспользоваться методами преобразования данных. Один из "хитрых", хотя и менее эффективных способов, который был упомянут в обсуждении, — это получение даты из строкового представления или использование серверных функций для извлечения реквизитов.
Пример использования функции из типового модуля УТ 11:
РаботаСКурсамиВалют.ПересчитатьВВалюту(
ДолгУвеличение,
ВалютаВзаиморасчетов,
ДоходыИРасходыСервер.ПолучитьВалютуУправленческогоУчета(),
ДенежныеСредстваКлиентСервер.ПолучитьДатуИзСтроки(Регистратор.Дата)
)
Выясним причину, почему этот способ работает: функция ПолучитьДатуИзСтроки принудительно преобразует представление ссылки в формат даты, понятный для 4-го параметра функции пересчета. Однако мы не рекомендуем использовать этот метод в высоконагруженных отчетах, так как строковые операции сильно замедляют расчет каждой строки.
Проанализируем ситуацию с точки зрения производительности. Когда вы используете функцию ПересчитатьВВалюту в вычисляемых полях, 1С выполняет следующий алгоритм:
ПересчитатьВВалюту происходит обращение к регистру сведений КурсыВалют.Если в вашем отчете 5 000 строк, система сделает 5 000 дополнительных запросов к регистру курсов валют. Это классическая проблема производительности. Чтобы ее избежать, лучше всего:
КурсыВалют).Валюта и ДатаДокумента (или Период).Сумма * Курс / Кратность прямо в выражении поля СКД или в основном запросе.Для реализации корректного отчета «Расчеты с поставщиками» с пересчетом валют выполните следующие шаги:
Регистратор и для него включена роль «Период» или «Обязательное».Период.СуммаВВалютеУпр).Период в качестве даты.Использование Регистратор.Дата через псевдоним в запросе является наиболее сбалансированным решением, сочетающим простоту реализации и корректность получения данных в 1С:Предприятие 8.3.