gifts2017

Под капотом управляемых форм

Опубликовал Андрей Овсянкин (Evil Beaver) в раздел Программирование - Практика программирования

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

Введение

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

Немного истории

Исторически сложилось, что клиентское приложение 1С всегда было реализовано в виде так называемого «толстого» клиента – программы, которая сама все делает в плане обработки данных. Это создавало заметную нагрузку на сеть, а кроме того, требовало наличия мощных клиентских машин.

Толстый клиент имеет и свои преимущества, поскольку прост, понятен и часто не требует дополнительных архитектурных звеньев в виде сервера приложений.

Версия 8.0 принесла нам трехзвенную архитектуру, в которой появился «сервер 1С:Предприятия» – отдельный программный компонент, который мог выполнять код бизнес-логики на специально выделенной мощной машине (сервере), тем самым, снизив объем данных, гуляющих по сети и требования к аппаратной части клиентских машин.

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

В основном, все оставалось по-старому, и клиентское приложение так и оставалось «толстым» клиентом, гоняющим сотни мегабайт по сети.

Версия 8.2 кардинально сломала устоявшийся подход к работе приложения и заставила по-новому взглянуть на архитектуру приложения. Об этом новом подходе и пойдет речь в данной статье.

Волшебный зверь Клиент-сервер

С выходом версии 8.0 все учебные курсы, книжки, статьи на ИТС и прочее, и прочее, все в один голос твердили нам – «обработка данных должна идти на сервере», «все нужно выполнять на сервере». Волшебное заклинание «на сервере» плотно забило мозг, так сильно, что на него уже никто внимания не обращал, как на информационный шум.

Опыт показывает, что рядовой программист практически никогда не знал, как нужно перенести код на сервер и что это вообще значит – «на сервер». Удивительно часто встречался код, который переносился «на сервер», но был написан с явным непониманием того, что это в итоге принесет.

На самом деле, все просто. Фраза «выполнить на сервере», означает, что ваш код будет выполнен на физически другой машине. Совсем на другом компьютере (который может располагаться на другом континенте), со всеми вытекающими эффектами. Там будет другая структура каталогов, другие права доступа и даже другая операционная система.

Однако многие уже опытные разработчики запросто писали такой код:

  • - Выбирается локальный файл
  • - Его путь передается на сервер
  • - Там по этому пути файл пытается открыться и падает с ошибкой «Файл не найден» (еще бы, он же остался на клиенте).

Переход на сервер

До версии 8.2 перенести исполнение кода на сервер можно было только одним способом – а именно, вызовом общего модуля с флагом «Сервер». Причем, только с этим флагом. Если помимо флага «сервер» поставить «клиент», то перехода не произойдет. По этому поводу на Инфостарте не так давно была неплохая статья про флажки в свойствах общих модулей (к сожалению, не могу найти ссылку, подскажете?).

Суть всех флагов модуля сводится к простым правилам:

  1. Флаг показывает, где будет скомпилирован код модуля (на клиенте, на сервере, во внешнем соединении)
  2. Если модуль скомпилирован в нескольких местах, то он будет виден только в соответствии с флагами. Клиентский – на клиенте, серверный на сервере. Переноса исполнения с машины на машину не будет.
  3. Перенос исполнения кода возможен только если в текущем контексте исполнения нет вызываемого модуля, но он есть в другом месте (если – модуль есть только на сервере, а на клиенте его нет, то будет сделан вызов сервера)

Флаг «Вызов сервера»

В версии 8.2 добавился флаг «вызов сервера», который помогает разрулить условия перехода на другую машину. Если модулю назначить этот флаг, то модуль будет виден с клиента, если нет – то попытка вызова с клиента приведет к ошибке. Код модуля виден не будет, как будто его нет совсем.

Таким образом, в обычном толстом клиенте перенести код на сервер можно, только если с клиента вызвать общий модуль, для которого:

  1. Установлен флажок «Сервер»
  2. Установлен флажок «Вызов сервера»
  3. Сняты все «клиентские» флажки

Особенности перехода на сервер

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

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

Это объясняет, почему не все объекты можно передавать на сервер. Это все потому, что не все они поддерживают сериализацию (превращение в строку и обратно). На сервер нельзя передать, например, «ДокументОбъект», т.к. у него в модуле объекта могут быть глобальные переменные, а в них записаны какие-нибудь сложные несериализуемые значения, вроде COM-объектов… Короче, ограничения по обмену с сервером понятны и обоснованны. Нужно следить за тем, что мы передаем на сервер и что возвращаем назад.

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

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

Отсутствие контекста (состояния) на сервере

Существует такая модель серверных приложений, когда сервер только отвечает на запросы, но ничего не сохраняет у себя в промежутке между двумя запросами. Эта модель называется моделью «без состояния» (англ. state-less).

Все HTTP-серверы современного интернета работают именно так. Клиенты посылают запросы, сервер выдает ответ и забывает все, что получал от клиента. Разумеется, есть вариации, но общая модель именно такая: сервер отрабатывает запрос и очищает все данные.

Сервер 1С работает по такому же принципу. В общем случае, в памяти сервера нельзя сохранить промежуточные данные между вызовами. Нельзя определить переменную, которая будет хранить данные между двумя вызовами.

Есть специальные объекты, в которых можно хранить очень незначительную часть данных – так называемые «параметры сеанса», но это именно специально выделенное место для хранения состояния. Каждый серверный вызов выполняет некоторую работу, возвращает результат и забывает все свои данные. В управляемом режиме про это всегда необходимо помнить.

Управляемое приложение

С выходом управляемого приложения фирма «1С» поступила с клиент-серверным взаимодействием, на мой взгляд, совершенно правильно. Она не стала его прятать, наоборот, она заставила всех видеть его, тыкнула всех носом: «смотрите, тут вы пишете код для физически разных машин, думайте, что делаете».

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

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

Тонкий клиент

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

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

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

Чтение данных из ИБ в форму и запись из формы в ИБ выполняется практически явно, этот момент можно отловить в событиях формы.

Тонкий клиент стал поистине «клиентом». Он больше не обрабатывает данные, он их показывает и позволяет редактировать. Всю обработку мы теперь явно переносим на сервер.

Устройство управляемой формы

Давайте рассмотрим, из каких частей состоит управляемая форма.

Самая важная часть в управляемой форме, это ее реквизиты. Те, синенькие, что расположены в панели справа вверху. Это, собственно, данные формы, ее основа. Только то, что указано в реквизитах можно разместить на форме.

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

Данные формы

Есть старая уже хохма про ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокументИмениНуралиеваБорисаГеоргиевича.

Управляемая форма добавляет очередного претендента на звание длинного и непонятного идентификатора: ДанныеФормыСтруктураСКоллекцией и еще ряд новых классов с именами вида «ДанныеФормы….что-то там». Давайте попробуем выяснить, что это за новые объекты.

Как уже говорилось выше, сервер предприятия не сохраняет свое состояние между двумя вызовами. Когда мы обратимся к серверу, он что-то выполнит для нас и тут же очистит все данные, созданные во время вызова. Объекты с именами «ДанныеФормы…» это как раз то место, в котором мы можем сохранять свои данные между двумя серверными вызовами. На сервере нельзя создать глобальную переменную уровня формы. Такой глобальной переменной должен быть реквизит в данных формы.

Обратите внимание, что классы данных формы любопытно называются «ДанныеФормыСтруктура» или «ДанныеФормыКоллекция». Это вообще, как мне кажется, неспроста. Эти объекты – это просто немного модифицированная стандартная Структура (или ТаблицаЗначений, соответственно).

