Каждый разработчик 1С рано или поздно сталкивается с мистической ситуацией: вы добавляете новое поле в запрос отчета схемы компоновки данных (СКД), проверяете запрос в консоли — всё работает идеально, данные выводятся. Но стоит открыть отчет в режиме «1С:Предприятие», как поле бесследно исчезает. Его нет ни в доступных полях, ни в настройках компоновщика, ни в самом отчете. При этом у пользователя могут быть полные права, а тип данных поля — самый простой (например, ссылка на справочник).
В этой статье мы подробно разберем, почему СКД ведет себя подобным образом, как на доступность полей влияют внутренние механизмы платформы «1С:Предприятие 8.3» и какими способами можно решить эту проблему.
Прежде чем перейти к методам решения, давайте проанализируем, почему возникает расхождение между консолью и СКД. Это поможет понять логику работы платформы и избежать подобных ошибок в будущем.
Консоль запросов выполняет «сырой» запрос к СУБД напрямую. Она проверяет только базовые права текущего пользователя на чтение физических таблиц (и то не всегда, если консоль запущена в привилегированном режиме). Консоль полностью игнорирует интерфейсные настройки прикладного решения.
Система компоновки данных (СКД) — это высокоуровневый декларативный механизм, который глубоко интегрирован со всей метаструктурой конфигурации. Перед тем как сгенерировать и выполнить финальный SQL-запрос, компоновщик СКД анализирует множество параметров:
Если хотя бы одна проверка не проходит (например, реквизит привязан к отключенной функциональной опции или у пользователя нет прав на чтение связанного объекта), СКД автоматически, без предупреждений и ошибок исключает это поле из выборки, списка доступных полей и настроек группировок.
Это наиболее частая причина «исчезновения» реквизитов. В типовых конфигурациях 1С (таких как «Документооборот», «Управление торговлей», «ERP Управление предприятием», «Комплексная автоматизация») практически все ключевые разрезы учета привязаны к константам и функциональным опциям.
Рассмотрим, какие именно опции могут блокировать вывод контрагентов в различных конфигурациях:
Контрагент во всех документах (включая справочник ВнутренниеДокументы).ИспользоватьПартнеровИКонтрагентов (связанная с одноименной константой). При её отключении СКД блокирует любые прямые пути к полям контрагентов в документах.Как проверить и исправить в Конфигураторе:
ВнутренниеДокументы -> реквизит Контрагент).Иногда возникают ситуации, когда включить функциональную опцию в режиме предприятия невозможно (например, учет контрагентов действительно не требуется вести штатным образом, но для конкретного кастомного отчета эти данные необходимы). В этом случае можно прибегнуть к программному обходу ограничений СКД.
Выясним, почему у автора темы на форуме сработал вариант с временной таблицей. В типовых решениях функциональная опция обычно отключает не весь справочник Контрагенты целиком, а только конкретный реквизит Контрагент внутри документов. Когда СКД видит прямое обращение вида Док.Контрагент, она сверяет его с ФО и вырезает. Но если мы выберем данные напрямую из справочника во временную таблицу, СКД не увидит явной связи реквизита документа и ФО.
Рассмотрим пример запроса, который позволяет обойти ограничение:
ВЫБРАТЬ
Спр.Ссылка КАК КонтрагентСсылка
ПОМЕСТИТЬ ВТ_Контрагенты
ИЗ
Справочник.Контрагенты КАК Спр;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Док.Ссылка КАК Документ,
ЕСТЬNULL(ВТ.КонтрагентСсылка, ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)) КАК Контрагент
ИЗ
Справочник.ВнутренниеДокументы КАК Док
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Контрагенты КАК ВТ
ПО Док.Контрагент = ВТ.КонтрагентСсылка
При таком подходе СКД считает поле КонтрагентСсылка доступным, так как оно получено из независимой временной таблицы справочника, который сам по себе не заблокирован функциональной опцией. Соединение в секции ПО отрабатывает на уровне СУБД, и поле успешно выводится в отчет.
Если функциональные опции ни при чем, обязательно проверьте внутренние настройки схемы компоновки данных. Возможно, ограничение наложили вы сами или предыдущий разработчик.
Разобьем проверку по шагам:
Еще одна частая причина невидимости полей в СКД связана со спецификой работы прав доступа на уровне записей (RLS) при использовании составных типов данных.
Представим сценарий: вы строите отчет по регистру накопления (например, Продажи) и хотите вывести поле организации через регистратор: Регистратор.Организация. Поле Регистратор имеет составной тип данных, включающий десятки видов документов.
Если у текущего пользователя нет прав (даже по RLS) на чтение хотя бы одного из видов документов, входящих в состав типа Регистратор, то платформа 1С превентивно заблокирует вывод поля Регистратор.Организация для всей таблицы регистра. СКД просто исключит его из списка доступных.
Как решить эту проблему:
Необходимо явно ограничить тип данных в запросе с помощью конструкции ВЫРАЗИТЬ. Распишем пример запроса:
ВЫБРАТЬ
ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РеализацияТоваровУслуг).Организация КАК ОрганизацияРеализации,
Продажи.СуммаОборот КАК Сумма
ИЗ
РегистрНакопления.Продажи.Обороты КАК Продажи
Используя явное приведение типов, мы указываем СКД, что работаем только с конкретным типом документа, на который у пользователя точно есть права. В этом случае поле гарантированно появится в списке доступных полей компоновщика.
Если вы проделали все вышеописанные шаги, добавили поле в конфигураторе, проверили права и функциональные опции, но в режиме «1С:Предприятие» под вашим пользователем поля по-прежнему нет — дело может быть в банальном кэшировании настроек.
Платформа 1С сохраняет пользовательские настройки отчетов (расположение колонок, выбранные поля, группировки) в системных хранилищах. Если вы ранее уже открывали этот отчет, система при повторном открытии пытается применить старые настройки поверх новой схемы. В результате новые поля просто не отображаются в активном варианте.
Как сбросить кэш настроек:
Если вы выводите отчет не через стандартную общую форму, а формируете его полностью программно (например, во внешней обработке или в модуле объекта отчета), вы можете явно управлять механизмом проверки прав и функциональных опций.
При инициализации компоновщика макета компоновки за это отвечает параметр ПроверятьДоступностьПолей метода Выполнить. Если передать туда значение Ложь, СКД проигнорирует отключенные функциональные опции и выведет все поля, которые физически присутствуют в таблицах базы данных.
Посмотрим на пример программной инициализации схемы:
// Создаем объекты компоновки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
// Передаем Ложь в шестой параметр метода "Выполнить", чтобы отключить проверку доступности полей
МакетКомпоновки = КомпоновщикМакета.Выполнить(
СхемаКомпоновкиДанных,
КомпоновщикНастроек.ПолучитьНастройки(),
ДанныеРасшифровки,
,
,
Ложь
);
// Далее выполняем стандартный запуск процессора компоновки
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);
Использование этого параметра позволяет гибко управлять поведением СКД в нестандартных задачах автоматизации, когда системные ограничения прав или функциональных опций мешают формированию консолидированной технической отчетности.
Если в вашем отчете СКД пропало поле, действуйте по следующему алгоритму:
ВЫРАЗИТЬ).