1с передача параметров из общего модуля
В 1С на УФ можно из серверного кода формы передать форму как параметр в серверный общий модуль. И далее из серверного общего модуля в другой серверный общий модуль.
Но из клиенского кода формы и из клиентского модуля невозможно передать форму в серверный общий модуль.
Можно передать форму только из клиентского кода формы в серверный код формы.
Для решения проблемы из клиентского кода формы или клиентского общего модуля вызывают серверный метод формы, который уже передает форму в серверный общий модуль.
Это крайне ужасное решение, которое провоцирует весь код писать в форме, не разнося ее по модулям. Нужно как можно скорее убрать это противоречивое ограничение.
(5) ну вот ты написал некую серверную процедуру Процедура(Форма) в общем модуле МойСервер.
А теперь хочешь эту процедуру вызывать из общего модуля Клиент, куда управление попадает из формы.
и получаешь ошибку невозможности передать форму на сервер.
В этот раз соглашусь с ТС !
Вот ни разу невнятное ограничение. Чем общий модуль хуже серверной процедуры формы . Геноцид.
(10) Нечасто. Но попадалось здоровые штуки делать, и это нелепое (на первый взгляд) ограничение неприлично нервов попортило.
(0) может в каком то частном случае это и нужно, но пока не сталкивался с таким, проблем написать в модуле формы нету
Иногда неудобно, согласен.
Но тут думаю вопрос в целом такой - сложные объекты не передать туда/обратно.
Каждый раз вызывая серверные етоды мы передаем туда весь контекст формы!(а не только ссылку на нее)
теперь первая форма на клиенте закрылась. Если на клиенте нет на нее ссылок, то 1С имеет право ее положить в мусор. Не бегать же за подсчетом ссылок на сервер?
Теперь вызывает так:
ВтораяФорма.ПолучитьРеквизитСудногоДня().Обновить(); //простите что? оно же в мусоре!
+(20) именно поэтому всякие массивы передаются с клиента на сервер как копии своих значений, чтобы не заниматься подсчетом ссылок
(20) в статье я описал, что при вынесении кода в общие модули с этой проблемой встретишься гарантированно. Это не неудобство, это БЕДА 1С
обычно думаешь, как бы оптимизировать: где несколько вызовов в один объединить, где по значению передавать, где без контекста, а то и без серверного вызова
тс думает, как бы сделать, чтобы говнокодить было проще
(24) если кодить проще, то результат лучше получается. Для этого 1с и была задумана, чтобы доступно и всерьез.
как видишь, из-за этой шняги все пишут формы не разбивая ее по модулям.
Что вредит читаемости, повторному использованию кода и т.п.
обрати внимание, что в формах на ОФ было принято использовать модуль формы, в УФ это рудиментом стало.
(32) я вот все хочу посмотреть на этот "нормальный код", но все скрывают, приходится самому статьи писать, просвещать дремучих
Мда уж. "Гении" не пытаются разобраться/почитать мануалы, они сразу, по своим поверхностным представлениям выдают шедевры космической глупости.
"Т.к. данные формы доступны и на клиенте и на сервере, то основным хранилищем всех данных выступает сервер, просто потому что взаимодействие клиента и сервера инициируется только с клиента. Это означает, что в момент работы в памяти сервера находятся все данные формы, и доступ к ним осуществляется напрямую. На клиенте же имеется в общем случае частичное представление этих данных, при необходимости подгружаемое с сервера. При дальнейшей работе с формой изменения данных могут передаваться туда и/или обратно для синхронизации состояний клиента и сервера."
(41) и? любая существующая на клиенте форма существует на сервере. В параметре передается просто ссылка на эту форму. В чем парадокс? Почему эту ссылку нельзя передать с клиента на сервер? Алле? Что за отрицание реальности?
(20) а в чем проблема? Если форма не закрыта, она существует на сервере и следовательно, на нее существует ссылка на клиенте. Даже если все ссылки на клиенте закрыты, если форма открыта, она существует и ее можно получить через коллекцию форм. Проблема надумана и отсосана из пальца
любая ссылка на форму - это ссылка на контекст формы (на клиенте и на сервере). Пока форма жива, эта ссылка имеет смысл, после закрытия формы она обращается в ничто.
(47) при вызове команды закрытия формы она фактически закрывается (т.е. в интерфейсе закрывается). И все ссылки на клиенте и сервере обращаются в Неопределено. В чем проблема?
(47) если ты именно про ссылки на созданные формы, то если форма создана и явно не уничтожена, она должна храниться в памяти. Она будет доступна в коллекции форм, если что.
(48) во первых это не так, никто не будет оббегать все объекты в поисках ссылок, это дорого
во-вторых, для этого понадобилось внезапно бы лезть еще раз на сервер
(49) внезапно мнение поменялось
ты вообще знаешь как устроены системы с управляемой памятью и сборщиком мусора?
Способ вызывать форму из клиента через функцию-посредник формы есть. значит, платформа может это делать, но не делает.
В итоге провоцируется длинный монокод формы.
(52) ты что-то не уловил. Никакого подсчета ссылок. Нет явной команды уничтожения формы - форма хранится.
(52) как сборщики мусора устроены. знаю. Теперь расскажи, как ты это применяешь для форм.
(53) да, но только в контексте одной формы, ты войдешь в этом контексте на сервере и выйдешь из него в нем же, другие формы на сервере ты так не изменишь
Подключили на форме 2 обработчика ожидания. В них передаем форму в разные методы (или даже модули) на сервер. Там параллельно с формой что-то делается.
Как синхронизировать потом на клиенте эти изменения?
(58) платформа стандартно все делает, в чем проблема? Для тебя удивительно, что все формы синхронизируются на клиенте и сервере.
Мы передаем не форму, а ссылку на нее. Форма всегда есть на клиенте и сервере.
Если с событиями объектов в 1С все хорошо – на них можно подписаться и встраивать свою логику в штатные алгоритмы, не изменяя модулей конфигурации, то, как известно, с событиями обычных форм дела обстоят хуже.
В этой статье я расскажу, как все-таки научиться управлять неуправляемыми формами из общих модулей.
1. Осмотримся
Попробуем понять, что именно может помешать нам в использовании механизма, подобного механизму подписок. В платформе есть возможность менять процедуру обработчика события формы или элемента управления на форме - можно, например, написать в общем модуле:
ФормаИлиЭлементФормы.УстановитьДействие(ИмяСобытия, Новый Действие («ИмяВашейпроцедуры»));
Попробуйте! И столкнетесь сразу с тремя проблемами:
1 – действие можно установить только для существующего экземпляра формы объекта, т.е. нужно отследить момент создания интересующей нас формы, получить ее экземпляр и произвести подмену действия (в управляемых формах ситуация улучшилась).
2 – наша процедура, которой мы замещаем штатный обработчик события формы, согласно встроенной справке 1С должна находиться в модуле формы и сигнатура этой процедуры должна совпадать с сигнатурой штатного обработчика, иначе платформа выдаст ошибку:
УстановитьДействие(, )
Процедура должна быть экспортируемой и располагаться в модуле формы , при этом количество параметров должно совпадать с необходимым количеством параметров события, инициирующего вызов действия.
То есть необходимо добавить в модуль формы для каждого возможного числа параметров по универсальной процедуре, подменяющей штатное действие.
Кстати, условие экспортируемости, по-моему, необязательно, поскольку процедура-обработчик вызывается самой формой локально. По крайней мере, у меня все работает без модификатора «Экспорт».
3 – естественно хотелось бы иметь возможность в нужных местах вызывать штатный обработчик, чтобы не дублировать его код в своем общем модуле. Но чтобы штатный обработчик можно было бы запустить извне формы, он должен быть экспортируемой функцией или в форме должна быть универсальная экспортная обертка для вызова штатных обработчиков .
2. Обдумаем увиденное
Исходя из всего вышесказанного, приходим к простым логическим выводам:
1 - инициализация механизма управления формой должна происходить в обработчике одного из первых событий в жизни формы, например, «Перед открытием», чтобы у нас было время для подмены всех нужных нам из числа остальных еще не вызванных обработчиков. Чтобы не менять код формы, можно внедриться в код какой-нибудь процедуры общего модуля, вызываемой при создании нужных нам форм.
2 – модуль формы должен содержать блок оберток универсального обработчика , которые будут вызываться нашим механизмом и в свою очередь будут вызывать универсальный (один для всех форм и их событий) обработчик, находящийся в нашем общем модуле. Отличаться друг от друга эти обертки будут только числом параметров, которое для личного комфорта можно отразить в названии этих процедур.
3 – модуль формы должен содержать универсальную экспортную процедуру-обертку для вызова произвольных локальных штатных процедур обработки событий формы и ее элементов.
3. Набросаем эскиз
Согласно этим умозаключениям модуль формы (пример из реально работающей и легко обслуживаемой конфигурации Комплексной Автоматизации на платформе 8.2) модифицируется следующим способом:
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
НашМодуль . НастроитьФормуДокумента ( ДокументОбъект , ЭтаФорма );
Процедура УниверсальныйОбработчик0()
Процедура УниверсальныйОбработчик1(П1)
Процедура УниверсальныйОбработчик2(П1, П2)
Процедура УниверсальныйОбработчик3(П1, П2, П3)
Процедура УниверсальныйОбработчик4(П1, П2, П3, П4)
Процедура ШтатныйОбработчик(Команда, П1, П2, П3, П4) Экспорт
Наши вставки в штатный модуль формы выделены цветом, они во всех формах абсолютно одинаковы, никогда не меняются и легко автоматизируются.
Что я имею в виду под автоматизацией – возможность скриптом убрать эти изменения в модулях форм перед обновлением конфигурации и последующей их обратной вставки после обновления.
Выше я показал, что это необходимый минимум. Если этих изменений в формах хватит для реализации подписок на события форм и их элементов, то этот механизм будет самым компактным из всех возможных. Если бы что-то подобное было встроено в платформу, то настройка форм вообще не требовала бы их изменения.
4. Первоисточники
Идеи почерпнуты из статьи, в которой есть все необходимое для реализации описываемого механизма:
Данная статья описывает, как штатными средствами передать в качестве параметра значение при открытии управляемой формы 8.2 в сравнении с тем, как аналогичную операцию получалось реализовать в обычных формах.
Как передаются параметры в обычных формах
В обычных формах для передачи параметра было 2 возможности:
- менее распространенный способ: в форме объекта на вкладке «Реквизиты» добавлялся реквизит, при необходимости определялся доступ визуальными средствами
- более распространенный способ: в модуле формы объявлялась экспортная переменная и в обработчике « ПередОткрытием » значение обрабатывалось
в обоих случаях вызов формы выглядел примерно так:
Форма = Объект . ПолучитьФорму ( "ФормаВыбора" , ВладелецФормы , КлючУникальности );
Форма . Параметр = ЗначениеПараметра ;
Форма . Открыть ();
Как передаются параметры в управляемых формах
В управляемых формах теперь есть возможность сразу передавать параметры при получении формы. Параметры передаются в виде структуры:
Параметры = Новый Структура ( "ТекущееЗначение" , ПоследнийЭлемент );
ФормаВыбора = ПолучитьФорму ( "Справочник.Номенклатура.ФормаВыбора" , Параметры );
НайденыйЭлемент = ФормаВыбора . ОткрытьМодально ();
Также у управляемой формы появились «расширения формы» (объект, справочник, документ, отчет). В зависимости от типа объекта определяется состав доступных параметров. Например, если в форме выбора справочника нужно позиционироваться на определенном элементе, то используется параметр «ТекущееЗначение». Большим плюсом является, что в самой форме не требуется писать обработчиков для предопределенных параметров, сокращает количество кода.
Также у разработчика появилась возможность определять свои параметры (в конструкторе управляемой формы вкладка «Параметры»). Время жизни параметров ограничено обработчиком ПриСозданииНаСервере , что логично т.к. параметры требуются только при создании формы, но если данный параметр определяет уникальность формы (установлен флаг «ключевой параметр» в свойствах параметра) он будет доступен и в других обработчиках.
Для передачи специфического параметра манипуляций требуется сделать немного больше:
В обработчике ПриСозданииНаСервере определить обработку данного параметра (обращение к переданным параметрам через свойство « Параметры », имеющее тип ДанныеФормыСтруктура )
- Описать получение формы и передать значение нового параметра в параметрах функции ПолучитьФорму.
Таким образом код будет иметь вид:
Параметры = Новый Структура ( "НовыйПараметр" , ПоследнийЭлемент );
ФормаВыбора = ПолучитьФорму ( "Справочник.Номенклатура.ФормаВыбора" , Параметры );
Заключение
Возможно данная статья кому-то пригодится, с экономит время и убережет от лишнего кода. Для более детальной информации о полном списке параметров управляемой формы рекомендуется посмотреть справку «Интерфейс управляемый \ Управляемая форма».
Небольшим заместителем глобальных переменных могут служить параметры сеанса, которые доступны в общих модулях. Но параметры сеанса могут сохранять не все типы значений, например, не получится так сохранить коллекцию значений (массив, структуру, список значений, таблицу значений и т.д.) Без преобразования в строку эти значения нельзя сохранить в параметре сеанса.
Кроме того, в параметрах сеанса не получается хранить сложные объекты, типа COM-объектов (в том числе из внешних компонент), обработок и др.
В некоторых случаях будет полезным следующий трюк:
В конфигурации создается обработка, которая обеспечивает доступ к модулю приложения из общего модуля.
В модуле обработки (не путать с модулем формы) размещаются следующие процедуры и функции:
Теперь в процедурах и функциях общих модулей можно делать следующие вещи:
Я думаю, вы выясните самостоятельно, как передавать параметры в процедуры и функции.
Еще хочу заметить, что такая обработка представляет собой ДЫРУ В БЕЗОПАСНОСТИ, потому что позволяет выполнить произвольный программный код и вызвать любую процедуру или функцию модуля приложения и общих модулей.
Еще хочу заметить, что этот трюк не соответствует идеологии платформы и возможно, что такая конфигурация не пройдет "1С:Совместимо", станет запутаннее и сложнее.
Кроме того, обращение к глобальным переменным будет довольно накладным (требуется создание объекта ОбработкаОбъект), но целью данной статьи является демонстрация технологических возможностей платформы на принципах "AS-IS". Вся ответственность за ваши программы лежит на вас.
Рекомендуется по возможности:
1. Обходиться вообще без глобальных переменных
2. Передавать информацию через параметры процедур и функций
3. Использовать параметры сеанса
4. Не допускать выполнения чужого программного кода
5. Комментировать сложные участки программы
Альтернативное решение, посредством общей формы вместо обработки
Недостаток вышеприведенного метода - в каждой функции общего модуля нужно создавать экземпляр обработки.
Реализация: :
Если есть общая-рабочий стол, то используем её, иначе создаем новую "ТестоваяФорма". На форму кладем ПолеВвода "рез" составного типа данных, и если форма-рабочий_стол,- то ещё два поляВвода "выражение_" и "парам".
В модуль формы кладем код
В модуль приложения
Пример использования
(не забудьте ф = ПолучитьОбщуюФорму("ТестоваяФорма", ,"ТестоваяФорма") в каждом модуле)
для формы, которая рабочий стол
- дополнение к статье писалось быстро - ошибки не исключены. Позже пересмотрю
- Код не поддерживает получение результата глоб.функций, точнее он не различает что выполняет - функцию или переменную. Позже перепишу что бы понимал
- При выполнении функций, процедур не поддерживается параметр локального контекста, например
Передача параметра в обычную форму
Из этой формы нам нужно открыть некоторую дополнительную форму, при этом текст из поля формы должен передаваться в открываемую форму. Дополнительная форма имеет следующий вид:
Таким образом, при на нажатии на кнопку "Выполнить открывается дополнительная форма с уже введенным текстом в поле:
Рассмотрим способ решения подобной задачи.
Решение
Для передачи параметров между обычными формами можно либо воспользоваться глобальной экспортной переменной модуля формы, либо создать реквизит формы. Рассмотрим оба способа для в рамках нашей задачи.
1. Использование глобальной экспортной переменной модуля формы.
В основную форму для процедуры-обработчика кнопки "Выполнить" добавим следующий программный код:
Переменная текст добавлена в модуль открываемой формы вместе с обработчиком события "ПередОткрытием":
Задача решена, причем достаточно просто!
2. Использование реквизита формы.
Для второго способа нам даже не нужно переписывать обработчики кнопки "Выполнить" и "ПередОткрытием". Все, что необходимо - это добавить в открываемую форму реквизит "Текст" с типом строка.
Выводы
В управляемых формах передавать параметры намного проще. В обычных формах в большинстве случаев используется описанный подход.
Обработку с примером из статьи Вы можете скачать по ссылке .
Когда количество изменений на предприятии превышает критический уровень в сторону необновляемых конфигураций - 1С предлагает создание управляемого приложения
Перенос данных из БЭСТ в ЗКБУ
Подбор номенклатуры и нечеткий поиск
Читайте также: