Как найти сотрудников, которым не начислили зарплату или не выплатили деньги в ЗУП 3.1?

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом IT и автоматизация бизнеса
← На главную

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

Постановка задачи

Нам необходимо получить два списка сотрудников:

  1. Работающие, но без начислений: Люди, которые числятся в штате на определенный период, но в регистрах расчета по ним нет записей.
  2. С начислениями, но без выплат: Люди, у которых есть начисленная сумма, но не закрыт остаток по взаиморасчетам.

Способ 1. Решение стандартными средствами (Без программирования)

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

Лайфхак с документом начисления

Один из самых быстрых способов найти тех, кого «забыли» при расчете зарплаты, — использовать механизм автоматического заполнения документа Начисление зарплаты и взносов. Алгоритм действий следующий:

  1. Создадим новый документ Начисление зарплаты и взносов.
  2. Укажем нужный месяц начисления.
  3. Не будем указывать конкретное подразделение (оставим поле пустым).
  4. Нажмем кнопку «Заполнить».

Система автоматически подтянет всех сотрудников, по которым в данном месяце еще не был произведен окончательный расчет. Если вы уже рассчитали основную массу людей, в этот документ попадут только те, кого пропустили. Это отличный способ для экспресс-проверки перед закрытием месяца.

Использование отчетов

Для анализа ситуации используем типовые отчеты:

Способ 2. Программное решение (Запрос 1С)

Если нам необходимо получить эти данные программно (например, для создания собственной обработки контроля или рассылки уведомлений), нам потребуется написать запрос. Разберем основную сложность, с которой сталкиваются разработчики при решении этой задачи — правильное использование ЛЕВОЕ СОЕДИНЕНИЕ.

Логика запроса

Чтобы найти сотрудников без начислений, мы должны соединить две таблицы:

  1. Таблица 1 (Левая): Все работающие сотрудники (из кадровой истории или справочника).
  2. Таблица 2 (Правая): Таблица начислений за период.

Условие отбора целевых записей: Таблица2.Сотрудник ЕСТЬ NULL.

Распространенная ошибка

Рассмотрим типичную ошибку при написании такого запроса. Часто разработчики накладывают условия на период регистрации или вид расчета в секции ГДЕ. Посмотрим на неправильный пример:


ВЫБРАТЬ
	Сотр.Сотрудник
ИЗ
	ВТ_ВсеСотрудники КАК Сотр
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.Начисления КАК Нач
		ПО Сотр.Сотрудник = Нач.Сотрудник
ГДЕ
	Нач.ПериодРегистрации МЕЖДУ &НачалоПериода И &КонецПериода
	И Нач.Сотрудник ЕСТЬ NULL

Почему это не сработает?
Как только мы добавляем условие ГДЕ Нач.ПериодРегистрации ..., мы отсекаем все строки, где присоединилась пустота (NULL), потому что NULL не может быть «между датами». В итоге ЛЕВОЕ СОЕДИНЕНИЕ фактически превращается во ВНУТРЕННЕЕ СОЕДИНЕНИЕ, и мы получаем только тех, у кого начисления были, а не наоборот.

Правильное решение

Чтобы запрос отработал корректно, все условия фильтрации правой таблицы (период, вид расчета) необходимо перенести внутрь условия соединения (в секцию ПО). Тогда СУБД сначала отфильтрует правую таблицу, а затем попытается присоединить её к левой. Если записей не найдется, вернется NULL, который мы и ищем.

Разберем правильный код запроса по шагам:

  1. Получаем список работающих сотрудников.
    Для чистоты эксперимента лучше брать не справочник Сотрудники, а регистр сведений КадроваяИсторияСотрудников.СрезПоследних. Это исключит уволенных ранее сотрудников.

    
    ВЫБРАТЬ
    	КадроваяИстория.Сотрудник КАК Сотрудник
    ПОМЕСТИТЬ ВТ_Работающие
    ИЗ
    	РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(&КонецПериода, ) КАК КадроваяИстория
    ГДЕ
    	КадроваяИстория.ВидСобытия <> ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.Увольнение)
    ;
    
  2. Соединяем с начислениями.
    Используем ЛЕВОЕ СОЕДИНЕНИЕ и переносим отборы в ПО.

    
    ВЫБРАТЬ
    	ВТ_Работающие.Сотрудник,
    	ЕСТЬNULL(Начисления.Результат, 0) КАК СуммаНачисления
    ИЗ
    	ВТ_Работающие КАК ВТ_Работающие
    		ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.Начисления КАК Начисления
    		ПО ВТ_Работающие.Сотрудник = Начисления.Сотрудник
    		// ВАЖНО: Условия на правую таблицу находятся здесь!
    		И (Начисления.ПериодРегистрации МЕЖДУ &НачалоПериода И &КонецПериода)
    		// Если нужно исключить конкретные виды расчета, добавляем и их сюда
    ГДЕ
    	// Оставляем только тех, кто не присоединился
    	Начисления.Сотрудник ЕСТЬ NULL
    

Важное примечание по оптимизации:
Вместо РегистрРасчета.Начисления часто эффективнее использовать оборотный регистр накопления НачисленияУдержанияПоСотрудникам. Он содержит уже итоговые суммы и работает быстрее в сложных запросах. Логика соединения остается той же: условия на период оборотов (или виртуальной таблицы оборотов) должны применяться до соединения или внутри условия соединения.

Поиск сотрудников без выплат

Вторая часть задачи — найти тех, кому начислили, но не выплатили. Здесь логика немного иная. Нам не нужно искать NULL, нам нужно сравнить приход и расход или посмотреть остаток.

Для этого обратимся к регистру накопления ВзаиморасчетыССотрудниками (или ЗарплатаКВыплате в зависимости от конфигурации и настроек). Самый надежный способ — получить остатки на конец периода.


ВЫБРАТЬ
	ВзаиморасчетыОстатки.Сотрудник,
	ВзаиморасчетыОстатки.СуммаВзаиморасчетовОстаток КАК ДолгЗаОрганизацией
ИЗ
	РегистрНакопления.ВзаиморасчетыССотрудниками.Остатки(&КонецПериода, ) КАК ВзаиморасчетыОстатки
ГДЕ
	ВзаиморасчетыОстатки.СуммаВзаиморасчетовОстаток > 0

Этот запрос покажет всех, кому организация должна деньги на указанную дату. Обратите внимание, что в ЗУП 3.1 структура долга может быть детализирована (по месяцам, статьям финансирования), поэтому при анализе остатков убедитесь, что вы не сворачиваете разрезы, которые могут скрывать пересортицу (например, плюс по одной статье и минус по другой).

← На главную