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