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