Механизм включения/отключения кода и обход защищенных модулей.

09.09.25

Разработка - Универсальные функции

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

Если жизнь предоставляет тебе лимоны, сделай лимонад.

Каждый день - шанс стать лучше.

Алгоритмы на каждый день. Часть 2.

Продолжаю тему простых алгоритмов, которые могут быть вам полезны.

Сегодня поговорим:

1. о механизме, который облегчит доработку сложных подсистем, конфигураций, в которых вы не знаете все взаимосвязи процессов и объектов, и

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

1. Механизм динамического включения и отключения кода

   Механизм динамического включения и отключения кода (алгоритма) родился не на пустом месте. Столкнулся с рабочей ситуацией - конфигурация для меня новая, сама конфигурация 15-тилетней давности, сильно доработана разными 1сниками и компаниями за эти годы, процессы не описаны, спросить некого.

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

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

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

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

 
 Как было раньше

 

//как было
// ...комментируется весь код, который изменяется...
//к = 1;

//как стало
к = 10;

 

Сейчас с использованием нового механизма конструкция поменялась на следующую - используем "Если Тогда Иначе" для выбора нового или прежнего алгоритмов. 

 
 как стало сейчас

 

Если НашОбщийМодуль.ИспользоватьКод(555, 1) Тогда //как стало
	к = 10;
Иначе //как было
	к = 1;
КонецЕсли;

Функция общего модуля выглядит незамысловато, то есть просто.  

Функция ИспользоватьКод(НомерЗадачи, КлючСтроки, СтруктураДанных = Неопределено, СтрокаОтвета = "") Экспорт
		
	УстановитьПривилегированныйРежим(Истина);
	
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	|	ТестАлгоритмовЛокализацияКода.Вкл,
	|	ТестАлгоритмовЛокализацияКода.ВклЛог
	|ИЗ
	|	Справочник.ТестАлгоритмов.ЛокализацияКода КАК ТестАлгоритмовЛокализацияКода
	|ГДЕ
	|	ТестАлгоритмовЛокализацияКода.Ссылка.НомерЗадачи = &НомерЗадачи
	|	И ТестАлгоритмовЛокализацияКода.Ссылка.ПометкаУдаления = ЛОЖЬ
	|	И ТестАлгоритмовЛокализацияКода.КлючСтроки = &КлючСтроки";
	
	Запрос.УстановитьПараметр("НомерЗадачи", НомерЗадачи);
	Запрос.УстановитьПараметр("КлючСтроки", КлючСтроки);
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	Рез = Ложь; 
	Если Выборка.Следующий() Тогда
		
		Рез = Выборка.Вкл;
		  		
		... //дополнительный код для регистрации события в ЖР
	
	КонецЕсли;
	
	УстановитьПривилегированныйРежим(Ложь);
	
	Возврат Рез;
	
КонецФункции

 

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

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

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

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

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

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

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

В дальнейшем, если ошибок не возникает, алгоритмы упрощаются - остается только код "как стало", прежний код комментируется, сама конструкция "Если Тогда Иначе" или комментируется, или удаляется. Справочник "Тест алгоритмов" по данной задаче "обнуляется" - проставляется 0, строки в табличной части очищаются. Данный элемент справочника в дальнейшем можно использовать для новых задач и новых локализаций кода.

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

Реализовал оба решения через механизм включения /отключения алгоритмов: задача максимум включалась, когда НашМодуль.ИспользоватьКод(НомерЗадачи, КлючСтроки) = Истина, иначе включалась задача -минимум. 

После обновления рабочей базы и тестов, стало понятно, что обе задачи (минимум и максимум) решены корректно.

По этому механизму у меня все.

   

2. Доработка процедур, которые вызываются из защищенных (невидимых) модулей

Буду описывать на гипотетическом примере, чтобы не обидеть вендора отраслевого решения. Имеется защищенный модуль - который нам внедренцам-разработчикам не доступен и не виден. Мы можем видеть вызов этого модуля и вызов некой процедуры, например ПриОткрытии(Форма), которая что-то проверяет и ,допустим, блокирует работу с формой документа с выводом блокирующего окна-предупреждения, которую мы сейчас открываем.

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

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

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

