Управляемые формы 1с 8 2. Под капотом управляемых форм. Принципы разработки управляемых форм


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

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

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

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

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

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

А у документа Поступление товаров и услуг состав основных форм будет уже другим:

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

Автогенерируемые формы

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

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

Связь формы с данными

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

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

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

Структура формы

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

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

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

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

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

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

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

С появлением платформы 1С Предприятие 8.2 механизм разработки пользовательского интерфейса значительно изменился. Появилась возможность создания управляемых форм и приложений (Рисунок 1).

Рисунок 1

Кроме этого предлагается новая система разделения функциональности между клиентским приложением и сервером.
Управляемое приложение поддерживает следующие типы клиентов:

  • Толстый клиент (обычный и управляемый режим запуска),
  • Тонкий клиент,
  • Веб-клиент.

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

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

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

  • типы, которые непосредственно используются в форме – это те типы, которые существуют на стороне тонкого и Веб-клиента (например, Число, СправочникСсылка.Товары, ГрафическаяСхема, ТабличныйДокумент);
  • типы, которые будут преобразованы в специальные типы данных – типы данных управляемой формы. Такие типы отображаются в списке реквизитов формы в круглых скобках, например (СправочникОбъект.Товары);
  • динамический список.

Функционирование управляемых форм имеет следующие отличительные особенности (Рисунок 2):

  • Форма существует и на клиенте и на сервере.

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

  • Форма не работает с прикладными объектами


Рисунок 2

В форме используются специальные универсальные объекты
ДанныеФормы (Рисунок 3).


Рисунок 3

Прикладные объекты работают только на сервере и только во время выполнения некоторых операций.
При открытии формы:

  • Объект считывается из базы данных,
  • Объект конвертируется в данные формы,
  • Объект удаляется (из памяти),
  • Данные формы передаются на клиента.

При записи:

  • Данные формы получаются с клиента,
  • Данные формы конвертируются в объект,
  • Объект записывается в базу данных,
  • Объект удаляется (из памяти).

Управляемые формы уже давно и плотно вошли в жизнь 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С» поступила с клиент-серверным взаимодействием, на мой взгляд, совершенно правильно. Она не стала его прятать, наоборот, она заставила всех видеть его, тыкнула всех носом: «смотрите, тут вы пишете код для физически разных машин, думайте, что делаете».

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

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

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

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

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

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

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

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

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

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

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

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

Данные формы

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Не все так плохо (IMG:)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Модуль формы

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

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

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

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

контекст формы, т.е. ее данные. Когда мы вызываем сервер «с контекстом», то контекст должен быть передан на сервер, поскольку его там в данный момент просто не существует (сервер state-less).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Краткий итог

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

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

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

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

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

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

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

[необходимо зарегистрироваться для просмотра ссылки]

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

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

  • Самостоятельное формирование структуры формы и размещение полей платформой. Если раньше разработчики описывали положение поля, указывая пиксели, то теперь есть возможность лишь указать вид группировки;
  • Форма состоит из реквизитов, представляющих данные формы, и команд – выполняемых процедур и функций;
  • Код формы выполняется на стороне и сервера, и клиента. Ведь сама по себе форма – это объект конфигурации, создаваемый на сервере и отображаемый на клиенте. Значит, объединяет в себе клиентскую и серверную часть;
  • На клиентской стороне стали недоступны многие типы данных и теперь отсутствует возможность изменить данные в информационной базе;
  • Для каждой процедуры или функции должна быть указана специальная настройка – директива компиляции. Она отвечает за место выполнения кода и может принимать следующие значения:
    • Наклиенте;
    • НаСервере;
    • НаСервереБезКонтекста;
    • НаКлиентеНаСервере;
    • НаКлиентеНаСервереБезКонтекста.

Последний пункт особо остро стоит в режиме управляемых форм. Если разработчик плохо разбирается в директивах или взаимодействии клиента и сервера, то ему будет крайне сложно создать управляемую форму. Все новые принципы построения управляемых форм в 1С:Предприятие 8.3 объединены общим понятием трехзвенной архитектуры. В нее входят клиентские компьютеры, сервер 1С и СУБД, где хранятся данные.

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

  1. Элементы интерфейса формы. Слева вверху расположено окно, где перечислены все поля, отраженные на выбранной форме, обеспечивающие взаимодействие программы с пользователем;
  2. Реквизиты формы. Справа вверху расположены все данные, с которыми работает форма. Именно в них хранится информация на клиентской стороне;
  3. Отображение управляемой формы. Снизу мы видим предварительный внешний вид на основе элементов интерфейса;
  4. Модуль формы. Раздел, содержащий процедуры и функции, используемые данной формой. Здесь можно найти код алгоритмов взаимодействия программы и с пользователем, и с базой данных.

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

