Найти свои поля внутри группы: Find → Index → Get перед счетом750 +300 =1050

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

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

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

8.5.1.1343, собственная новая File CF, тонкий управляемый клиент и сервер формы; проверки ПутьКДанным только на сервере.

Подготовка

  1. Задача: перед расчетом счета найти именно свои три поля и кнопку внутри одной управляемой группы. Первый собственный товар: 3 штуки по250 =750; второй: 2 по150 =300. Общий итог: 5 единиц и1050. Не путайте число элементов интерфейса4 с количеством товаров5.

  2. Вручную создайте НОВУЮ пустую файловую ИБ C:\1c-labs\OwnFormChildInvoice85_034f3d98-2f2e-49ce-a58c-cb8ea89fbc46\IB. Конфигурация УчебныйСчетЭлементы85, РежимСовместимости=НеИспользовать, ОсновнойРежимЗапуска=УправляемоеПриложение. Windows, платформа8.5.1.1343, тонкий клиент. UUID в пути является маркером своего стенда, не UUID ИБ. Код принимает только точную строку File="путь"; без чужих каталогов и суффиксов.

  3. Оставьте новую CF без справочников, документов и четырех видов регистров. Создайте только свою роль Элементы85Администратор с полными правами этой учебной CF, включая администрирование для ПолучитьПользователей, и единственного пользователя Элементы85Ученик. Код сравнивает настоящий UUID текущего пользователя с единственным Users[0], а не с выдуманной ссылкой. Здесь подготовка не выполнялась.

  4. Общие → Общие формы → СвойСчет85: создайте УПРАВЛЯЕМУЮ форму. Реквизиты Количество85 и ВсегоКоличество85 — Число10,0; Цена85 и Всего85 — Число12,2; Этап85 — Число1,0; Остановка85 — Булево. Эти реквизиты принадлежат форме, не документу. ВсегоКоличество85, Этап85 и Остановка85 пользователю не выводите.

  5. В редакторе элементов формы создайте группу СвояГруппа85. Непосредственно внутри нее разместите ровно четыре элемента: ПолеВвода Количество85 с ПутьКДанным=Количество85; ПолеВвода Цена85 с ПутьКДанным=Цена85; ПолеВвода Всего85 с ПутьКДанным=Всего85 и ТолькоПросмотр=Истина; КнопкаФормы Добавить85. Имена здесь — имена элементов редактора; это не текст их заголовков. Не вкладывайте поля в дополнительную группу и не добавляйте в эту группу декорации или командную панель.

  6. В разделе Команды этой формы создайте Добавить85, Действие=ДобавитьПозицию85. Свяжите кнопку Добавить85 с этой командой: ИмяКоманды=Добавить85. ПриСозданииНаСервере формы назначьте одноименной процедуре(Отказ, СтандартнаяОбработка). Вставьте основной CODE целиком в модуль формы. Команда получает один параметр Команда; это не событие Нажатие с дополнительным Элемент. Никакие обработчики вручную не вызываются.

  7. Конфигурация → Открыть модуль управляемого приложения: вставьте supporting module УправляемоеПриложение. Вручную обновите только новую CF и запустите ее единственным своим пользователем в тонком клиенте. Native ПриНачалеРаботыСистемы() откроет собственную форму; серверное событие проверит группу, реальные привязки и пользователя, затем задаст3/250 и нулевые итоги.

  8. Нажмите Добавить85 один раз: фактический итог должен стать750, количество3, этап1. Затем вручную измените Количество85 на2, Цена85 на150; завершите редактирование полей Tab и нажмите Добавить85 снова. Итог должен стать1050, количество5, этап2. Не нажимайте третью кнопку и не меняйте поле Всего85. Иной ввод приводит к sticky остановке, а не к исправлению данных автоматически.

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

  10. Здесь изготовлены только тексты и статические тесты. CF/ИБ/пользователи/компиляция/1С/UI не создавались и не запускались; ниже описан ожидаемый будущий ручной результат. Разрешение работы в своей File ИБ не превращает код в sandbox безопасности чужой CF.

