Имитация директивы компиляции &НаКлиентеНаСервере в форме, с полными контекстами и минимальными "костылями"

04.12.22

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

То, о чем долго мечтали: Имитация директивы компиляции &НаКлиентеНаСервере в форме через объявление разных процедур для каждого контекста с единым кодом исполнения. Для тех, кому удобство применения на практике превыше запретов стандартов.

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
Обработка с директивой компиляции почти &НаКлиентеНаСервере.
.epf 6,17Kb
0 1 850 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

С удивлением для себя обнаружил, что интерпретатор 1С вне зависимости от версии платформы позволяет в инструкции препроцессора отделить наименование объявляемой процедуры от её параметров и "тела". Именно это и позволяет написать единое "тело" процедуры для обоих контекстов, подставив это "тело" в разные для клиента и для сервера процедуры (объявить эти процедуры с разными наименованиями, по одной для каждого контекста).

Также параметры этих процедур можно сделать как зависящим от директивы компиляции (оставить их после наименования процедуры внутри инструкции препроцессора), так и независящими (оставить их после инструкции препроцессора перед "телом" процедуры).

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Реквизит1 = "123";
	Реквизит2 = "";
	Реквизит1Заполнен = Ложь;
	Реквизит2Заполнен = Истина;
	Реквизит1ПриИзмененииНаСервере();
	Реквизит2ПриИзмененииНаСервере();
КонецПроцедуры

#Область Реквизит1ПриИзменении
// Вариант процедуры с разным составом параметров.
#Если НаКлиенте Тогда 
	// Обработчик события ПриИзменении элемента Реквизит1.
	&НаКлиенте 
	Процедура Реквизит1ПриИзменении(Элемент)
#Иначе 
	&НаСервере 
	Процедура Реквизит1ПриИзмененииНаСервере()
#КонецЕсли
	Реквизит1Заполнен = ЗначениеЗаполнено(Реквизит1);
КонецПроцедуры
#КонецОбласти //Реквизит1ПриИзменении.


