При разработке и доработке отчетов в 1С мы часто сталкиваемся с необходимостью вывода дополнительных вычисляемых полей. Одной из распространенных задач является расчет разницы дат, например, между текущей датой и датой документа, используя функцию РАЗНОСТЬДАТ. Однако, пользователи 1С нередко сталкиваются с ситуацией, когда такие вычисляемые поля, корректно работающие в консоли запросов, остаются пустыми или вовсе не отображаются в Универсальном отчете или отчетах на Системе Компоновки Данных (СКД).
Давайте вместе разберем эту проблему, выясним ее причины и найдем эффективные способы решения. Мы проанализируем, почему универсальный отчет может игнорировать вычисляемые поля запроса и какие шаги необходимо предпринять для их корректного отображения.
Мы выясним, почему вычисляемые поля, даже если они корректно определены в запросе и работают в консоли, могут не появляться в отчете. Основные причины кроются в особенностях работы Системы Компоновки Данных (СКД), которая лежит в основе большинства универсальных отчетов 1С.
Это самая простая, но часто упускаемая причина. Даже если поле присутствует в списке доступных полей построителя отчета, мы должны явно добавить его в состав выбранных полей для отображения в отчете. Для Универсального отчета это обычно делается в его настройках на вкладках, связанных с выбором полей или структурой отчета. Мы можем забыть установить флажок напротив нового поля или не перетащить его в нужную область.
NULL.
Если какое-либо из полей, участвующих в вычислении (например, ДатаДокумента или ТекущаяДата в случае с РАЗНОСТЬДАТ), может быть неопределенным (NULL), то результат вычисляемого поля также может стать NULL. В этом случае поле будет отображаться пустым. Мы должны всегда предусматривать такую возможность и использовать функцию ЕСТЬNULL или оператор ВЫБОР КОГДА ... ЕСТЬ NULL ТОГДА ... ИНАЧЕ ... КОНЕЦ в выражении запроса или СКД, чтобы задать значение по умолчанию (например, 0 или пустую дату) для полей, которые могут быть NULL.
ВЫБОР
КОГДА Взаиморасчеты.ДокументРасчетовСКонтрагентом.Дата ЕСТЬ NULL
ТОГДА 0
ИНАЧЕ РАЗНОСТЬДАТ(Взаиморасчеты.ДокументРасчетовСКонтрагентом.Дата, &ТекущаяДата, ДЕНЬ)
КОНЕЦ КАК ДнейЗадолженности
Или используя ЕСТЬNULL:
РАЗНОСТЬДАТ(ЕСТЬNULL(Взаиморасчеты.ДокументРасчетовСКонтрагентом.Дата, ДАТАВРЕМЯ(1,1,1)), &ТекущаяДата, ДЕНЬ) КАК ДнейЗадолженности
Хотя СКД обычно достаточно гибка, мы должны проверить, правильно ли указан тип значения для вычисляемого поля (например, число, строка, дата). Неправильный тип может привести к некорректному отображению или отсутствию данных. В СКД тип поля обычно определяется автоматически, но иногда может потребоваться ручная корректировка, особенно если выражение сложное или результат может меняться.
Убедимся, что для вычисляемого поля не установлены ограничения видимости или условия оформления, которые могут его скрывать. В настройках отчета на вкладке "Условное оформление" или "Прочие настройки" мы можем обнаружить правила, которые делают поле невидимым при определенных условиях.
В некоторых случаях, при программном добавлении вычисляемого поля в универсальный отчет (особенно если мы модифицируем схему компоновки данных в коде), оно может не отображаться, пока не будет явно добавлено в предопределенную группировку строк отчета. Мы должны проверить структуру отчета и убедиться, что поле присутствует в выбранных полях и, при необходимости, в одной из группировок.
Это ключевой момент, выявленный в нашем обсуждении. Оказывается, универсальный отчет (и СКД) может игнорировать поля, которые являются простыми константами или вычисляются без прямой ссылки на поля набора данных в самом запросе. Например, конструкция | 1 КАК ТекущаяДата или | ДАТАВРЕМЯ(2022, 8, 31, 14, 47, 0) КАК ТекущаяДата в запросе может не отображаться в отчете. Но если мы берем существующее поле из регистра и просто переименовываем его (например, | Взаиморасчеты.ДокументРасчетовСКонтрагентом.Дата КАК ТекущаяДата), то оно выводится. Это указывает на то, что СКД ожидает, что вычисляемое поле будет производным от полей набора данных, а не абсолютно новым, не связанным с данными полем, добавленным напрямую в запрос.
Давайте рассмотрим последовательные шаги, которые мы можем предпринять для решения данной проблемы. Мы будем исходить из того, что запрос с функцией РАЗНОСТЬДАТ уже написан и корректно работает в консоли запросов.
Прежде всего, убедимся, что наш запрос действительно выдает ожидаемый результат в консоли запросов. Это подтвердит, что синтаксис РАЗНОСТЬДАТ и логика вычисления верны. Мы должны убедиться, что все параметры запроса, такие как &ТекущаяДата, передаются корректно и имеют правильный тип.
ВЫБРАТЬ
Взаиморасчеты.ДокументРасчетовСКонтрагентом,
Взаиморасчеты.ДокументРасчетовСКонтрагентом.Дата КАК ДатаДокумента,
РАЗНОСТЬДАТ(Взаиморасчеты.ДокументРасчетовСКонтрагентом.Дата, &ТекущаяДата, ДЕНЬ) КАК ДнейЗадолженности
ИЗ
РегистрНакопления.Взаиморасчеты КАК Взаиморасчеты
В данном примере &ТекущаяДата должен быть параметром запроса, который мы устанавливаем, например, как ТекущаяДата() или фиксированную дату.
Если наш запрос корректен, но поле не выводится, проведем эксперимент. Попробуем добавить в запрос простую константу:
ВЫБРАТЬ
Взаиморасчеты.ДокументРасчетовСКонтрагентом,
Взаиморасчеты.ДокументРасчетовСКонтрагентом.Дата КАК ДатаДокумента,
РАЗНОСТЬДАТ(Взаиморасчеты.ДокументРасчетовСКонтрагентом.Дата, &ТекущаяДата, ДЕНЬ) КАК ДнейЗадолженности,
1 КАК ТестовоеПолеКонстанта,
ДАТАВРЕМЯ(2023, 1, 1) КАК ТестоваяДатаКонстанта
ИЗ
РегистрНакопления.Взаиморасчеты КАК Взаиморасчеты
Если ТестовоеПолеКонстанта и ТестоваяДатаКонстанта также не отображаются в Универсальном отчете, но при этом поле Взаиморасчеты.ДокументРасчетовСКонтрагентом.Дата (или его алиас) отображается, то мы имеем дело с той самой особенностью СКД, когда новые, не привязанные к наборам данных поля из запроса игнорируются при выводе. В этом случае мы переходим к следующему шагу.
Наиболее надежным и правильным способом для вывода таких полей в Универсальном отчете (который использует СКД) является определение их как "Вычисляемых полей" в самой схеме компоновки данных. Мы не будем создавать их в запросе, а добавим их уже после того, как СКД получит данные из основного набора.
ДнейЗадолженности или РазницаДатДокумента.Пример выражения для поля ДнейЗадолженности:
РазностьДат(ДокументРасчетовСКонтрагентом.Дата, ТекущаяДата(), "ДЕНЬ")
Здесь ДокументРасчетовСКонтрагентом.Дата - это поле, которое мы получили из регистра накопления в нашем основном запросе. Функция ТекущаяДата() доступна в СКД для получения текущей даты и времени на сервере.
Если нам нужно добавить еще какие-либо расчеты, например, вычесть дней отсрочки, это также можно сделать здесь:
РазностьДат(ДокументРасчетовСКонтрагентом.Дата, ТекущаяДата(), "ДЕНЬ") - ДнейОтсрочки
где ДнейОтсрочки также должно быть полем, доступным в наборе данных.
После создания вычисляемого поля на закладке "Вычисляемые поля", мы должны убедиться, что оно включено в структуру отчета для отображения. Перейдем на вкладку "Поля" или "Структура" (в зависимости от версии и типа Универсального отчета) и:
ДнейЗадолженности в список выбранных полей для вывода.Без этого шага поле не будет отображено, даже если оно корректно вычисляется.
NULL в вычисляемых полях СКД.
Как мы уже обсуждали, это критически важный момент. Если поле ДокументРасчетовСКонтрагентом.Дата может быть пустым, наше вычисляемое поле также будет пустым. Мы можем модифицировать выражение следующим образом:
РазностьДат(ЕСТЬNULL(ДокументРасчетовСКонтрагентом.Дата, ДАТАВРЕМЯ(1,1,1)), ТекущаяДата(), "ДЕНЬ")
В этом случае, если ДокументРасчетовСКонтрагентом.Дата будет NULL, вместо него подставится минимальная дата, и разница будет вычислена корректно (хоть и даст очень большое число, если исходная дата была NULL). Или же мы можем использовать более сложную логику, чтобы выводить 0 или пустое значение для таких случаев:
ВЫБОР
КОГДА ДокументРасчетовСКонтрагентом.Дата ЕСТЬ NULL
ТОГДА 0
ИНАЧЕ РазностьДат(ДокументРасчетовСКонтрагентом.Дата, ТекущаяДата(), "ДЕНЬ")
КОНЕЦ
Это позволит нам контролировать вывод для строк, где дата документа отсутствует.
После добавления вычисляемого поля, мы должны проверить, что оно доступно во всех нужных местах настроек отчета (например, в полях сортировки, отбора, условного оформления). Также можем проверить его тип в списке полей СКД. Если тип определился как "Неопределенный", это может указывать на ошибку в выражении.
После любых изменений в настройках или схеме компоновки данных отчета, всегда необходимо его обновить и перезагрузить, чтобы изменения вступили в силу. В Универсальном отчете это обычно делается нажатием кнопки "Сформировать" после сохранения настроек.
Проблема с невыводом вычисляемых полей из запроса в Универсальном отчете 1С, особенно если это константы или выражения, не связанные напрямую с полями набора данных, является распространенной особенностью работы СКД. Вместо того чтобы пытаться заставить СКД отображать такие поля, определенные в тексте запроса, мы должны использовать функциональность "Вычисляемых полей" самой Системы Компоновки Данных.
Мы настоятельно рекомендуем использовать следующий подход:
РАЗНОСТЬДАТ, используя поля, полученные из запроса.NULL с помощью ЕСТЬNULL или ВЫБОР КОГДА.Такой подход обеспечит корректное и надежное отображение всех необходимых вычисляемых данных в Универсальном отчете, делая его более гибким и информативным для пользователей.