Принципы разработки управляемых форм

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

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

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

&НаСервере Процедура ПолучитьПлатежноРасчетныеДокументыИзХранилища(НовыйАдресВХранилище) &НаСервереБезКонтекста Функция ЕстьРасчетыСКлиентом(ДокументОснование) &НаСервереБезКонтекста Процедура ЗаполнитьСписокВыбораКПП(СписокВыбора, Контрагент, ДатаСведений) &НаКлиенте Процедура ЗаполнитьГоловногоКонтрагентаЗавершение(ВыбранноеЗначение, ДополнительныеПараметры) &НаСервере Процедура УстановитьТекстПлатежноРасчетныхДокументов() &НаСервере Функция ЕстьЗаполненныеИсходныеДокументы()

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

  1. Простота сопровождения конфигурации и повышенная читаемость кода. Отсюда можно сделать вывод, что алгоритм, написанный одним разработчиком, всегда сможет поправить другой сотрудник, не тратя много времени;
  2. Разделение кода, выполняемого на клиенте и сервере. Учитывая, насколько отличается функционал, доступный на каждой из этих сторон, разделить их было бы правильным шагом;
  3. Более глубокое понимание разработчиками логики платформы, взаимодействия клиента и сервера и алгоритмов, которые они пишут. В версиях 8.0 и ранее очень часто можно было встретить формы документов или справочников, разработанные без понимания клиент-серверной части;
  4. Повышение быстродействия конфигураций и снижение нагрузки на клиентские компьютеры;
  5. Снижение затрат на закупку компьютеров для рабочих мест ввиду отсутствия необходимости приобретения мощных ПК.

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

Цель статьи – показать применение шаблонов Remote Facade и Data Transfer Object к структуризации кода, управляемой формы в среде 1С 8.2.

Введение

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

В 2008 году стала доступна новая версия платформы 1С: Предприятие 8.2 (далее Управляемое приложение), которая полностью меняет весь слой работы с интерфейсом. Сюда относится и командный интерфейс, и формы, и оконная система. При этом не только меняется модель разработки пользовательского интерфейса в конфигурации, но и предлагается новая архитектура разделения функциональности между клиентским приложением и сервером.

Управляемое приложение поддерживает следующие типы клиентов:

  • Толстый клиент (обычный и управляемый режим запуска)
  • Тонкий клиент
  • Веб-клиент

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

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

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

Перечислим директивы компиляции методов формы:

&НаКлиенте

&НаСервере

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

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

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

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

Обозначим проблему

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

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

Рассмотрим структуру кода (модуль формы) в нескольких формах одной типовой конфигурации и попробуем найти закономерности.

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

Секция обработчиков событий

Метод – наклиенте

Метод – насервере

Метод - наклиенте

Секция служебных процедур и функций

Вспомогательные функции управления вводом

Служебные процедуры и функции

Документы оплаты

Ценности

Обработчики событий

Служебные процедуры на сервере

Служебные процедуры на клиенте

Служебные процедуры на сервере без контекста

Обработчики событий шапки

Обработчики событий команд

Процедуры общего назначения

Обработчики событий формы

Процедуры подсистемы «контактная информация»

По сути, структура кода отсутствует, или мягче говоря, она аналогична тому, что было в формах 8.1:

  • Неинформативные слова «Общие, Служебные, Вспомогательные».
  • Робкие попытки разделить клиентские и серверные методы.
  • Часто методы группируются по интерфейсным элементам «Работа с табличной частью Товары, Контактной информацией».
  • Произвольное расположение методов и групп кода. Например, Обработчики событий могут быть в одной форме вверху, в другой внизу, в третьей вообще не выделены и т.д.
  • И не будем забывать, что это все в рамках одной конфигурации.
  • Да бывают конфигурации, в которых слова «Общие, Служебные, Вспомогательные» всегда находятся на одних и тех же местах но…

Зачем нужна структура кода?

  • Упрощение сопровождения.
  • Упрощение обучения.
  • Фиксация общих/важных/удачных принципов.
  • …ваш вариант