Здесь стоит немного вспомнить обычные формы. Ведь как мы привыкли – В форме справочника достаточно присвоить переменной «Наименование» какой-то текст и этот текст попадет в СправочникОбъект, а оттуда – в информационную базу.

У управляемой форме все почти так, за исключением того, что все совсем не так :).Платформа предпринимает массу усилий, чтобы в повседневной работе программиста ему не приходилось с этим заморачиваться. Как правило, мы, как и раньше, присваиваем свойства реквизитам формы, а они попадают в СправочникОбъект, а оттуда – в ИБ.

Разница заключается в том, что теперь на клиенте не существует «СправочникОбъект». Как я уже говорил, это сложный объект, он не сериализуется, а значит, его нельзя передавать с клиента на сервер. Вместо «Объекта» на клиенте существует его упрощенный аналог – хранилище данных – объект ДанныеФормы.

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

Адресация данных формы

Данные формы доступны непосредственно в коде по тем именам, как они расположены в дереве реквизитов формы (в окне редактора)

Реквизиты верхнего уровня доступны сразу. Вложенные реквизиты доступны через точку. Раньше в обычной форме мы обращались к данным объекта напрямую. Мы писали «Наименование = «АААААА» и данные попадали в объект. Теперь надо писать «Объект.Наименование = «ААААА», потому, что реквизит «Наименование» вложен внутрь реквизита «Объект».

Обмен формы с сервером

Основным «двигателем» всех аспектов управляемой формы является то, что у нас state-less сервер. На нем не сохраняется ничего, никаких промежуточных данных. Всё состояние формы (текст в полях ввода, строки табличных частей и т.п.) хранится на клиенте. Вся совокупность данных формы называется контекстом формы.

Весь клиент-серверный обмен выполняется через сериализацию данных, а это, в свою очередь накладывает ограничения на те типы данных, которые можно передавать на сервер и обратно. Объект ДанныеФормыСтруктура и его «родственники» является этаким «хранилищем», которое гуляет с клиента на сервер и обратно. Только то, что хранится в данных формы, может сохраняться в промежутках между серверными вызовами.

Жизненный цикл формы объекта

Давайте рассмотрим, что происходит, когда мы открываем форму существующего элемента справочника.

  1. На клиенте вызывается метод «ОткрытьФорму» или мы просто открываем форму из какого-либо списка справочника. Начинается серверный вызов
  2. В памяти сервера создается новый СправочникОбъект, выполняется код модуля объекта (тот, что написан в самом низу модуля)
  3. Данные объекта считываются из базы данных, присваиваются значения реквизитов, наполняются табличные части объекта СправочникОбъект.
  4. В памяти сервера создается новая управляемая форма элемента
  5. Вызывается событие формы ПриЧтенииНаСервере, куда передается свежесозданный СправочникОбъект в параметре ТекущийОбъект
  6. Основной реквизит формы «Объект», тот, что в списке реквизитов выделен жирным шрифтом наполняется данными на основании данных СправочникОбъект. Здесь происходит обычное поэлементное присваивание свойствам объекта ДанныеФормы значений, записанных в одноименных свойствах объекта СправочникОбъект. По сути, происходит «ЗаполнитьЗначенияСвойств(ДанныеФормы, СправочникОбъект)
  7. СправочникОбъект уничтожается. Все его данные стираются из памяти сервера.
  8. Вызывается событие формы «ПриСозданииНаСервере», в котором мы получаем уже заполненные ДанныеФормы
  9. Данные формы сериализуются и отправляются на клиента, где форма отображается пользователю

Обратите внимание, что СправочникОбъект, к которому мы так привыкли в обычном приложении, уничтожился. Если в модуле объекта были какие-либо глобальные переменные, экспортные или не экспортные, все они стали потеряны.

Сохранить что-либо в данных объекта больше нельзя, все сохранение состояния должно выполняться в ДанныхФормы.

Теперь, давайте рассмотрим процесс записи данных справочника:

  1. Пользователь нажимает кнопку «Записать»
  2. Выполняется обработчик формы «ПередЗаписью» (на клиенте)
  3. Происходит серверный вызов
  4. В памяти сервера создается новый СправочникОбъект, он наполняется данными на основании данных текущей формы (что-то вроде ЗаполнитьЗначенияСвойств, но в обратном направлении – пишется из формы в объект)
  5. Вызывается обработчик события формы «ПередЗаписьюНаСервере», куда передается свежесозданный СправочникОбъект. С этого момента, если мы хотим что-то записать в базу данных, то менять нужно именно СправочникОбъект. Изменения данных формы не отразятся в записываемом объекте.
  6. Вызывается обработчик «ПередЗаписью» самого СправочникОбъект (в модуле объекта)
  7. Вызывается обработчик «ПриЗаписи» самого СправочникОбъект (в модуле объекта)
  8. Вызывается обработчик события формы «ПриЗаписиНаСервере», транзакция записи еще не завершена и можно отменить запись
  9. Вызывается обработчик события формы «ПослеЗаписиНаСервере», транзакция записи уже завершена
  10. СправочникОбъект уничтожается
  11. Выполняется возврат на клиента, где вызывается обработчик события формы «ПослеЗаписи»

Обратите внимание, серверное состояние восстанавливается с нуля, каждый раз создается новый СправочникОбъект. В промежутках между вызовами сервера он не сохраняется.

Конвертация данных формы

Для упрощения жизни существуют простые способы преобразования универсальных объектов «ДанныеФормы….» в привычные прикладные объекты и наоборот.

Так, например, можно получить наполненный данными СправочникОбъект на основании данных формы, если вызвать метод «РеквизитФормыВЗначение(«Объект»). При этом произойдет то, что описано выше – будет создан новый СправочникОбъект и наполнен данными из указанного реквизита данных формы.

Обратное преобразование выполняется методом «ЗначениеВРеквизитФормы». Если мы произвели какие-то действия с данными СправочникОбъект, например, очистили табличную часть, то мы должны поместить наши изменения обратно в форму, иначе будет что?

Правильно, измененный СправочникОбъект будет уничтожен при возврате на клиента, а данные формы останутся неизменными. Цикл записи объекта будет построен на старых данных формы, а стало быть, изменение табличной части просто пропадет.

Не все так плохо ;)

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

Команды формы

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

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

Каждая команда может быть размещена в командной панели, подменю, или на самой форме. Создаются команды на закладке «Команды» в редакторе формы.

Параметры формы

Параметры, это специальные переменные, которые можно передать в форму в момент ее открытия. Параметры задаются на закладке «Параметры» редактора формы и о них речь пойдет чуть ниже.

Управление открытием формы

Отображение форм на экране в управляемом режиме также претерпело некоторые изменения. Прежде всего, формы получили имена, по которым к ним можно обращаться. Например, форма списка справочника  «Контрагенты» будет называться «Справочник.Контрагенты1.ФормаСписка».

Методика открытия формы теперь такова: форма должна открываться одной строчкой кода и одним вызовом сервера. Эту задачу на себя берет глобальный метод «ОткрытьФорму». В данный метод мы должны передать имя формы (см. выше), параметры формы, владельца и ключ уникальности. Все параметры, кроме имени являются необязательными.

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

Для этого и нужны Параметры формы. Это структура, которую можно передать в метод «ОткрытьФорму». Переданные параметры можно проанализировать в серверном коде формы и предпринять какие-то действия на основании переданных параметров.

