← Назад к вопросам
Выбор работающих сотрудников на дату
2.0 Middle🔥 181 комментариев
#Запросы и оптимизация
Условие
Напишите запрос для выбора сотрудников, которые работали в организации на определённую дату.
Дано:
- Справочник "Сотрудники"
- Регистр сведений "КадроваяИстория" (периодический) с измерением "Сотрудник" и ресурсом "Состояние" (Работает/Уволен)
Требования
- Получить срез последних записей на указанную дату
- Отфильтровать только записи со статусом "Работает"
Параметр запроса
- &ДатаОтчёта — дата, на которую нужно получить список работающих сотрудников
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Выбор работающих сотрудников на дату
Решение с СРЕЗОМ ПОСЛЕДНИХ
Функция ПолучитьСотрудниковНаДату(ДатаОтчёта, Организация = Неопределено)
Запрос = Новый Запрос();
Запрос.Текст =
"ВЫБРАТЬ
| КадроваяИстория.Сотрудник,
| КадроваяИстория.Состояние
|ИЗ РегистрСведений.КадроваяИстория.СрезПоследних(&ДатаОтчёта, ) КАК КадроваяИстория
|ГДЕ КадроваяИстория.Состояние = ЗНАЧЕНИЕ(Перечисления.СостояниеСотрудника.Работает)";
Запрос.УстановитьПараметр("ДатаОтчёта", ДатаОтчёта);
Результат = Запрос.Выполнить();
Возврат Результат.Выгрузить();
КонецФункции
Объяснение:
СрезПоследних()— встроенная функция 1С, которая берёт последнюю запись по каждому сотруднику на указанную дату- Параметры: дата, фильтры (пусто = без фильтров)
- Фильтруем по состоянию "Работает"
- Результат — все сотрудники, работавшие на эту дату
Более сложный вариант с условиями
Функция ПолучитьСотрудниковСУсловиями(ДатаОтчёта, Организация, Подразделение = Неопределено)
Запрос = Новый Запрос();
Запрос.Текст =
"ВЫБРАТЬ
| КадроваяИстория.Сотрудник,
| Сотрудники.Наименование,
| Сотрудники.Подразделение,
| Сотрудники.Должность,
| КадроваяИстория.Состояние
|ИЗ РегистрСведений.КадроваяИстория.СрезПоследних(&ДатаОтчёта, ) КАК КадроваяИстория
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Сотрудники КАК Сотрудники
| ПО КадроваяИстория.Сотрудник = Сотрудники.Ссылка
|ГДЕ КадроваяИстория.Состояние = ЗНАЧЕНИЕ(Перечисления.СостояниеСотрудника.Работает)
| И Сотрудники.Организация = &Организация";
Если ЗначениеЗаполнено(Подразделение) Тогда
Запрос.Текст = Запрос.Текст + " И Сотрудники.Подразделение = &Подразделение";
КонецЕсли;
Запрос.УстановитьПараметр("ДатаОтчёта", ДатаОтчёта);
Запрос.УстановитьПараметр("Организация", Организация);
Если ЗначениеЗаполнено(Подразделение) Тогда
Запрос.УстановитьПараметр("Подразделение", Подразделение);
КонецЕсли;
Результат = Запрос.Выполнить();
Возврат Результат.Выгрузить();
КонецФункции
Особенности:
ВНУТРЕННЕЕ СОЕДИНЕНИЕ— берёт только сотрудников, которые есть в справочнике и в истории- Дополнительные фильтры по организации и подразделению
- Возвращает полную информацию о сотруднике
Вариант с диапазоном дат
Если нужны сотрудники, работавшие на начало периода:
Функция ПолучитьСотрудниковНаПериод(НачалоПериода, КонецПериода)
Запрос = Новый Запрос();
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| КадроваяИстория.Сотрудник
|ИЗ РегистрСведений.КадроваяИстория КАК КадроваяИстория
|ГДЕ КадроваяИстория.Период >= &НачалоПериода
| И КадроваяИстория.Период <= &КонецПериода
| И КадроваяИстория.Состояние = ЗНАЧЕНИЕ(Перечисления.СостояниеСотрудника.Работает)";
Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
Результат = Запрос.Выполнить();
Возврат Результат.Выгрузить();
КонецФункции
Альтернатива с проверкой дат найма и увольнения
Если информация хранится в самом справочнике (ДатаПриема, ДатаУвольнения):
Функция ПолучитьСотрудниковПроверкойДатДиректно(ДатаОтчёта)
Запрос = Новый Запрос();
Запрос.Текст =
"ВЫБРАТЬ
| Сотрудники.Ссылка,
| Сотрудники.Наименование,
| Сотрудники.ДатаПриема,
| Сотрудники.ДатаУвольнения
|ИЗ Справочник.Сотрудники КАК Сотрудники
|ГДЕ Сотрудники.ДатаПриема <= &ДатаОтчёта
| И (Сотрудники.ДатаУвольнения = '00010101' ИЛИ Сотрудники.ДатаУвольнения > &ДатаОтчёта)";
Запрос.УстановитьПараметр("ДатаОтчёта", ДатаОтчёта);
Результат = Запрос.Выполнить();
Возврат Результат.Выгрузить();
КонецФункции
Объяснение:
ДатаПриема <= ДатаОтчёта— сотрудник уже приняёт на дату отчётаДатаУвольнения = '00010101'— не был уволен (пустая дата в 1С = 1 января 0001 года)ДатаУвольнения > ДатаОтчёта— был уволен ПОСЛЕ даты отчёта
Проверка в 1С:ЗУП (реальный пример)
Функция ПолучитьСписокСотрудников(ДатаОтчёта) Экспорт
Запрос = Новый Запрос();
Запрос.Текст =
"ВЫБРАТЬ
| СоседокПоследних.Сотрудник,
| Справочник.Сотрудники.Наименование,
| Справочник.Сотрудники.ЛичныйНомер,
| СоседокПоследних.СтатусЗанятости
|ИЗ РегистрСведений.СотрудникиОрганизаций.СрезПоследних(&ДатаОтчёта, ) КАК СоседокПоследних
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Сотрудники КАК Справочник.Сотрудники
| ПО СоседокПоследних.Сотрудник = Справочник.Сотрудники.Ссылка
|ГДЕ СоседокПоследних.СтатусЗанятости = ЗНАЧЕНИЕ(Перечисления.СтатусЗанятости.РазрешеноТрудиться)";
Запрос.УстановитьПараметр("ДатаОтчёта", ДатаОтчёта);
Результат = Запрос.Выполнить();
Возврат Результат.Выгрузить();
КонецФункции
Ключевые моменты
| Подход | Когда использовать | Плюсы | Минусы |
|---|---|---|---|
| СрезПоследних | История в регистре | Быстро, точно | Нужен периодический регистр |
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ | С доп. информацией | Много данных | Сложнее запрос |
| Проверка дат | История в справочнике | Просто | Медленнее, менее гибко |
| Диапазон дат | По периодам | Гибко | Может вернуть дубли |
Оптимальное решение для production
Функция ПолучитьСотрудниковНаДату(ДатаОтчёта, Организация) Экспорт
// Кэшируем результат на день
КлючКэша = "СотрудникиНа" + Формат(ДатаОтчёта, "ДФ=yyyymmdd") + Организация.УникальныйИдентификатор();
Если НЕ ЗначениеЗаполнено(Неопределено) Тогда // Проверка кэша
Возврат ПолучитьИзКэша(КлючКэша);
КонецЕсли;
Запрос = Новый Запрос();
Запрос.Текст =
"ВЫБРАТЬ
| КадроваяИстория.Сотрудник,
| Сотрудники.Наименование
|ИЗ РегистрСведений.КадроваяИстория.СрезПоследних(&ДатаОтчёта, ) КАК КадроваяИстория
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Сотрудники КАК Сотрудники
| ПО КадроваяИстория.Сотрудник = Сотрудники.Ссылка
| И Сотрудники.Организация = &Организация
|ГДЕ КадроваяИстория.Состояние = ЗНАЧЕНИЕ(Перечисления.СостояниеСотрудника.Работает)
|УПОРЯДОЧИТЬ ПО Сотрудники.Наименование";
Запрос.УстановитьПараметр("ДатаОтчёта", ДатаОтчёта);
Запрос.УстановитьПараметр("Организация", Организация);
Результат = Запрос.Выполнить().Выгрузить();
СохранитьВКэш(КлючКэша, Результат);
Возврат Результат;
КонецФункции
Рекомендация: используйте СрезПоследних с ВНУТРЕННИМ СОЕДИНЕНИЕМ — это самый быстрый и надёжный способ в 1С.