Почему существующий стандарт разработки от фирмы 1С не помогает?

  • Минимизируйте число серверных вызовов.
  • Максимум вычислений на сервере.
  • Неконтекстные вызовы сервера быстрее контекстных.
  • Программируйте с учетом клиент-серверного взаимодействия.
  • и т.п.

Это лозунги, абсолютно верные, но как их реализовать? Как минимизировать число вызовов, что значит программировать в клиент-серверном режиме?

Шаблоны проектирования или мудрость поколений

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

  • Remote Facade (далее Интерфейс удаленного доступа)
  • Data Transfer Object (далее Объект переноса данных)

Слово Мартину Фаулеру, его описание данных принципов:

  • … каждый объект, потенциально предназначенный для удаленного доступа, должен иметь интерфейс с низкой степенью детализации, что позволит максимально уменьшить количество вызовов, необходимых для выполнения определенной процедуры. … Вместо того, чтобы запрашивать счёт и все его пункты отдельно, надо считать и обновить все пункты счёта за одно обращение. Это влияет на всю структуру объекта.…Запомните: интерфейс удаленного доступа не содержит логики домена.
  • …если бы я был заботливой мамой, то обязательно сказал бы своему ребенку: «Никогда не пиши объекты переноса данных!» В большинстве случаев объекты переноса данных представляют собой не более чем раздутый набор полей … Ценность этого омерзительного монстра состоит исключительно в возможности передавать по сети несколько элементов информации за один вызов - прием, который имеет большое значение для распределенных систем.

Примеры шаблонов в платформе 1С

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

Например метод ОткрытьФорму(), типичный «огрубленный» интерфейс.

ПараметрыОткрытия = Новый Структура("Параметр1, Параметр2, Параметр3", Значение1, Значение2, Значение3);

Форма = ОткрытьФорму(ИмяФормы, ПараметрыОткрытия);

Сравните с принятым в v8.1 стилем.

Форма = ПолучитьФорму(ИмяФормы);

Форма.Параметр1 = Значение1;

Форма.Параметр2 = Значение2;

Форма.Открыть();

В контексте управляемой формы множество «Объектов переноса данных». Можно выделить системные и определяемые разработчиком.

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

ДанныеФормыСтруктура

ДанныеФормыКоллекция

ДанныеФормыСтруктураСКоллекцией

ДанныеФормыДерево

Преобразование системных объектов переноса данных в прикладные типы и обратно выполняется методами:

ЗначениеВДанныеФормы()

ДанныеФормыВЗначение()

КопироватьДанныеФормы()

ЗначениеВРеквизитФормы()

РеквизитФормыВЗначение()

Часто явное преобразование используется при адаптации существующего решения. Методы могут ожидать (использовать особенности) входные параметры, например ТаблицаЗначений, а не ДанныеФормыКоллекция, или метод был определен в контексте прикладного объекта и стал недоступен для прямого вызова из формы.

Пример 1С v8.1:

// на клиенте в контексте формы

ЗаполнитьКэшПользователей(ПодразделениеСсылка)

Пример 1С v8.2:

// на сервере в контексте формы

ОбработкаОбъект = РеквизитФормыВЗначение("Объект");

ОбработкаОбъект.ЗаполнитьКэшПользователей(ПодразделениеСсылка);

ЗначениеВРеквизитФормы(ОбработкаОбъект, "Объект");

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

Примитивные типы (строка, число, булево)

Структура

Соответствие

Пример: метод принимает список заказов для изменения статуса и возвращает клиенту описание ошибок.

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

Функция СерверИзменитьСтатусЗаказов(Заказы, НовыйСтатус)

Ошибки = Новый Соответствие(); // [заказ][описание ошибки]

Для Каждого Заказ Из Заказы Цикл

НачатьТранзакцию();

Попытка

ДокОб = Заказ.ПолучитьОбъект();

…. другие действия, возможно не только с заказом…

Исключение

ОтменитьТранзакцию();

Ошибки.Вставить(Заказ, ОписаниеОшибки());

КонецПопытки;

КонецЦикла;

Возврат Ошибки;

КонецФункции // СерверИзменитьСтатусЗаказов()

Структурируем код

