Сравнить шесть способов получения форм справочника на своём пульте

Учебные задачи

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

Где и как запускать

Полный модуль ОБЫЧНОЙ формы Пульт собственной обработки. Только толстый клиент, обычное приложение; отдельные модули ниже. Не выполнялся.

Подготовка

  1. Создайте НОВУЮ пустую файловую базу 8.5.1.1343 с именем конфигурации УчебныеВыборкиКаталога85, совместимость НеИспользовать. Основной режим запуска ОбычноеПриложение. Запускайте толстым клиентом в обычном приложении; тонкий/веб-клиент и управляемые формы для этих шести методов не подходят. Здесь UI не запускался: runtimeVerifiedScenarios=0.

  2. Единственный справочник УчебныеТовары: иерархия групп и элементов, владельцев и предопределенных данных нет, Код Строка(10), автонумерация выключена, контроль уникальности включён, Наименование(100), единственный Артикул Строка(20), для групп и элементов, Индексировать. Остальные объекты хранения, подписки, задания, разделители и расширения отсутствуют; справочник пуст.

  3. УчебныеТовары → Формы: создайте пять ОБЫЧНЫХ форм мастером соответствующего назначения: ФормаСписка, ФормаВыбора, ФормаВыбораГруппы, ФормаЭлемента, ФормаГруппы. Назначьте их основными для списка, выбора элемента, выбора группы, элемента и группы соответственно. Не оставляйте выбор основной формы на автоопределении.

  4. В ФормаЭлемента и ФормаГруппы проверьте основной реквизит СправочникОбъект типа СправочникОбъект.УчебныеТовары, созданный мастером. На форме только поля Код, Наименование, Артикул и Родитель. В обеих формах вставьте полный отдельный модуль проверки собственного нового объекта ниже. Модули объекта и менеджера справочника пусты.

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

  6. Создайте неглобальный общий модуль УчебныйКаталог85: Сервер=Да, Вызов сервера=Да, клиентские флаги=Нет, привилегированный режим=Нет. Вставьте полный отдельный модуль защиты стенда ниже; в этом уроке он не содержит подготовки/записи товаров.

  7. Создайте обработку УчебныеОкнаКаталога85 с обычной основной формой Пульт и восемью кнопками: СписокПоИмени, ОсновнойСписок, ВыборТовара, ВыборГруппы, НовыйТовар, НоваяГруппа, ПовторитьПоИмени, ЗакрытьСвоиОкна. Назначьте одноимённые действия, события ПриОткрытии и ПередЗакрытием. Вставьте полный основной модуль. Обновите конфигурацию базы, выполните F7 и вручную сверяйте назначения основных форм.

  8. Не используйте рабочую конфигурацию или её копию: ТолькоПросмотр — свойство UI, не права доступа и не защита от неизвестных обработчиков записи. Код не вызывает Записать и не заполняет объект; формы новых объектов остаются новыми и незаписанными. Здесь не было запуска в 1С.

Перем СвоиОкна;
Перем СвойСписокПоИмени;

Процедура ПриОткрытии()
    УчебныйКаталог85.ПроверитьСвойСтенд();
    СвоиОкна = Новый Массив;
    СвойСписокПоИмени = Неопределено;
КонецПроцедуры

Процедура СписокПоИмени(Кнопка)
    УчебныйКаталог85.ПроверитьСвойСтенд();
    Ключ = Новый УникальныйИдентификатор;
    Окно = Справочники.УчебныеТовары.ПолучитьФорму("ФормаСписка", ЭтаФорма, Ключ);
    ПоказатьСвоеОкно(Окно, Ключ, "Список по явному имени", Неопределено);
    СвойСписокПоИмени = Окно;
КонецПроцедуры

Процедура ОсновнойСписок(Кнопка)
    УчебныйКаталог85.ПроверитьСвойСтенд();
    Ключ = Новый УникальныйИдентификатор;
    Окно = Справочники.УчебныеТовары.ПолучитьФормуСписка(, ЭтаФорма, Ключ);
    ПоказатьСвоеОкно(Окно, Ключ, "Основная форма списка", Неопределено);
КонецПроцедуры

Процедура ВыборТовара(Кнопка)
    УчебныйКаталог85.ПроверитьСвойСтенд();
    Ключ = Новый УникальныйИдентификатор;
    Окно = Справочники.УчебныеТовары.ПолучитьФормуВыбора(, ЭтаФорма, Ключ);
    ПоказатьСвоеОкно(Окно, Ключ, "Форма выбора товара: просмотр", Неопределено);
КонецПроцедуры

Процедура ВыборГруппы(Кнопка)
    УчебныйКаталог85.ПроверитьСвойСтенд();
    Ключ = Новый УникальныйИдентификатор;
    Окно = Справочники.УчебныеТовары.ПолучитьФормуВыбораГруппы(, ЭтаФорма, Ключ);
    ПоказатьСвоеОкно(Окно, Ключ, "Форма выбора группы: просмотр", Неопределено);
КонецПроцедуры

Процедура НовыйТовар(Кнопка)
    УчебныйКаталог85.ПроверитьСвойСтенд();
    Ключ = Новый УникальныйИдентификатор;
    Окно = Справочники.УчебныеТовары.ПолучитьФормуНовогоЭлемента(, ЭтаФорма, Ключ);
    ПоказатьСвоеОкно(Окно, Ключ, "Новый товар в памяти: без записи", Ложь);
КонецПроцедуры

Процедура НоваяГруппа(Кнопка)
    УчебныйКаталог85.ПроверитьСвойСтенд();
    Ключ = Новый УникальныйИдентификатор;
    Окно = Справочники.УчебныеТовары.ПолучитьФормуНовойГруппы(, ЭтаФорма, Ключ);
    ПоказатьСвоеОкно(Окно, Ключ, "Новая группа в памяти: без записи", Истина);
