Как сделать из &НаКлиентеНаСервереБезКонтекста почти &НаКлиентеНаСервере
Разработка - Универсальные функции
Для обновления свойств всех элементов формы в зависимости от ее реквизитов я в большинстве случаев создаю одну главную процедуру и вызываю ее при любом изменении влияющих реквизитов формы.
В случае управляемой формы такая процедура должна быть доступна и на клиенте и на сервере и не должна делать серверных вызовов. К сожалению в модуле управляемой формы недоступна директива компиляции &НаКлиентеНаСервере, а вместо нее есть &НаКлиентеНаСервереБезКонтекста. Поэтому у этой процедуры я всегда делаю параметр ЭтаФорма и передаю в него саму форму. Таким образом в теле процедуры контекст формы будет доступен через этот параметр.
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) НастроитьЭлементыФормы(ЭтаФорма); КонецПроцедуры &НаКлиенте Процедура Реквизит2ПриИзменении(Элемент) НастроитьЭлементыФормы(ЭтаФорма); КонецПроцедуры &НаКлиентеНаСервереБезКонтекста Процедура НастроитьЭлементыФормы(ЭтаФорма) Элементы = ЭтаФорма.Элементы; Элементы.Реквизит1.Видимость = ЭтаФорма.Реквизит2; КонецПроцедуры
Однако контекстная подсказка конфигуратора не будет понимать, что в параметре ЭтаФорма находится контекстная форма. Чтобы заставить ее думать, что там находится контекстная форма, можно применить следующую комбинацию инструкций препроцессора и директив компиляции
#Если Сервер И Не Сервер Тогда &НаСервере #Иначе &НаКлиентеНаСервереБезКонтекста #КонецЕсли
Правда в EDT парсер модуля ломается на такой легальной конструкции и исправлять эту ошибку не собираются.
В итоге модуль будет выглядеть так
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) НастроитьЭлементыФормы(ЭтаФорма); КонецПроцедуры &НаКлиенте Процедура Реквизит2ПриИзменении(Элемент) НастроитьЭлементыФормы(ЭтаФорма); КонецПроцедуры // Реальная директива здесь - &НаКлиентеНаСервереБезКонтекста, остальные директивы нужны для контекстной подсказки по параметру ЭтаФорма #Если Сервер И Не Сервер Тогда &НаСервере #Иначе &НаКлиентеНаСервереБезКонтекста #КонецЕсли Процедура НастроитьЭлементыФормы(ЭтаФорма) Элементы = ЭтаФорма.Элементы; Элементы.Реквизит1.Видимость = ЭтаФорма.Реквизит2; КонецПроцедуры
Вступайте в нашу телеграмм-группу Инфостарт
НаКлиентеНаСервереБезКонтекста НаКлиентеНаСервере
Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.
См. также
Универсальные функции 1С 8.3 1С:Документооборот Россия Платные (руб)
ДО+ — расширение конфигурации, в котором собран постоянно пополняемый набор из 33 востребованных доработок для 1С:Документооборот КОРП 3.0: согласование задач прямо из мессенджеров MAX и Telegram, отзыв согласования и исполнения, гибкие повторные круги, эскалация с точностью до минут, контроль исполнительской дисциплины, выгрузка вложений в ZIP и склейка PDF, реестр документов в Excel, проверка дублей контрагентов и регистрационных номеров. Каждая возможность активируется отдельным флажком в режиме предприятия — включается только то, что нужно конкретной организации. Список функций расширяется с каждым релизом — текущая версия 2.1.0. Режим AddOn: типовая конфигурация не модифицируется, обновления ДО ставятся штатно, дополнительные лицензии и внешние компоненты не требуются. Внедрение силами администратора — около часа.
30000 руб.
09.07.2026 1395 1 0
Загрузка и выгрузка в Excel Универсальные функции Разработчик 1С:Предприятие 8 Россия Бесплатно (free)
Описанный ниже подход позволяет в три шага заполнять формулы в Excel файлы, вне зависимости от ОС сервера (MS Windows Server или Linux). Подход подразумевает отказ от работы с COM-объектом в пользу работы через "объектную модель документа" (DOM).
30.10.2025 8732 Abysswalker 11
Универсальные функции Работа с интерфейсом Разработчик 1С:Предприятие 8 Бесплатно (free)
Порой необходимо временно отключить расширение 1С, не удаляя его, чтобы не потерять данные. Но в этом случае при каждом запуске всем будет лезть уведомление о неактивном расширении, хотя очевидно, это техническая информация, которой не стоит лишний раз пугать пользователей.
14.05.2025 14456 DeerCven 16
Инструментарий разработчика Универсальные функции Запросы Разработчик 1С:Предприятие 8 1C:Бухгалтерия 1С:Бухгалтерия 3.0 1С:Зарплата и Управление Персоналом 3.x Бесплатно (free)
Внешняя обработка для создания запроса на основании табличных данных.
22.07.2024 11941 276 ixijixi 10
Универсальные функции Разработчик 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)
Благодаря этим пяти строчкам можно больше не заморачиваться с загрузкой из внешних файлов. Пользуюсь везде, всегда и постоянно.
21.05.2024 68716 dimanich70 87
Универсальные функции Разработчик 1С:Предприятие 8 1C:Бухгалтерия Абонемент ($m)
Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.
1 стартмани
18.03.2024 9278 7 John_d 13
Универсальные функции Разработчик Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)
Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.
12.02.2024 85757 atdonya 31
Универсальные функции Разработчик 1С:Предприятие 8 Бесплатно (free)
На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.
30.11.2023 13468 ke.92@mail.ru 18
Но можно еще проще так директиву написать:
#Если Ложь Тогда
&НаСервере
#Иначе
&НаКлиентеНаСервереБезКонтекста
#КонецЕсли;
#Если Ложь
#Если Истина
#Если Штаны
Уже давно я попросил компанию 1С считать такие выражения некорректными, чтобы снизить вероятность скрытых опечаток, но пока они не стали этого делать.
Похоже они таки услышали. Причем буквально.
Такой код даже не компилируются:
#Если ИСТИНА Тогда
Сообщить("Истина");
#КонецЕсли
#Если Ложь Тогда
Сообщить("Ложь");
#КонецЕсли
Зато спокойно компилируется и отрабатывает вот такой код:
#Если Не МишкаКосолапый Тогда
Сообщить("Фигня");
#КонецЕсли
платформа еще 8.3.8
Если выдает ошибки при сохранении. Если сохранить, то при открытии:
"Ошибка в операторе препроцессора
#Если <<?>>ИСТИНА Тогда
Пропущен оператор препроцессора Если (If)"
Это кто ошибку дает?
Если выдает ошибки при сохранении.
Ошибка при сохранении:
{ВнешняяОбработка.ВнешняяОбработка1.Форма.Форма.Форма(5,8)}: Ошибка в операторе препроцессора
#Если <<?>>ИСТИНА Тогда (Проверка: Сервер)
{ВнешняяОбработка.ВнешняяОбработка1.Форма.Форма.Форма(7,3)}: Пропущен оператор препроцессора Если (If)
#<<?>>КонецЕсли (Проверка: Сервер)
{ВнешняяОбработка.ВнешняяОбработка1.Форма.Форма.Форма(5,8)}: Ошибка в операторе препроцессора
#Если <<?>>ИСТИНА Тогда (Проверка: Тонкий клиент)
{ВнешняяОбработка.ВнешняяОбработка1.Форма.Форма.Форма(7,3)}: Пропущен оператор препроцессора Если (If)
#<<?>>КонецЕсли (Проверка: Тонкий клиент)
Вот такой код будет корректен, но никогда не выполнится:
#Если Фигня Тогда
Сообщить("Фигня");
#КонецЕсли
А если перед ним написать:
Фигня = Истина;
то конфигуратор даже не среагирует. А при попытке открыть, выбросит исключение. Ведь снова получается:
#Если Истина Тогда
Да и любые комбинации, которые дают логическое значение, так же не будут работать.
#Если Север Тогда или так
&НаСервереНаКлиентеБезКонтекстаТо есть опечатки или просто не правильные имена (когда подразумевалось правильное имя директивы)
А вообще в 1С лучше бы ввели оператор как с С++ #define, чтобы можно было самому определять свои директивы (и самому же их обрабатывать), как-то так:
#Define MyOption ой, простите, - по русски:
#ОПРЕДЕЛЕНИЕ МояОпция
...
//где-то в далёком далёком модуле в одном месте алгоритма
#ЕСЛИ МояОпция ТОГДА
//некий алгоритм, завсящий от наличия выставленной опции МояОпция
#КОНЕЦЕСЛИ
Показать"#ОПРЕДЕЛЕНИЕ МояОпция" можно дополнить и окончанием "#ОПРЕДЕЛЕНИЕ МояОпция #КОНЕЦОПРЕДЕЛЕНИЯ"
Было бы круто! Можно было бы самостоятельно код ветвить ещё на стадии компиляции....
Хотя.... тут нужно более чётко логику прорабатывать
С одной стороны хочется чтобы эти опции можно было бы устанавливать в момент выполнения программного кода (но тогда это не как с C++ #define), чтобы можно было программно опцию выставлять - но это уже не директива препроцессора - и формально это решается либо константами, либо функциональными опциями, либо даже параметрами сеанса, с приправой кешированием через модули повторного использования.
Если же делать их именно классическими сишными, т.е. определяемыми в момент компилирования - тогда встаёт вопрос - где их размещать, чтобы алгоритмы ветвления корректно отработали. Но это, в рамках логики 1С, не проблема - ведь можно же найти сначала все дефайны во всех модулях (ну или хотя бы общих модулях)- сразу их все определить и затем уже ветвить компилить алгоритмы всех модулей конфигурации (и внешних обработок/отчётов кстати тоже, но уже при их открытии-создании).
Можно и просто отдельный новый модуль завести - типа как "Модуль сеанса" (или именно его и использовать) - где можно было бы размещать такие определения директив (и нигде больше).
Кстати, можно было бы сделать и гибридный вариант - т.е. дать возможность управлять определениями программно - но только в специальном модуле - который отрабатывал бы только в момент компиляции конфигурации. Вообще - такая исполнение - ОГОНЬ было бы! Эдакий модуль первичной инициализации конфигурируемого решения!
Ну и ещё, такие определения хотелось бы вешать не только на код алгоритмов, но и на метаданные -
Добавил, например, измерение регистру, пометил его как использующее определение "МояОпция" на значение ИСТИНА - если при компиляции конфигурации оно будет определено как ИСТИНА - измерение будет добавлено в конфигурацию информационной базы. Иначе - его там не будет. Ну, а, соответствующим образом (через ветвление по этом определение), помеченные алгоритмы, сами разберутся, когда использовать это измерение, а когда не использовать.
Суперский был способ упрощать и оптимизировать сложные конфигурации - отключая не используемые механизмы или делая их более вариабельными, модульными ещё на этапе компиляции, а не исполнения.
Эх.... наверное никогда этого не дождёмся.... :-(
Хотя, знаете, именно сейчас, пока 1С не прикрыла работу такой лавочки
#Если МояОпция Тогда
#КонецЕсливполне можно было бы это всё реализовать самому - попросту прогоняя тексты модулей через свой внешний препроцессор и заменяя
#Если МояОпция Тогда
...
#КонецЕслина
// так, увы, уже нельзя #Если ИСТИНА Тогда
#Если Сервер ИЛИ НЕ Сервер Тогда
...
#КонецЕслиКогда в каком-то модуле будет определно значения МояОпция = ИСТИНА
Как определить? Да хоть так
///#ОПРЕДЕЛЕНИЕ МояОпция = ИСТИНАФормально для 1С это не исполняемый и не компилируемый текст, но свой препроцессор может вполне его правильно разобрать
Ну, аналогично можно и с метаданными конфигурации
Правда помещать пометку придётся в свойство "Комментарий", как то так
"#ЕСЛИ МояОпция=ИСТИНА #КОНЕЦЕСЛИ" без "ТОГДА" оно здесь не нужно
Ну, в общем, что-то я совсем от темы удалился....
Мне статья понравилась, узнал что такая конструкция может иметь место быть
#Если Сервер И Не Сервер Тогда
&НаСервере
#Иначе
&НаКлиентеНаСервереБезКонтекста
#КонецЕсли
процедура какаято()....
(0) Раз пошла такая пьянка, то можно вообще упроститься до
#Если Сервер Или Не Сервер Тогда
//#Если Клиент Или Не Клиент Тогда <<или так
&НаКлиентеНаСервереБезКонтекста
#КонецЕслиПлатформа будто бы говорит "ой, всё! да вот вам чертов серверный контекст и не дурите голову!", предполагая что когда-нибудь этот бред все-таки не выполнится))
У меня сработал такой вариант:
#Если А Тогда
&НаСервере
#Иначе
&НаКлиентеНаСервереБезКонтекста
#КонецЕслиТолько минус во всех этих подходах, что подсказка работает, но только для серверных методов, т.к. была объявлена директива &НаСервере.
(17)
Это важное замечание.
Объявлять &НаСервере и не обязательно. Похоже что при наличии любых условий (##) такая директива добавляется в контекстной автоматом как директива по-умолчанию. Попробовал добиться, чтобы были видны клиентские методы (например, ПодключитьОбработчикОжидания) - вообще никак не получилось при любых вариациях с наличием условия (#Если + &НаКлиенте). Только при чистом &НаКлиенте видны.
Баловство это, но все равно интересно )
Мои примеры "работают", все проверил... Т.е. у меня одно есть контекстная подсказка, больше ни у кого нет?
&НаКлиентеНаСервереБезКонтекста
#КонецЕсли
Такой пример дает серверную контекстную подсказку без объявления где-либо НаСервере. Отлично бесконтекстно выполняется при и при клиентском и серверном вызове.
Блин, в чем тут заблуждение????
Причина оказалась в версиях платформы.
Например, На 8.3.6.2390 подсказка в моем примере еще была, на актуальной 8.3.10 - уже нет.
В данном конкретном случае снегопат просто выводит в своём списке содержимое штатной контекстной подсказки. Определяется это просто - если рамка вокруг списка толстая - это список, который составляет сам снегопат. Если рамка тонкая - это перехваченный снегопатом штатный список.
#Если Сервер Или Не Сервер Тогда
&НаКлиентеНаСервереБезКонтекста
#КонецЕслиИ в данном случае к контексту подсказки добавляется контекст по-умолчанию для модуля форм, т.е. &Сервер.
Если же #КонецЕсли будет после метода, то и контекст будет только тот, что указан препроцессору.
На ошибку нарвался буквально вчера в одной из обработок, которая раьше благополучно работала без этой инструкции..
Процедура УстановитьОграниченияТипа()
Попытка
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
РегистрационныеДанные = ОбработкаОбъект.СведенияОВнешнейОбработке();
Исключение
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
НСтр("ru = 'Возможно, обработка (отчет) устарела или не является дополнительной:'")
+ КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
Возврат;
КонецПопытки;
КонецПроцедуры
Показать&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
НастроитьЭлементыФормы(ЭтаФорма);
КонецПроцедуры
&НаКлиенте
Процедура Реквизит2ПриИзменении(Элемент)
НастроитьЭлементыФормы(ЭтаФорма);
КонецПроцедуры
// ---------------------->>>
&НаСервере
Процедура НастроитьЭлементыФормы(ЭтаФорма)
Элементы = ЭтаФорма.Элементы;
Элементы.Реквизит1.Видимость = ЭтаФорма.Реквизит2;
КонецПроцедуры ПоказатьВ противном случае нам за глаза хватило бы &НаСервереБезКонтекста передали нужные данные обработали, вернули на клиента и настраиваем форму как хотим :)
К сожалению, не понял как вы пришли к такому выводу, а может и к счастью.
(38)
Не нужно вырывать фразы из контекста. Речь идет о настройке формы. Например, смена доступности элемента. Или вы считаете, что для этого нужно обязательно бежать на сервер. А о политике 1С ничто не говорит лучше чем их официальные источники:
Как раз в этой заметке разработчики платформы признают, что не очень оптимально вызывать сервер для смены видимости элемента и начиная с 8.3.7 этот механизм перенесен на клиента.
Ни вижу смысла дальше развивать эту тему. Каждый случай индивидуален. И посему откланиваюсь
Также я понимаю, что не все изменения можно обработать без серверных вызовов. Такая обработка уже выполняется в обычном клиент-серверном стиле.
Не пытайтесь спорить сами с собой...
Никто не говорил что нужно ОБЯЗАТЕЛЬНО бежать на сервер.
Речь идет о том что не обязательно ждать когда управление вернется клиенту.
А ведь 1С могла решить проблему подсказок одной конструкцией, о которой давно мечтаю - типизированием параметров методов.
Т.е. чтобы можно было описывать методы как-то так:
Процедура СделатьЧтоТо(Форма: УправляемаяФорма, Список: СписокЗначений)
Понятно, что язык 1С не строго типизированный, но это можно сделать не для ограничения типов параметров, а только для подключения подсказки.
Да, это случай особый, но ту функцию, которую я описал, все равно иметь хочется. :-)
1С вполне могла бы так сделать, но пока она лишь ввела вывод подсказок параметров для места использования функций, из комментариев этих функций.
В модуле формы можно спокойно объявить несколько функций с одним наименованием, если они все будут с директивой &НаКлиентеНаСервереБезКонтекста
Обнаружил это случайно при парсинге модулей ERP 2.4
Там в нескольких отчетах такая копипаста.
При вызове функции берется вроде как первая объявленная
&НаКлиентеНаСервереБезКонтекста
Процедура ОдноИмя()
Сообщить(1);
КонецПроцедуры
&НаКлиентеНаСервереБезКонтекста
Процедура ОдноИмя()
Сообщить(2);
КонецПроцедуры
&НаКлиентеНаСервереБезКонтекста
Процедура ОдноИмя()
Сообщить(3);
КонецПроцедуры ПоказатьНе ругается, при вызове выводит "1". Что-то разработчики платформы вообще "без контекста".
А в модуле формы это невозможно из-за толстого клиента. В нем все на клиенте исполняется, соответственно получится дублирование процедур.
Реквизиты обработки - не видны на форме; реквизиты формы - не найдешь в другой форме и в общем модуле...
Не так. Без директивы в модуле формы УФ будет по-умолчанию "НаСервере"(Толстый клиент УФ файлового варианта не рассматриваем). Да, она будет доступна с клиента, но как серверный метод с контекстным вызовом.
С удивлением для себя обнаружил, что компилятор 1с позволяет при помощи инструкций препроцессора разрывать наименование процедуры с его параметрами как при вызове процедуры, так и при описании "тела" процедуры.
Это позволяет без передачи "ЭтаФорма" обращаться к контексту формы и выполнить одинаковый код как с клиента, так и с сервера.
#Если НаКлиенте Тогда
&НаКлиенте
Процедура Подключаемый_ОбработчикСобытия(
#Иначе
&НаСервере
Процедура Подключаемый_ОбработчикСобытияНаСервере(
#КонецЕсли
Параметр1 = NULL, Параметр2 = NULL, Параметр3 = NULL, Параметр4 = NULL,
Параметр5 = NULL, Параметр6 = NULL, Параметр7 = NULL) Экспорт
// Единый код обработки события для клиента и для сервера.
#Если НаКлиенте Тогда
УниверсальныйОбработчикСобытий(
#Иначе
УниверсальныйОбработчикСобытийНаСервере(
#КонецЕсли
Параметр1, Параметр2, Параметр3
, Параметр4, Параметр5, Параметр6, Параметр7);
КонецПроцедуры
ПоказатьВы можете заказать платную консультацию или разработку у автора. Будет создан приватный заказ на «Бирже заказов» для автора.
№ 671436
Создание 10.09.17 10:07
Обновление 19.04.23 13:45
Просмотры 79149
Загрузки 0
Рейтинг
157
Комментарии 79
Код открыт Да
Рубрики Универсальные функции
Кому Разработчик
Тип файла Нет файла
Платформа 1С:Предприятие 8
Конфигурация 1C:Бухгалтерия
Операционная система Не имеет значения
Страна Россия
Отрасль Не имеет значения
Налоги Не имеет значения
Вид учета Не имеет значения
Доступ к файлу Бесплатно (free)