Простой пример, открытие формы списка с отбором. Для того, чтобы список справочника открылся с отбором по определенному условию нужно открыть форму списка и передать ей параметр с именем «Отбор», значением которого будет структура с полями отбора и значениями отбора.

УсловияОтбора = Новый Структура;
УсловияОтбора.Вставить("ТипКонтрагента", "Поставщик");
УсловияОтбора.Вставить("Лояльность", "Надежный");
ОткрытьФорму("Справочник.Контрагенты.ФормаСписка", УсловияОтбора);

Существуют системные параметры, на которые реагирует сама платформа. Упомянутый параметр «Отбор» как раз является системным, если он передан форме списка, то платформа сама установит отбор на список.

Кроме того, параметры можно создавать произвольные, в редакторе формы. Более того, параметры можно передавать даже с теми именами, которые не объявлены в форме, они все равно будут видны в серверном коде формы.

Жизненный цикл параметров

Все параметры, переданные в форму в момент ее открытия видны только в процедуре «ПриСозданииНаСервере». После создания все параметры уничтожаются и более не доступны в форме.

Исключение составляют параметры, которые в редакторе формы объявлены с признаком «Ключевой параметр». Такой параметр будет существовать до тех пор, пока существует сама форма.

Процедура ПриСозданииНаСервере(Отказ)

    Если Параметры.ЗапуститьЯдерныйРеакторПриОткрытии Тогда
        УправлениеРеактором.Запустить();
    КонецЕсли;

КонецПроцедуры

 

Ключевые параметры определяют уникальность окна. В обычных формах был такой атрибут «Ключ уникальности». Если запрашивалась форма, то она сначала искалась в уже открытых. Ключ уникальности позволял варьировать условия при которых создавалась новая форма или возвращалась существующая. Ту же самую роль играют ключевые параметры. Если метод «ОткрытьФорму» вызван два раза подряд с одним и тем же значением ключевого параметра, то второй вызов не откроет новое окно, а активирует существующее.

Модуль формы

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

Справедливости ради стоит отметить, что они доступны не только в модулях форм, но, как правило, используются только там. Директива компиляции это строчка вида &НаКлиенте перед объявлением процедуры.

Для модуля форм возможны следующие директивы:

  • &НаКлиенте
  • &НаСервере
  • &НаСервереБезКонтекста
  • &НаКлиентеНаСервереБезКонтекста

Директива указывает компилятору, где нужно скомпилировать указанную процедуру. С директивами «НаКлиенте» и «НаСервере» все понятно, а вот с добавкой «БезКонтекста» нужно разобраться подробнее.

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

Теперь, пользователь нажимает кнопку, которая вызывает процедуру с директивой «НаСервере». Все данные формы, должны быть отправлены на сервер, чтобы там с ними можно было поработать. Процедуры «с контекстом» (НаКлиенте и НаСервере) видят контекст формы, т.е. ее данные. Когда мы вызываем сервер «с контекстом», то контекст должен быть передан на сервер, поскольку его там в данный момент просто не существует (сервер state-less).

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

Поскольку все происходит настолько для нас прозрачно, что порой кажется: «какая красота, не надо заморачиваться, можно всегда писать «НаСервере» и на сервере все будет доступно». Однако, как видно из предыдущего абзаца, такая прозрачность не бесплатна. Все данные формы должны упаковаться, отправиться на другой континент, там распаковаться, после чего должен быть выполнен серверный код, и потом обратная упаковка и возврат изменений на клиента. Понятно, что накладные расходы на передачу контекста очень высоки.

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

Для облегчения клиент-серверного обмена введено понятие серверного вызова «без контекста». Отличается он тем, что при вызове «без контекста» контекст формы не передается и в серверном коде будет недоступен. Процедура «без контекста» не видит данных формы. Фактически, это вообще не модуль формы, а некий отдельный модуль, который ничего про форму не знает.

Во внеконтекстный метод можно передавать параметры и можно получать возвращаемые значения, однако, нельзя обращаться к данным формы, поскольку, нет самой формы.

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

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

Переменные уровня модуля формы

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

Причем, переменная, которая объявлена НаКлиенте, будет доступна все время жизни формы, а переменная НаСервере будет очищаться каждый раз при возврате с сервера (уничтожении данных серверного вызова).

Временное хранилище – секретное оружие

При работе с управляемыми формами быстро становится ясно, что ограничения клиент-серверного взаимодействия очень сильно сужают возможности разработчика. Поэтому, платформа 1С предоставляет хитрый секретный ход под названием «ВременноеХранилище». Эта сущность позволяет сохранить на сервере некоторое состояние между двумя серверными вызовами. Я слышу возгласы: «А кто сказал, что состояние нельзя хранить!» Справедливое замечание, состояние хранить все-таки можно, но недолго.

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

Для работы со временным хранилищем используются методы ПоместитьВоВременноеХранилище и ПолучитьИзВременногоХранилища.

С методом «Получить» все просто, он по заданному адресу возвращает значение, которое лежит в хранилище.

С методом «Поместить» несколько сложнее. Дело в том, что помещать можно в 2 разных хранилища – простое и хранилище формы. Хранилище формы живет на сервере столько, сколько живет сама форма. Простое хранилище живет ровно 2 серверных вызова. В синтакс-помощнике об этом написано целых несколько умных строк. Я никогда не понимал, что они означают. Опытным путем было установлено, что срок жизни – 2 серверных вызова.

  • Первый – мы помещаем что-то в хранилище и возвращаем адрес на клиента.
  • Клиент делает второй вызов и по этому адресу может получить данные.
  • В третьем вызове по этому адресу уже ничего не будет. Платформа очистит хранилище

С хранилищем формы ситуация более интересная. Если вторым параметром метода «ПоместитьВоВременноеХранилище» передать идентификатор формы (ЭтаФорма.УникальныйИдентификатор), то данные в хранилище будут привязаны к сроку жизни формы и не будут удалятся ни в первых, ни во вторых, ни во всех прочих вызовах сервера.

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

Особенности временного хранилища

Временное хранилище лучше всего представить себе, как файл на сервере. Технически это не так, но особенности оптимизации могут попить крови. Проще думать о нем, как о файле.

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

Как примерно работает временное хранилище:

  • Данные помещаются в ВХ
  • Управление возвращается на клиента
  • Клиент делает повторный серверный вызов
  • Менеджер кластера переключает вызов на другую машину из кластера (не ту, что помещала данные в хранилище)
  • И вот тут, если данные в хранилище были сериализуемые, то все отлично, мы получим их даже на другой машине кластера.
  • Если данные не были сериализуемые (СправочникОбъект, COM-объект, что-то еще), то они просто пропадут, ибо нефиг.

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

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

Если тип данных, помещенных в хранилище не поддерживал сериализацию, то данные просто уничтожаются.

Данные помещаются в хранилище по ссылке. Это значит, что помещая данные в хранилище и изменяя их вне хранилища мы, фактически, меняем и само хранилище, т.к. в нем лежит только ссылка на данные. Пример:

Массив = Новый Массив; Массив.Добавить("Привет");

Адрес = ПоместитьВоВременноеХранилище(Массив);

Массив.Добавить("До свидания");

МассивИзХранилища = ПолучитьИзВременногоХранилища(Адрес);

Сообщить(Массив = МассивИзХранилища); // Истина

Сообщить(МассивИзХранилища.Количество()); // 2 элемента

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

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

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