КонецПроцедуры

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

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

Процедура ЗакрытьСвоиОкна(Кнопка)
    ЗакрытьСозданныеОкна();
КонецПроцедуры

Процедура ЗакрытьСозданныеОкна()
    Если СвоиОкна = Неопределено Тогда
        Возврат;
    КонецЕсли;
    Для Каждого Окно Из СвоиОкна Цикл
        Если Окно.Открыта() Тогда
            Окно.Закрыть();
            Если Окно.Открыта() Тогда
                ВызватьИсключение "Собственное окно отказалось закрываться";
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    СвоиОкна.Очистить();
    СвойСписокПоИмени = Неопределено;
КонецПроцедуры

Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
    ЗакрытьСозданныеОкна();
КонецПроцедуры
УчебныеТовары.ФормаЭлемента/ФормаГруппы

УчебныеВыборкиКаталога85 → Справочники → УчебныеТовары → Формы → ФормаЭлемента и ФормаГруппы → Модуль каждой формы

Один и тот же полный модуль вставьте отдельно в обе подготовленные обычные объектные формы. Не выполнялся.

Функция ПроверитьСвоеСоздание(ОжидаемаяГруппа) Экспорт
    Если Не ЭтаФорма.ТолькоПросмотр Тогда
        ВызватьИсключение "Своя учебная форма должна открываться только для просмотра";
    КонецЕсли;
    Если Не СправочникОбъект.ЭтоНовый() Или Не СправочникОбъект.Ссылка.Пустая()
        Или СправочникОбъект.ЭтоГруппа <> ОжидаемаяГруппа Тогда
        ВызватьИсключение "Нужен свой новый незаписанный элемент или группа ожидаемого вида";
    КонецЕсли;
    Возврат Истина;
КонецФункции
УчебныйКаталог85.ПроверкаСтенда

УчебныеВыборкиКаталога85 → Общие → Общие модули → УчебныйКаталог85

Полный серверный общий модуль, вызов сервера разрешён; ни одной записи в базу. Не выполнялся.

Процедура ПроверитьСвойСтенд() Экспорт
    Если Метаданные.Справочники.Количество() <> 1 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Каталог = Метаданные.Справочники[0];
    Если Каталог.Имя <> "УчебныеТовары" Или Не Каталог.Иерархический
        Или Каталог.Реквизиты.Количество() <> 1 Или Каталог.Реквизиты.Найти("Артикул") = Неопределено Тогда
        ВызватьИсключение "Нужен собственный иерархический справочник с единственным реквизитом Артикул";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры

Разбор по шагам

  1. ПолучитьФорму("ФормаСписка") использует явное подготовленное имя. ПолучитьФормуСписка с пропущенным первым аргументом использует назначенную основную форму списка; второй и третий аргументы всё равно владелец и ключ.

  2. ПолучитьФормуВыбора и ПолучитьФормуВыбораГруппы используют разные основные назначения. Сейчас показываем их только для просмотра; справочник пуст, значения пользователю не возвращаются.

  3. ПолучитьФормуНовогоЭлемента и ПолучитьФормуНовойГруппы получают новые объекты, не формы существующей ссылки. Собственный экспортный метод дочерней формы проверяет ЭтоНовый, пустую ссылку и ЭтоГруппа=Ложь/Истина до открытия.

  4. Каждый новый опыт имеет UUID. Перед любым изменением свойств проверяем тип Форма, отсутствие отказа создания, закрытое состояние, переданный ключ и владельца — именно этот Пульт. Чужие и открытые окна не перенастраиваются.

  5. ТолькоПросмотр устанавливается перед Открыть; АвтоЗаголовок выключен, поэтому проверяемое название задаётся явно. Это делает назначение окна читаемым, не подменяет основной реквизит и не записывает его.

  6. ПовторитьПоИмени работает только со своим запомненным открытым списком. Те же имя, владелец и ключ должны вернуть тот же экземпляр; новый UUID у кнопки СписокПоИмени создаёт отдельный опыт.

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

Как проверить результат

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

  2. СписокПоИмени → ПовторитьПоИмени: появляется сообщение о том же экземпляре, без второго окна. Ещё раз СписокПоИмени: новый UUID создаёт другое собственное окно.

  3. Закройте одно дочернее окно крестиком, затем ЗакрытьСвоиОкна. Закрытое пропускается, остальные собственные закрываются. Окна другого пульта не должны закрыться.

  4. Закройте Пульт с оставшимися дочерними окнами: событие ПередЗакрытием убирает свои экземпляры. Затем проверьте учебный справочник — записанных товаров/групп нет.

  5. Проверка отказа: в копии основной формы нового товара уберите основной реквизит или экспортную функцию. F7 либо вызов проверки должны сообщить ошибку; не заменяйте проверку константой Истина ради открытия.

Ожидаемый результат

Подготовлены собственный пульт, пять обычных форм и проверки нового объекта, владельца, ключа, повторного получения и уборки собственных окон. runtimeVerifiedScenarios=0.

На что обратить внимание

  1. Обычная Форма и УправляемаяФорма — разные типы. Не заменяйте толстоклиентские методы универсальным ОткрытьФорму без пересмотра параметров и контекста.

  2. ТолькоПросмотр не является системой прав и не запрещает произвольному коду выполнить Записать. Поэтому модули и команды собственного стенда заданы явно.

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

  4. Просмотр форм выбора не означает успешный подбор элемента. Передача выбранного значения и уведомления владельца разобраны в отдельном уроке.

  5. Платформа может сохранять параметры окон в пользовательском профиле. Уникальные собственные UUID не являются очисткой этого профиля; чужие настройки не удаляются.

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

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.