Поговорим о расширениях

05.02.24

Разработка - Механизмы платформы 1С

Если у вас одно расширение, то намного больше преимуществ от его использования, чем проблем. Но стоит позволить количеству одновременно примененных расширений вырасти, как пропорция резко изменяется на менее привлекательную, вплоть до стойкого желания все удалить и перенести функционал в основную конфигурацию.

Иногда при работе с несколькими расширениями можно с удивлением обнаружить неочевидное поведение, которое или не было описано в документации, или описано значительно позже момента, когда большинство специалистов ознакомились с технологией и сейчас ошибочно считают свои знания актуальными.

 

Типы расширений и порядок применения

Те, кто изучал расширения в первых версиях, возможно, будут удивлены факту, что 1С ввело классификацию по ожидаемому применению:

  • Исправление - как понятно из названия, для исправления ошибок и временных правок, которые со временем должны удаляться;
  • Адаптация - для доработок, которые на постоянной основе изменяют базовую логики работы (желательно только одно подобное на всю базу);
  • Дополнение - для добавления новой функциональности, которая оказывает минимальное влияние на логику системы (например, новые отчеты).

Контроль использования не предусмотрен. Можно в "исправлениях" делать целые подсистемы с документами и регистрами, а в дополнениях вести правки ошибок в ожидании обновлений от вендора. Таким образом, вся ответственность за варианты применения лежит на разработчике расширений, которые, согласно моим наблюдениям на различных проектах, не заморачиваются и оставляют "адаптацию", которая устанавливается по умолчанию.

Пусть такое разделение сильно условно и не охватывает все варианты желаемого применения, но оно дает разработчикам небольшое преимущество - это возможность управления порядком применения расширений. Подключение функционала всегда происходит в строгой последовательности: Исправление, Адаптация и  последним Дополнение.

Порядком применения расширений равен порядку в списке расширения. Можно сказать, что список фактически  поделен на три сегмента и каждое новое расширение добавляется в конец соответствующего сегмента.

Пример. Пусть в базе есть расширение Адаптация1 и Дополнение1. Тогда расширение Адаптация2 будет добавлено на второе место, а Дополнение1 перейдет со второй позиции на третью. А если добавить Исправление1, то оно будет вставлено первым, а все остальные будут сдвинуты на одну позицию вниз.

 

К сожалению, на сегодняшний день помимо указания "назначения" не существует других штатных и удобных инструментов изменения порядка подключения расширений, если он по каким-то причинам не устраивает. Единственный доступный способ требует очень значительных усилий:

  1. Нужно выгрузить в файлы все расширения нужного типа (оставить только те, порядок которых удовлетворяет требованиям)
  2. Отключить им активность, после чего удалить эти расширения из базы
  3. Создать расширения-пустышки в нужном количестве (тип не важен)
  4. Загрузить в пустышки расширения из файлов в требуемом порядке. 

Только при выполнении описанной последовательности шагов следует учесть, что если в расширениях были добавлены новые объекты или реквизиты к существующим, то эти данные будут безвозвратно удалены из БД при удалении расширений. Следовательно, сперва нужно создать дополнительное служебное расширение, в котором продублировать все нужные к сохранению метаданные, а потом в режиме предприятия скопировать  в них все требуемые данные. После восстановления в базе расширений, нужно будет выполнить обратную операцию и восстановить данные из копий на оригинальные места.

 

Результат применения порядка подключения расширений

Для визуальных объектов, таких как формы и макеты, результат "расширения" зачастую равен эффекту сравнения-объединения с режимом сравнения по Именам. Поэтому желательно не надеяться на отсутствие конфликтов с другими расширениями и будущими обновлениями основной конфигурации, а безопасно вносить требуемые изменения с помощью добавления и/или расширения кода. В обоих случаях возможны проблемы :)

 

Добавление кода в расширяемый модуль

В расширенный модуль можно добавлять любой код, но проверка уникальности наименований выполнится только в сравнении с кодом основной конфигурации.

Для примера создадим несколько расширений, расширим в каждое из них форму и поместим в модуль каждой из форм процедуру с одним и тем же именем, но разным содержимым.

Если в основной конфигурации будет эта же процедура, то получим ошибку:

 

 

Если же убрать процедуру из основного модуля формы, то все ОК и никаких ошибок. Почему так? Неужели в расширениях возможна изоляция кода?!

Как оказалось, последнее из очереди применяемых к форме расширений оставит только свой вариант реализации метода!

 

 

И пусть теперь кто-то посмеет заявлять, что в 1С нет ООП-наследования :)