&НаСервере
Процедура ПроверитьСвойСтенд85()
    Если Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Или СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1c-labs\OwnFormChildInvoice85_034f3d98-2f2e-49ce-a58c-cb8ea89fbc46\IB"";" Тогда
        ВызватьИсключение "Только свой отдельный File-стенд 8.5.1.1343; другой формат регистрации откажет";
    КонецЕсли;
    Если ИмяФормы <> "ОбщаяФорма.СвойСчет85" Или Метаданные.ОбщиеФормы.Количество() <> 1
        Или Метаданные.ОбщиеФормы.Найти("СвойСчет85") = Неопределено
        Или Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0
        Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0
        Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Тогда
        ВызватьИсключение "Нужна своя единственная общая форма без прикладных объектов";
    КонецЕсли;
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Текущий = ПользователиИнформационнойБазы.ТекущийПользователь();
    Если Текущий = Неопределено Или Пользователи.Количество() <> 1 Тогда
        ВызватьИсключение "Нужен один реальный учебный пользователь";
    КонецЕсли;
    Если Текущий.Имя <> "Элементы85Ученик" Или Текущий.УникальныйИдентификатор <> Пользователи[0].УникальныйИдентификатор Тогда
        ВызватьИсключение "Текущий пользователь не совпал с единственным настоящим пользователем своей ИБ";
    КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПроверитьСвоиЭлементы85()
    Группа = Элементы.СвояГруппа85;
    Если ТипЗнч(Группа) <> Тип("ГруппаФормы") Или Группа.Имя <> "СвояГруппа85" Тогда
        ВызватьИсключение "Не подтверждена собственная управляемая группа";
    КонецЕсли;
    Коллекция = Группа.ПодчиненныеЭлементы;
    Если Коллекция.Количество() <> 4 Тогда
        ВызватьИсключение "В своей группе нужны три поля и одна кнопка, без посторонних детей";
    КонецЕсли;
    Имена = Новый Массив;
    Имена.Добавить("Количество85");
    Имена.Добавить("Цена85");
    Имена.Добавить("Всего85");
    Для Каждого ИмяПоля Из Имена Цикл
        Поле = Коллекция.Найти(ИмяПоля);
        Если Поле = Неопределено Или ТипЗнч(Поле) <> Тип("ПолеФормы") Тогда
            ВызватьИсключение "Не найдено настоящее собственное поле: " + ИмяПоля;
        КонецЕсли;
        ИндексПоля = Коллекция.Индекс(Поле);
        Если ТипЗнч(ИндексПоля) <> Тип("Число") Или ИндексПоля <> Цел(ИндексПоля)
            Или ИндексПоля < 0 Или ИндексПоля >= Коллекция.Количество() Тогда
            ВызватьИсключение "Поле не принадлежит фактической коллекции своей группы";
        КонецЕсли;
        ПрочитанноеПоле = Коллекция.Получить(ИндексПоля);
        Если ПрочитанноеПоле <> Поле Или Поле.Имя <> ИмяПоля
            Или Поле.Вид <> ВидПоляФормы.ПолеВвода Или Поле.ПутьКДанным <> ИмяПоля Тогда
            ВызватьИсключение "Find/Index/Get либо реальная привязка поля не совпали";
        КонецЕсли;
    КонецЦикла;
    Кнопка = Коллекция.Найти("Добавить85");
    Если Кнопка = Неопределено Или ТипЗнч(Кнопка) <> Тип("КнопкаФормы") Тогда
        ВызватьИсключение "Не найдена собственная кнопка команды";
    КонецЕсли;
    ИндексКнопки = Коллекция.Индекс(Кнопка);
    Если ИндексКнопки < 0 Или ИндексКнопки >= Коллекция.Количество() Тогда
        ВызватьИсключение "Кнопка не принадлежит своей группе";
    КонецЕсли;
    Если Коллекция.Получить(ИндексКнопки) <> Кнопка Или Кнопка.Имя <> "Добавить85"
        Или Кнопка.ИмяКоманды <> "Добавить85" Или Команды.Добавить85.Действие <> "ДобавитьПозицию85" Тогда
        ВызватьИсключение "Кнопка должна быть связана с собственной реальной командой";
    КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Попытка
        ПроверитьСвойСтенд85();
        ПроверитьСвоиЭлементы85();
        Этап85 = 0;
        Количество85 = 3;
        Цена85 = 250;
        Всего85 = 0;
        ВсегоКоличество85 = 0;
        Остановка85 = Ложь;
    Исключение
        Остановка85 = Истина;
        Отказ = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаСервере
