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