При разработке собственных обработок для автоматического заполнения документов выплаты зарплаты в конфигурациях «Зарплата и кадры государственного учреждения» (ЗКГУ) или «Зарплата и управление персоналом» (ЗУП) редакции 3.1 программисты часто сталкиваются с ошибкой: «Не заполнена колонка "Идентификатор строки" в строке №...». Даже если это поле заполнено числом, документ может не проводиться, выдавать ошибку «Индекс находится за границами массива» или просто «терять» суммы после записи. Рассмотрим подробно, как устроена архитектура этих документов и как правильно реализовать автоматическое заполнение реквизитов программно. При необходимости заполнить документ без самостоятельной разработки можно использовать обработку для загрузки ведомости в банк из Excel.
Для начала проанализируем, почему стандартного добавления строки в табличную часть Состав недостаточно. В современных конфигурациях на базе ЗУП 3.1 документ «Ведомость» (в банк, в кассу, на счета) имеет сложную структуру. Данные в нем распределены по нескольким связанным табличным частям:
Связующим звеном между всеми этими таблицами выступает поле ИдентификаторСтроки. Если вы добавили строку только в Состав, система при проведении пытается найти расшифровку в ТЧ Зарплата по этому идентификатору. Не найдя её, она либо очищает сумму, либо выдает ошибку заполнения.
В сообщениях форума часто возникает путаница: какой тип данных использовать? Некоторые советуют Новый УникальныйИдентификатор, однако в типовых ведомостях ЗУП 3.1 поле ИдентификаторСтроки имеет тип Число (также изучите дополнительные реквизиты табличных частей). Это внутренний счетчик связей. Рассмотрим, как правильно генерировать этот идентификатор в цикле при заполнении документа.
Выясним причину ошибки «Индекс находится за границами массива». Она возникает в общем модуле ВедомостьНаВыплатуЗарплатыРасширенный. Когда система проверяет соответствие сумм, она обращается к массиву расшифровок. Если расшифровка (строка в ТЧ Зарплата) отсутствует, массив оказывается пустым, и обращение к его первому элементу [0] вызывает фатальную ошибку.
Рассмотрим пример кода, который позволит корректно заполнить ведомость. Предположим, у нас есть результат запроса или выборка данных, которую нужно перенести в документ.
// Предположим, ОбъектДокумента - это ВедомостьВБанкОбъект
ТабЧастьСостав = ОбъектДокумента.Состав;
ТабЧастьЗарплата = ОбъектДокумента.Зарплата;
ИдентификаторСчетчик = 1; // Начинаем нумерацию
Пока РезультатЗапроса.Следующий() Цикл
// 1. Заполняем основную ТЧ "Состав"
НоваяСтрокаСостав = ТабЧастьСостав.Добавить();
НоваяСтрокаСостав.ФизЛицо = РезультатЗапроса.ФизЛицо;
НоваяСтрокаСостав.Выплачено = РезультатЗапроса.Сумма;
// Устанавливаем числовой идентификатор
НоваяСтрокаСостав.ИдентификаторСтроки = ИдентификаторСчетчик;
// 2. ОБЯЗАТЕЛЬНО заполняем ТЧ "Зарплата" (расшифровка)
НоваяСтрокаЗарплата = ТабЧастьЗарплата.Добавить();
НоваяСтрокаЗарплата.Сотрудник = РезультатЗапроса.Сотрудник;
НоваяСтрокаЗарплата.ФизическоеЛицо = РезультатЗапроса.ФизЛицо;
НоваяСтрокаЗарплата.Сумма = РезультатЗапроса.Сумма;
НоваяСтрокаЗарплата.ПериодВзаиморасчетов = ОбъектДокумента.ПериодРегистрации;
НоваяСтрокаЗарплата.СтатьяФинансирования = РезультатЗапроса.СтатьяФинансирования;
НоваяСтрокаЗарплата.СтатьяРасходов = РезультатЗапроса.СтатьяРасходов;
// Идентификатор должен совпадать с ТЧ Состав!
НоваяСтрокаЗарплата.ИдентификаторСтроки = ИдентификаторСчетчик;
// 3. Если ведомость предполагает НДФЛ, заполняем и ТЧ НДФЛ
// (Аналогично с тем же ИдентификаторСчетчик)
ИдентификаторСчетчик = ИдентификаторСчетчик + 1;
КонецЦикла;
Важный момент: если вы программно меняете суммы в уже существующем документе, не забудьте обновить их во всех связанных таблицах. Если сумма в Состав будет отличаться от суммы в Зарплата, при записи документа типовые механизмы «Зарплаты» могут пересчитать (или обнулить) данные, основываясь на своей логике приоритетов ТЧ.
Чтобы не изобретать велосипед с ручным счетчиком, мы можем посмотреть, как это делает сама система. В конфигурации часто используется служебный реквизит документа МаксимальныйИдентификаторСтроки (он скрыт на форме). Проанализируем, как использовать его:
// Получаем текущий максимум, чтобы не нарушить существующие связи
ТекущийID = ОбъектДокумента.МаксимальныйИдентификаторСтроки;
НоваяСтрока = ОбъектДокумента.Состав.Добавить();
ТекущийID = ТекущийID + 1;
НоваяСтрока.ИдентификаторСтроки = ТекущийID;
// Не забываем обновить максимум в самом объекте
ОбъектДокумента.МаксимальныйИдентификаторСтроки = ТекущийID;
Если вы заполнили ИдентификаторСтроки, но после нажатия кнопки «Записать» суммы в колонке «К выплате» становятся нулевыми, это означает, что проверка заполнения не нашла соответствий в табличной части Зарплата.
В 1С:ЗУП 3.1 сумма в главной таблице — это вычисляемое поле. Оно суммируется по всем строкам расшифровки с соответствующим ID. Если расшифровки нет — сумма превращается в ноль. Поэтому правило номер один для программиста ЗУП: всегда заполняй ТЧ Зарплата вместе с ТЧ Состав.
В некоторых сообщениях форума упоминается, что проблема может быть в «глюках» платформы 8.3.13. Хотя определенные ошибки в этой версии действительно были, в данном случае проблема на 99% кроется в нарушении логики связи таблиц. Переход на другую платформу не поможет, если в коде обработки отсутствует заполнение аналитических разрезов (статьи финансирования, периоды и т.д.) в подчиненных таблицах.
Для успешного проведения документа ведомости программным способом выполним следующие шаги:
ИдентификаторСтроки (а не UUID).Состав, Зарплата и НДФЛ.Соблюдение этих правил гарантирует корректную работу документа и отсутствие ошибок при его последующей проверке и проведении системой. Для сверки сумм удержанного налога можно применить отчет для контроля правильности заполнения НДФЛ в ведомостях.