Краткий итог

  • - Взаимодействие с сервером теперь не спрятано от разработчика. Наоборот, оно каждую минуту напоминает о себе. И это хорошо.
  • - Сервер 1С не сохраняет данные между обращениями клиента к серверу. Нужно проектировать взаимодействие с учетом этой особенности
  • - Временное хранилище – мощное средство, которое нивелирует сложности state-less взаимодействия и позволяет строить сложные схемы серверных вызовов.
  • - У формы есть контекст, который передается с клиента на сервер и обратно при каждом контекстном вызове сервера. Для несложных вызовов, где не требуется вся форма целиком, следует использовать внеконтекстные вызовы.

Заключение

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

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

Литература к прочтению

Новичкам однозначно нужно прочитать книжку Максима Радченко «Разработка управляемого интерфейса». На старости лет мог напутать с точным названием, извиняйте. Книжка зеленоватая такая.

Все основные моменты разработки не только форм, но и вообще всего управляемого приложения в ней описаны просто замечательно.

Постскриптум

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

Удачи вам в разработке управляемых форм. Если вы дочитали до конца, значит, вам было что узнать. Скорее ставьте плюсик :)

См. также

Вознаграждение за ответ
Сумма: 0 $m
Добавили:
Юрий Юршин (donikx) (1.00 $m), Sofiya Imamova (Sofi975) (0.75 $m), Вадим Тихонов (Farpost) (0.05 $m)
Подписаться Добавить вознаграждение
Комментарии
1. Сергей Ожерельев (Поручик) 26.08.13 19:07
(0) Дочитал до конца, но нового ничего не узнал. Так, чисто время занять, пока большой файл скачивается.
Всё написано и разжёвано в книге Хрусталёвой Разработка управляемого интерфейса.
2. Андрей Овсянкин (Evil Beaver) 26.08.13 19:22
В аннотации про это честно сказано :)
3. B2B (B2B) 26.08.13 20:34
Сервер 1С работает по такому же принципу. В общем случае, в памяти сервера нельзя сохранить промежуточные данные между вызовами.

Не согласен.
хранилище данных

Зря использовали это словосочетание. Оно напоминает "ХранилищеЗначений". Кто-то может спутать.
СправочникОбъект уничтожается. Все его данные стираются из памяти сервера.

Не согласен.

При открытии формы элемента справочника СправочникОбъект остается на сервере, а на клиент передается описывающий его ДанныеФормыСтруктура*. И будет существовать этот СправочникОбъект на сервере до тех пор, пока форма не будет уничтожена (ну, может еще по таймауту).

Именно поэтому существуют контекстные и бесконтекстные вызовы сервера. Это подчеркивает, что контекст существует и на сервере и на клиенте.
4. Александр Лыткин (TrinitronOTV) 26.08.13 21:37
(3) B2B, не смотря на ваши замечания, всё равно прочитал с большой пользой для себя. Спасибо автору статьи за данный материал
5. Сергей Марченко (MarSeN) 26.08.13 21:53
(3) B2B,
Именно поэтому существуют контекстные и бесконтекстные вызовы сервера. Это подчеркивает, что контекст существует и на сервере и на клиенте

Рискую ошибится, но думаю, что это ни о чем не говорит.

Я рассуждаю так: если СправочникОбъект остается на сервере, тогда зачем в принципе нужно разделение на контекстные и бесконтекстгые процедуры? Ведь контекст остался на сервере?
Но тут возникают но... Данные на форме могли поменяться и поэтому при контекстном вызове их надо обновить (должно происходить если на сервере контекст сохранен), либо если контекст уничтожен на сервере, тогда контекстный вызов просто необходим.
На личном опыте замечено что не важно сколько ты информации изменил на форме, на скорости контекстного вызова это не сказывается (т.е. платформа не отслеживает только измененные объекты и не передает только их) что косвенно подтверждает теорию отсутствия СправочникОбъект на сервере. Либо говорит о том что 1С здесь чего-то не доработало.
Это мое сугубо личное мнение и оно, возможно, является ошибочным.
6. B2B (B2B) 26.08.13 22:09
(5) Суть контекстных и бесконтекстных вызвовов следующая: в случае контекстного вызова на сервер кроме всех параметров формы передается контекст (некий идентификатор), по которому сервер находит и обновляет состояние СправочникОбъект, а бесконтекстный вызов всего этого не делает.
7. Андрей Овсянкин (Evil Beaver) 26.08.13 22:30
(6) B2B, грубейшая ошибка. С чего вы взяли про идентификатор какой-то?
СправочникОбъект уничтожается при возврате на клиента. Контекст формы существует только в виде ДанныхФормы и ее элементов. У вас есть подтверждения ваших слов про то, что СправочникОбъект живет на сервере пока открыта форма?
IvanBoychuk123; Bukaska; +2 Ответить 1
8. Андрей Овсянкин (Evil Beaver) 26.08.13 22:33
Коллеги, еще раз: из СправочникОбъект-а создается структура с такими же свойствами, заполняется данными из СправочникОбъект-а. Все, дальше в форме живет только эта структура.

Доказательство - ХранилищеЗначения в реквизитах объекта.
Домашнее задание - сделать управляемую форму справочника с реквизитом типа ХранилищеЗначения. В хранилище нужно записать файл, выбранный с диска.
9. Сергей Марченко (MarSeN) 26.08.13 23:35
(8) Evil Beaver,
Такое задание делал не раз на работе ))))
10. Олег Сорокин (Oleg_nsk) 27.08.13 07:17
Однозначно, за управляемым интерфейсом будущее, и я не видел еще ни одного человека, который поработав с управляемыми формами, захотел бы вернуться к обычным.


Работаю с УФ полгода и хотел бы вернуться к обычным. Часто занимаюсь конвертацией данных и сложными обменами между базам. Скорость разработки увеличилась. Нагрузка на сеть для меня не критична. Сложно организовать простой прогресс бар. Передавать файл через временное хранилище грустно. Но плюсы тоже есть, однако минусы их перекрывают.
mdSerg; sashapere; Arc; talych; dr2c; Uncore; alek-sand-er; Krio2; ogonek!; DoctorRoza; Windsor77; Eremita; gigapevt; tunesoft; andreydmv; bidond; okami; RadoLex; bankir1982; DenP2010; Программулькин; PONOM; nazareth; j3d; adhocprog; susorov; kote; EmpireSer; logos; Yakud3a; CratosX; Mortiferus; ditiatko; Evil Beaver; Stradivari; +35 Ответить 2
11. Сергей Кудашкин (sikuda) 27.08.13 08:30
(0) О Книжках:
"Разработка управляемого интерфейса" Ажеронок, Островерх, Радченко, Хрусталева - зеленая
"1C:Предприятие 8.2 Коротко о главном" Радченко - коричневая
DmitrySinichnikov; RadoLex; nazareth; MitRhyme; Evil Beaver; +5 Ответить
12. Андрей Овсянкин (Evil Beaver) 27.08.13 09:14
(10) Oleg_nsk, поддержу в плане прогресс-бара. Точную индикацию прогресса организовать можно только извратившись. Однако, как мне кажется, для большинства прочих задач УФ намного удобнее.
13. Евгений Велюга (veluga) 27.08.13 09:21
а ещё хочется отметить, что не все методы работает на сервере -
например если база развернута на 64битном сервере, то поработать на нем, к примеру с XBase не получиться.
d0dger; wunderland; +2 Ответить
14. Игорь Сарафанов (ivs200999) 27.08.13 09:42
Спасибо. Уже почти год как вынужден был вернуться к обычным формам, кое-что по УФ начало забываться, благодаря публикации память рефрешнута.
15. Евгений Шабалин (xzorkiix) 27.08.13 09:46
(12) Evil Beaver, Oleg_nsk