Вот мы отловили процедуру ПроверитьПраваПользователя() Экспорт.

Что теперь делаем: добавляем "параметр по умолчанию" в процедуру:

ПроверитьПраваПользователя(ВызовИзЗащищенногоМодуля = Истина) Экспорт.

Далее внутри видимой и открытой для редактирования данной процедуры мы изменяем логику:

Процедура ПроверитьПраваПользователя(ВызовИзЗащищенногоМодуля = Истина) Экспорт
...
Если НашОбщийМодуль.ИспользоватьКод(555, 1) Тогда //как стало
	//перехватили проверку права - возвращаем всегда истину без проверки
	...
	Если ВызовИзЗащищенногоМодуля = Истина Тогда //то есть вызывается из защищенного модуля
		Возврат Истина;
	КонецЕсли;   				
	
Иначе //как было
	//ничего не меняем - то есть получение права происходит ниже по коду без изменений	
КонецЕсли;  
...
КонецПроцедуры

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

Там, где нам надо изменить логику проверки прав пользователя - в местах, где эта процедура вызывается открыто и с возможностью доработки, мы добавляем такой вызов:  

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

Если НашОбщийМодуль.ИспользоватьКод(555,1) Тогда //как стало
    Разрешено = ПроверитьПраваПользователя(Ложь);
... //далее прописываем свою логику блокировки формы документа
Иначе //как было
    Разрешено = ПроверитьПраваПользователя();
КонецЕсли;

На этом все. Всем хоккей и добра!

С пользой для клиентов, Рустем

 
 См. также
  1. Анализ прав и ролей. Поиск подходящего профиля - алгоритмический анализ и поиск
  2. Оцифровка и визуализация склада - программная прорисовка склада
  3. Удаление документов для любых баз на управляемых формах
  4. Удаление справочников для любых баз на управляемых и обычных формах
  5. Перенумерация документов и справочников - с учетом префиксов номеров
  6. Свертка базы УТ 10.3 подокументно - новая концепция 
  7. Матричное программирование - демо-стенд матричного калькулятора
  8. Справочное хранение товаров в КА 2.5 - кейс запуска адресного склада
  9. Мини-обзор разных задач - от очевидного до неочевидного
  10. Поиск отчета по документам - пример анализа незнакомых конфигураций
  11. Флажок в динамическом списке - от теории до практики "как бы простой" задачи
  12. Из Json в ДеревоЗначений - удобный просмотрщик json-структуры
  13. Внедрение адресного склада в КА 2.5 - кейс запуска адресного склада
  14. Фрилансеру: про цены, про клиентов, про планирование - мое исследование
  15. Что такое форматированный документ - прекрасная возможность раскрасить любой текст
  16. Программная работа с упаковками в КА 2.5 - примеры адаптаций механизмов упаковок в КА 2.5
  17. Универсальное сравнение регистров накопления - связь по измерениям, сравнение по ресурсам
  18. Обход объекта рекурсивно - просмотр реквизитов документа с бесконечным открытием подуровней

Вступайте в нашу телеграмм-группу Инфостарт

обновление конфигурации защищенные модули

См. также

Универсальные функции Работа с интерфейсом Программист 1С v8.3 Бесплатно (free)

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

14.05.2025    3356    DeerCven    8    

45

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

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

21.05.2024    40645    dimanich70    83    

157

Универсальные функции Программист 1С v8.3 1C:Бухгалтерия Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    5999    6    John_d    11    

57

Универсальные функции Программист Стажер 1С v8.3 1C:Бухгалтерия Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    48613    atdonya    30    

65

Универсальные функции Программист 1С v8.3 Бесплатно (free)

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

30.11.2023    7763    ke.92@mail.ru    17    

66

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

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

28.08.2023    20915    YA_418728146    8    

174

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    6118    92    progmaster    17    

4
Для отправки сообщения требуется регистрация/авторизация