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