СериализаторXDTO

Типы · XDTOSerializer

Сериализатор значений платформы "1С:Предприятие 8" в XML и JSON на основе XDTO.

Полное описание, параметры и ограничения

СериализаторXDTO (XDTOSerializer)

СериализаторXDTO (XDTOSerializer)

Доступен, начиная с версии 8.1.

Свойства:
Фабрика (Factory)

Методы:
XMLЗначение (XMLValue)
XMLСтрока (XMLString)
XMLТип (XMLType)
XMLТипЗнч (XMLTypeOf)
ВозможностьЧтенияXML (CanReadXML)
ЗаписатьJSON (WriteJSON)
ЗаписатьXDTO (WriteXDTO)
ЗаписатьXML (WriteXML)
ИзXMLТипа (FromXMLType)
ПолучитьXMLТип (GetXMLType)
ПрочитатьJSON (ReadJSON)
ПрочитатьXDTO (ReadXDTO)
ПрочитатьXML (ReadXML)

Конструкторы:
На основании XDTO
По умолчанию

Описание:

Сериализатор значений платформы "1С:Предприятие 8" в XML и JSON на основе XDTO.

Доступность:

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

См. также:
Глобальный контекст, свойство СериализаторXDTO

Использование в версии:

Доступен, начиная с версии 8.1.

Методическая информация

Практические примеры

Передать учебный контакт через XML в памяти

Тип ДанныеКонтакта поддерживает XML-сериализацию. Проверяем имя и собственный почтовый элемент; мобильная синхронизация при этом не выполняется.

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

Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.

Подготовка

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

  2. Вся персона вымышлена: Учебный Ученик Тестович, организация Учебный магазин. Телефоны 000-000-01/02 — демонстрационные строки, адрес student@example.invalid учебный. Ничего не отправляйте и не звоните.

  3. Код создаёт объекты только в памяти. Он не вызывает менеджер контактов устройства, синхронизацию, геокодирование, интернет или запись справочника Партнеры/КонтактныеЛица.

Контакт = Новый ДанныеКонтакта;
Контакт.Имя = "Учебный";
Контакт.Фамилия = "Ученик";
Контакт.Отчество = "Тестович";
Контакт.АдресаЭлектроннойПочты = Новый Массив;
Контакт.АдресаЭлектроннойПочты.Добавить(Новый ЭлементДанныхКонтакта(ТипАдресаЭлектроннойПочтыДанныхКонтакта.Рабочий, "student@example.invalid"));
Сообщить(XMLСтрока(Контакт.Имя) = "Учебный");
Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
Попытка
    Сериализатор.ЗаписатьXML(Запись, Контакт, НазначениеТипаXML.Явное);
    СтрокаXML = Запись.Закрыть();
Исключение
    Запись.Закрыть();
    ВызватьИсключение;
КонецПопытки;
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(СтрокаXML);
Попытка
    Чтение.ПерейтиКСодержимому();
    Копия = Сериализатор.ПрочитатьXML(Чтение, Тип("ДанныеКонтакта"));
Исключение
    Чтение.Закрыть();
    ВызватьИсключение;
КонецПопытки;
Чтение.Закрыть();
Сообщить(ТипЗнч(Копия) = Тип("ДанныеКонтакта"));
Сообщить(Копия.Имя = "Учебный");
Сообщить(Копия.Фамилия = "Ученик");
Сообщить(Копия.Отчество = "Тестович");
Сообщить(Копия.АдресаЭлектроннойПочты.Количество() = 1);
Сообщить(Копия.АдресаЭлектроннойПочты[0].Значение = "student@example.invalid");

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

  1. Новый контакт имеет собственные имя и почтовый элемент с системным типом Рабочий.

  2. XMLСтрока используется только для простого строкового поля имени: это не сериализация составного контакта.

  3. Для всей карточки создаём СериализаторXDTO со стандартной ФабрикаXDTO, пишем с явным типом и читаем в ДанныеКонтакта. Чтение и запись закрываем также при ошибке.

  4. В копии проверяем тип, три части имени, количество и содержимое почты. Устройство и менеджер синхронизации не вызываются.

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

  1. Семь сообщений Истина.

  2. XML остаётся в строке памяти: ни файл, ни внешний сервис не нужны.

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

