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