Главные цели, которые должен отражать модуль управляемой формы и подходы к решению.

  • Четкое разделение клиентского и серверного кода. Не будем забывать, в момент выполнения это два взаимодействующих процесса, в каждом из которых существенно отличается доступный функционал.
  • Четкое выделение интерфейса удаленного доступа, какие методы сервера можно вызывать с клиента, а какие нельзя? Названия методов удаленного интерфейса начинаются с префикса «Сервер». Это позволяет, читая код сразу видеть переход управления на сервер, и упрощает использование контекстной подсказки. Отметим, что официальная рекомендация (ИТС) предлагает именовать методы с постфиксами, например, так ИзменитьСтатусЗаказовНаСервере(). Однако повторим не все серверные методы можно вызывать с клиента, и поэтому более важна логическая доступность, а не место компиляции. Поэтому префиксом «Сервер» отмечаем только методы доступные для клиента, метод-пример назовем СерверИзменитьСтатусЗаказов().
  • Удобочитаемость. Дело вкуса, принимаем порядок, когда модуль начинается с процедур создания формы на сервере и методов удаленного доступа.
  • Сопровождаемость. Должно быть однозначно определено место для добавления нового кода. Важный момент, автоматически создаваемые конфигуратором заготовки методов добавляются в конец модуля. Т.к чаще всего автоматически создаются обработчики событий элементов формы, то соответствующий блок расположен последним, чтобы не перетаскивать каждый обработчик в другое место модуля.

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

  • Графический вариант – наглядно показывает основной поток выполнения.
  • Текстовый вариант - это пример оформления шаблона для быстрой вставки структуры в новый модуль формы.

// <Описание>

//

//

////////////////////////////////////////////////////////////////////////////////

// ПЕРЕМЕННЫЕ МОДУЛЯ

////////////////////////////////////////////////////////////////////////////////

// НА СЕРВЕРЕ

//******* СОБЫТИЯ НА СЕРВЕРЕ *******

&НаСервере

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

//Вставить содержимое обработчика

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

//******* ИНТЕРФЕЙС УДАЛЕННОГО ДОСТУПА *******

//******* БИЗНЕС-ЛОГИКА НА СЕРВЕРЕ *******

////////////////////////////////////////////////////////////////////////////////

// ОБЩИЕ МЕТОДЫ КЛИЕНТА И СЕРВЕРА

////////////////////////////////////////////////////////////////////////////////

// НА КЛИЕНТЕ

//******* БИЗНЕС-ЛОГИКА НА КЛИЕНТЕ *******

//******* КОМАНДЫ *******

//******* СОБЫТИЯ НА КЛИЕНТЕ *******

////////////////////////////////////////////////////////////////////////////////

// ОПЕРАТОРЫ ОСНОВНОЙ ПРОГРАММЫ

Связанные вопросы

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

  • Варианты реализации интерфейса удаленного доступа. Асинхронность, степень детализации...
  • Кэширование. В 1С приняли неудачное архитектурное решение, введя кэширование только на уровне вызова методов общих модулей и не предоставив возможности управления (время актуальности, сброс по требованию).
  • Неявные серверные вызовы. Не забывайте о технологических особенностях, многие «безобидные» операции на клиенте провоцируют платформу на обращение к серверу.
Выбор редакции
Всем огромный привет! Спешу опять порадовать вас самым популярным августовским блюдом. Угадайте с трех раз! О чем я хочу написать? Каких...

Екатерина II – великая российская императрица, царствование которой стало самым значимым периодом в русской истории. Эпоха Екатерины...

Как выяснила «Газета.Ru», эксперты, расследующие катастрофу Robinson R-66 на Телецком озере в Республике Алтай, склоняются к версии, что...

Во время германской компании на Востоке, Messershmitt BF 109 был основным самолетом истребительной авиации Люфтваффе. Несмотря на их...
Гороскоп совместимости: цветы по знакам зодиака лев - самое полное описание, только доказанные теории, основанные на астрологических...
Символ рока и судьбы, предотвратить которую невозможно. Руна Наутиз означает вынужденные обстоятельства, ограничения, несвободу выбора....
Как приготовить лаваш в кляре Сегодня мы предлагаем вам приготовить блюдо, способное стать и замечательной закуской на праздничном столе,...
Чудеса Пресвятой Богородицы в наши дни не перестают удивлять и радовать христиан, а ее помощь приходит всем христианам, которые молятся...
Варенье из крыжовника в мультиварке готовить довольно легко, оно отличается от обычного лакомства, сваренного на плите, лишь своей...