Получена отдельная XML-копия собственного учебного контакта.

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

  1. Это собственные учебные объекты, не контакт, уже полученный от операционной системы или сохранённый на устройстве.

  2. XML-сериализация платформы не является универсальным vCard или JSON-контрактом сторонней CRM.

  3. Для входного неизвестного XML необходимы отдельные ограничения размера и согласованный контракт; этот пример читает только свой источник.

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

Параметр связи СКД: объявление строковых кодов и согласованные режимы = / В

Создаём свой источник A01/3 и приёмник с буквальными строками A01/500, B01/700 внутри настоящего вложенного запроса. Объявляем КодыСвязи85 в схеме, связываем его с полем источника, переключаем полное условие запроса и Булево разрешения списка вместе, проверяем восстановление и независимую копию без исполнения.

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

Полный серверный общий модуль УчебныеЗадачи новой пустой конфигурации УчебныеПараметрыСвязи85; в1С не запускался.

Подготовка

  1. НОВАЯ отдельная учебная база, не копия рабочей: точно8.5.1.1343, конфигурация УчебныеПараметрыСвязи85, совместимость Не использовать. Нет бизнес-объектов, расширений, подписок и фоновых заданий; модули вручную пустые, кроме данного общего модуля.

  2. Конфигуратор → Общие → Общие модули → УчебныеЗадачи: Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Вставить весь основной модуль. Создать свою внешнюю обработку УчебныеПараметрыСвязи85 → управляемая Форма: команда/кнопка Выполнить с действием Выполнить. Отдельный полный модуль формы дан ниже; реквизиты не нужны.

  3. Будущая ручная подготовка вне опыта: завершить прежний свой сеанс, сохранить, Конфигурация → Обновить конфигурацию базы данных (F7), открыть свежий собственный клиент и свою обработку. Здесь F7, BSL, запросы, компоновщик и процессор не запускались.

  4. Источник и приёмник объявлены самим кодом: четыре уникальных пути, в каждом наборе Строка/Число. Приёмник использует вложенный запрос как таблицу-источник, объединяющую две собственные буквальные строки; рабочих таблиц и неизвестных параметров нет.

  5. Числовые поля имеют разные явные учебные контракты: КоличествоИсточника — целое 0–9, ЦенаПриемника — целое 0–999. Собственные буквальные значения3,500,700 укладываются в них. КвалификаторыЧисла передаются вторым аргументом ОписаниеТипов; это не утверждение, что рабочие цены всегда целые или ограничены999.

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

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

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

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

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

Функция СвойЗапросПриемника(СписокРазрешен)
    Если СписокРазрешен Тогда
        Возврат "ВЫБРАТЬ Данные.Код КАК КодПриемника, Данные.Цена КАК ЦенаПриемника ИЗ (ВЫБРАТЬ ""A01"" КАК Код, 500 КАК Цена ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ""B01"" КАК Код, 700 КАК Цена) КАК Данные ГДЕ Данные.Код В (&КодыСвязи85)";
    КонецЕсли;
    Возврат "ВЫБРАТЬ Данные.Код КАК КодПриемника, Данные.Цена КАК ЦенаПриемника ИЗ (ВЫБРАТЬ ""A01"" КАК Код, 500 КАК Цена ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ""B01"" КАК Код, 700 КАК Цена) КАК Данные ГДЕ Данные.Код = &КодыСвязи85";
КонецФункции