Глобальный контекст (Global context)
Состояние (Status)
Синтаксис:

Состояние(<ТекстСообщения>, <Прогресс>, <Пояснение>, <Картинка>)
Параметры:

<ТекстСообщения> (необязательный)

Тип: Строка.
Строка, предназначенная для вывода в панель состояния. Если параметр не указан, возобновляется вывод системного текста в панель состояния.
<Прогресс> (необязательный)

Тип: Число.
Значение индикатора прогресса (от 1 до 100).
Если не задан, индикатор прогресса не отображается.
<Пояснение> (необязательный)

Тип: Строка.
Текст пояснения.
<Картинка> (необязательный)

Тип: Картинка.
Картинка.
Описание:

Выводит текст в панель состояния.

Доступность:

Тонкий клиент, веб-клиент, толстый клиент.
Примечание:

Для режима запуска ОбычноеПриложение используется только параметр <ТекстСообщения>, а вывод текста осуществляется в панель состояния.
Пример:

Состояние("Выполняется обновление информационной базы");


Частота исполнения строго на плечи программиста реализующего серверное решение.
16. mxm2 mxm2 (mxm2) 27.08.13 09:49
ОткрытьФорму("Справочник.Контрагенты.ФормаСписка", "УсловияОтбора");


очепятка во втором параметре (он должен быть без ковычек)
Mortiferus; +1 Ответить
17. mxm2 mxm2 (mxm2) 27.08.13 09:52
(15) xzorkiix, тут напрягает то, что нужно постоянно "выныривать" на уровень клиента. Логичнее решать проблему отображения хода вычислений через асинхронное фоновое задание.
18. Гость 27.08.13 10:04
Данные помещаются в хранилище по ссылке. Это значит, что помещая данные в хранилище и изменяя их вне хранилища мы, фактически, меняем и само хранилище, т.к. в нем лежит только ссылка на данные. Пример:

Массив = Новый Массив; Массив.Добавить("Привет");
Адрес = ПоместитьВоВременноеХранилище(Массив);
Массив.Добавить("До свидания");
МассивИзХранилища = ПолучитьИзВременногоХранилища(Адрес);
Сообщить(Массив = МассивИзХранилища); // Истина
Сообщить(МассивИзХранилища.Количество()); // 2 элемента
...Показать Скрыть


Если этот код выполнять с клиента, то результат будет вовсе не таким, как написано.
19. Андрей Овсянкин (Evil Beaver) 27.08.13 10:14
(18) BH, это серверный код, выполнять надо в одной серверной процедуре. Кстати, результат, скорее всего, будет таким, как написано, однако, я там же говорил, что процесс хранения управляется платформой и она может сериализовать данные по своему усмотрению. Поэтому, в общем случае, поведение непредсказуемое.
20. Андрей Овсянкин (Evil Beaver) 27.08.13 10:15
(15) xzorkiix, да, а еще нужен реальный сервер, ибо в файловом режиме фоновые задания работают извращенскими методами и, де-факто, не применяются вовсе.
21. Евгений Шабалин (xzorkiix) 27.08.13 10:26
(20) Поторопился с примером, каюсь, метод выполняется строго на клиенте. Тут скорее в решении платформы должна быть реализация методов, которые бы работали с пользовательским интерфейсом без прерывания серверного кода, те клиент паралельно всегда должен ожидать каких либо откликов со стороны сервера. Тот же метод Состояние. Возможно, это будет реализовано так позже. Пока я сомневаюсь, что разработчики платформы настроены на реализацию асинхронного вызова силами 1С-программиста.
22. Анна Коломак (foliage) 27.08.13 10:50
Статья понравилась и четким изложением "по пунктам", и содержанием. Эту информацию пришлось с полгода назад выискивать по разным источникам, в т.ч. в упоминаемой книге. Но и из статьи немало узнала, спасибо автору!
Однозначный "плюс", мне бы эту статью в начале работы с УФ :)
23. Сергей Ожерельев (Поручик) 27.08.13 10:53
(10) Работаю с УФ три года и не хотел бы возвращаться к обычным на постоянную основу или на долгое время. Во-первых, больше престижа, во-вторых, достоинства УФ с лихвой перекрывают недостатки. Так что перестраивайте мышление.

С обычными формами работаю время от времени, но только по превеликой просьбе клиентов.

Франч, УТ 11, Розница 2, свои конфигурации.
TreeDogNight; MarSeN; +2 Ответить 1
24. al petrov (petrov_al) 27.08.13 10:55
Спасибо за публикацию, хоть освежил свою память поскольку редко работаю с уф.
25. Сергей Ожерельев (Поручик) 27.08.13 11:00
(8) А что его делать? Справочник Файлы или регистри ХранимыеФайлыВерсий, ПрисоединенныеФайлы в любой типовой на БСП.
26. Андрей Овсянкин (Evil Beaver) 27.08.13 11:04
(25) Поручик, Помещать ДвоичныеДанные во временное хранилище формы, а в ДанныхФормы завести реквизит "АдресДвоичныхДанных".
Затем, в событии "ПередЗаписьюНаСервере" проверять, если по этому адресу что-то лежит, то засунуть эти данные в ТекущийОбъект.
27. Alex Stasyuk (GreenFox) 27.08.13 13:59
Автору спасибо, сейчас начинаю плотно работать с УФ - приходится восстанавливать знания по ним после сдачи спеца.
28. Serg Nyk (sergnik) 27.08.13 14:24
С УФ работаю где-то полгода, некоторые моменты, описанные в статье, изучал методом тыка)
Как раз подхожу под
Введение
Данная статья ориентирована на разработчиков, которые волею судеб не успели плотно поработать с управляемыми формами. Если вы уже хорошо знаете, как работают УФ и вообще управляемый интерфейс приложения, то можете статью не читать, поскольку, вряд ли узнаете много нового.


Автору спасибо, буду ссылаться на Вашу статью)
29. Иван (SinglCOOLer) 27.08.13 15:06
Хорошо написано, еще много вопросов вызывает Условное оформление(особенно если строки надо подсветить), его программное добавление и т.п., отборы в списках
30. Александр Кстенин (ant2be) 27.08.13 16:41
31. Николай Зайков (Mortiferus) 27.08.13 19:10
Спасибо автору - как всегда качественное изложение материала. До многого сам своими мозгами доходил, раньше бы на полгодика эту статью... Тем не менее еще раз спасибо, лишний раз утряслось все по полочкам.
32. B2B (B2B) 27.08.13 21:14
(7) Извините, был не прав :(
33. John Bolshakov (soulsteps) 27.08.13 23:04
34. Алексей (alsoftik) 28.08.13 07:58
Как раз статья кстати, вчера поставил в контору конфы 8.2 УТ и БП, бум разбираться. Еще раз спс за статью.
35. Олег Сорокин (Oleg_nsk) 28.08.13 08:45
(23) Поручик, Перечислите пожалуйста достоинства УФ кроме "престижа", уменьшения сетевой нагрузки и простоты конструирования форм? У вас на самом деле уходит меньше времени на разработку? Какая специфика ваших задач? Вот сегодня например прилетела задача по УТ11 при заполнении установки цен на основании документа поступление заполнить свою цену ценой поставщика с НДС. Эта задача была оценена на полчаса. При попытки вникнуть в суть кода разработчиков чуть не поехала крыша. Создание временного хранилища со схемой скд, её извлечение, двойное перезаполнение и т.п. В общем задача заняла у меня 4 часа. На толстом клиенте на это ушло бы минут пять. Добавление внешних печатных форм отчетов и обработок стало каким-то муторным. Не говорю о том что отладка на клиент-сервере невозможна без флага -debug и приходится делать файловую копию большой базы. Знаю людей которым нравятся УФ, но не знаю никого, кто-бы работал с ними быстрее чем под толстым клиентом. Сам я проходил курсы по УФ и знаю все его основные особенности, читал спецлитру, мышление перестроил под него, однако, остаюсь при своем мнении, что разработка под толстым клиентом проще и быстрее. Если будет время согласен устроить соревнование - решение нескольких шаблонных задач на скорость параллельно в УФ и на толстом клиенте :)
alest; Arc; nemo888; 7OH; tormozit; frost_a; den_bat; ccserg; torg1c; klinval; prodines; orfos; MOHCTP; Rabot; Death_eye; uri1978; krendel; Morales; svetanik; talych; Shida; Yakud3a; Tsprogrammist1; rosinfo1; alanto23; +25 Ответить 4
36. artur rakhmatulin (нормальный такой) 28.08.13 09:20
(35) Oleg_nsk, и меня подпишите)