Процедура ДобавитьНаСервере85()
    Если Остановка85 Или (Этап85 <> 0 И Этап85 <> 1) Тогда
        Остановка85 = Истина;
        ВызватьИсключение "Продолжение этого экземпляра запрещено";
    КонецЕсли;
    Попытка
        ПроверитьСвойСтенд85();
        ПроверитьСвоиЭлементы85();
        Если ТипЗнч(Количество85) <> Тип("Число") Или ТипЗнч(Цена85) <> Тип("Число")
            Или Количество85 <> Цел(Количество85) Или Цена85 <> Цел(Цена85) Тогда
            ВызватьИсключение "Для этого счета вручную введите целое количество и целую цену";
        КонецЕсли;
        Если (Этап85 = 0 И (Количество85 <> 3 Или Цена85 <> 250 Или Всего85 <> 0 Или ВсегоКоличество85 <> 0))
            Или (Этап85 = 1 И (Количество85 <> 2 Или Цена85 <> 150 Или Всего85 <> 750 Или ВсегоКоличество85 <> 3)) Тогда
            ВызватьИсключение "Не совпали собственный ввод и полный предыдущий итог; повтор/подмена запрещены";
        КонецЕсли;
        СуммаСтроки = Количество85 * Цена85;
        НовыйИтог = Всего85 + СуммаСтроки;
        НовоеКоличество = ВсегоКоличество85 + Количество85;
        Если (Этап85 = 0 И (СуммаСтроки <> 750 Или НовыйИтог <> 750 Или НовоеКоличество <> 3))
            Или (Этап85 = 1 И (СуммаСтроки <> 300 Или НовыйИтог <> 1050 Или НовоеКоличество <> 5)) Тогда
            ВызватьИсключение "Расчет по реальному вводу не совпал с контрольным счетом";
        КонецЕсли;
        Всего85 = НовыйИтог;
        ВсегоКоличество85 = НовоеКоличество;
        Этап85 = Этап85 + 1;
        Если Всего85 <> НовыйИтог Или ВсегоКоличество85 <> НовоеКоличество Тогда
            ВызватьИсключение "Повторное чтение своих числовых реквизитов не совпало";
        КонецЕсли;
    Исключение
        Остановка85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ДобавитьПозицию85(Команда)
    Если Остановка85 Или (Этап85 <> 0 И Этап85 <> 1) Или ТипЗнч(Команда) <> Тип("КомандаФормы")
        Или Команда <> Команды.Добавить85 Тогда
        Остановка85 = Истина;
        ВызватьИсключение "Только собственная команда на ожидаемом этапе";
    КонецЕсли;
    Попытка
        ДобавитьНаСервере85();
        Если (Этап85 = 1 И (Всего85 <> 750 Или ВсегоКоличество85 <> 3))
            Или (Этап85 = 2 И (Всего85 <> 1050 Или ВсегоКоличество85 <> 5))
            Или (Этап85 <> 1 И Этап85 <> 2) Тогда
            ВызватьИсключение "Клиент не получил полностью проверенный результат своего счета";
        КонецЕсли;
        Сообщить(СтрШаблон("Своих позиций: %1; количество: %2; сумма: %3", Этап85, ВсегоКоличество85, Всего85));
    Исключение
        Остановка85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры
Полный startup модуль своей File CF

Конфигурация → Открыть модуль управляемого приложения

Тонкий клиент, управляемое приложение

