Разработка и поддержка расширений в экосистеме 1С — это мощный инструмент, который призван минимизировать трудности при обновлении типовых конфигураций. Однако на практике разработчики часто сталкиваются с неприятной ситуацией: после очередного обновления типовой базы (например, «1С:Зарплата и управление персоналом 3.1» или «1С:ERP») десятки расширений «отваливаются», а платформа при проверке логической целостности выдает пугающие сообщения о наличии неразрешимых ссылок.
В этой статье мы подробно разберем, почему возникает эта ошибка, как быстро и эффективно находить проблемные места в конфигураторе, почему автообъединение форм затирает ваши обработчики событий и какие архитектурные подходы нужно внедрить в практику, чтобы навсегда забыть об этой проблеме.
Когда мы заимствуем форму, документ или справочник в расширение, платформа создает внутренние связи между объектами расширения и объектами основной конфигурации. Эти связи строятся не только по именам объектов, но и по их внутренним уникальным идентификаторам — GUID.
При обновлении основной конфигурации разработчики фирмы «1С» могут изменить структуру метаданных:
Если в вашем расширении осталась заимствованная форма, которая ссылается на измененный или удаленный объект основной конфигурации, механизм контроля логической целостности платформы не сможет сопоставить старую связь с новой структурой. В результате мы получаем ошибку: «Неразрешимые ссылки на объекты метаданных». При этом конфигуратор часто ведет себя неинформативно, не указывая конкретный элемент формы, который привел к сбою.
Если расширений много, а заимствованные формы содержат сотни элементов, искать «сломанную» связь вручную в визуальном редакторе — задача крайне трудоемкая. Рассмотрим эффективные методы решения этой проблемы.
Это самый быстрый и надежный способ локализовать битые ссылки. Поскольку конфигурация расширения в текстовом виде представляет собой набор XML-файлов, мы можем применить к ней глобальный поиск.
Разберем этот процесс по шагам:
Ctrl + Shift + F).GUID.Как только вы обнаружите конкретный XML-файл формы и строку с некорректной ссылкой, вы сразу поймете, какой именно элемент (кнопка, поле ввода, группа) вызывает ошибку. После этого вы можете либо удалить этот элемент прямо в XML и загрузить конфигурацию обратно из файлов, либо точечно исправить его в визуальном редакторе Конфигуратора.
Если выгрузка в файлы по каким-то причинам неудобна, можно воспользоваться классическим методом исключения:
Иногда визуально свойства элемента формы (например, «Путь к данным» или «Тип значения») выглядят абсолютно корректно, но платформа все равно выдает ошибку. Это происходит из-за рассинхронизации кэша метаданных.
Чтобы исправить это, перейдите в свойства проблемного элемента, нажмите на кнопку с тремя точками в поле ПутьКДанным, выберите любой другой реквизит, а затем верните исходный. Такой простой «перевыбор» заставляет платформу перезаписать внутренние связи объекта и очистить битые ссылки.
При обновлении типовой конфигурации структура оригинальной формы поставщика меняется. Когда вы открываете заимствованную форму в расширении, конфигуратор распознает изменения и предлагает обновить форму в расширении для приведения ее в соответствие с основной конфигурацией.
В процессе этого интерактивного обновления запускается механизм трехстороннего сравнения и объединения. Алгоритмы платформы пытаются автоматически объединить структуру формы поставщика, изменения в основной конфигурации и ваши доработки в расширении. К сожалению, этот алгоритм несовершенен:
Именно поэтому интерактивное заимствование форм «как есть» ведет к постоянным затратам времени на их восстановление при каждом релизе.
Для того чтобы расширения действительно облегчали процесс обновления конфигурации, необходимо кардинально изменить подход к их проектированию. Рассмотрим основные архитектурные правила, которые уберегут ваш код от затирания.
Это самый важный принцип разработки отказоустойчивых расширений. Никогда не заимствуйте форму в редактор расширения целиком, если вам нужно просто добавить кнопку, поле ввода, изменить видимость или доступность элементов.
Вместо этого используйте программное создание элементов:
ПриСозданииНаСервере с аннотацией &После (&After).Рассмотрим пример программного добавления кнопки и назначения ей обработчика команды:
&После("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Проверим, нет ли уже нашей кнопки на форме (на случай повторного вызова)
Если Элементы.Найти("Расш1_КнопкаЗаполнения") = Неопределено Тогда
// Создаем команду формы в расширении
НоваяКоманда = Команды.Добавить("Расш1_КомандаЗаполнения");
НоваяКоманда.Действие = "Расш1_ВыполнитьЗаполнение";
НоваяКоманда.Заголовок = "Заполнить по шаблону";
// Добавляем кнопку на командную панель формы
Родитель = Элементы.ФормаКоманднаяПанель;
НоваяКнопка = Элементы.Добавить("Расш1_КнопкаЗаполнения", Тип("КнопкаФормы"), Родитель);
НоваяКнопка.ИмяКоманды = "Расш1_КомандаЗаполнения";
НоваяКнопка.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
КонецЕсли;
КонецПроцедуры
При таком подходе в метаданных расширения нет никаких «жестких» визуальных связей с элементами оригинальной формы. Если при обновлении конфигурации «1С» изменит положение кнопок или дизайн формы, ваш код все равно выполнится корректно, добавит кнопку программно, и платформа никогда не выдаст ошибку логической целостности.
Часто программисты заимствуют модули объектов (документов или справочников) только ради того, чтобы встроиться в транзакцию записи или проведения (например, события ПередЗаписью, ПриЗаписи, ОбработкаПроведения). Это плохая практика, так как изменения структуры модуля объекта при обновлении могут привести к конфликтам.
Создавайте Подписки на события непосредственно внутри самого расширения. Они работают точно так же, как и подписки в основной конфигурации, полностью изолируя ваш код от стандартных модулей. При обновлении метаданных оригинальные объекты могут изменяться как угодно — ваши подписки продолжат стабильно выполнять свои функции.
Заимствуйте в расширение только те объекты метаданных, без которых ваш код физически не сможет скомпилироваться. Если в коде расширения вам нужно прочитать реквизит справочника ФизическиеЛица, вам абсолютно не требуется заимствовать весь справочник со всеми его формами, макетами и командами. Достаточно заимствовать сам справочник и только один этот реквизит.
Чем меньше площадь соприкосновения расширения с основной конфигурацией, тем ниже вероятность того, что очередное обновление заденет заимствованные объекты и вызовет появление неразрешимых ссылок.
Проблема неразрешимых ссылок после обновления — это не недостаток платформы 1С, а следствие неоптимальной архитектуры самого расширения. Использование интерактивного переноса элементов форм создает жесткие зависимости, которые ломаются при малейшем изменении конфигурации поставщика.
Переход на программное создание элементов управления через обработчик ПриСозданииНаСервере, использование подписок на события и минимизация заимствованного дерева метаданных позволят вам создавать стабильные, долговечные расширения, которые будут безболезненно переживать любые обновления конфигурации.