в высоконагруженых системах, считаю, без УФ никуда, в параллель с обязательным клиент-сервером.
вот вы привели, что толстые формы быстрее в разработке, так давайте вернемся к 77 где вообще все просто как 3 рубля.
не помню где читал про похожий холивар, "усложнение" мол разработки, но в конечном итоге ведь - все во благо! а по другому никак. прогресс так сказать.
37. Олег Сорокин (Oleg_nsk) 28.08.13 10:15
(36) нормальный такой, В высоконагруженных, возможно. Однако, я работаю с небольшими фирмами. Переход с 77 на 8 проходил относительно безболезненно, т.к. 8 позволяла именно ускорить процесс разработки и давала новые возможности. Усложнение меня не пугает, однако, сама концепция реализации тонкого клиента увеличивает время разработки. У меня претензии к тому, что тонкий клиент давая преимущества в тех аспектах, которые для меня не важны усложнил жизнь в тех, которые составляли 90% моей работы. Теперь выгоднее стало уйти на крупное предприятие нежели работать со многими небольшими фирмами, т.к. завышение цены на услуги в 1.5-2 раза никому не нравится.
Дмитрий74Чел; +1 Ответить
38. Роман Грук (gruk) 28.08.13 10:37
39. Епрст (Ёпрст) 28.08.13 10:38
еб@нутый каталог.. хз чего я там поставил, + или минус ?
п..ц наступил, аутор, если че, я плюсую
40. Роман Грук (gruk) 28.08.13 10:50
Мне, как начинающему, понравилось. Основные принциы изложены кратко и доходчиво. Название "под капотом" четко дает понять что это не "руководство по экспуатации и ремону".
ЗЫ. Побежал читать Радченко
Прикрепленные файлы:
41. Елена Пименова (Bukaska) 28.08.13 11:05
Спасибо автору! Отличная статья)
42. Павел Заяш (Pavl0) 28.08.13 11:08
Статья отличная, рекомендую к прочтению.
Много нюансова разжевано.
43. Саша Безымяный (help1Ckr) 28.08.13 12:18
(35) Oleg_nsk, Вы знаете, когда делал на обычных формах документ и в момент сдачи пользователи попросили добавить маленький реквизхит - просто текстовое поле типа комментария. Добавил вроде ничего такого не трогал, но как полетели у меня привязки - полчаса потом выравнивал((((((( в тот момент я подумал что УФ это рай на земле)
45. doxflow (bonv) 28.08.13 13:29
[QUOT]
Ключевые параметры определяют уникальность окна. В обычных формах был такой атрибут «Ключ уникальности». Если запрашивалась форма, то она сначала искалась в уже открытых. Ключ уникальности позволял варьировать условия при которых создавалась новая форма или возвращалась существующая. Ту же самую роль играют ключевые параметры. Если метод «ОткрытьФорму» вызван два раза подряд с одним и тем же значением ключевого параметра, то второй вызов не откроет новое окно, а активирует существующее.
[/QUOT]
Не совсем верно. Поиск по ключевым параметрам это поведение по умолчанию.
Но при этом у метода ОткрытьФорму есть параметр <Уникальность>, если его заполнить, то поиск среди открытых окон будет выполняться по нему.
46. Саша Безымяный (help1Ckr) 28.08.13 13:30
(35) Oleg_nsk, кстати. на вскидку - преимущества уф - функциональные опции, которые позволяют скрывать ненужное от пользователя. "Самоформирующийся" интерфейс
47. Андрей Овсянкин (Evil Beaver) 28.08.13 13:33
(45) doxflow,
Не совсем верно. Поиск по ключевым параметрам это поведение по умолчанию.
Но при этом у метода ОткрытьФорму есть параметр <Уникальность>, если его заполнить, то поиск среди открытых окон будет выполняться по нему.


Не знал. Думал, что они друг-друга дополняют. Спасибо.
48. Олег Сорокин (Oleg_nsk) 28.08.13 13:51
(46) help1Ckr, Да. Плюс. Для разработчиков решений. Но я не разрабатываю конфигурации с нуля, а дорабатываю типовые в основном. Там таких проблем нет. С привязками ну было у меня пару раз что сбивались когда начинал на 8.0, потом понял как они работают и более затруднений не возникало.
49. bulpi bulpi (bulpi) 28.08.13 14:06
" Все кто поработал с УФ более-менее плотно не хотят возвращаться назад, как в страшный кошмар."
Ну ты за всех-то не расписуйся :) После таких заявок так и хочется минус влепить.
mdSerg; bankir1982; uri1978; rosinfo1; +4 Ответить
50. bulpi bulpi (bulpi) 28.08.13 14:07
"Один и тот же код работает и в браузере, и в родном клиенте."
А это просто неправда.
51. Юрий Юршин (donikx) 28.08.13 15:46
Интересная и полезная информация. Все важное об управляемых форма в одной статье. Буду использовать в моей практике.
52. Андрей Овсянкин (Evil Beaver) 28.08.13 16:14
(50) bulpi, :) Скажем так, в идеале, один и тот же код работает и там и там.
Понятно, что есть документированные особенности, как то "РасширениеРаботыСФайлами" и прочее...
А что именно неправда?
53. bulpi bulpi (bulpi) 28.08.13 16:28
Код, отлаженный в тонком клиенте, вовсе не обязательно будет работать в веб-интерфейсе. У меня была куча странных ошибок в браузере. Помогали только танцы с бубнами.
54. Андрей Овсянкин (Evil Beaver) 28.08.13 17:02
(53) bulpi, это да, веб-клиент имеет недостатки. Но о них надо сообщать и скорее всего их будут править.
Проектная идеология подразумевает корректную работу кода в тонком и веб-клиентах.
55. doxflow (bonv) 28.08.13 17:58
(53) bulpi, и обратное тоже верно: код отлаженный в веб-клиенте не обязательно будет работать в тонком)
Evil Beaver; +1 Ответить
56. Harleq2 Harleq2 (harleq2) 29.08.13 03:18
57. Саша Безымяный (help1Ckr) 29.08.13 09:52
(48) Oleg_nsk, ну так речь была о разработке) ну и построение интерфейса с функциональными опциями это тоже плюшка для доработки типовых - сколько мне пришлось рабочих столов делать и отдельных интерфейсов для типовых потом у как каждый руководитель ларька считает что его информация обладает ценностью для пентагона и потому надо закрыть везде доступ.
58. Андрей Овсянкин (Evil Beaver) 29.08.13 10:38
Коллеги, а что за странная тенденция прикреплять картинки с аватарками? Это новая фича редизайна от Инфостарта? Особо везучие вместо своего поста публикуют аватарку крупного размера?
59. Анна Денисова (aimerlive) 30.08.13 15:21
спасибо за статью, побольше бы таких. доходчивым языком для новичков основы.
60. Алексей Белов (Karmerruk) 31.08.13 23:07
Спасибо за статью, прояснила некоторые моменты. :)
61. Макс Зеленский (mzelensky) 02.09.13 12:00
Прочел статью. К самому написанию никаких вопросов - все довольно доходчиво изложено. Не понравилось только то, что автор безустанно "втирает" идею "УФ - ЭТО ЛУЧШЕЕ, ЧТО С НАМИ БЫЛО".

По мне так УФ это г***о полное. Я работал с УФ и плевался на всем протяжении работы. Если кто-то все-таки захочет поспорить на счет "быстроты разработки", то я тоже подписываюсь! Я вижу УФ только в качестве того случая, когда нужно разработать функционал под "веб" (т.е. для работы в браузере).
lap_soft; lsv; mdSerg; 7OH; ketr; tormozit; frost_a; sashapere; Rodnaya; ccserg; ZVN; Arc; user_2010; Идальго; Uncore; alek-sand-er; Krio2; Windsor77; prodines; Eremita; dicwork; tunesoft; Fominro; e-aleks; bidond; bankir1982; t278; Death_eye; DenP2010; uri1978; Morales; Программулькин; PONOM; nazareth; j3d; adhocprog; NCCSOFT; mihan; rosinfo1; Ёпрст; +40 Ответить 1
62. Росинфо 1 (rosinfo1) 02.09.13 14:11
(36) нормальный такой, У меня есть заказчик, оптовая торговая фирма, 30 пользователей, 500 документов в день, включая субботу и воскресенье, работают на 7.7 самописная "примитивная" конфигурация, 15 документов, 5 регистров, и несколько сотен отчетов и обработок. Работают в терминале, файловая база. Они счастливы, довольны и скоростью и производительностью, и тем, что я им функционал под каждый чих, быстро дорабатываю. По функционалу, УТ 11 только сейчас придвинунась, к тем идеям, которые у них были реализованы еще 10 лет назад. Торговые представители через карманник, подключаются по терминалу к базе. Внешние клиенты также, у них урезанные интерфейсы, делают самостоятельно заказы. Один блок логистики, загрузки автомобилей, и доставки по районам чего стоит. Также блок производства и фасовки, со сдельными рассчетами зарплаты. Учет бонусов и откатов. Учет затрат и себестоимости, точки безубыточности. Обмен с БП 2.0 типовой конфигурацией реализован, аффилирование клиентов, как в УТ 11. Им УФ нафиг не нужны, и УТ 11 это кошмар, для их бизнеса - тормоза, и лишние затраты в ИТ инфраструктуру, а также расходы на программистов.
frost_a; landrev; Krio2; pmb17; Дмитрий74Чел; j3d; +6 Ответить 1
63. artur rakhmatulin (нормальный такой) 02.09.13 14:27
(62) rosinfo1, Дорогой мой! Я за Вас очень рад! правда!
В каждом конкретном случае ессесно свои решения, вот Вы нашли такой вот подход, и самое классное что он работает! Но если делать на УФ и можно таки вообще развернуть веб сервер и юзверя с "карманников" не будут подымать rdp и т.д!
Каждому своё, и вы правильно указали, 500 документов в день, у кого то их 5000 на 500 пользователей, и тут, простите, файловым вариантом не отделаться. Сразу начнете изучать управляемые блокировки и кластеризацию.
Впрочем не стоит раздувать этот бесконечный холивар коих на просторах тырнета не счесть.
Я учился с 8ки, с 77 тоже сталкивался и работал (но не разрабатывал с "нуля") и то что я успел потрогать мне не очень понравилось. Сейчас у нас уже 83 накатываем, и то что мы видим нам очень нра :)
64. yuraskas Рупышев (yuraskas) 02.09.13 16:15
Вопрос новичка в УФ. Все что здесь написано, относится к клиент-серверному варианту работы 1С? А с файловым вариантом можно писать как и раньше и не заморачиваться с &НаКлиенте и &НаСервере?
65. S nic (snic) 02.09.13 16:35
Спасибо. Кратко и понятно.
66. Андрей Овсянкин (Evil Beaver) 02.09.13 22:54
(64) yuraskas, нельзя.
(61) mzelensky, я тоже плевался поначалу. Когда поработаете подольше (будут ломки) то поймете преимущества.
67. Сергей Ожерельев (Поручик) 03.09.13 00:06
Вброшу и пойду спать.
Короче говоря, кто плюётся от управляемых форм, просто неудачники, не умеющие осваивать новые технологии и перестраивать мышление. Мозг жиром заплыл.
sks; Lo1jke; ccserg; Euroset1; Invis91; zqzq; aduyunov_2015; komatoza; starik-2005; DmitrySinichnikov; IT_Avito; vladdt; TreeDogNight; Agrognom; tushich; heavymetal; and-blag; headMade; kser87; +19 6 Ответить
68. 1cSupport - третий (Зеленоград) 03.09.13 11:55

