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