При обновлении типовых конфигураций 1С, таких как "Управление торговлей" (УТ) версии 11, особенно когда в системе используются расширения, часто возникают сложности. Одна из распространенных проблем — это конфликт имен объектов или реквизитов, который проявляется при проверке применимости расширений. Мы рассмотрим ситуацию, когда система выдает ошибку "Уже существует объект с именем - ДокументЗаказ.Товары.ДатаОтгрузки", уточненную далее как ЗаказПоставщику.Товары.ДатаОтгрузки. Этот реквизит присутствует как в основной конфигурации после обновления, так и в расширении, но в расширении он был создан как новый, а не заимствован.
Такая ситуация означает, что ранее в типовой конфигурации этого реквизита не было, и разработчики расширения добавили его "с нуля". Теперь, когда в новой версии типовой конфигурации (в нашем случае УТ 11.5.8.410) появился реквизит с аналогичным именем, возникает конфликт, поскольку платформа не может однозначно определить, какой из объектов следует использовать.
Прежде чем приступать к активным действиям, нам необходимо провести тщательный анализ и подготовительные работы, чтобы избежать потери данных и минимизировать риски. Всегда выполняйте эти шаги на копии базы данных, никогда не работайте напрямую с рабочей информационной базой.
ЗаказПоставщику.Товары.ДатаОтгрузки, который находится в расширении. Для этого мы можем воспользоваться консолью запросов или написать небольшую обработку.Например, мы можем выполнить следующий запрос, чтобы увидеть, есть ли заполненные значения в этом реквизите:
ВЫБРАТЬ
ДокЗаказПоставщикуТовары.Ссылка.Ссылка КАК СсылкаНаДокумент,
ДокЗаказПоставщикуТовары.НомерСтроки КАК НомерСтроки,
ДокЗаказПоставщикуТовары.ДатаОтгрузки КАК ДатаОтгрузкиРасширения
ИЗ
Документ.ЗаказПоставщику.Товары КАК ДокЗаказПоставщикуТовары
ГДЕ
ДокЗаказПоставщикуТовары.ДатаОтгрузки ЕСТЬ НЕ NULL
Если запрос возвращает строки, значит, данные в реквизите есть, и их необходимо будет перенести. Зафиксируйте эти данные, возможно, выгрузите их в таблицу или текстовый файл для дальнейшего сравнения.
Теперь, когда мы провели подготовку и анализ, приступим к решению проблемы. Наш основной план будет состоять в том, чтобы временно переименовать реквизит в расширении, обновить типовую конфигурацию, заимствовать новый типовой реквизит и затем перенести в него данные.
Начнем с модификации расширения, чтобы устранить непосредственный конфликт имен до обновления основной конфигурации.
ЗаказПоставщику. В нем найдите табличную часть Товары. Внутри этой табличной части вы увидите реквизит ДатаОтгрузки, который был добавлен расширением (он не будет иметь значка заимствования, обозначающего что он свой, а не типовой). Переименуйте его, например, в удДатаОтгрузки (сокращение от "устаревшая ДатаОтгрузки") или Расш_ДатаОтгрузки. Главное, чтобы новое имя было уникальным и не пересекалось с типовыми объектами.удДатаОтгрузки были, они должны быть доступны.После успешного переименования реквизита в расширении, мы можем приступить к обновлению основной конфигурации.
ЗаказПоставщику, в табличной части Товары, теперь присутствует реквизит ДатаОтгрузки. Это тот самый типовой реквизит, который вызвал конфликт.Теперь, когда новый типовой реквизит существует, нам нужно, чтобы расширение работало именно с ним, а не с его устаревшей версией.
ЗаказПоставщику в основной конфигурации (не в расширении). Перетащите его в расширение или используйте контекстное меню для заимствования. Если документ ЗаказПоставщику уже заимствован, перейдите к его табличной части Товары. Найдите типовой реквизит ДатаОтгрузки и заимствуйте его. После заимствования, этот реквизит в расширении будет отмечен специальным значком, указывающим на его заимствованность.Это самый ответственный шаг, если у вас были данные в реквизите удДатаОтгрузки. Нам нужно перенести их в новый типовой реквизит ДатаОтгрузки, при этом не создавая лишних записей в журналах регистрации изменений для обмена данными.
Предположим, что вы переименовали реквизит в расширении на удДатаОтгрузки, а новый типовой реквизит называется ДатаОтгрузки.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗаказПоставщикуТовары.Ссылка.Ссылка КАК СсылкаНаДокумент,
| ЗаказПоставщикуТовары.НомерСтроки КАК НомерСтроки,
| ЗаказПоставщикуТовары.удДатаОтгрузки КАК УстаревшаяДатаОтгрузки
|ИЗ
| Документ.ЗаказПоставщику.Товары КАК ЗаказПоставщикуТовары
|ГДЕ
| ЗаказПоставщикуТовары.удДатаОтгрузки ЕСТЬ НЕ NULL"; // Выбираем только те строки, где устаревшая дата заполнена
Выборка = Запрос.Выполнить().Выбрать();
НачалоТранзакции(); // Опционально: можно выполнять в транзакции для атомарности
Пока Выборка.Следующий() Цикл
Попытка
ДокументОбъект = Выборка.СсылкаНаДокумент.ПолучитьОбъект();
Если ДокументОбъект = Неопределено Тогда
Сообщить("Внимание: Не удалось получить объект документа по ссылке " + Выборка.СсылкаНаДокумент + ". Пропускаем.");
Продолжить;
КонецЕсли;
// Устанавливаем флаги для предотвращения регистрации изменений и блокировки обмена
// Это критически важно, чтобы запись не вызвала регистрацию для обмена с другими базами (например, с Бухгалтерией)
ДокументОбъект.ДополнительныеСвойства.Вставить("ОтключитьМеханизмРегистрацииОбъектов", Истина);
ДокументОбъект.ОбменДанными.Загрузка = Истина;
// Ищем нужную строку табличной части
НайденаСтрока = Ложь;
Для Каждого СтрокаТабличнойЧасти Из ДокументОбъект.Товары Цикл
Если СтрокаТабличнойЧасти.НомерСтроки = Выборка.НомерСтроки Тогда
СтрокаТабличнойЧасти.ДатаОтгрузки = Выборка.УстаревшаяДатаОтгрузки; // Переносим данные
НайденаСтрока = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НайденаСтрока Тогда
// Записываем документ без регистрации изменений
ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);
Сообщить("Данные по документу " + ДокументОбъект.Ссылка + " строка " + Выборка.НомерСтроки + " успешно перенесены.");
Иначе
Сообщить("Внимание: Строка " + Выборка.НомерСтроки + " не найдена в документе " + ДокументОбъект.Ссылка + ". Данные не перенесены.");
КонецЕсли;
Исключение Э
Сообщить("Ошибка при переносе данных для документа " + Выборка.СсылкаНаДокумент + ": " + Э.Описание);
КонецПопытки;
КонецЦикла;
// Опционально: Если использовалась транзакция, необходимо либо ЗафиксироватьТранзакцию(), либо ОтменитьТранзакцию()
// ЗафиксироватьТранзакцию();
Сообщить("Процесс переноса данных завершен.");
Объясним использованные методы:
ДокументОбъект.ДополнительныеСвойства.Вставить("ОтключитьМеханизмРегистрацииОбъектов", Истина);: Эта строка указывает платформе, что изменения, сделанные в данном объекте, не должны быть зарегистрированы для обмена данными. Это полезно, когда мы делаем технические изменения и не хотим, чтобы они ушли в другие связанные базы (например, в 1С:Бухгалтерию).ДокументОбъект.ОбменДанными.Загрузка = Истина;: Этот флаг обычно устанавливается при загрузке данных извне. Он также предотвращает выполнение некоторых проверок и регистраций, предполагая, что данные приходят из доверенного источника (в нашем случае, мы сами переносим их внутри одной базы).ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);: Документ записывается с указанным режимом.Эти флаги критически важны для корректного переноса данных без нежелательных побочных эффектов, таких как отправка документов в обмен, которые фактически не менялись в бизнес-логике.
После миграции данных, нам нужно убедиться в корректности всех изменений и, при необходимости, удалить устаревший реквизит.
ДатаОтгрузки теперь содержит правильные значения, которые были перенесены из старого реквизита. Вы можете также повторно выполнить запрос из Шага 1, но уже для нового реквизита, чтобы убедиться в его заполнении.Ctrl+Shift+F), проверьте, нет ли где-либо в коде или формах расширения ссылок на реквизит удДатаОтгрузки. Если вы найдете такие ссылки, их необходимо будет скорректировать, чтобы они использовали новый типовой реквизит ДатаОтгрузки.удДатаОтгрузки больше нигде не используется и все данные успешно перенесены, вы можете удалить его из расширения. Это поможет поддерживать чистоту кода и структуры данных. Не забудьте обновить конфигурацию базы данных после удаления.Чтобы избежать подобных конфликтов при следующих обновлениях, мы рекомендуем придерживаться следующих практик при разработке расширений:
Следуя этим рекомендациям и выполняя предложенные шаги, мы сможем эффективно устранить конфликты при обновлении конфигураций 1С с расширениями, обеспечив стабильную работу системы и целостность данных.