Функция СоздатьСвоюОсновуПараметра()
    Схема = Новый СхемаКомпоновкиДанных;
    Источник = Схема.ИсточникиДанных.Добавить();
    Источник.Имя = "СвоиПараметры85";
    Источник.ТипИсточникаДанных = "Local";
    ИменаНаборов = СтрРазделить("Источник85,Приемник85", ",");
    Запросы = Новый Массив;
    Запросы.Добавить("ВЫБРАТЬ ""A01"" КАК КодИсточника, 3 КАК КоличествоИсточника");
    Запросы.Добавить(СвойЗапросПриемника(Ложь));
    ПоляНаборов = Новый Массив;
    ПоляНаборов.Добавить(СтрРазделить("КодИсточника,КоличествоИсточника", ","));
    ПоляНаборов.Добавить(СтрРазделить("КодПриемника,ЦенаПриемника", ","));
    Для ИндексНабора = 0 По 1 Цикл
        Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
        Если ТипЗнч(Набор) <> Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда
            ВызватьИсключение "Нужен собственный набор запроса";
        КонецЕсли;
        Набор.Имя = ИменаНаборов[ИндексНабора];
        Набор.ИсточникДанных = "СвоиПараметры85";
        Набор.АвтоЗаполнениеДоступныхПолей = Ложь;
        Набор.Запрос = Запросы[ИндексНабора];
        ИменаПолей = ПоляНаборов[ИндексНабора];
        Для Индекс = 0 По 1 Цикл
            Поле = Набор.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
            Если ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда
                ВызватьИсключение "Нужно собственное простое объявление поля";
            КонецЕсли;
            Поле.Поле = ИменаПолей[Индекс];
            Поле.ПутьКДанным = ИменаПолей[Индекс];
            Поле.ТипЗначения = СвойТипПоляПараметра(ИменаПолей[Индекс]);
        КонецЦикла;
    КонецЦикла;
    Параметр = Схема.Параметры.Добавить();
    Если ТипЗнч(Параметр) <> Тип("ПараметрСхемыКомпоновкиДанных") Тогда
        ВызватьИсключение "Нужен настоящий собственный параметр схемы";
    КонецЕсли;
    Параметр.Имя = "КодыСвязи85";
    Параметр.ТипЗначения = Новый ОписаниеТипов("Строка");
    Параметр.Значение = "";
    Параметр.Использование = ИспользованиеПараметраКомпоновкиДанных.Авто;
    ВыбираемыеПоля = СтрРазделить("КодИсточника,КоличествоИсточника,ЦенаПриемника", ",");
    Для Каждого Путь Из ВыбираемыеПоля Цикл
        Выбор = Схема.НастройкиПоУмолчанию.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
        Если ТипЗнч(Выбор) <> Тип("ВыбранноеПолеКомпоновкиДанных") Тогда
            ВызватьИсключение "Нужно собственное явно выбранное поле";
        КонецЕсли;
        Выбор.Поле = Новый ПолеКомпоновкиДанных(Путь);
        Выбор.Использование = Истина;
    КонецЦикла;
    ПроверитьСвоюОсновуПараметра(Схема, Ложь);
    Возврат Схема;
КонецФункции

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

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

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

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

Своя внешняя обработка УчебныеПараметрыСвязи85 → управляемая Форма → Модуль

Полный отдельный модуль своей формы с серверным вызовом; здесь не запускался.

&НаКлиенте
Процедура Выполнить(Команда)
    ВыполнитьНаСервере();
    Сообщить("Объявление параметра, полный запрос приёмника и скалярный/списочный режим связи проверены");
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
    УчебныеЗадачи.ВыполнитьПример();
