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