Как исправить дублирование ГУИД при копировании документа и ошибку «Объект не может быть перепозиционирован» в 1С 7.7?

Программист 1С v7.7 Управленческий учет Промышленность, строительство и АПК
← На главную

При работе в конфигурации «1С:Подрядчик строительства 2.3» на платформе 7.7 программисты часто сталкиваются с проблемой уникальности строк в регистрах. Одной из специфических проблем является копирование документа Предварительная заявка. Если в системе используется механизм идентификации строк через ГУИД (GUID), то при обычном копировании (клавиша F9) новый документ полностью наследует эти идентификаторы. В результате при проведении в регистр Предварительные заявки записываются строки с одинаковыми ГУИДами, что в дальнейшем приводит к неверным остаткам и ошибкам в отчетах.

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

Анализ ошибки «Объект не может быть перепозиционирован!»

Рассмотрим ситуацию: разработчик пытается в модуле документа перед проведением проверить наличие текущего ГУИДа в регистре. Для этого используется метод ВыгрузитьИтоги(). Однако система выдает ошибку: Объект не может быть перепозиционирован!. Давайте выясним причину этого поведения.

В 1С 7.7 внутри процедуры ОбработкаПроведения() обращение к регистру через встроенное слово Регистр.ПредварительныеЗаявки создает прямую связь с текущими движениями документа. Этот объект «занят» процессом записи движений. Когда мы вызываем метод ВыгрузитьИтоги или пытаемся установить фильтр (УстановитьФильтр), система пытается изменить внутренний индекс или состояние выборки регистра, что запрещено в момент активной транзакции проведения для этого конкретного объекта.

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


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

Такой подход позволяет избежать конфликта блокировок и успешно получить данные из базы, не мешая основному процессу записи движений документа.

Решение проблемы дублирования ГУИД при копировании

Перейдем к основной задаче: как сделать так, чтобы при копировании документа Предварительная заявка ГУИДы в строках становились новыми или очищались? Проанализируем два способа: через настройки метаданных и через программный код.

Способ 1: Использование свойств метаданных

Самый простой и эффективный способ, не требующий написания сложного кода, — это использование стандартных свойств конфигуратора. Выполним следующие шаги:

  1. Откроем Конфигуратор.
  2. Найдем документ ПредварительнаяЗаявка.
  3. Перейдем на вкладку «Табличная часть».
  4. Выберем реквизит ГУИД (или ID, в зависимости от версии вашей конфигурации).
  5. В окне свойств реквизита найдем флажок «Очищать при копировании» и установим его.

После этого при нажатии F9 в новом документе колонка ГУИД будет пустой. Если ваша логика проведения (как в Сообщении 1 темы форума) содержит проверку на заполненность ГУИДа, пользователь просто не сможет провести документ, пока не сгенерирует новые ID. Это надежно страхует базу от появления дублей.

Способ 2: Программная генерация в процедуре ВводНового

Если специфика бизнес-процесса требует, чтобы ГУИДы генерировались автоматически сразу при копировании, нам необходимо отредактировать модуль формы документа. Рассмотрим процедуру ВводНового(Копирование). Параметр Копирование принимает значение 1, если документ создается путем копирования другого.

Проанализируем пример кода, который нужно добавить в модуль формы:


Процедура ВводНового(Копирование)
    // Стандартные действия при вводе нового
    Автор = глПользователь;
    ДатаДок = ТекущаяДата();
    
    Если Копирование = 1 Тогда
        // Проходим циклом по всем строкам скопированного документа
        ВыбратьСтроки();
        Пока ПолучитьСтроку() = 1 Цикл
            // Очищаем старый ГУИД или генерируем новый
            // Если в конфигурации есть функция генерации, вызываем её
            // Например, через компоненту V7Plus
            ГУИД = ""; // Очищаем, чтобы сработала логика заполнения при записи
            
            // Или, если хотим сразу новый ID:
            // ГУИД = глПолучитьНовыйGUID(); 
        КонецЦикла;
        
        Сообщить("Внимание: Идентификаторы строк были очищены для создания уникальных записей.");
    КонецЕсли;
КонецПроцедуры

Важный нюанс: в конфигурации «Подрядчик строительства» генерация ГУИДов часто завязана на внешнюю компоненту v7plus.dll. Перед использованием программной генерации убедитесь, что объект V7Plus.СистемнаяУтилита инициализирован в глобальном модуле.

Исправление существующих ошибок в базе данных

Если в вашем регистре уже появились записи с одинаковыми ГУИДами, простая правка кода проведения не поможет — нужно «вылечить» уже существующие документы. Разберем алгоритм действий:

  1. Поиск дублей: напишем простую обработку, которая выгрузит таблицу значений из регистра ПредварительныеЗаявки и сгруппирует её по измерению СтрокаЗаявки (где хранится ГУИД). Если количество (счетчик) больше 1 — у вас есть проблема.
  2. Отмена проведения: все документы, в которых найдены дублирующиеся ГУИДы, необходимо сначала распровести. Это крайне важно, чтобы очистить регистр от «плохих» записей.
  3. Перегенерация ID: программно присвоим реквизитам ГУИД в табличных частях этих документов новые уникальные значения.
  4. Проведение: проведем исправленные документы заново. Теперь в регистр попадут корректные, уникальные записи.

Для массового исправления удобно использовать универсальную обработку Uchoice.ert (Поиск и замена значений), которая входит в стандартный набор инструментов администратора 1С 7.7, либо написать небольшой скрипт для перебора документов.

Резюме по работе с регистрами в 1С 7.7

Мы выяснили, что работа с регистрами в модуле документа требует внимательности к контексту:

Соблюдение этих правил позволит вам избежать критических ошибок в учете и обеспечит стабильную работу системы «1С:Подрядчик строительства».

← На главную