КонецПроцедуры

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

  1. Полностью объявить свой параметр Схема.Параметры.Добавить(): имя КодыСвязи85, ОписаниеТипов("Строка"), строковое значение по умолчанию пустое, использование Авто. В КА2 АнализСчета настоящий параметр связи Ссылки также объявлен в схеме, тип соответствует полю источника.

  2. Не устанавливать Всегда механически: по справке этот режим всегда использует значение настройки. В своём опыте проверяется Авто и передача кода через Параметр связи; пустой default не выдаётся за полученное значение источника.

  3. Параметр свойства связи — имя без амперсанда: КодыСвязи85. В запросе используется &КодыСвязи85. Значение определяется ВыражениеИсточник="КодИсточника"; ВыражениеПриемник="КодПриемника" указывает реальный ключ приёмника. ЦенаПриемника нужна в выборе; источник кода также выбран.

  4. Скалярная версия запроса содержит Данные.Код = &КодыСвязи85 и РазрешенСписокПараметров=Ложь. Списочная версия содержит Данные.Код В (&КодыСвязи85) и флаг Истина. СвойЗапросПриемника возвращает полный точный запрос режима, а УстановитьСвойРежимСвязи меняет запрос и флаг согласованно.

  5. Условие находится во внешнем запросе с настоящим ИЗ (вложенный запрос) КАК Данные, не в выдуманном ГДЕ без источника. Вложенные источники документированы установленной справкой; поля Данные.Код/Цена объявлены внутренним списком выборки.

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

  7. Копия создаётся заново со своим параметром и исходным запросом =. Во время режима В оригинала копия остаётся скалярной. После возврата режима удалить текущую связь как объект, не индекс, подтвердить0 при сохранённом объявлении параметра и запросах, создать новую; очистить оригинальный каталог и восстановить снова.

  8. Списочный режим разрешает обработку списка, но код не присваивает Массив строковому ТипЗначения параметра и не запускает движок. Конкретная упаковка значений компоновщиком и данные результата остаются будущей runtime-проверкой.

  9. СвойТипПоляПараметра различает все четыре настоящих имени поля: коды Строка, количество Число(1,0,Неотрицательный), цена Число(3,0,Неотрицательный). Проверка каждого числового поля сверяет все три квалификатора, а не только наличие Число в Типы(). Строковый параметр КодыСвязи85, запросы и переключение = / В остаются прежними.

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

  1. Будущий итог проверки модели: единственный строковый КодыСвязи85 с пустым default/Авто; два исходных набора и полный скалярный запрос; одна связь Источник85→Приемник85, КодИсточника→КодПриемника, Параметр=КодыСвязи85, флаг списка Ложь. Копия сохраняет то же исходное состояние.

  2. Буквальные строки задают A01/500 и B01/700. По математической логике = для A01 выбирает первый код, а В для списка A01/B01 допускает оба кода, но здесь список источников не формировался и запрос не выполнялся: это объяснение режимов, не полученные строки или обещание производительности.

  3. Будущий отрицательный контроль: после согласованного перехода в режим В вручную заменить только Связь.РазрешенСписокПараметров на Ложь, не меняя эталон Истина и полный запрос. Проверка должна отказать. Альтернативно заменить имя параметра связи на НетТакогоПараметра85 при прежних запросах. Вернуть код, сохранить/F7 вне опыта и открыть новый свой сеанс; здесь контроль не выполнялся.

  4. runtimeVerifiedScenarios=0. Сохранность прежних материалов и native-контракты проверяются статически. Нет выполнения 1С, запросов, записи, сети, реального компоновщика, печати или изменения конфигураций пользователя.

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

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

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

  1. Параметр связи хранит имя параметра, не его значение и не текст &КодыСвязи85. Амперсанд нужен в языке запроса; строка свойства задаётся без него. Полный текст запроса не сводится к поиску подстроки В.

  2. Список допустим при использовании параметра в операции В. Не включайте Истина при сохранённом сравнении = и не подменяйте ОписаниеТипов строкового элемента типом Массив без документированного основания.

  3. Авто и Всегда имеют разный смысл. Этот урок не утверждает, что default пустой станет A01 сам по себе: это работа будущего компоновщика при использовании связи, здесь ни её исполнение, ни фактическая передача не проверялись.

  4. Буквальный вложенный запрос позволяет изучать контракты без чужих таблиц. Наличие параметрической связи не обещает выполненный SQL, количество обращений или готовый визуальный отчёт.

  5. Копия содержит новые собственные объекты. После Удалить и Очистить старые ссылки связи не используются; объявление параметра и оба набора сохраняются. XML получает только собственное ПолеКомпоновкиДанных и пишет строку в памяти.

  6. Методы жизненного цикла каталога параметров и параметры функциональных опций не привязываются как бессмысленные заглушки: им нужны отдельные содержательные задачи.

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

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

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

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

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