#Область Реквизит2ПриИзменении
// Вариант процедуры с единым составом параметров.
#Если НаКлиенте Тогда 
	// Обработчик события ПриИзменении элемента Реквизит2.
	&НаКлиенте 
	Процедура Реквизит2ПриИзменении(
#Иначе 
	&НаСервере 
	Процедура Реквизит2ПриИзмененииНаСервере(
#КонецЕсли
	Элемент = NULL)
	Реквизит2Заполнен = ЗначениеЗаполнено(Реквизит2);
КонецПроцедуры
#КонецОбласти // Реквизит2ПриИзменении.

Даже процедура "Реквизит1ПриИзменении" доступна для выбора в палитре свойств элемента Реквизит1 для события "ПриИзменении". В варианте "с единым составом" процедуру "Реквизит2ПриИзменении" в палитре свойств для события "При изменении" необходимо будет "заполнять текстом", так как в списке выбора будет только процедура "Реквизит1ПриИзменении".

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

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

3. Не следует разрывать инструкциями препроцессора ... объявления и места вызова процедур и функций.

Хоть конкретного примера "неправильного" разрыва инструкцией объявления процедуры в этой статье и не приведено, но все-равно применять или нет это способ имитации &НаКлиентеНаСервере каждый должен решать для себя "на свой страх и риск".

Альтернативное решение предложено в статье Как сделать из &НаКлиентеНаСервереБезКонтекста почти &НаКлиентеНаСервере, где контекст передается параметром ЭтаФорма в единую серверную процедуру "без контекста", а все производимые изменения процедуры выполняются в значении этого параметра.

Тестировалось на платформе 8.3.22.1709.

В приложении к статье находится обработка с кодом из листинга этой статьи.

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

Директива компиляции НаКлиентеНаСервере инструкция препроцессора

См. также

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

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

14.05.2025    5397    DeerCven    15    

57

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

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

21.05.2024    46286    dimanich70    83    

164

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

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

1 стартмани

18.03.2024    6837    6    John_d    13    

59

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

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

12.02.2024    57339    atdonya    31    

68

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

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

30.11.2023    8603    ke.92@mail.ru    17    

68

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

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

28.08.2023    22757    YA_418728146    8    

174
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. ixijixi 2070 04.12.22 18:36 Сейчас в теме
Интересно, и даже забавно. Но практического применения не предвижу)
2. Glebis 13 04.12.22 18:43 Сейчас в теме
(1) Одно применение точно есть и оно приведено в листинге статьи: вызывать клиентскую процедуру настройки состояния элементов формы (особенно видимость с её скрытым вызовом сервера) при выполнении события ПриСозданииНаСервере вместо клиентской ПриОткрытии.
3. ixijixi 2070 04.12.22 20:26 Сейчас в теме
(2) Традиционно это делается по-другому
4. Glebis 13 04.12.22 20:41 Сейчас в теме
(3) А где можно посмотреть на эту традицию?
6. ixijixi 2070 05.12.22 10:02 Сейчас в теме
(4) Любую типовую открыть
5. tormozit 7323 04.12.22 22:57 Сейчас в теме
Описанный способ имеет много недостатков по сравнению с монолитным. Например редактор не покажет параметры в подсказке по параметрам и т.д. Так что рекомендация в ИТС имеет веские причины. Я его не использовал и не буду использовать и другим не рекомендую, исключая желание поэскпериментировать.
Прикрепленные файлы:
12. triviumfan 102 12.12.22 12:00 Сейчас в теме
(5) Думал, edt будет умнее, но нет, тут даже хуже.
В этом "тестовом редакторе на стероидах" не просто контекстная подсказка не видит обработчик, но ещё и сам матом ругается.
Прикрепленные файлы:
14. Glebis 13 16.12.22 13:05 Сейчас в теме
(5) Да, при выносе параметров процедуры из блока инструкций (2й вариант) не отображаются параметры. Если параметры оставить рядом с наименованием объявляемой процедуры (вариант 1), то подсказка работает исправно.
7. triviumfan 102 05.12.22 14:13 Сейчас в теме
Согласен с предыдущими коментариями, чувствуется какая-то опасность.
8. Glebis 13 05.12.22 15:17 Сейчас в теме
(7) Пока не понял чем это опасно. При тестировании все работает идентично коду:
&НаКлиенте 
Процедура Реквизит1ПриИзменении(Элемент)
	Реквизит1Заполнен = ЗначениеЗаполнено(Реквизит1);
КонецПроцедуры

&НаСервере 
Процедура Реквизит1ПриИзмененииНаСервере()
	Реквизит1Заполнен = ЗначениеЗаполнено(Реквизит1);
КонецПроцедуры
Показать


Даже Экспорт процедур работает.
9. triviumfan 102 05.12.22 17:10 Сейчас в теме
(8) Да что-то очково. Проверял это на веб/мобильном/толстом клиентах? Где-то тут подвох.
Прикрепленные файлы:
10. Glebis 13 11.12.22 01:04 Сейчас в теме
(9) Пока только на толстом клиенте проверил, работает без проблем. Перенес в один из продактов на работе.

P.s. Коллеги, а за что вы без аргументации ставите минусы статье?
11. triviumfan 102 12.12.22 11:44 Сейчас в теме
(10) Я не ставил, т.к. заструдняюсь оценивать, просто подозрительно нестандартное решение.
Ещё добавил скрины из EDT
13. Glebis 13 16.12.22 12:47 Сейчас в теме
(11) EDT позволяет выбрать обе процедуры в качестве обработчиков событий формы даже в таком написании. Синтаксис контроль ругается, но форма работает исправно.
К огромному моему сожалению, после (ниже по коду) такой конструкции EDT отказывается вообще показывать контекстовую подсказку. Но если вызов этих процедур сделать до объявления процедур, то все работает: и переход к определению и подсказка о параметрах.
Прикрепленные файлы:
Для отправки сообщения требуется регистрация/авторизация