Скажите, коллеги - фраза "Все кто поработал с УФ более-менее плотно не хотят возвращаться назад, как в страшный кошмар" только мне кажется недостоверной, или я отстал от прогресса и то, что делалось на НФ за час теперь можно делать за 15 минут?
70. Дмитрий (dimk@a) 03.09.13 13:13
[B]Evil Beaver[\B], спасибо за статью - все четко изложил и доходчиво. Вот про то что ВременноеХранилище живет два серверных вызова даже не знал, точнее не сталкивался.
71. Дмитрий (dimk@a) 03.09.13 13:17
(64) yuraskas, С файловым все так же, надо разделять процедуры на серверные и клиентские.
72. Дмитрий (dimk@a) 03.09.13 13:25
(58) Evil Beaver, у меня в Хроме инфостарт вообще неадекватно работает... с редактированием сообщений полная фигня
73. Андрей Овсянкин (Evil Beaver) 03.09.13 14:55
(68) 1cSupport - третий, видимо, все-таки, кому как. Для всех моих знакомых эта фраза полностью достоверна. Да, на УФ я могу форму нарисовать намного быстрее, чем на обычных. Двигать элементы по пикселям уже просто противно. А уж если вставить что-то в середину существующей сложной обычной формы....
TreeDogNight; heavymetal; +2 Ответить
74. Вадим Кушнер (Foma4382) 03.09.13 16:47
75. Инна Суханова (in_nochka) 05.09.13 13:25
Спасибо за статью, очень полезно.
76. Дмитрий (sommid) 05.09.13 18:33
77. Роман Зиновьев (Широкий) 06.09.13 15:43
"ОткрытьФорму("Справочник.Контрагенты.ФормаСписка", "УсловияОтбора");"
Передаешь все-таки текстовую строку или структуру?
78. Alex_IT (Alex_IT) 07.09.13 20:28
Структуру. Опечатался автор, вон сколько букв. Ничего страшного, поправит.

