Получает элемент коллекции по индексу. Работает аналогично оператору [].
Синтаксис
Получить(<Индекс>)Полное описание, параметры и ограничения
ВыраженияОтбораКомпоновкиДанныхСхемыЗапроса.Получить (QuerySchemaDataCompositionFilterExpressions.Get)
ВыраженияОтбораКомпоновкиДанныхСхемыЗапроса (QuerySchemaDataCompositionFilterExpressions)
Получить (Get)
Доступен, начиная с версии 8.3.14.
Синтаксис:
Получить(<Индекс>)
Параметры:
<Индекс> (обязательный)
Тип: Число.
Индекс элемента.
Возвращаемое значение:
Тип: ВыражениеОтбораКомпоновкиДанныхСхемыЗапроса.
Описание:
Получает элемент коллекции по индексу. Работает аналогично оператору [].
Доступность:
Сервер, толстый клиент, внешнее соединение.
Использование в версии:
Доступен, начиная с версии 8.3.14.
Методическая информация
Практические примеры
Выражения отбора СКД: найти текущий элемент, удалить цену, восстановить и очистить
В своей модели запроса разрешаем отбор по коду и цене. Ищем реальные элементы по их представлению, удаляем только цену числовым индексом, восстанавливаем её и очищаем исходную схему. Независимая копия сохраняет весь отбор; данные базы не читаются.
Где и как запускать
Полный серверный общий модуль УчебныеЗадачи своего нового стенда УчебныеПараметрыТаблицы85; BSL в1С не запускался.
Подготовка
Нужна НОВАЯ отдельная учебная база, не копия рабочей, на точно платформе8.5.1.1343. Имя конфигурации УчебныеПараметрыТаблицы85, совместимость Не использовать. Единственный независимый регистр сведений УчебнаяИстория85, В пределах секунды; измерение КодТовара Строка3, ресурс Цена Число12,2, без реквизитов/обработчиков. Остальных прикладных объектов, расширений, подписок и заданий нет. Записи не нужны.
Своя конфигурация → Общие → Общие модули → УчебныеЗадачи: Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Вставьте весь основной модуль. Другие вручную создаваемые модули пусты.
Создайте свою внешнюю обработку УчебныйОтборЗапроса85, управляемую Форму и команду/кнопку Выполнить с действием Выполнить. Реквизиты не нужны. Полный отдельный модуль формы дан ниже; схема остаётся на сервере.
До опыта завершите прежний свой сеанс без транзакции, сохраните/F7: Конфигурация → Обновить конфигурацию базы данных. Только после успеха свежий собственный управляемый клиент и своя обработка. Здесь F7 и BSL не запускались.
Процедура ВыполнитьПример() Экспорт
ПроверитьСвойМинимальныйСтенд();
ПроверитьСвойРегистр();
Схема = Новый СхемаЗапроса;
Схема.РежимКомпоновкиДанных = Истина;
Схема.УстановитьТекстЗапроса("ВЫБРАТЬ История.КодТовара КАК КодТовара, История.Цена КАК Цена
|ИЗ РегистрСведений.УчебнаяИстория85 КАК История");
Отбор = ПолучитьСвойОтбор(Схема);
ПроверитьСвойОтбор(Схема, 0);
ПроверитьПовторныйРазборОтбора(Схема, 0);
Код = Отбор.Добавить("История.КодТовара");
Код.Псевдоним = "КодДляОтбора";
Код.ИспользоватьРеквизиты = Ложь;
Цена = Отбор.Добавить(Новый ВыражениеСхемыЗапроса("История.Цена"));
Цена.Псевдоним = "ЦенаДляОтбора";
Цена.ИспользоватьРеквизиты = Ложь;
ПроверитьСвойОтбор(Схема, 2);
ПроверитьПовторныйРазборОтбора(Схема, 2);
Если Отбор.Индекс(Цена) <> 1 Тогда
ВызватьИсключение "Перед удалением нужен фактический индекс своей цены";
КонецЕсли;
Отбор.Удалить(1);
ПроверитьСвойОтбор(Схема, 1);
ПроверитьПовторныйРазборОтбора(Схема, 1);
ВосстановленнаяЦена = Отбор.Добавить(Новый ВыражениеСхемыЗапроса("История.Цена"));
ВосстановленнаяЦена.Псевдоним = "ЦенаДляОтбора";
ВосстановленнаяЦена.ИспользоватьРеквизиты = Ложь;
ПроверитьСвойОтбор(Схема, 2);
ПроверитьПовторныйРазборОтбора(Схема, 2);
Копия = Новый СхемаЗапроса;
Копия.РежимКомпоновкиДанных = Истина;
Копия.УстановитьТекстЗапроса(Схема.ПолучитьТекстЗапроса());
ПроверитьСвойОтбор(Копия, 2);
Отбор.Очистить();
ПроверитьСвойОтбор(Схема, 0);
ПроверитьПовторныйРазборОтбора(Схема, 0);
ПроверитьСвойОтбор(Копия, 2);
Сообщить("Своя схема: выражений отбора0, обычных колонок2; самостоятельная копия: два полных выражения с признаком Ложь");
КонецПроцедуры
Процедура ПроверитьСвойМинимальныйСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 1 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвойРегистр()
Если ПривилегированныйРежим() Тогда
ВызватьИсключение "Привилегированный режим для учебного разбора не нужен";
КонецЕсли;
МетаРегистр = Метаданные.РегистрыСведений.Найти("УчебнаяИстория85");
Если МетаРегистр = Неопределено Тогда
ВызватьИсключение "Нужен только собственный регистр УчебнаяИстория85";
КонецЕсли;
Если МетаРегистр.РежимЗаписи <> Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.Независимый
Или МетаРегистр.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Секунда
Или МетаРегистр.Измерения.Количество() <> 1 Или МетаРегистр.Ресурсы.Количество() <> 1
Или МетаРегистр.Реквизиты.Количество() <> 0 Тогда
ВызватьИсключение "Нужен независимый периодический регистр с одним измерением и ресурсом";
КонецЕсли;
МетаКод = МетаРегистр.Измерения.Найти("КодТовара");
МетаЦена = МетаРегистр.Ресурсы.Найти("Цена");
Если МетаКод = Неопределено Или МетаЦена = Неопределено Тогда
ВызватьИсключение "Нужны свои КодТовара и Цена";
КонецЕсли;
КодТипы = МетаКод.Тип.Типы();
ЦенаТипы = МетаЦена.Тип.Типы();
Если КодТипы.Количество() <> 1 Или ЦенаТипы.Количество() <> 1 Тогда
ВызватьИсключение "Составные типы своих полей не подходят";
КонецЕсли;
Если КодТипы[0] <> Тип("Строка") Или ЦенаТипы[0] <> Тип("Число")
Или МетаКод.Тип.КвалификаторыСтроки.Длина <> 3
Или МетаЦена.Тип.КвалификаторыЧисла.Разрядность <> 12
Или МетаЦена.Тип.КвалификаторыЧисла.РазрядностьДробнойЧасти <> 2 Тогда
ВызватьИсключение "Не совпали полные собственные типы полей";
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСвойОператор(Схема)
Если Не Схема.РежимКомпоновкиДанных Или Схема.ПакетЗапросов.Количество() <> 1 Тогда
ВызватьИсключение "Нужна одна собственная схема в режиме СКД";
КонецЕсли;
Выбор = Схема.ПакетЗапросов.Получить(0);
Если ТипЗнч(Выбор) <> Тип("ЗапросВыбораСхемыЗапроса") Или Выбор.Операторы.Количество() <> 1 Тогда
ВызватьИсключение "Нужен один собственный запрос выбора и оператор";
КонецЕсли;
Оператор = Выбор.Операторы.Получить(0);
Если ТипЗнч(Оператор) <> Тип("ОператорВыбратьСхемыЗапроса") Или Оператор.Источники.Количество() <> 1 Тогда
ВызватьИсключение "Нужен один собственный источник";
КонецЕсли;
Источник = Оператор.Источники.Получить(0);
Таблица = Источник.Источник;
Если ТипЗнч(Таблица) <> Тип("ТаблицаСхемыЗапроса")
Или НРег(Таблица.ИмяТаблицы) <> НРег("РегистрСведений.УчебнаяИстория85")
Или Таблица.Псевдоним <> "История" Тогда
ВызватьИсключение "Только свой физический источник История, без виртуальных или вложенных таблиц";
КонецЕсли;
Возврат Оператор;
КонецФункции
Функция ПолучитьСвойВыбор(Схема)
Оператор = ПолучитьСвойОператор(Схема);
Выбор = Схема.ПакетЗапросов.Получить(0);
Если Выбор.Колонки.Количество() <> 2 Или Оператор.ВыбираемыеПоля.Количество() <> 2 Тогда
ВызватьИсключение "Нужны ровно две собственные исходные колонки";
КонецЕсли;
Для Индекс = 0 По 1 Цикл
Колонка = Выбор.Колонки.Получить(Индекс);
Если Индекс = 0 Тогда
Имя = "КодТовара";
Выражение = Новый ВыражениеСхемыЗапроса("История.КодТовара");
ОжидаемыйТип = Тип("Строка");
Иначе
Имя = "Цена";
Выражение = Новый ВыражениеСхемыЗапроса("История.Цена");
ОжидаемыйТип = Тип("Число");
КонецЕсли;
Если ТипЗнч(Колонка) <> Тип("КолонкаСхемыЗапроса") Или Колонка.Псевдоним <> Имя
Или Выбор.Колонки.Найти(Имя) <> Колонка Или Колонка.Поля.Количество() <> 1
Или ТипЗнч(Колонка.Поля.Получить(0)) <> Тип("ВыражениеСхемыЗапроса")
Или Колонка.Поля.Получить(0) <> Выражение Тогда
ВызватьИсключение "Не совпали имя, порядок и полное выражение собственной колонки";
КонецЕсли;
Если ТипЗнч(Колонка.ТипЗначения) <> Тип("ОписаниеТипов") Тогда
ВызватьИсключение "Нужно описание типа собственной колонки";
КонецЕсли;
Типы = Колонка.ТипЗначения.Типы();
Если Типы.Количество() <> 1 Или Типы[0] <> ОжидаемыйТип Тогда
ВызватьИсключение "Не совпал полный набор типов собственной колонки";
КонецЕсли;
КонецЦикла;
Возврат Выбор;
КонецФункции
Функция ПолучитьСвойОтбор(Схема)
Выбор = ПолучитьСвойВыбор(Схема);
Оператор = Выбор.Операторы.Получить(0);
Отбор = Оператор.ВыраженияОтбораКомпоновкиДанных;
Если ТипЗнч(Отбор) <> Тип("ВыраженияОтбораКомпоновкиДанныхСхемыЗапроса") Тогда
ВызватьИсключение "Нужен собственный контейнер выражений отбора СКД оператора";
КонецЕсли;
Возврат Отбор;
КонецФункции
Процедура ПроверитьСвойОтбор(Схема, ОжидаемоеКоличество)
Отбор = ПолучитьСвойОтбор(Схема);
Если Отбор.Количество() <> ОжидаемоеКоличество Тогда
ВызватьИсключение "Не совпало полное число собственных выражений отбора СКД";
КонецЕсли;
Для Индекс = 0 По Отбор.Количество() - 1 Цикл
Элемент = Отбор.Получить(Индекс);
Если Индекс = 0 Тогда
Ожидаемое = Новый ВыражениеСхемыЗапроса("История.КодТовара");
Псевдоним = "КодДляОтбора";
Иначе
Ожидаемое = Новый ВыражениеСхемыЗапроса("История.Цена");
Псевдоним = "ЦенаДляОтбора";
КонецЕсли;
Если ТипЗнч(Элемент) <> Тип("ВыражениеОтбораКомпоновкиДанныхСхемыЗапроса")
Или ТипЗнч(Элемент.Выражение) <> Тип("ВыражениеСхемыЗапроса") Или Элемент.Выражение <> Ожидаемое
Или ТипЗнч(Элемент.Псевдоним) <> Тип("Строка") Или Элемент.Псевдоним <> Псевдоним
Или ТипЗнч(Элемент.ИспользоватьРеквизиты) <> Тип("Булево") Или Элемент.ИспользоватьРеквизиты
Или Отбор.Индекс(Элемент) <> Индекс Или Отбор[Индекс] <> Элемент Тогда
ВызватьИсключение "Не совпали полный тип, выражение, псевдоним, признак и индекс собственного отбора";
КонецЕсли;
Представление = Строка(Элемент.Выражение);
Если Представление = "" Или Отбор.Найти(Представление) <> Элемент Тогда
ВызватьИсключение "Найти по фактическому полному представлению должен вернуть именно текущий элемент";
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ПроверитьПовторныйРазборОтбора(Схема, ОжидаемоеКоличество)
Текст = Схема.ПолучитьТекстЗапроса();
Если ТипЗнч(Текст) <> Тип("Строка") Или Текст = "" Тогда
ВызватьИсключение "Нужен реальный сформированный текст собственной схемы";
КонецЕсли;
Повторная = Новый СхемаЗапроса;
Повторная.РежимКомпоновкиДанных = Истина;
Повторная.УстановитьТекстЗапроса(Текст);
ПроверитьСвойОтбор(Повторная, ОжидаемоеКоличество);
КонецПроцедурыУчебныйОтборЗапроса85.Форма
Своя внешняя обработка УчебныйОтборЗапроса85 → управляемая Форма → Модуль
Полный отдельный модуль своей управляемой формы; схемы работают на сервере, здесь не исполнялся.
&НаКлиенте
Процедура Выполнить(Команда)
ВыполнитьНаСервере();
Сообщить("Поиск, удаление, очистка и независимая копия своего отбора СКД проверены");
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
УчебныеЗадачи.ВыполнитьПример();
КонецПроцедурыРазбор по шагам
Включить режим СКД до разбора своего обычного текста. Проверить один физический источник История, две колонки КодТовара и Цена, их полный порядок/выражения/типы. Контейнер отбора берётся именно у своего ОператорВыбратьСхемыЗапроса, не из параметров виртуальной таблицы.
Исходный список пуст. Добавить История.КодТовара строкой, а История.Цена объектом ВыражениеСхемыЗапроса. Назначить КодДляОтбора и ЦенаДляОтбора; в ЭТИХ элементах ИспользоватьРеквизиты поддерживает запись, поэтому явно установить Ложь. Свойство Выражение readonly: его задаёт Добавить.
Для обоих элементов проверить точный тип, полное выражение, строковый псевдоним, Булево Ложь, Индекс, Получить и []. Положительный Найти получает фактическое полное Строка(Элемент.Выражение), не один псевдоним и не произвольную строку. Для ВыражениеСхемыЗапроса установленная справка явно документирует строковое преобразование и сравнение по строке; найденный объект должен совпасть с текущим элементом.
Проверить фактический индекс цены1 и вызвать Удалить(1). Остаться должен код0 с прежним полным выражением/псевдонимом/признаком. Удалённую Цена больше не читать. Добавить новый элемент цены по тому же собственному выражению и восстановить весь исходный список.
После каждого состояния 0→2→1→2→0 сформировать текст и заново разобрать НОВОЙ схемой в режиме СКД: пять полных контрольных разборов, не поиск подстроки в тексте. Каждый раз также проверяются неизменные обычные колонки.
Перед финальной очисткой сохранить независимую Копия со всеми двумя выражениями. Очистить только свой исходный контейнер. Оригинал пуст, копия хранит код и цену со всеми ожидаемыми свойствами. Дочерние элементы между схемами не переносятся.
Как проверить результат
Будущий результат: исходная схема после очистки имеет0 выражений отбора и2 обычные колонки. Копия имеет2 выражения в порядке История.КодТовара/КодДляОтбора и История.Цена/ЦенаДляОтбора, оба ИспользоватьРеквизиты=Ложь. Никаких строк регистра не прочитано и не записано.
Будущий отрицательный контроль вне опыта: поменять только ожидаемое полное выражение цены в ПроверитьСвойОтбор на История.КодТовара. После сохранения/F7 до нового собственного сеанса проверка должна отказать, хотя число элементов2. Вернуть код и до нового сеанса снова сохранить/F7. Здесь контроль не выполнялся.
runtimeVerifiedScenarios=0: структуры, форма и сериализация в1С не исполнялись. Сохранение описаний фильтра не доказывает фактический результат СКД-процессора, интерфейс настройки или права на реальные данные.
Ожидаемый результат
Удаление и очистка затрагивают только принадлежащую своему оператору модель отбора; полные самостоятельные разборы и копия проверяют смысл выражений, а не только их количество.
На что обратить внимание
У выражения отбора Выражение Только чтение, ИспользоватьРеквизиты Чтение и запись. Не путать этот тип с ПолеВыбораКомпоновкиДанныхСхемыЗапроса, где одноимённый признак в установленной справке readonly.
Удалить принимает Число, не элемент. Индекс принимает реальный элемент. Найти принимает строку представления; формат не составляется вручную. После удаления/очистки старые описания не читаются.
Эта коллекция описывает доступные выражения отбора СКД, но не устанавливает сама условие Цена>100 и не выбирает данные. Источник, две обычные колонки и поля выбора СКД — отдельные части модели.
Запрос.Выполнить, транзакции, записи, сеть и рабочие конфигурации здесь отсутствуют. Все классы схемы работают в серверном модуле только своей новой базы.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Схема запроса: обычные параметры среза и отдельные параметры СКД, с повторным разбором
Свой периодический регистр нужен только как описание таблицы. Меняем обычный период, добавляем отдельный период и поле отбора СКД, затем заново разбираем сформированный текст и проверяем каждое выражение, тип, индекс и псевдоним. Данные регистра не читаются и не записываются.
Где и как запускать
Полный серверный общий модуль УчебныеЗадачи только собственного нового стенда УчебныеПараметрыТаблицы85. Только метаданные и структуры в памяти; запрос данных и запуск в1С не выполнялись.
Подготовка
Создайте НОВУЮ отдельную пустую учебную базу, не копию рабочей, точно на8.5.1.1343. Имя конфигурации УчебныеПараметрыТаблицы85, совместимость Не использовать. Нет справочников, документов, прочих регистров, расширений базы/сеанса, подписок и фоновых заданий; другие модули вручную пусты. Проверки не умеют прочитать текст этих модулей.
Регистры сведений → Добавить → УчебнаяИстория85. Режим записи Независимый, периодичность В пределах секунды. Одно измерение КодТовара: Строка, длина3. Один ресурс Цена: Число12,2. Без реквизитов, регистраторов и обработчиков. СрезПоследних доступен именно периодическому регистру; непериодический регистр не заменяет эту подготовку. Записи для этой задачи вообще не нужны.
Общие → Общие модули → УчебныеЗадачи. Сервер=Истина, Глобальный=Ложь, ВызовСервера=Ложь, Привилегированный=Ложь; клиенты и внешнее соединение выключены, повторное использование выключено. Вставьте ВЕСЬ основной модуль, включая функции и процедуры после ВыполнитьПример.
Создайте свою новую внешнюю обработку УчебныеПараметры85 с управляемой Формой, командой и кнопкой Выполнить, действие Выполнить. Реквизиты формы не нужны. Полный отдельный модуль формы приведён ниже. Схема и её дочерние объекты остаются на сервере, в тонкий клиент не передаются.
После всей подготовки сохраните свою конфигурацию и завершите прежний свой сеанс без активной транзакции. В Конфигураторе: Конфигурация → Обновить конфигурацию базы данных (F7); дождитесь успеха только своей учебной конфигурации. Затем свежий собственный сеанс и кнопка Выполнить. Здесь 1С и F7 не запускались.
СхемаЗапроса разбирает описание, а не выполняет запрос. Здесь нет Новый Запрос, Выполнить запроса, Прочитать, Записать, транзакций, файлов и сети. Подготовленные метаданные дают таблицу и типы полей, но не служат доказательством каких-либо цен или строк базы.
Процедура ВыполнитьПример() Экспорт
ПроверитьСвойМинимальныйСтенд();
ПроверитьСвойРегистр();
Схема = Новый СхемаЗапроса;
Схема.РежимКомпоновкиДанных = Истина;
ИсходныйТекст = "ВЫБРАТЬ Срез.КодТовара КАК КодТовара, Срез.Цена КАК Цена
|ИЗ РегистрСведений.УчебнаяИстория85.СрезПоследних(&ДатаЗапроса, КодТовара = &КодТовара) КАК Срез";
Схема.УстановитьТекстЗапроса(ИсходныйТекст);
Таблица = ПолучитьСвоюТаблицу(Схема);
ПроверитьСвоиОбычныеПараметры(Таблица, "ДатаЗапроса");
Параметры = Таблица.Параметры;
ПервыйОбычный = Параметры.Получить(0);
ПервыйОбычный.Выражение = Новый ВыражениеСхемыЗапроса("&ДатаРасчета");
ПроверитьСвоиОбычныеПараметры(Таблица, "ДатаРасчета");
ПараметрыСКД = Таблица.ПараметрыКомпоновкиДанных;
Если ПараметрыСКД.Количество() <> 2 Тогда
ВызватьИсключение "У своей виртуальной таблицы нужны две позиции параметров СКД";
КонецЕсли;
ПериодСКД = ПараметрыСКД.Получить(0);
ОтборСКД = ПараметрыСКД.Получить(1);
Если ТипЗнч(ПериодСКД) <> Тип("ПараметрТаблицыСхемыЗапроса")
Или ТипЗнч(ОтборСКД) <> Тип("ВыраженияОтбораКомпоновкиДанныхСхемыЗапроса") Тогда
ВызватьИсключение "Нельзя считать все параметры СКД одинаковыми объектами";
КонецЕсли;
Если ОтборСКД.Количество() <> 0 Тогда
ВызватьИсключение "Свой исходный текст не содержит выражений отбора СКД";
КонецЕсли;
ПериодСКД.Выражение = Новый ВыражениеСхемыЗапроса("&ДатаОтчета");
КодСКД = ОтборСКД.Добавить("КодТовара");
КодСКД.Псевдоним = "КодДляОтбора";
КодСКД.ИспользоватьРеквизиты = Ложь;
ПроверитьСвоиПараметрыСКД(Таблица);
ПроверитьСвоиОбычныеПараметры(Таблица, "ДатаРасчета");
СформированныйТекст = Схема.ПолучитьТекстЗапроса();
Если ТипЗнч(СформированныйТекст) <> Тип("Строка") Или СтрНайти(СформированныйТекст, "{") = 0 Тогда
ВызватьИсключение "Схема должна сформировать реальный текст с расширением СКД";
КонецЕсли;
ПовторнаяСхема = Новый СхемаЗапроса;
ПовторнаяСхема.РежимКомпоновкиДанных = Истина;
ПовторнаяСхема.УстановитьТекстЗапроса(СформированныйТекст);
ПовторнаяТаблица = ПолучитьСвоюТаблицу(ПовторнаяСхема);
ПроверитьСвоиОбычныеПараметры(ПовторнаяТаблица, "ДатаРасчета");
ПроверитьСвоиПараметрыСКД(ПовторнаяТаблица);
ПервыйОбычный.Выражение = Новый ВыражениеСхемыЗапроса("&ДатаЗапроса");
ПроверитьСвоиОбычныеПараметры(Таблица, "ДатаЗапроса");
ПроверитьСвоиПараметрыСКД(Таблица);
ПроверитьСвоиОбычныеПараметры(ПовторнаяТаблица, "ДатаРасчета");
ПроверитьСвоиПараметрыСКД(ПовторнаяТаблица);
Если ИсходныйТекст <> "ВЫБРАТЬ Срез.КодТовара КАК КодТовара, Срез.Цена КАК Цена
|ИЗ РегистрСведений.УчебнаяИстория85.СрезПоследних(&ДатаЗапроса, КодТовара = &КодТовара) КАК Срез" Тогда
ВызватьИсключение "Свой исходный строковый текст не должен измениться";
КонецЕсли;
Сообщить(СформированныйТекст);
Сообщить("Обычных параметров2; позиций СКД2; поле отбора1; повторный разбор и независимость схем проверены");
КонецПроцедуры
Процедура ПроверитьСвойМинимальныйСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 1 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвойРегистр()
Если ПривилегированныйРежим() Тогда
ВызватьИсключение "Привилегированный режим для учебного разбора не нужен";
КонецЕсли;
МетаРегистр = Метаданные.РегистрыСведений.Найти("УчебнаяИстория85");
Если МетаРегистр = Неопределено Тогда
ВызватьИсключение "Нужен только собственный регистр УчебнаяИстория85";
КонецЕсли;
Если МетаРегистр.РежимЗаписи <> Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.Независимый
Или МетаРегистр.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Секунда
Или МетаРегистр.Измерения.Количество() <> 1 Или МетаРегистр.Ресурсы.Количество() <> 1
Или МетаРегистр.Реквизиты.Количество() <> 0 Тогда
ВызватьИсключение "Нужен независимый периодический регистр с одним измерением и ресурсом";
КонецЕсли;
МетаКод = МетаРегистр.Измерения.Найти("КодТовара");
МетаЦена = МетаРегистр.Ресурсы.Найти("Цена");
Если МетаКод = Неопределено Или МетаЦена = Неопределено Тогда
ВызватьИсключение "Нужны свои КодТовара и Цена";
КонецЕсли;
КодТипы = МетаКод.Тип.Типы();
ЦенаТипы = МетаЦена.Тип.Типы();
Если КодТипы.Количество() <> 1 Или ЦенаТипы.Количество() <> 1 Тогда
ВызватьИсключение "Составные типы своих полей не подходят";
КонецЕсли;
Если КодТипы[0] <> Тип("Строка") Или ЦенаТипы[0] <> Тип("Число")
Или МетаКод.Тип.КвалификаторыСтроки.Длина <> 3
Или МетаЦена.Тип.КвалификаторыЧисла.Разрядность <> 12
Или МетаЦена.Тип.КвалификаторыЧисла.РазрядностьДробнойЧасти <> 2 Тогда
ВызватьИсключение "Не совпали полные собственные типы полей";
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСвоюТаблицу(Схема)
Если Не Схема.РежимКомпоновкиДанных Или Схема.ПакетЗапросов.Количество() <> 1 Тогда
ВызватьИсключение "Нужна одна собственная схема в режиме СКД";
КонецЕсли;
Выбор = Схема.ПакетЗапросов.Получить(0);
Если ТипЗнч(Выбор) <> Тип("ЗапросВыбораСхемыЗапроса") Или Выбор.Операторы.Количество() <> 1 Тогда
ВызватьИсключение "Нужен один собственный запрос выбора с одним оператором";
КонецЕсли;
Оператор = Выбор.Операторы.Получить(0);
Если ТипЗнч(Оператор) <> Тип("ОператорВыбратьСхемыЗапроса") Или Оператор.Источники.Количество() <> 1 Тогда
ВызватьИсключение "Нужен один собственный источник без соединений";
КонецЕсли;
Источник = Оператор.Источники.Получить(0);
Таблица = Источник.Источник;
Если ТипЗнч(Таблица) <> Тип("ТаблицаСхемыЗапроса") Тогда
ВызватьИсключение "Источником должна быть реальная таблица схемы запроса";
КонецЕсли;
Если НРег(Таблица.ИмяТаблицы) <> НРег("РегистрСведений.УчебнаяИстория85.СрезПоследних")
Или Таблица.Псевдоним <> "Срез" Тогда
ВызватьИсключение "Не совпали своя таблица и псевдоним";
КонецЕсли;
Для Каждого ИмяПоля Из СтрРазделить("КодТовара,Цена", ",") Цикл
Поле = Таблица.ДоступныеПоля.Найти(ИмяПоля);
Если ТипЗнч(Поле) <> Тип("ДоступноеПолеСхемыЗапроса") Тогда
ВызватьИсключение "Не найдено собственное доступное поле " + ИмяПоля;
КонецЕсли;
Если ИмяПоля = "КодТовара" Тогда
ОжидаемыйТип = Тип("Строка");
Иначе
ОжидаемыйТип = Тип("Число");
КонецЕсли;
Если Не Поле.ТипЗначения.СодержитТип(ОжидаемыйТип) Тогда
ВызватьИсключение "Не совпал тип собственного доступного поля " + Поле.Имя;
КонецЕсли;
КонецЦикла;
Возврат Таблица;
КонецФункции
Процедура ПроверитьСвоиОбычныеПараметры(Таблица, ДатаИмя)
Параметры = Таблица.Параметры;
Если ТипЗнч(Параметры) <> Тип("ПараметрыТаблицыСхемыЗапроса") Или Параметры.Количество() <> 2 Тогда
ВызватьИсключение "Нужны два обычных параметра собственного СрезПоследних";
КонецЕсли;
Для Индекс = 0 По 1 Цикл
Элемент = Параметры.Получить(Индекс);
Если ТипЗнч(Элемент) <> Тип("ПараметрТаблицыСхемыЗапроса") Или Параметры.Индекс(Элемент) <> Индекс Тогда
ВызватьИсключение "Не совпали тип и индекс собственного обычного параметра";
КонецЕсли;
Если Индекс = 0 Тогда
Текст = "&" + ДатаИмя;
Иначе
Текст = "КодТовара = &КодТовара";
КонецЕсли;
Ожидаемое = Новый ВыражениеСхемыЗапроса(Текст);
Если ТипЗнч(Элемент.Выражение) <> Тип("ВыражениеСхемыЗапроса") Или Элемент.Выражение <> Ожидаемое Тогда
ВызватьИсключение "Не совпало полное выражение обычного параметра";
КонецЕсли;
Найденный = Параметры.Найти(Строка(Элемент.Выражение));
Если Найденный <> Элемент Или Параметры.Получить(Параметры.Индекс(Найденный)) <> Элемент Тогда
ВызватьИсключение "Поиск форматированного выражения должен вернуть тот же реальный элемент";
КонецЕсли;
КонецЦикла;
Если Параметры.Количество() <> 2 Тогда
ВызватьИсключение "Обход не должен расширять собственные обычные параметры";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвоиПараметрыСКД(Таблица)
ПараметрыСКД = Таблица.ПараметрыКомпоновкиДанных;
Если ТипЗнч(ПараметрыСКД) <> Тип("ПараметрыКомпоновкиДанныхТаблицыСхемыЗапроса") Или ПараметрыСКД.Количество() <> 2 Тогда
ВызватьИсключение "Нужны два возможных параметра СКД собственной таблицы";
КонецЕсли;
ПериодСКД = ПараметрыСКД.Получить(0);
ОтборСКД = ПараметрыСКД.Получить(1);
Если ТипЗнч(ПериодСКД) <> Тип("ПараметрТаблицыСхемыЗапроса")
Или ТипЗнч(ОтборСКД) <> Тип("ВыраженияОтбораКомпоновкиДанныхСхемыЗапроса") Тогда
ВызватьИсключение "Период — одиночный параметр, отбор — отдельная коллекция выражений";
КонецЕсли;
Если ПараметрыСКД.Индекс(ПериодСКД) <> 0 Или ПараметрыСКД.Индекс(ОтборСКД) <> 1 Тогда
ВызватьИсключение "Не совпали индексы разных типов параметров СКД";
КонецЕсли;
ОжидаемыйПериод = Новый ВыражениеСхемыЗапроса("&ДатаОтчета");
Если ПериодСКД.Выражение <> ОжидаемыйПериод Или ОтборСКД.Количество() <> 1 Тогда
ВызватьИсключение "Не совпал собственный период или число выражений СКД";
КонецЕсли;
КодСКД = ОтборСКД.Получить(0);
ОжидаемыйКод = Новый ВыражениеСхемыЗапроса("КодТовара");
Если ТипЗнч(КодСКД) <> Тип("ВыражениеОтбораКомпоновкиДанныхСхемыЗапроса")
Или КодСКД.Выражение <> ОжидаемыйКод Или КодСКД.Псевдоним <> "КодДляОтбора"
Или ТипЗнч(КодСКД.ИспользоватьРеквизиты) <> Тип("Булево") Или КодСКД.ИспользоватьРеквизиты
Или ОтборСКД.Индекс(КодСКД) <> 0 Тогда
ВызватьИсключение "Не совпали все свойства собственного поля отбора СКД";
КонецЕсли;
КонецПроцедурыУчебныеПараметры85.Форма
Своя внешняя обработка УчебныеПараметры85 → управляемая Форма → Модуль
Полный отдельный модуль формы; схема и дочерние объекты не передаются на клиент.
&НаКлиенте
Процедура Выполнить(Команда)
ВыполнитьНаСервере();
Сообщить("Обычные параметры, параметры СКД и повторный разбор текста проверены");
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
УчебныеЗадачи.ВыполнитьПример();
КонецПроцедурыРазбор по шагам
Включить РежимКомпоновкиДанных ДО УстановитьТекстЗапроса. Получить настоящий ТаблицаСхемыЗапроса через пакет→запрос выбора→оператор→источник. Сохранить обе родительские схемы в переменных на всё время работы с дочерними объектами; источник не удаляется и между схемами не переносится.
Проверить своё имя виртуальной таблицы, псевдоним Срез и доступные КодТовара/Цена со строковым и числовым типами. ДоступныеПоля не являются строками среза и не читают цены. Параметры и ПараметрыКомпоновкиДанных — разные readonly-коллекции одного собственного источника.
Обычных параметров два: индекс0 — &ДатаЗапроса, индекс1 — КодТовара = &КодТовара. Для каждого проверяются точный тип, полное выражение, Индекс и поиск по Строка(Выражение). Найти принимает строковое выражение с учётом форматирования, а не имя регистра, индекс или объект ВыражениеСхемыЗапроса.
Заменить Выражение первого обычного параметра новым ВыражениеСхемыЗапроса("&ДатаРасчета"). Это чтение и запись свойства внутри своей схемы, не установка значения параметра для выполнения запроса. Второе обычное условие должно остаться полностью прежним.
Получить две позиции параметров СКД. Первый объект — ПараметрТаблицыСхемыЗапроса для периода; второй — ВыраженияОтбораКомпоновкиДанныхСхемыЗапроса, то есть коллекция, а не один такой же параметр. Явно проверить оба типа, индексы и пустоту исходного собственного отбора.
В период СКД записать выражение &ДатаОтчета. Во второй контейнер добавить доступное поле КодТовара, дать псевдоним КодДляОтбора, оставить ИспользоватьРеквизиты=Ложь. Строковое поле не превращается в ссылочный объект с подчинёнными реквизитами. Выражение элемента отбора readonly; оно задаётся при Добавить, а не присваиванием свойства.
Сформировать текст через ПолучитьТекстЗапроса. Не сочинять фигурные скобки вручную: их формирует объектная модель. Наличие скобки — лишь дополнительная проверка, главное — повторный разбор этого текста НОВОЙ схемой в режиме СКД и полная повторная сверка обычных/СКД-параметров.
Вернуть обычный период исходной схемы в &ДатаЗапроса. Отдельная повторная схема должна сохранить &ДатаРасчета, а обе — &ДатаОтчета и КодДляОтбора. Исходная строка текста не меняется. Это проверяет независимость двух собственных структур, не перенос дочерних объектов между ними.
Как проверить результат
Будущий результат: первая схема после восстановления имеет обычный период &ДатаЗапроса; повторная имеет &ДатаРасчета. В каждой обычный второй параметр КодТовара = &КодТовара, период СКД &ДатаОтчета и ровно одно поле отбора СКД КодТовара с псевдонимом КодДляОтбора и флагом Ложь.
Положительное сообщение формы выводится только после возврата серверного модуля. Перед ним показывается реально сформированный текст; форматирование, отступы и регистр ключевых слов не объявляются побайтово фиксированными. Проверка выражений опирается на документированное сравнение ВыражениеСхемыЗапроса.
Будущий отрицательный контроль: вне опыта заменить только ожидаемый псевдоним в проверяющей процедуре на ОшибочныйКод; сохранить/F7 до свежего сеанса. Полная проверка должна отказать, несмотря на правильное число параметров. Вернуть ожидание, снова F7 до свежего сеанса. Здесь контроль не исполнялся.
Python-тесты проверяют состав нашего кода, подготовку, точные API-контракты и собственную модель ожиданий. Схема, разбор текста, метаданные и форма в1С не запускались; runtimeVerifiedScenarios=0.
Ожидаемый результат
Полный собственный пример отличает обычное выражение периода, расширение СКД и будущие значения параметров запроса. Две структуры сверены после сериализации и независимого восстановления, без неизвестного входного объекта.
На что обратить внимание
У ПараметрыТаблицыСхемыЗапроса.Получить есть документированный побочный эффект расширения коллекции при индексе больше количества; оператор [] за границей выдаёт ошибку. Здесь используются только0и1 после проверки количества2, затем число элементов сверяется повторно. Это не правило обычного Массив или всех коллекций.
Найти здесь ищет по форматированному выражению. Для положительного поиска передаётся Строка уже существующего собственного выражения. Не обещается конкретный результат отсутствующего совпадения, который отдельный прочитанный контракт не описывает.
Возможные параметры СКД имеют разные типы. Их количество зависит от виртуальной таблицы; число2 относится к своему СрезПоследних и не переносится на Обороты, бухгалтерские или расчётные таблицы.
Коллекции Таблица.Параметры, Таблица.ПараметрыКомпоновкиДанных, ИмяТаблицы и ДоступныеПоля readonly. Изменяется только поддерживаемое Выражение реального параметра, собственный контейнер отбора и его RW-псевдоним/флаг; readonly-полю Выражение элемента отбора ничего не присваивается.
В режиме СКД недоступны свойства итогов и текст с ИТОГИ вызывает исключение при установке. Здесь нет ИТОГИ и обращения к этим полям; обычная схема без СКД не является взаимозаменяемой подготовкой.
Сформированный текст с расширением — описание для СКД, не доказательство строк данных и не команда для прямого Запрос.Выполнить. Здесь ни значения дат/кодов для исполнения, ни строки регистра не создаются. Реальное выполнение и интерфейс редактора не проверены.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.