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

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

При работе с крупными документами в 1С:Зарплата и управление персоналом (ЗУП) 3.1, такими как Премия, часто возникает необходимость автоматизировать очистку списка сотрудников. Одной из типичных задач является удаление тех лиц, которые уже уволены на дату формирования документа. Рассмотрим, как правильно реализовать внешнюю обработку заполнения табличной части (ТЧ), избежав распространенных ошибок начинающих разработчиков.

Анализ типичных ошибок при разработке обработки заполнения

Разберем типичные ошибки, которые возникают на начальном этапе, основываясь на ситуации автора темы. Проанализируем, почему стандартные подходы могут не работать:

  1. Передача несовместимых типов между клиентом и сервером. Попытка передать объект типа ВыборкаИзРезультатаЗапроса с сервера на клиент приводит к ошибке XDTO. Платформа 1С не умеет сериализовать такие объекты для передачи через границу «клиент-сервер».
  2. Неправильный цикл удаления строк. При использовании цикла Для Счетчик = 0 По ВсегоСтрок - 1 удаление первой строки сдвигает индексы всех последующих. В результате код пропускает строки или обращается к несуществующим индексам.
  3. Работа с ссылкой вместо объекта. Метод Загрузить() или попытка изменения данных требует получения объекта (ПолучитьОбъект()), но в управляемых формах работа должна идти напрямую с реквизитом формы Объект.

Выясним причину неудач: для эффективной работы с табличными частями в ЗУП 3.1 необходимо использовать серверный контекст и выполнять манипуляции с данными максимально близко к базе данных или напрямую в данных формы.

Реализация фильтрации сотрудников через запрос

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

В ЗУП 3.1 состояние сотрудника хранится в регистре сведений СостоянияСотрудников. Нам нужно получить срез последних данных на дату документа. Проанализируем структуру запроса:


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

В данном примере мы используем метод Загрузить(). Это важный момент: он полностью заменяет содержимое табличной части данными из таблицы значений. Это гораздо быстрее, чем удаление строк в цикле.

Особенности работы во внешней обработке (БСП)

Если вы создаете именно подключаемую обработку для БСП (Библиотеки стандартных подсистем), процедура ВыполнитьКоманду должна корректно принимать параметры формы. Разберем по шагам, как организовать вызов:


&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив, ПараметрыВыполнения) Экспорт
    
    // Обычно в параметрах выполнения передается форма владельца
    ФормаДокумента = ПараметрыВыполнения.ЭтаФорма;
    УдалитьУволенныхНаСервере(ФормаДокумента.Объект);
    
КонецПроцедуры

Обратите внимание: использование РеквизитФормыВЗначение и ЗначениеВРеквизитФормы позволяет обновить данные в экранной форме без немедленной записи документа в базу. Это дает пользователю возможность проверить результат перед сохранением, что является хорошим тоном разработки.

Использование программного интерфейса (API) ЗУП 3.1

Для более профессиональной разработки в ЗУП 3.1 рекомендуется не писать прямые запросы к регистрам состояний, а использовать встроенные функции общего модуля КадровыйУчет. Это гарантирует, что ваше решение не сломается при обновлении конфигурации, если структура регистров изменится.

Рассмотрим альтернативный способ проверки состояний:


// Пример получения только работающих сотрудников через API ЗУП
МассивСотрудников = Объект.Начисления.ВыгрузитьКолонку("Сотрудник");
ТаблицаСостояний = КадровыйУчет.ТекущиеСостоянияСотрудников(МассивСотрудников, Объект.Дата);

// Далее можно обойти ТЧ с конца и удалять тех, кого нет в ТаблицаСостояний 
// или у кого состояние "Увольнение"
Всего = Объект.Начисления.Количество();
Для Счетчик = 1 По Всего Цикл
    ТекущаяСтрока = Объект.Начисления[Всего - Счетчик];
    // Логика проверки состояния через ТаблицаСостояний...
    // Если Уволен Тогда Объект.Начисления.Удалить(ТекущаяСтрока); КонецЕсли;
КонецЦикла;

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

Нюансы с идентификаторами строк

В сложных документах ЗУП, таких как расчет премий или начисление зарплаты, строки табличной части Начисления часто связаны с данными на других вкладках (НДФЛ, Взносы) через поле ИдентификаторСтроки. Если вы просто удалите строку, связанные с ней расчеты НДФЛ могут остаться "висеть" в документе.

Важный совет: после программного изменения состава сотрудников рекомендуется инициировать пересчет документа. В модулях многих документов ЗУП есть экспортные процедуры для обновления зависимых таблиц. Если их нет, пользователю стоит нажать кнопку "Пересчитать" вручную.

Подведем итог: наиболее эффективным решением задачи является использование серверной процедуры, которая либо через запрос, либо через API ЗУП получает актуальные статусы сотрудников и обновляет данные формы с помощью методов Загрузить или обратного цикла удаления строк. Это обеспечивает стабильную работу без ошибок передачи типов и корректное отображение изменений для пользователя.

← На главную