Обновление конфигураций на БСП, у которых в расширениях есть собственные объекты с данными
Программирование - Практика программирования
Как все хорошо начиналось
Платформа версии 8.3.11 принесла программистам новую, доселе не виданную радость - возможность создавать в расширениях свои объекты, хранящие данные. Чем я и решил воспользоваться. Насоздавал в расширении справочников, регистров, и начал радоваться жизни... ровно до того момента, как решил накатить штатное обновление конфигурации.
Беда пришла откуда не ждали
При обновлении вдруг выползло страшное окошко, которое ничего хорошего не обещало:
Первая мысль - "WTF?", ведь до этого расширение работало и ни на что не жаловалось.
Вторая мысль - ок, я сделаю как ты просишь, только не бей. И вот тут облом! Сообщение любезно подсказывает, что можно сделать, но эти действия ни к чему не приводят!
За чашечкой кофе приходит третья мысль - хочешь записи в справочниках? Будут тебе записи в справочниках! Быстренько пишу обработку, которая эти записи туда вносит (ну не то чтобы быстренько... пришлось поковырять исходники), запускаю... И ничего! И не просто ничего, а ничего с приколом - мои с любовью внесенные записи оказались помечены на удаление. "WTF?" снова подумал я и сел курить исходники более вдумчиво.
Ларчик открывался достаточно просто
В модуле менеджера справочника ИдентификаторыОбъектовМетаданных есть функция СвойстваКоллекцийОбъектовМетаданных, а в ней вот такие строки:
// Роли
Строка = СвойстваКоллекцийОбъектовМетаданных.Добавить();
Строка.Идентификатор = Новый УникальныйИдентификатор("115c4f55-9c20-4e86-a6d0-d0167ec053a1");
Строка.Имя = "Роли";
Строка.Синоним = НСтр("ru = 'Роли'");
Строка.ИмяВЕдЧисле = "Роль";
Строка.СинонимВЕдЧисле = НСтр("ru = 'Роль'");
Строка.БезДанных = Истина;
Строка.БезКлючаОбъектаМетаданных = Истина;
Строка.ОбъектыРасширений = Истина;
// ПланыОбмена
Строка = СвойстваКоллекцийОбъектовМетаданных.Добавить();
Строка.Идентификатор = Новый УникальныйИдентификатор("269651e0-4b06-4f9d-aaab-a8d2b6bc6077");
Строка.Имя = "ПланыОбмена";
Строка.Синоним = НСтр("ru = 'Планы обмена'");
Строка.ИмяВЕдЧисле = "ПланОбмена";
Строка.СинонимВЕдЧисле = НСтр("ru = 'План обмена'");
// Справочники
Строка = СвойстваКоллекцийОбъектовМетаданных.Добавить();
Строка.Идентификатор = Новый УникальныйИдентификатор("ede89702-30f5-4a2a-8e81-c3a823b7e161");
Строка.Имя = "Справочники";
Строка.Синоним = НСтр("ru = 'Справочники'");
Строка.ИмяВЕдЧисле = "Справочник";
Строка.СинонимВЕдЧисле = НСтр("ru = 'Справочник'");
// Справочники
Строка = СвойстваКоллекцийОбъектовМетаданных.Добавить();
Строка.Идентификатор = Новый УникальныйИдентификатор("ede89702-30f5-4a2a-8e81-c3a823b7e161");
Строка.Имя = "Справочники";
Строка.Синоним = НСтр("ru = 'Справочники'");
Строка.ИмяВЕдЧисле = "Справочник";
Строка.СинонимВЕдЧисле = НСтр("ru = 'Справочник'");
Строка.ОбъектыРасширений = Истина;
Запускаем, ждем, ошибка пропала, записи в нужных справочниках создались. Почти чудо. Почему почти? Потому что через некоторое время в ходе обновления мы получим вторую ошибку:
Вот тут есть два пути:
- Добавить наши объекты в нужные обработчики. Это конечно самый правильный путь, но это снятие с поддержки. А именно снятия с поддержки мы и хотим избежать используя расширения.
- Заставить систему игнорировать наши объекты, для этого в модуле ИнтеграцияСТехнологиейСервиса есть процедура ПриОпределенииИсключенийНеразделенныхДанных
Вот теперь красота и умиротворение.
В присоединенном файле находится расширение, оно полностью повторяет то что написано в статье. Просто добавьте его в свою конфигурацию перед обновлением.
Надеюсь мой опыт кому-то пригодится и поможет сэкономить несколько часов жизни. Обсуждения и конструктивная критика приветствуются.
Скачать файлы
Наименование | Файл | Версия | Размер | |||
---|---|---|---|---|---|---|
Обновление конфигураций на БСП, у которых в расширениях есть собственные объекты с данными:
.cfe 7,95Kb
12.02.18
46
|
.cfe | 7,95Kb | 46 | Скачать |
См. также
Специальные предложения
&После("ПриОпределенииИсключенийНеразделенныхДанных")
Процедура Фикс_ПриОпределенииИсключенийНеразделенныхДанных(Исключения)
//Раскомментировать Возврат, если используется разделение
//Возврат;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
//Справочники
Для Каждого ОбъектМетаданных Из Метаданные.Справочники Цикл
Расш = ОбъектМетаданных.РасширениеКонфигурации();
Если Расш <> Неопределено Тогда
Если ОбъектМетаданных.ПринадлежностьОбъекта = Метаданные.СвойстваОбъектов.ПринадлежностьОбъекта.Собственный Тогда
Исключения.Добавить(ОбъектМетаданных);
КонецЕсли;
КонецЕсли;
КонецЦикла;
//Регистры сведений
Для Каждого ОбъектМетаданных Из Метаданные.РегистрыСведений Цикл
Расш = ОбъектМетаданных.РасширениеКонфигурации();
Если Расш <> Неопределено Тогда
Если ОбъектМетаданных.ПринадлежностьОбъекта = Метаданные.СвойстваОбъектов.ПринадлежностьОбъекта.Собственный Тогда
Исключения.Добавить(ОбъектМетаданных);
КонецЕсли;
КонецЕсли;
КонецЦикла;
//Документы
Для Каждого ОбъектМетаданных Из Метаданные.Документы Цикл
Расш = ОбъектМетаданных.РасширениеКонфигурации();
Если Расш <> Неопределено Тогда
Если ОбъектМетаданных.ПринадлежностьОбъекта = Метаданные.СвойстваОбъектов.ПринадлежностьОбъекта.Собственный Тогда
Исключения.Добавить(ОбъектМетаданных);
КонецЕсли;
КонецЕсли;
КонецЦикла;
//Планы обмена
Для Каждого ОбъектМетаданных Из Метаданные.ПланыОбмена Цикл
Расш = ОбъектМетаданных.РасширениеКонфигурации();
Если Расш <> Неопределено Тогда
Если ОбъектМетаданных.ПринадлежностьОбъекта = Метаданные.СвойстваОбъектов.ПринадлежностьОбъекта.Собственный Тогда
Исключения.Добавить(ОбъектМетаданных);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
ПоказатьДругое дело, что если вы хотите использовать новые возможности, то нужно режим совместимости у конфигурации менять. Но это меняет только корень, да и в последующем новые релизы будут штатно поддерживать 8.3.11
В типовых бывает есть и проверка версии текущего режима совместимости установленного в конфе с тем что в коде зашит как поддерживаемый.
Тогда приходится лезть и ломать эту проверку все так же редактируя типовыую.
В БСП 3.Х ряд проблем 1С уже порешала давно, однако в типовых пока этой БСП не видел.
Есть стойкое ощущение, что мы БСП 3 еще не скоро увидим в типовых
Либо опять же перекрывать проверку в расширении.
Например, если к примеру в ERP под юзером с правами маркетолога и манагера по продажам попытаться открыть справочник номенклатуры то ловится ошибка
{ОбщийМодуль.ПодборТоваровСервер.Модуль(2872)}: Поле объекта не обнаружено (ВидыНоменклатурыСоздать)
Форма.Элементы.ВидыНоменклатурыСоздать.Видимость = Ложь;
Я воспринимаю это как ошибку платформы, так как что-то не нашел в описании к платформе 8.3.12 такого нового поведения.
Суть того что происходит: В форме списка номенклатуры есть панель справа в которой можно осуществлять навигацию по иерархии папок или видов номенклатуры. В навигации по видам номенклатуры используется динамический список по справочнику ВидыНоменклатуры. В этом списке есть контекстное меню с добавленными разработчиками конфигурации вручную командами типа Создать, СоздатьГруппу... Команды самые стандартные, платформенные. В коде же разработчики конфы проверяют есть ли у юзера права на редактирование справочника ВидыНоменклатуры и если их нет, то программно прячут пункты контекстного меню. Но вот на 8.3.12 по видимому платформа стала сама прятать эти пункты меню со стандартными командами, если у юзера нет прав. В итоге имеем массу ошибок. Было дело думаю давай заглушек расширением наставлю, а оно то в одном месте, то в другом глюк, и сразу бросил это дело, так как так можно всю конфу заплатками облепить.
&НаСервере
Процедура ПриСозданииНаСервереПеред(Отказ, СтандартнаяОбработка)
// Добавление этих элементов необходимо для того, чтобы при выполнении штатного кода модуля "ПодборТоваровСервер"
// не вываливалось с ошибкой об их отсутствии (функция "УстановитьСтраницуВариантаНавигации()" (2865))
// при попытке открыть подбор номенклатуры под пользователем, у которого нет прав на изменение видов номенклатуры.
Если Элементы.Найти("ВидыНоменклатурыСоздать") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("ВидыНоменклатурыСоздать", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("ВидыНоменклатурыСоздатьГруппу") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("ВидыНоменклатурыСоздатьГруппу", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("ВидыНоменклатурыИзменить") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("ВидыНоменклатурыИзменить", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("ВидыНоменклатурыСкопировать") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("ВидыНоменклатурыСкопировать", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("ВидыНоменклатурыУстановитьПометкуУдаления") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("ВидыНоменклатурыУстановитьПометкуУдаления", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("СоздатьВидНоменклатуры") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("СоздатьВидНоменклатуры", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("СоздатьГруппуВидовНоменклатуры") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("СоздатьГруппуВидовНоменклатуры", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("СоздатьГруппуНоменклатуры") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("СоздатьГруппуНоменклатуры", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("ИерархияНоменклатурыКонтекстноеМенюСоздатьГруппу") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("ИерархияНоменклатурыКонтекстноеМенюСоздатьГруппу", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("ИерархияНоменклатурыКонтекстноеМенюИзменить") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("ИерархияНоменклатурыКонтекстноеМенюИзменить", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("ИерархияНоменклатурыКонтекстноеМенюСкопировать") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("ИерархияНоменклатурыКонтекстноеМенюСкопировать", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("ИерархияНоменклатурыКонтекстноеМенюУстановитьПометкуУдалени я") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("ИерархияНоменклатурыКонтекстноеМенюУстановитьПометкуУдалени я", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("СписокСтандартныйПоискНоменклатураСоздать") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("СписокСтандартныйПоискНоменклатураСоздать", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("СписокСтандартныйПоискНоменклатураСкопировать") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("СписокСтандартныйПоискНоменклатураСкопировать", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("СписокСтандартныйПоискНоменклатураУстановитьПометкуУдаления ") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("СписокСтандартныйПоискНоменклатураУстановитьПометкуУдаления ", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("СписокРасширенныйПоискНоменклатураСоздать") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("СписокРасширенныйПоискНоменклатураСоздать", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("СписокРасширенныйПоискНоменклатураСкопировать") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("СписокРасширенныйПоискНоменклатураСкопировать", Тип("КнопкаФормы"));
КонецЕсли;
Если Элементы.Найти("СписокРасширенныйПоискНоменклатураУстановитьПометкуУдаления ") = Неопределено Тогда
НовЭлемент = ЭтаФорма.Элементы.Добавить("СписокРасширенныйПоискНоменклатураУстановитьПометкуУдаления ", Тип("КнопкаФормы"));
КонецЕсли;
КонецПроцедуры
ПоказатьКостыль конечно, но городить что-то более основательное нет желания, потом все равно исправят
Если не секрет, какой объем затычек таким образом сделан?
В 1С не писали по этой фиче?
Может это реально косяк такой.
Хотя с другой стороны судя по тому количеству кода, что они пишут сейчас в типовой сами, наверное это их забадало и решили платформу научить делать скрытие кнопок самостоятельно.
1С жалуется на справочник и регистр сведений.
В расширении перекрыт метод &После("ПриОпределенииИсключенийНеразделенныхДанных") модуля ИнтеграцияСТехнологиейСервиса, в менеджере справочника ИдентификаторыОбъектовМетаданных перекрыт &Вместо("СвойстваКоллекцийОбъектовМетаданных").
Чего ей ещё не хватает?
Платформа 8.3.11.3034, режим совместимости: не использовать. Конфигурация УП. Модифицированная псевдофранчами (судя по ужастному коду). Пытался обновить до версии 2.4.2.144. Но первый запуск после обновления вызывает "рекурсию": упомянутая выше ошибка с возможностью лишь выйти, перезапустить, или открыть обработку, т.е. обновление не завершается.
Ситуация на данный момент самая стандартная: производится перенос изменений из основной базы в расширение. Это должно вызвать и перенос данных в объекты расширения. Для каждого этапа ваять отдельную обработку переноса несколько нелогично. Корректнее было бы использовать типовой механизм обновления, но с опорой уже на версию расширения, а не подсистемы.
Но при переносе объектов из конфы в расширение обнаружена серьезная проблема: Есть справочник, в котором есть только Наименование и еще один реквизит - строка без ограничений. Этот справочник невозможно открыть в 1С, - выдается ошибка "Отсутствует отображение для типа '<некий_guid>'". У справочника нет ни одной формы. Не понимаю, чего ему от меня надо...?
Еще хуже обстоит дело с регистром сведений, - выдается ошибка "Отсутствует отображение для типа '<некий_guid>'" и далее две кнопки: Закрыть или Перезапустить. Но у РС я догадываюсь о возможной причине: в одном из измерений используется перечисление, а перечисления в расширения добавлены только в 12 релизе. Будем думать, что это глюк именно 11 релиза...
Но почему простейший справочник нельзя создать в расширении? - это непонятно...
Да. Пробовал менять вид расширения, - не помогает (предположил, что новые объекты будут работать только в режиме "Дополнение").
Документ.bk1_ПримененныеСкидки, РегистрСведений.bk1_ПримененныеСкидки в виде объектов, которые созданы только в расширении. И в этом случае я не могу их например включить в состав ОбластьДанныхОсновныеДанные, так как элементы не видны для конфигурации.:
{ОбщийМодуль.РаботаВМоделиСервиса.Модуль(4014)}: Обнаружены ошибки в структуре метаданных конфигурации:
1. Все объекты метаданных, не входящие в состав разделителей БСП (
ОбластьДанныхОсновныеДанные,
ОбластьДанныхВспомогательныеДанные),
должны быть включены в состав подписок на события
(
КонтрольНеразделенныхНаборовЗаписейПриЗаписи,
КонтрольНеразделенныхНаборовЗаписейПриЗаписиТехнологияСервис
КонтрольНеразделенныхОбъектовПриЗаписи,
КонтрольНеразделенныхОбъектовПриЗаписиТехнологияСервиса,
КонтрольНеразделенныхОбъектовПриЗаписиЭД),
контролирующих
невозможность записи неразделенных данных в разделенных сеансах.
Следующие объекты метаданных не удовлетворяют этому критерию: Документ.bk1_ПримененныеСкидки, РегистрСведений.bk1_ПримененныеСкидки.
ВызватьИсключение РезультирующееИсключение;

Просмотры 12724
Загрузки 46
Комментарии 41
Создание 12.02.18 16:32
Обновление 12.02.18 16:32
№ Публикации 784534
Рубрики
Практика программирования,
Тестирование и исправление
Кому
Системный администратор ,
Программист
Тип файла Расширение (cfe)
Платформа
Платформа 1С v8.x (все механизмы) ,
Управляемые формы
Конфигурация Конфигурации 1cv8
Операционная система Не имеет значения
Страна Не имеет значения
Отрасль Не имеет значения
Налоги Не имеет значения
Вид учета Не имеет значения
Раздел учета Не имеет значения
Доступ к файлу Абонемент ($m)
Код открыт Да