Важно. Даже если кажется, что ваши процедуры и функции из расширений на 100% уникальны и точно нигде не могут повториться, все равно сделайте лишнее движение и добавьте к названию метода префикс расширения - минус к красоте кода, но плюс к его предсказуемости!

 

Расширение существующего кода

У процедур как изолированного места для выполнения кода и у возвращающих значение функций из-за указанных различий есть отличия в механике их расширения.

Для процедур доступны четыре режима: "Вызвать перед", "Вызвать после", "Вызвать вместо" и "Вызвать вместо (с контролем)". Для функций доступны только два последних варианта: "Вызвать вместо" и "Вызвать вместо (с контролем)".

С уникальными вариантами вставки кода в начало и конец процедур все понятно и нужно только учитывать, что в точки "перед всем кодом" и "после всего кода" вставляют все расширения по порядку из списка расширений. Т.е. для второго по порядку расширения будет добавление кода в конец ПОСЛЕ кода первого расширения, но в начале добавление уже ПЕРЕД основным кодом и кодом первого расширения:

 

 

Режимы "Вызвать перед", "Вызвать после" максимально безопасны в применении, а вот со вторыми двумя нужно быть очень аккуратными!

Если расширять процедуры или функции с помощью "Вызвать вместо (с контролем)" в более чем в одном расширении, то будет применяться только первое из списка, а остальные будут проигнорированы, а пользователю будет выдано уведомление в нижнем правом углу (где все время пишут про загрузку курсов валют, обновление классификаторов, про необходимость настроить бэкапирование и прочий спам, к которому все давно привыкли и не читают):

<ИмяРасширения>: Обычная: Ошибка применения модуля "<ИмяРасширения> <ИмяМодуля>". Аннотация "ИзменениеИКонтроль" уже применена к методу "<ИмяМетода>"

 

Реакция на множественное расширение в режиме "Вызвать вместо" будет с точностью до наоборот - будет вызван код не из первого, а только из последнего по порядку расширения, где с помощью вызова метода ПродолжитьВызов() можно подняться сквозь расширения до основного кода:

 

Важно. Если применять режим расширения методов "Вызвать вместо" и забыть про возвратный вызов ПродолжитьВызов(), то выполнится код только из самого последнего расширения из списка. Если же используется режим "Вызвать вместо (с контролем)", то выполняться будет только код из первого расширения!

 

Различная реализация для клиента и сервера

Какой режим устанавливается для новых расширений по умолчанию и какой режим не сменит ваш сисадмин, которому поручат установить в базу новое расширение? Верно - "Безопасный режим". 

Особенностью расширения методов в безопасном режиме является то, что клиентские модули продолжают работать штатно, а весь серверный код расширений (за некоторыми исключениями) просто игнорируются. В конфигураторе никакие проверки об этом не скажут. И только при попытке непосредственного вызова пользователю выдаются сообщения в "спамерском уголке":

<ИмяРасширения>: Обычная: Ошибка расширения модуля <ИмяМодуля>': расширение модуля запрещено из-за того, что расширение <ИмяРасширения>' подключено в безопасном режиме

 

но в то же время:

 

 

Важно. Если в вашем расширении есть любые серверные методы, кроме обработчиков событий формы (почему-то на них ограничения безопасного режима не работают), то желательно организовать проверку, что расширение работает в нормальном, а не в ограниченном "безопасном" режиме.

 

Итоги

Работая с расширениями, я сталкивался с различными проблемами - неотключаемые права на непосредственное удаление у справочников из расширения, переставшие работать команды для расширенных объектов и еще несколько подобных мелочей. Но баги на то и баги, что их исправляют, и они больше не доставляют неприятностей. Я же хотел поговорить не про баги, а про документированные фичи.

Если у вас есть ряд расширений, которые добавляют новые элементы формы и расширение по управлению статусами документа, которая должна сделать "только чтение" на все реквизиты кроме, скажем, Комментария. Разделение по типам "использования" тут идеально подойдет. Если все расширения по умолчанию на "адаптации", то расширение со статусами делаем "дополнением" - хотя это с точность до наоборот к рекомендациям от 1С, но зато сразу работает, и не нужно во все расширения копировать знание про существование статусов.

Если после добавления расширений от третьих лиц код из вашего расширения внезапно выборочно перестал работать, то делаем поиск по всем расширениям имени проблемного расширяемого метода и смотрим на то, чтобы в новых расширениях не использовали аннотацию &ИзменениеИКонтроль или второй вариант - аннотацию &Вместо без возвратного ПродолжитьВызов().

