Как в СКД создать пользовательское поле с отбором по регистратору и почему возникает ошибка «Поле не найдено»

Программист 1С v8.3 (Управляемые формы) Управленческий учет
← На главную

При работе с типовыми отчетами в 1С:Зарплата и управление персоналом 3.1, такими как «Свод начислений, удержаний и выплат», пользователи часто сталкиваются с необходимостью вывода дополнительных данных, которых нет в стандартном наборе колонок. Одной из самых частых задач является вывод наименования банка из документов выплаты (ведомостей). Однако попытка решить эту задачу «в лоб» через создание пользовательского поля в режиме «1С:Предприятие» часто приводит к ошибке «Поле не найдено: Регистратор.Банк» или синтаксическим ошибкам парсера СКД.

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

Разбор проблемы: почему прямое обращение к Регистратору не работает

Рассмотрим ситуацию, с которой столкнулся автор темы. В отчете «Свод по зарплате» поле Регистратор имеет составной тип данных. Это означает, что регистратором может выступать любой документ, делающий движения по регистрам накопления, связанным с зарплатой: «Начисление зарплаты», «Отпуск», «Больничный лист», а также «Ведомость в банк» или «Ведомость перечислением».

Автор пытается использовать следующую конструкцию в пользовательском поле:


Выбор 
    Когда ТипЗначения(Регистратор) = Тип("Документ.ВедомостьНаВыплатуЗарплатыВБанк") 
        Тогда [Регистратор.ЗарплатныйПроект.Банк] 
    Когда ТипЗначения(Регистратор) = Тип("Документ.ВедомостьНаВыплатуЗарплатыПеречислением") 
        Тогда [Регистратор.Банк] 
    Иначе Значение(Справочник.КлассификаторБанков.ПустаяСсылка) 
Конец

Проблема заключается в механизме работы Системы компоновки данных. Когда вы пишете Регистратор.Банк, СКД пытается проверить наличие реквизита Банк у каждого возможного типа документа, который входит в состав поля Регистратор. Поскольку у документов «Начисление зарплаты» или «Материальная помощь» нет реквизита Банк, система выдает ошибку еще на этапе проверки схемы, не доходя до выполнения условия Когда ТипЗначения....

Кроме того, в пользовательских полях (которые добавляются в режиме «1С:Предприятие») действуют жесткие ограничения:

Способ 1: Использование дерева доступных полей (Без программирования)

Прежде чем приступать к написанию формул, проанализируем настройки самого отчета. В 1С:ЗУП 3.1 многие поля уже доступны «через точку», но они скрыты глубоко в иерархии. Выясним, можно ли вытащить банк без создания нового поля:

  1. Зайдите в настройки отчета и переключитесь в Расширенный режим.
  2. Перейдите на вкладку Поля и сортировки.
  3. Нажмите кнопку Добавить.
  4. В списке доступных полей найдите Регистратор. Нажмите на «плюсик» рядом с ним.
  5. В развернувшемся списке вы увидите перечисление всех типов документов. Найдите Ведомость на выплату зарплаты в банк и раскройте её.
  6. Внутри вы найдете Зарплатный проект, а внутри него — Банк.

Важное ограничение: Если в конфигураторе разработчик типового отчета наложил ограничение на типы поля Регистратор в наборе данных, нужные документы могут не отобразиться. В этом случае данный способ не сработает.

Способ 2: Использование расширения и вычисляемых полей

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

Разберем алгоритм реализации:

  1. Создайте новое расширение конфигурации (или используйте существующее).
  2. Добавьте в расширение схему компоновки данных нужного отчета (например, ПФ_MXL_СводНачисленийЗаплат).
  3. Перейдите на закладку Вычисляемые поля.
  4. Добавьте новое поле с заголовком «Банк».
  5. В колонке «Выражение» напишите код, используя оператор ВЫРАЗИТЬ. Это позволит системе однозначно понять, к какому типу документа мы обращаемся:

Выбор 
    Когда ТипЗначения(Регистратор) = Тип("Документ.ВедомостьНаВыплатуЗарплатыВБанк") 
        Тогда ВЫРАЗИТЬ(Регистратор, Документ.ВедомостьНаВыплатуЗарплатыВБанк).ЗарплатныйПроект.Банк
    Когда ТипЗначения(Регистратор) = Тип("Документ.ВедомостьНаВыплатуЗарплатыПеречислением") 
        Тогда ВЫРАЗИТЬ(Регистратор, Документ.ВедомостьНаВыплатуЗарплатыПеречислением).Банк
    Иначе NULL 
Конец

Именно использование ВЫРАЗИТЬ(Регистратор КАК Документ...) снимает проблему «Поле не найдено», так как мы явно указываем системе, что в данном ветвлении условия Регистратор следует рассматривать как конкретный объект, у которого точно есть искомый реквизит.

Способ 3: Обход через левое соединение в запросе

Если вы редактируете сам запрос (в конфигураторе или через расширение), рассмотрим более производительный метод. Обращение «через точку» от регистратора в запросе создает неявные левые соединения ко всем таблицам, входящим в состав типа. Это может замедлить отчет.

Проанализируем ситуацию: нам нужно получить данные только из двух видов ведомостей. Мы можем добавить в основной запрос Левое соединение:


ЛЕВОЕ СОЕДИНЕНИЕ Документ.ВедомостьНаВыплатуЗарплатыВБанк КАК ВедомостьБанк
    ПО Истина.Регистратор = ВедомостьБанк.Ссылка
ЛЕВОЕ СОЕДИНЕНИЕ Документ.ВедомостьНаВыплатуЗарплатыПеречислением КАК ВедомостьПеречисление
    ПО Истина.Регистратор = ВедомостьПеречисление.Ссылка

После этого в поле выбора (SELECT) мы можем написать:


ЕСТЬNULL(ВедомостьБанк.ЗарплатныйПроект.Банк, ЕСТЬNULL(ВедомостьПеречисление.Банк, ЗНАЧЕНИЕ(Справочник.КлассификаторБанков.ПустаяСсылка))) КАК ПолеБанк

Этот метод считается «золотым стандартом» разработки на 1С, так как он наиболее прозрачен для СУБД и исключает ошибки типизации в компоновке.

Особенности реквизитов в ЗУП 3.1

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

Совет: Всегда проверяйте структуру реквизитов в конфигураторе перед написанием формул в СКД. Если вы ошибетесь в имени реквизита (например, напишете Банк вместо ЗарплатныйПроект.Банк), вы получите ту же самую ошибку «Поле не найдено», которая будет сбивать с толку.

Резюме

Подведем итоги нашего анализа:

  1. Пользовательские поля в режиме предприятия крайне ограничены. Они не понимают оператор ВЫРАЗИТЬ и не умеют работать с составными типами регистратора, если реквизит отсутствует хотя бы в одном документе-регистраторе.
  2. Для простого вывода данных сначала попробуйте найти нужные поля, раскрывая дерево регистратора в настройках отчета.
  3. Если это не помогает, используйте Вычисляемые поля в расширении конфигурации с обязательным использованием функции ВЫРАЗИТЬ.
  4. Для обеспечения максимальной производительности используйте левые соединения в тексте запроса набора данных.

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

← На главную