Процедура ПриНачалеРаботыСистемы()
#Если ТонкийКлиент Тогда
    Если СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1c-labs\OwnFormChildInvoice85_034f3d98-2f2e-49ce-a58c-cb8ea89fbc46\IB"";" Тогда
        ВызватьИсключение "Только собственный тонкий клиент и точный File-стенд этого урока";
    КонецЕсли;
    ОткрытьФорму("ОбщаяФорма.СвойСчет85", , , Истина);
#Иначе
    ВызватьИсключение "Для данного протокола используйте тонкий клиент 8.5.1.1343";
#КонецЕсли
КонецПроцедуры

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

  1. Источник Элементы — ВсеЭлементыФормы для прямого доступа. Сначала получаем настоящую собственную ГруппаФормы СвояГруппа85, затем ее readonly ПодчиненныеЭлементы. Именно эта коллекция имеет native FormItems методы; не объявляем AllFormItems тем же типом и не используем @FormItems в вызове Тип().

  2. Для каждого собственного поля выполняем Найти по точному имени. Неопределено означает отсутствие и немедленный отказ. Из фактического найденного объекта получаем Индекс, проверяем целочисленность и диапазон0..Count−1, затем Получить(Индекс). Сравниваем тот же объект, Имя, Вид=ПолеВвода и server-only ПутьКДанным. Позиции не зафиксированы: перестановка четырех детей допустима.

  3. Таким же путем проверяем собственную кнопку и связь ее реальной команды. Четыре контрола не создаются конструкторами и не передаются извне; их создает платформа из вручную подготовленной формы. Никакой readonly коллекции не присваивается значение.

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

  5. После присваивания сервер повторно читает числа. Клиент отдельно сверяет полный результат750/3 либо1050/5. При исключении клиент и сервер независимо устанавливают sticky остановку: серверная ошибка не считается гарантией доставки измененного флага клиенту. Повтор/rollback/retry отсутствуют.

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

  1. Будущий ручной протокол: первоначально Количество3/Цена250/Всего0; после первой команды Всего750 и сообщение количество3; после ввода2/150 и второй команды Всего1050, количество5, позиций2.

  2. Все три primary вызова относятся только к native детям собственной managed группы. Lookup возвращает реальный контрол; Index и Get проверяются до расчета. Ни значения схемы, ни имя переменной не являются самостоятельным proof владельца.

  3. Static native/contexts/readonly/arity/alias/negative проверки не доказывают компиляцию CF, доставку RPC, правильность пикселей, numeric formatting по локали или выполнение ручного ввода. Runtime здесь0.

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

Ожидаемый будущий результат собственной формы: две позиции,5 единиц,1050; фактические контроли найдены по именам и независимо подтверждены Index/Get. Здесь runtime результат не получен.

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

  1. ПутьКДанным доступен только в серверном контексте. Код не читает и не меняет его из клиентской команды. Управляемая ПолеФормы — не ordinary ПолеВвода; значения читаются из собственных связанных реквизитов формы.

  2. Поиск возвращает Неопределено при отсутствии; Get требует уже проверенный действительный индекс. Count4 — интерфейс, не число позиций счета. Индекс зависит от состава и порядка реальной группы, потому0/1/2 не подставляются.

  3. Это callback собственной команды формы, не event525 контрол-событие с дополнительным Элемент. ПриСозданииНаСервере имеет2 native формальных параметра, startup0. Код не вызывает эти обработчики напрямую.

  4. Частичная ошибка UI/RPC не атомарна. Sticky флаг не сбрасывается после отказа и не выполняет автоматического восстановления. Закройте только собственный экземпляр и начните новый ручной протокол после исправления подготовки.

  5. Legacy ПараметрыФормированияКомандПланировщика не создается и не кредитуется: native type deprecated8.3.23, документированного ctor нет,9 свойств readonly; current event678 возвращает другой ПараметрыФормированияКомандПоляПланировщика. Старый объект не заменяется новым по похожему имени.

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

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

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

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

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