При работе в конфигурации «1С:Подрядчик строительства 2.3» на платформе 7.7 программисты часто сталкиваются с проблемой уникальности строк в регистрах. Одной из специфических проблем является копирование документа Предварительная заявка. Если в системе используется механизм идентификации строк через ГУИД (GUID), то при обычном копировании (клавиша F9) новый документ полностью наследует эти идентификаторы. В результате при проведении в регистр Предварительные заявки записываются строки с одинаковыми ГУИДами, что в дальнейшем приводит к неверным остаткам и ошибкам в отчетах.
В этой статье мы разберем, почему возникает ошибка при попытке программной проверки регистра, и как правильно реализовать уникальность идентификаторов при создании новых документов на основе существующих.
Рассмотрим ситуацию: разработчик пытается в модуле документа перед проведением проверить наличие текущего ГУИДа в регистре. Для этого используется метод ВыгрузитьИтоги(). Однако система выдает ошибку: Объект не может быть перепозиционирован!. Давайте выясним причину этого поведения.
В 1С 7.7 внутри процедуры ОбработкаПроведения() обращение к регистру через встроенное слово Регистр.ПредварительныеЗаявки создает прямую связь с текущими движениями документа. Этот объект «занят» процессом записи движений. Когда мы вызываем метод ВыгрузитьИтоги или пытаемся установить фильтр (УстановитьФильтр), система пытается изменить внутренний индекс или состояние выборки регистра, что запрещено в момент активной транзакции проведения для этого конкретного объекта.
Правильное решение: для проверки итогов или выполнения любых запросов к регистру внутри модуля проведения необходимо всегда создавать отдельный объект через СоздатьОбъект. Рассмотрим правильный пример кода:
Процедура ОбработкаПроведения()
// Создаем отдельный объект для доступа к итогам регистра
РегПроверка = СоздатьОбъект("Регистр.ПредварительныеЗаявки");
ТабИтогов = СоздатьОбъект("ТаблицаЗначений");
// Теперь мы можем свободно выгружать итоги или устанавливать фильтры
РегПроверка.ВыгрузитьИтоги(ТабИтогов, 1, 1);
// Далее следует основной код проведения через штатный объект РегЗаявки
РегЗаявки = Регистр.ПредварительныеЗаявки;
// ... логика проведения ...
КонецПроцедуры
Такой подход позволяет избежать конфликта блокировок и успешно получить данные из базы, не мешая основному процессу записи движений документа.
Перейдем к основной задаче: как сделать так, чтобы при копировании документа Предварительная заявка ГУИДы в строках становились новыми или очищались? Проанализируем два способа: через настройки метаданных и через программный код.
Самый простой и эффективный способ, не требующий написания сложного кода, — это использование стандартных свойств конфигуратора. Выполним следующие шаги:
ПредварительнаяЗаявка.ГУИД (или ID, в зависимости от версии вашей конфигурации).После этого при нажатии F9 в новом документе колонка ГУИД будет пустой. Если ваша логика проведения (как в Сообщении 1 темы форума) содержит проверку на заполненность ГУИДа, пользователь просто не сможет провести документ, пока не сгенерирует новые ID. Это надежно страхует базу от появления дублей.
Если специфика бизнес-процесса требует, чтобы ГУИДы генерировались автоматически сразу при копировании, нам необходимо отредактировать модуль формы документа. Рассмотрим процедуру ВводНового(Копирование). Параметр Копирование принимает значение 1, если документ создается путем копирования другого.
Проанализируем пример кода, который нужно добавить в модуль формы:
Процедура ВводНового(Копирование)
// Стандартные действия при вводе нового
Автор = глПользователь;
ДатаДок = ТекущаяДата();
Если Копирование = 1 Тогда
// Проходим циклом по всем строкам скопированного документа
ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл
// Очищаем старый ГУИД или генерируем новый
// Если в конфигурации есть функция генерации, вызываем её
// Например, через компоненту V7Plus
ГУИД = ""; // Очищаем, чтобы сработала логика заполнения при записи
// Или, если хотим сразу новый ID:
// ГУИД = глПолучитьНовыйGUID();
КонецЦикла;
Сообщить("Внимание: Идентификаторы строк были очищены для создания уникальных записей.");
КонецЕсли;
КонецПроцедуры
Важный нюанс: в конфигурации «Подрядчик строительства» генерация ГУИДов часто завязана на внешнюю компоненту v7plus.dll. Перед использованием программной генерации убедитесь, что объект V7Plus.СистемнаяУтилита инициализирован в глобальном модуле.
Если в вашем регистре уже появились записи с одинаковыми ГУИДами, простая правка кода проведения не поможет — нужно «вылечить» уже существующие документы. Разберем алгоритм действий:
ПредварительныеЗаявки и сгруппирует её по измерению СтрокаЗаявки (где хранится ГУИД). Если количество (счетчик) больше 1 — у вас есть проблема.ГУИД в табличных частях этих документов новые уникальные значения.Для массового исправления удобно использовать универсальную обработку Uchoice.ert (Поиск и замена значений), которая входит в стандартный набор инструментов администратора 1С 7.7, либо написать небольшой скрипт для перебора документов.
Мы выяснили, что работа с регистрами в модуле документа требует внимательности к контексту:
Регистр для получения итогов во время проведения. Используйте СоздатьОбъект("Регистр.Имя").ВводНового в модуле формы для тонкой настройки логики копирования данных.Соблюдение этих правил позволит вам избежать критических ошибок в учете и обеспечит стабильную работу системы «1С:Подрядчик строительства».