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