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