moonchild1; +1 Ответить
79. Яков Коган (Yashazz) 18.09.13 16:26
На спор с одним товарищем делали красивую сложную форму - он на УФ, я на обычных. Обогнал его на полчаса и сделал гораздо более симпатичный дизайн. Имхо, УФ намного неудобнее в плане конструирования в конфигураторе. И да, я поработал с УФ и я хочу работать с обычными, они гибче и круче. Жаль, что будущее за уродством вроде "такси". Не понимаю, почему толковые и безусловно полезные меры по клиент-серверной оптимизации сопровождаются такими извратами внешнего вида и его разработки. Что, трудно было оставить прежние возможности нелюбимой автором "пиксельной" работы, а потом уже транслировать в отрисовываемую?..
80. Андрей Овсянкин (Evil Beaver) 18.09.13 18:28
(79) Yashazz, да блин, вот вы все прицепились к скорости! Нравится вам делать обычные - ради Бога, я что, запрещаю что-ли? :) Или вам надо, чтобы я статью поменял? Ну сформулируйте тогда, что именно надо сказать, а я опубликую.
Дмитрий74Чел; +1 Ответить 1
81. Alister (Alister) 18.09.13 22:17
Спасибо автору за систематизацию информации для чайников... от чайника :)
82. Яков Коган (Yashazz) 20.09.13 01:05
(80) Да потому, что навязчивая, а зачастую оголтелая агитация за УФ (не от вас, а вообще) поднадоедает, вот и вышел крик души. Статья полезная, у кого нет Ажеронка-Островерха-Радченко-Хрусталёвой, тем и просто манна небесная. Хорошая статья. Не принимайте на свой счёт мои зубовные скрежеты )))
83. Владимир Дутлов (dutlovva) 24.09.13 10:41
84. Владимир Клименко (KliMich) 02.10.13 19:29
Спасибо! Без воды и для начинающих познавательно
85. Виктор Маркевич (warrior1985) 03.10.13 01:17
Отличная статья! Спасибо автору.
86. Владимир Аникин (Vo-Va) 03.10.13 15:03
Спасибо автору, реально получил ответы на многие вопросы. Недавно был случай. Заполнение таблицы формы на сервере выполнялось очень долго. Причем сам запрос отрабатывал за 3 сек, а переход с клиентской процедуры в серверную и обратно занимал порядка 20 сек. Причем если заставить исполняться весь код на клиенте с помощью директив и инструкций препроцессора в толстом клиенте весь код исполнялся да 3 сек. Т.е. запрос напрямую с клиента работает быстрее, чем запрос с сервера с последующей передачей результата на клиент!!! Я не понимал почему это происходит. Теперь понятно что в это "потерянное" время происходила сериализация таблицы. И скорость этого процесса упирается в мощность процессора.
prodines; +1 Ответить
87. Сергей Огнарев (ogoneksergei) 03.10.13 15:32
88. Денис Бойко (den_bo) 03.10.13 16:16
Спасибо! Особенно за разъяснения некоторых особенностей поведения временного хранилища.
89. Sirruf (Sirruf) 03.10.13 16:29
Так и как сохранять com-объекты, если их нельзя помещать во временное хранилище?
90. Андрей Овсянкин (Evil Beaver) 04.10.13 10:27
(89) Sirruf, а ответьте сами: есть кластер из 3-х серверов. 2 из них на Windows, третий на Linux.
Вызвали сервер, менеджер кластера передал вызов на машину с Windows, там создался ком объект. Предположим, что мы сможем его где-то сохранить.
Делаем другой вызов, менеджер кластера передает вызов на другую win-машину, где этот COM не создавался. Как его получить с первой машины?
Дальше-больше, третий вызов придет на машину с Linux, там вообще не бывает COM. Как вообще обеспечить работу такой информационной системы?

Ваша необходимость сохранять COM объекты между серверными вызовами, это архитектурный просчет и нужно менять само проектное решение.
91. Sirruf (Sirruf) 04.10.13 13:30
(90) Таким образом, вариант решения данной проблемы предложенный в статье http://kb.mista.ru/article.php?id=787 неверен. Тогда каким образом можно поменять проектное решение, если требуется хранить ком-объект долгое время, на протяжении работы всего сеанса, чтобы не создавать его каждый раз заново...
92. Андрей Овсянкин (Evil Beaver) 04.10.13 13:41
(91) Sirruf, решение предложенное в статье хоть и костыльное, но теоретически верное, т.к. тонкости создания объекта скрыты. Это как бы кеш, а не хранение состояния. Если жив объект, хорошо, а если нет, то фиг с ним, создадим заново.

Другой вопрос, если решается задача не кеширования объекта, а надежного хранения его состояния (состояния всех его внутренних переменных). В этом случае предложенное решение некорректно. В условиях нескольких серверов оно некорректно в принципе, даже если мы забудем про 1С и возьмем какую-то другую информационную систему.
93. Евгений Шабалин (xzorkiix) 04.10.13 13:52
(91) Sirruf, а что это за объект такой, если не секрет? Для чего он?
94. Sirruf (Sirruf) 04.10.13 14:47
(93) у меня часто используется VBScript.RegExp. Я его хранил в параметрах сеанса так как описано в статье на мисте, но в 8.3 этот прием не прокатывает - ругается при помещении ком-объекта в хранилище :(
95. Sirruf (Sirruf) 04.10.13 14:50
Вообще понятно, что ком-объеты лучше не использовать в принципе. Хочу реализовать через веб-сервисы, но это не так быстро сделать. Поэтому думаю как бы мне сейчас перейти на 8.3
96. Андрей Овсянкин (Evil Beaver) 04.10.13 15:12
(95) Sirruf, внешняя компонента, либо TRex от Орефкова (есть на Инфостарте)
97. Sirruf (Sirruf) 04.10.13 15:16
(96) Что это за зверь TRex? Не могу найти
98. Андрей Овсянкин (Evil Beaver) 04.10.13 15:45
(97) Sirruf, RexV8, попутал название.
http://infostart.ru/public/183084/

Я не пользовался, если вдруг не работает, пишите автору.
99. Sirruf (Sirruf) 04.10.13 16:22
100. Сергей Вн (EmpireSer) 10.10.13 13:53
Спасибо! Классная статья.
Но я не разделяю эту радость от управляемых форм. Мне больше хотелось видеть больше возможностей на стороне клиента. Ну например:
1) Зачем ограничения сериализацией? Если бы оставался контекст и на сервере, то для не поддерживаемых типов можно организовать было что-то типа "проксирование" (Remoting, RMI). Ведь "невидимый" вызов производится, если на клиенте обратится к какой-то ссылке через точку, типа такой же "фокус" можно было делать и тут.
Я согласен, что возможность распределять нагрузку в кластере - это хорошо, но, как я помню, даже в Oracle Weblogic есть возможность и держать северный контекст и даже запретить ему распределять его в кластере.
2) Что за странное ограничения на работу с таблицей значений?
3) Особенно огорчило отсутствие метода "СоздатьКолонки", т.к. нет возможности сгеренировать правильно столбцы для системных таблиц (например КомпоновщикНастроекКомпоновкиДанных.Настройки.Отбор)
4) Почему обработка СКД выполняется на сервере? А может я хочу поработать только с набором данных "объект" и просто его по особенному "обработать" (наложить сложные отборы, использовать вычисляемые поля)

Вместе с правильными новшествами были принесены ограничения "высосанные из пальца"...
nemo888; ZVN; user_2010; prodines; bidond; al_antonov; Rabot; Maximysis; RvvRvv; krendel; svetanik; nazareth; adhocprog; Evgen.Ponomarenko; the1; +15 Ответить
101. Сергей Вн (EmpireSer) 10.10.13 13:57
(94) Sirruf,
А что если тебе использовать общий модуль с повторным использованием на сеанс? Тоже хороший вариант
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа