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