Как программно изменить данные в документе Перенос данных в 1С

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом IT и автоматизация бизнеса
← На главную

При работе с конфигурациями 1С:Зарплата и управление персоналом 3.1 (ЗУП) или 1С:Зарплата и кадры государственного учреждения (ЗКГУ) специалисты часто сталкиваются с необходимостью массовой корректировки данных, перенесенных из предыдущих версий программ (например, из ЗУП 2.5 или ЗКБУ 1.0). Основным инструментом для хранения таких данных является документ Перенос данных. Однако этот документ имеет специфическую структуру, которая существенно отличается от привычных документов реализации или поступления.

В этой статье мы разберем, почему не получается изменить данные через привычную табличную часть, проанализируем структуру документа Перенос данных и рассмотрим наиболее эффективные программные способы корректировки информации.

В чем заключается сложность документа Перенос данных

Разберем ситуацию: вам необходимо изменить суммы в движениях документа (например, применить районный коэффициент к годовой премии). Первое логичное желание программиста — получить объект документа, найти нужную табличную часть и изменить в ней строки. Однако здесь нас поджидает архитектурная особенность: документ Перенос данных по своей сути является «контейнером» для записей различных регистров. В нем есть служебная табличная часть ТаблицаРегистров, но она содержит лишь список имен регистров, по которым документ делает движения, а не сами расчетные данные.

Проанализируем типичную ошибку при попытке изменить данные напрямую в табличной части:


&НаСервере
Процедура ИзменитьРКНаСервере()
    // Этот код НЕ изменит данные в регистрах
    Документ = Объект.Документ.ПолучитьОбъект();
    ТабЧасть = Документ.ТаблицаРегистров; 
    Для каждого Строка Из ТабЧасть Цикл
        // Здесь мы пытаемся изменить поле Сумма, которого нет в ТаблицеРегистров
        Строка.Сумма = Строка.Сумма * 1.15; 
    КонецЦикла;
    Документ.Записать();
КонецПроцедуры

Выясним причину неудачи: обращаясь к ТаблицаРегистров, вы работаете со списком метаданных (какие вкладки отображать в форме), а не с самими записями о начислениях. Сами данные (сотрудники, периоды, суммы) физически хранятся в соответствующих регистрах накопления или сведений.

Решение 1: Использование набора записей регистра (Оптимальный способ)

Рассмотрим наиболее быстрый и безопасный метод изменения данных. Вместо того чтобы открывать тяжелый объект документа, мы обратимся напрямую к записям регистра, используя НаборЗаписей. Этот метод позволяет работать с данными в базе данных более точечно.

Разберем алгоритм по шагам:

  1. Создаем набор записей конкретного регистра (например, ДанныеОНачисленияхДляРасчетаСреднегоЗаработкаОбщий).
  2. Устанавливаем отбор по регистратору (нашему документу Перенос данных).
  3. Читаем данные из базы.
  4. В цикле обходим записи и вносим необходимые изменения.
  5. Записываем набор обратно в базу данных с флагом Замещать = Истина.

Посмотрим на пример реализации этого метода:


&НаСервере
Процедура ИзменитьРКНаСервере()
    ДокументСсылка = Объект.Документ;
    
    // Выбираем конкретный регистр, в котором хранятся данные для среднего заработка
    Регистр = РегистрыНакопления.ДанныеОНачисленияхДляРасчетаСреднегоЗаработкаОбщий;
    Набор = Регистр.СоздатьНаборЗаписей();
    
    // Устанавливаем фильтр по документу-регистратору
    Набор.Отбор.Регистратор.Установить(ДокументСсылка);
    
    // ОБЯЗАТЕЛЬНО читаем текущие записи
    Набор.Прочитать();
    
    Счетчик = 0;
    Для каждого Запись Из Набор Цикл
        // Здесь можно добавить условие на вид начисления или статью дохода
        Запись.Сумма = Запись.Сумма * 1.15;
        Счетчик = Счетчик + 1;
    КонецЦикла;
    
    // Записываем измененный набор
    Набор.Записать(Истина);
    
    Сообщить("Успешно изменено строк в регистре: " + Счетчик);
КонецПроцедуры

Важный нюанс: При использовании Набор.Записать(Истина) все старые движения этого документа по данному регистру удаляются и заменяются новыми из вашего набора. Поэтому критически важно сначала вызвать метод Прочитать(), иначе вы рискуете очистить данные в документе.

Решение 2: Работа через коллекцию Движения документа

Если вам по какой-то причине необходимо работать именно с объектом документа (например, вы параллельно меняете реквизиты самого документа), можно использовать коллекцию Движения. Посмотрим, как это выглядит в коде:


&НаСервере
Процедура КорректировкаЧерезОбъект()
    ДокументОбъект = Объект.Документ.ПолучитьОбъект();
    
    // Получаем доступ к движениям конкретного регистра
    ДвиженияРегистра = ДокументОбъект.Движения.ДанныеОНачисленияхДляРасчетаСреднегоЗаработкаОбщий;
    
    // Читаем движения из базы, если они еще не загружены в объект
    ДвиженияРегистра.Прочитать();
    
    Для каждого СтрокаДвижения Из ДвиженияРегистра Цикл
        СтрокаДвижения.Сумма = СтрокаДвижения.Сумма * 1.15;
    КонецЦикла;
    
    // Устанавливаем признак необходимости записи движений
    ДвиженияРегистра.Записывать = Истина;
    
    // При записи объекта запишутся и измененные движения
    ДокументОбъект.Записать();
КонецПроцедуры

Проанализируем этот подход: он более "тяжелый", так как система считывает весь объект документа со всеми его реквизитами и остальными регистрами. Однако он удобен тем, что сохраняет целостность данных в рамках транзакции записи объекта.

Технические нюансы при работе с регистрами среднего заработка

Поскольку задача часто связана с корректировкой среднего заработка, проанализируем структуру регистра ДанныеОНачисленияхДляРасчетаСреднегоЗаработкаОбщий. При массовом изменении данных следует учитывать следующие моменты:

Рекомендации по проверке результата

После программного выполнения корректировки данных в документе Перенос данных, мы рекомендуем выполнить следующие действия:

  1. Откройте форму документа визуально и перейдите на вкладку соответствующего регистра. Убедитесь, что суммы обновились.
  2. Проверьте "Отчет по движениям документа", чтобы удостовериться, что данные записаны в базу.
  3. Проведите контрольный расчет. Создайте документ Отпуск или Больничный лист по одному из сотрудников, чьи данные вы меняли, и проверьте, как заполнилась вкладка "Средний заработок".

Использование метода с НаборЗаписей является стандартом де-факто для подобных задач в 1С 8.3, так как он минимизирует нагрузку на сервер и позволяет избежать блокировок при работе с большими объемами данных переноса.

← На главную