Открытие формы и передача информации между формамии

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

ЦЕЛЬ - хранение контактной информации в регистре сведений и отображение ее в справочнике. Задачи:
- необходимо из формы элемента справочника открыть форму записи регистра ;
- при закрытии формы регистра информация должна отобразиться в форме справочника.

1) Т.к. информация о месте жительства абитуриента будет храниться в регистре сведений «Контактная информация», добавим кнопку для открытия его формы записи. Для этого в свойствах поля адреса напротив "КнопкаВыбора" ставим "Да".

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

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

Листинг 1 – Процедура «АдресНачалоВыбора»

&НаКлиенте
Процедура АдресНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
   Если АбитуриентСуществует() Тогда
      Отбор = Новый Структура();
      Отбор.Вставить("Абитуриент", Объект.Ссылка);

      Массив = Новый Массив;
      Массив.Добавить(Отбор);
      КлючЗаписи = Новый("РегистрСведенийКлючЗаписи.КонтактИнф", Массив);
      ПараметрыФормы = Новый Структура("Ключ", КлючЗаписи);
      Попытка
          ОткрытьФорму("РегистрСведений.КонтактИнф.Форма.ФормаЗаписи", ПараметрыФормы);
      Исключение
          Форма = ОткрытьФорму("РегистрСведений.КонтактИнф.ФормаЗаписи", Отбор);
      КонецПопытки;
   КонецЕсли;
КонецПроцедуры

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

Листинг 2 – Функция «АбитуриентСуществует»

&НаСервере
Функция АбитуриентСуществует()
   АбитуриентыОбъект = РеквизитФормыВЗначение("Объект", Тип("СправочникОбъект.Абитуриенты"));
   Если АбитуриентыОбъект.ЭтоНовый() Тогда
      Сообщение = Новый СообщениеПользователю;
      Сообщение.Текст = "Для редактирования контактной информации необоходимо сначала записать объект!";
       Сообщение.Сообщить();
   Иначе Возврат Истина;
   КонецЕсли;
КонецФункции

С помощью метода управляемой формы «РеквизитФормыВЗначение» из формы получаем объект прикладного типа. Необходимо это для работы с методом «ЭтоНовый», котороый и проверит, записан ли объект в базе. В случае необходимости пользователя оповестит сообщение о необходимости сначала добавить элемент.

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

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

Выполняем попытку открыть форму существующей записи по заданным параметрам в структуре "ПараметрыФормы". Если записи с такими параметрами нет, произойдет ошибка и управление перейдет оператору исключения: выполнится открытие новой формы для заполнения. В этой форме необходимо автоматически заполнить поле с ФИО абитуриента.

Для этого напишем обработку, которая будет выполняться при создании формы. Открываем модуль формы записи регистра и добавляем процедуру «ПриСозданииНаСервере».

Листинг 3 – Процедура «ПриСозданииНаСервере»

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
   Если НЕ Параметры.Абитуриент.Пустая() Тогда
      ЗаписьОбъект = РеквизитФормыВЗначение("Запись");
      ЗаписьОбъект.Абитуриент = Параметры.Абитуриент;
      ЗаписьРеквизит = ЗначениеВРеквизитФормы(ЗаписьОбъект, "Запись");
   КонецЕсли;
КонецПроцедуры

2) После заполнения и сохранения данных и закрытия формы нужно, чтобы эта информация отобразилась в поле адреса, предварительно объединив данные адреса в одну строку. Тогда пользователю будет ясно, что данные сохранены. Здесь то и сталкиваемся с очередной трудностью: как передать данные из одной формы в другую? Варианты были разные, сводились они к тому, чтобы вызвать новую серверную процедуру и в ней указать значение реквизита "Адрес" элемента справочника. В этом случае данные изменятся в информационной базе, но не отобразятся в уже открытой форме справочника, а только при следующем открытии! Естественно это не удобно и будет вводить пользователя в заблуждение.

На помощь приходит механизм "Оповестить". Его параметром и будет строка с адресом. Помещаем его в процедуру «ПередЗаписью» здесь же, в модуле формы записи регистра.

Листинг 4 – Процедура «ПередЗаписью»

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
   КонтИнф = Запись.Страна + ", " + Запись.Регион + ", " + Запись.НаселенныйПункт + ", " + Запись.Улица + ", " + Запись.Дом + " - " + Запись.Квартира;
   Оповестить("ОбвновлениеКонтактнойИнформации", КонтИнф);
КонецПроцедуры

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

Листинг 5 – Процедура «ОбработкаОповещения»

&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
   Если ИмяСобытия = "ОбвновлениеКонтактнойИнформации" Тогда
      Объект.Адрес = Параметр;
   КонецЕсли;
КонецПроцедуры

А вот так будет выглядеть для пользователя работа описанного алгоритма.

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

Наталья 1С. (с) 2013г
Мысль выпуска:
Когда Вы знаете, что хотите, и хотите этого достаточно сильно, то Вы найдете способ получить это. Ответы, методы и решения, которые необходимы Вам для решения проблем на Вашем пути, станут открытыми для Вас:
Это здесь :   10 важнейших стратегий для любого предпринимателя
Здесь:   Видеокурс "Блог для Инфобизнеса за 15 шагов"
И здесь:   Как бесплатно создать видео, которое повысит ваши продажи на 30%
Цифровая книга "Идеальный план продвижения через социальные сети"

Положительные отзывы направляйте сюда  

База данных студентов для приемной комиссии ВУЗа на платформе 1С версии 8.2
Открытие формы и передача информации между формами
Новинка! Бесплатная книга "Мастер Реселлинга" + реселл комплект в подарок!