А вот опасность безопасного режима в том, что вы о проблемах можете даже не догадываться, если ваша правка серверной функции заключается в переопределении значений возвращаемых структур и при этом расширенные клиентские процедуры будут все так же давать нужный визуальный эффект, то догадаться о причинах проблемы будет очень сложно. Получаем классическое "а на моем компьютере работает".

И если в файловой версии с галочкой безопасного режима еще все просто, то в серверной версии намного хуже с их профилями безопасности, где на уровне кластера серверов нужно текстом прописывать имена модулей, в которых разрешены/запрещены расширения серверных методов. Ведь с одной стороны в десятках баз на кластере могут совпадать имена модулей (какие-то нужно расширять, какие-то нет), а с другой стороны общие модули имеют свойство менять названия - сомневаюсь, что этим широко пользуются (разве что от безнадеги):

 

расширения внедрения обслуживание

См. также

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    7412    bayselonarrend    20    

154

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    5938    dsdred    16    

80

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    17628    YA_418728146    26    

71

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    11212    dsdred    44    

130

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    23748    SeiOkami    48    

135

Механизмы платформы 1С Системный администратор Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    18815    human_new    27    

80

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14723    YA_418728146    7    

166
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. frkbvfnjh 805 05.02.24 06:59 Сейчас в теме
Вы лучше скажите как правильно роли настроить в расширении, такое ощущение, что они в расширениях сделаны номинально и не работают вообще.
2. RocKeR_13 1366 05.02.24 09:38 Сейчас в теме
(1) Вы пример конкретный приведите)
4. triviumfan 97 05.02.24 10:32 Сейчас в теме
(2) У меня есть пример:
У юзера есть доступ на подсистему "Отгрузка", но нету прав на вложенную подсистему "РабочиеМеста".
Добавляю роль в расширении на вложенную подсистему и это не работает.
Методом тыка выяснил, что в расширении нужно добавить права и на подсистему "Отгрузка".
6. RocKeR_13 1366 05.02.24 15:44 Сейчас в теме
(4) Я просто оставлю это здесь)
Прикрепленные файлы:
MishinVl; Dementor; +2 Ответить
8. triviumfan 97 05.02.24 16:38 Сейчас в теме
(6) Сейчас тоже воспроизвести не смог, возможно, из-за платформы (у меня довольно свежая 8.3.23.1782, а на проекте была 22ая)
9. RocKeR_13 1366 05.02.24 16:46 Сейчас в теме
(8) Так это не из-за расширения: на gif'ке пример как раз-таки с конфигурацией. Без прав на родительскую подсистему, подчиненная тоже не отображается
5. stvorl 1047 05.02.24 12:15 Сейчас в теме
(1) По крайней мере, до недавнего времени, был момент, что если заимствуете объект из конфигурации, и пытаетесь сделать для него некую роль, которая разрешит пользователю его использование, то, кроме взвода флажков внутри объекта (чтение, просмотр, редактирование и т.п. 15 шт. каких надо) потребуется позаимствовать все реквизиты шапки и все табличные части с реквизитами, и взвести внутри каждого реквизита пару флажков доступности.

Выбешивает неимоверно. Вендор, в ходе развития типового продукта, постоянно добавляет в конфигурацию новые реквизиты. Пользователь расширения, при этом, теряет возможность работать с этими объектами, т.к., допустим, при записи карточки, будет попытка перезаписать новый реквизит, а прав у него нет: приходится оперативно ловить такие случаи, бежать в расширение и добавлять реквизиты и права на них.
7. RocKeR_13 1366 05.02.24 15:52 Сейчас в теме
(5)
кроме взвода флажков внутри объекта (чтение, просмотр, редактирование и т.п. 15 шт. каких надо) потребуется позаимствовать все реквизиты шапки и все табличные части с реквизитами, и взвести внутри каждого реквизита пару флажков доступности.

А у роли ставили галку "Устанавливать права для реквизитов и табличных частей по умолчанию"? Активно работаю с режима совместимости 8.3.8 примерно и таких проблем не припомню
14. stvorl 1047 05.02.24 20:37 Сейчас в теме
(7)
Да, флажок стоит.
Он, насколько я помню, регулирует автопоявление этих галочек на реквизиты, которые будут добавлены [в данном случае, в расширении]. Не помню, влияет ли на новые заимствованные.

