Как проверить наличие записей в документе корректировки регистров и запросить подтверждение перезаписи?

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

При разработке обработок по переносу или исправлению данных часто возникает задача заполнения документа КорректировкаЗаписейРегистров. Если документ создается заново или обрабатывается повторно, важно избежать задвоения строк в наборах записей регистров и табличной части состава регистров. Разберем по шагам, как правильно сопоставить новые записи с уже существующими в документе и как организовать интерактивный диалог с пользователем перед их перезаписью.

Принцип сопоставления и проверки уникальности записей

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

Для регистров ВзаиморасчетыСКонтрагентами и ВзаиморасчетыСКонтрагентамиПоДокументамРасчетов ключевыми измерениями обычно выступают:

  1. Организация
  2. Контрагент
  3. ДоговорКонтрагента
  4. Сделка или ДокументРасчетовСКонтрагентом
  5. Период и ВидДвижения

Способ 1. Проверка набора записей через поиск строк и вызов диалога

Рассмотрим вариант, когда перед добавлением новой строки мы считываем текущий набор записей регистра документа и проверяем наличие аналогичной строки методом НайтиСтроки().

Разберем пример модификации обработчика, где при обнаружении совпадения вызывается вопрос пользователю:


// Считываем движения существующего документа
ВзаиморасчетыСКонтрагентами = ДвиженияКорр.ВзаиморасчетыСКонтрагентами;
ВзаиморасчетыСКонтрагентами.Прочитать();

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

Архитектурные особенности документа «Корректировка записей регистров»

Проанализируем важные нюансы работы с данным документом, которые необходимо учитывать при программном заполнении:

  1. Таблица состава регистров: В типовых конфигурациях список корректируемых регистров хранится в табличной части (ТаблицаРегистровНакопления). Нельзя просто вызывать метод Добавить() без проверки, иначе при каждом запуске обработки одна и та же строка регистра будет добавляться заново. Используем предварительный поиск:
    
    Отбор = Новый Структура("Имя", "ВзаиморасчетыСКонтрагентами");
    Если НовДокКоррЗап.ТаблицаРегистровНакопления.НайтиСтроки(Отбор).Количество() = 0 Тогда
        НовСтрРег = НовДокКоррЗап.ТаблицаРегистровНакопления.Добавить();
        НовСтрРег.Имя = "ВзаиморасчетыСКонтрагентами";
        НовСтрРег.Представление = "Взаиморасчеты с контрагентами";
    КонецЕсли;
    
  2. Очистка или взведение флага записи: Чтобы изменения сохранились в базе данных, для набора движений обязательно должен быть установлен флаг Записывать = Истина, либо должен вызываться метод Записать() самого документа-объекта.

Оптимизация: пакетная перезапись вместо множества диалогов

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

← На главную