Но чего он точно не отменяет - это необходимость, как минимум, позаимствовать все реквизиты исходного объекта в расширение, и впредь за таким своевременным "дозаимствованием" следить.
3. triviumfan 97 05.02.24 10:29 Сейчас в теме
В очередной раз повторяю "Расширения - от лукавого" :)
В расширенный модуль можно добавлять любой код, но проверка уникальности наименований выполнится только в сравнении с кодом основной конфигурации.

Если память не изменяет, то это поправили в какой-то из свежих платформ, вроде как расширение видит (или будет видеть) методы и объекты из других расширений.
И не совсем понятны примеры, ведь каждое расширение имеет свой префикс, и новые методы должны иметь его. А у вас "Дубли процедуры()" почему-то без префикса.
11. Dementor 1035 05.02.24 18:57 Сейчас в теме
(3) потому и без префикса, так как это не расширенная функция, а независимая.

Если память не изменяет, то это поправили в какой-то из свежих платформ, вроде как расширение видит (или будет видеть) методы и объекты из других расширений.

Читал документацию разных версий - там с точностью до наоборот. До какой-то версии расширения могли вызывать без Выполнить() методы друг друга, а потом это убрали. Но видимо я нашел лазейку с одинаковыми именами :)
12. triviumfan 97 05.02.24 19:03 Сейчас в теме
(11) и всё же:

Чтобы этого избежать, система при создании обработчиков событий использует при формировании имени обработчика значение свойства Префикс имен того расширения, в котором редактируется форма. Прикладному разработчику также рекомендуется использовать префикс для имен методов, добавляемых в расширяющем объекте. Если в результате образования результирующий формы все-таки образуется конфликт имен – возникает стандартная ошибка времени исполнения и результирующая форма оказывается полностью не работоспособной.

https://its.1c.ru/db/v837doc#bookmark:dev:TI000001528
Я все методы делаю с префиксом, чтобы избежать ошибок конфликтов имён.
13. Dementor 1035 05.02.24 19:10 Сейчас в теме
(12) я тестировал на 8.3.22 - форма выходит полностью работоспособной, просто в одном расширении вызывается код из соседнего расширения. Про необходимость делать префиксы для собственных методов я специально подчеркнул в конце блока про добавление нового кода.
15. stvorl 1047 05.02.24 20:40 Сейчас в теме
(3)
В очередной раз повторяю "Расширения - от лукавого" :)

Позволю себе с Вами немного не согласиться: многократно продавать разным заказчикам куда удобнее именно расширения, как модули для решения типовых задач. ;-)

Особенно если они все подключены к одному хранилищу конфигурации через удаленку, и вопрос централизованного их обновления существенно упрощен.

Так-то, конечно, есть много нюансов.
Скажем, к большей части БСП объекты из расширения не подключить. Сейчас это расстраивает больше всего.
triviumfan; +1 Ответить
10. RustIG 1747 05.02.24 18:48 Сейчас в теме
Я ряд алгоритмов из расширений перенес в конфигурацию. Естественно после долгих многочасовых тестов. Короче говоря, все что можно сделать через расширения, делайте через расширения. А что не получается, делайте через конфигуратор. Естественно для фреш не подойдёт. Такие выводы.
VyacheslavShilov; Dementor; +2 Ответить
16. RocKeR_13 1366 05.02.24 21:03 Сейчас в теме
(10) Тут главное продумать архитектуру расширений и правильно распределить между ними объекты. Пока в расширение не выношу только по причине каких-то технических ограничений. Например, в своё время пришлось так добавлять присоединённые файлы к документу через БСП (хотя потом пришла мысль сделать это через справочники "Файлы" и "Папки файлов"), когда нельзя было расширять определяемые типы. Вот о ролях пишут ещё, но я в принципе проблем с ролями в своей практике не встречал. Встречал непонимание, как работают роли на добавленные объекты, когда объект не появлялся у полноправных пользователей. А именно, если назначать пользователям права через БСПшные профили, не ставить галку "Использовать основные роли для всех пользователей" и не заимствовать полные права в это самое расширение
Dementor; +1 Ответить
17. user642369_vladimir2379 19.09.24 19:29 Сейчас в теме
(16)
Бухгалтерия предприятия КОРП, редакция 3.0, план счетов Хозрасчетный, модуль менеджера
Функция ПолучитьСчетаИсключения()
Там есть запрос "ВЫБРАТЬ ...". Когда ставлю полный запрет пользователям на зарплатные счета - валится в ошибку на этом запросе, так как не стоит РАЗРЕШЕННЫЕ. И таких мест(без РАЗРЕШЕННЫЕ) в БП 3.0 немало
Как Расширением решить эту ситуацию?
Оставьте свое сообщение