Параметр связи: код внешней продажи в запрос цен, равенство и В

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

Свой объектный источник A01/3 передаёт код в параметр собственного запроса цен. Согласованно сравниваем скалярный и списочный режимы, каждый на независимой новой схеме.

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

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

Подготовка

  1. НОВАЯ пустая файловая база 8.5.1.1343 с корневым Именем=УчебныеСвязиМакета85, совместимость НеИспользовать и управляемое приложение. Не рабочая КА2/УНФ/УТ/БП и не их копия. Без бизнес-метаданных, расширений, подписок, заданий и внешних действий. Здесь база не создавалась и примеры не выполнялись: runtimeVerifiedScenarios=0.

  2. Создайте общий модуль УчебныеСвязиМакета85: Сервер=Да, Клиент=Нет, Вызов сервера=Нет, Глобальный=Нет, Привилегированный=Нет. Вставьте ВЕСЬ основной код одного урока. Не объединяйте уроки с одинаковыми именами процедур. Все таблицы, схемы, настройки и макеты создаются самим модулем.

  3. В своей новой конфигурации создайте обработку УчебныеПродажиИЦены85 → управляемая форма Пульт → команда Выполнить с действием Выполнить и кнопкой. Полный модуль формы ниже. F7, затем обновление только собственного нового стенда перед будущим отдельно разрешённым тестом.

  4. Обычный стенд: источник A01/3 и B02/2, приёмник цен только A01/500. Параметрический стенд: внешняя таблица источника только A01/3, запрос приёмника содержит собственные буквальные A01/500 и B01/700. Эти таблицы не являются документами и не записываются в базу.

  5. Источник всегда объектный, поэтому это реальное связывание самостоятельных наборов, а не один SQL JOIN, который компоновщик мог бы получить слиянием двух запросов. Внешняя структура передаётся вторым аргументом Инициализировать. Макет создаёт генератор коллекции значений; настройки только детальные записи без таблиц и диаграмм.

  6. Будущий серверный просмотр: точки останова в ПроверитьСвоюСвязьМакета и ПроверитьСвойВыводСвязи. Читайте фактические имена и выражения макета, настоящий запрос параметрического приёмника и все реальные строки Результат. Таблицы и макеты не возвращайте в тонкий клиент.

  7. Редакторский урок переносит собственный полный макет через XDTO в строку памяти. Файлы, архивы и резервные копии не создаются. Дублированные черновые связи и очищенный каталог не исполняются. Для повторного вывода восстанавливается весь исходный макет из своей строки.

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

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

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

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

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

Функция СоздатьСвойОбъектныйНаборСвязи(Схема, Имя, ИменаПолей)
    Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
    Набор.Имя = Имя;
    Набор.ИмяОбъекта = Имя;
    Набор.ИсточникДанных = "СвоиСвязиМакета85";
    ДобавитьСвоиОписанияСвязи(Набор, ИменаПолей);
    Возврат Набор;
КонецФункции

Функция СоздатьСвоюОсновуСвязи(СПропущеннойЦеной)
    Схема = Новый СхемаКомпоновкиДанных;
    Источник = Схема.ИсточникиДанных.Добавить();
    Источник.Имя = "СвоиСвязиМакета85";
    Источник.ТипИсточникаДанных = "Local";
    СоздатьСвойОбъектныйНаборСвязи(Схема, "Источник85", СтрРазделить("КодИсточника,КоличествоИсточника", ","));
    ВнешниеДанные = Новый Структура;
    ВнешниеДанные.Вставить("Источник85", СоздатьСвоиДанныеСвязи(Истина, СПропущеннойЦеной));
    Возврат Новый Структура("Схема,ВнешниеДанные", Схема, ВнешниеДанные);
КонецФункции

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

Функция СкомпилироватьСвоюСвязь(Схема)
    Компоновщик = Новый КомпоновщикМакетаКомпоновкиДанных;
    Возврат Компоновщик.Выполнить(Схема, Схема.НастройкиПоУмолчанию, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
КонецФункции

Функция ПроверитьСвоюСвязьМакета(Макет, ЧерезПараметр, СписокРазрешен)
    Если ТипЗнч(Макет) <> Тип("МакетКомпоновкиДанных") Или Макет.НаборыДанных.Количество() <> 2 Тогда
        ВызватьИсключение "Нужны два реальных независимых набора полного своего макета";
    КонецЕсли;
    Каталог = Макет.СвязиНаборовДанных;
    Если ТипЗнч(Каталог) <> Тип("СвязиНаборовДанныхМакетаКомпоновкиДанных") Или Каталог.Количество() <> 1 Тогда
        ВызватьИсключение "Нужен один настоящий скомпилированный элемент связи";
    КонецЕсли;
    Связь = Каталог.Получить(0);
    Если ТипЗнч(Связь) <> Тип("СвязьНаборовДанныхМакетаКомпоновкиДанных") Тогда
        ВызватьИсключение "Нужна связь макета, не исходной схемы";
    КонецЕсли;
    НаборИсточник = Макет.НаборыДанных.Найти(Связь.НаборДанныхИсточник);
    НаборПриемник = Макет.НаборыДанных.Найти(Связь.НаборДанныхПриемник);
    Если НаборИсточник = Неопределено Или НаборПриемник = Неопределено Тогда
        ВызватьИсключение "Оба фактических имени связи должны находить настоящие наборы макета";
    КонецЕсли;
    Если НаборИсточник = НаборПриемник Или ТипЗнч(НаборИсточник) <> Тип("НаборДанныхОбъектМакетаКомпоновкиДанных") Тогда
        ВызватьИсключение "Здесь две разные стороны, источник — собственная внешняя таблица";
    КонецЕсли;
    Если НаборИсточник.ИмяОбъекта <> "Источник85" Или Связь.ВыражениеИсточник = "" Или Связь.ВыражениеПриемник = "" Тогда
        ВызватьИсключение "Нужны свой внешний ключ источника и оба настоящих выражения";
    КонецЕсли;
    Если Связь.ТипСвязи <> ТипСвязиНаборовДанныхКомпоновкиДанных.Внешняя
        И Связь.ТипСвязи <> ТипСвязиНаборовДанныхКомпоновкиДанных.Внутренняя Тогда
        ВызватьИсключение "Допустимы только два native-варианта типа связи";
    КонецЕсли;
    Если ЧерезПараметр Тогда
        Если ТипЗнч(НаборПриемник) <> Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Или Связь.Параметр = ""
            Или Связь.РазрешенСписокПараметров <> СписокРазрешен Тогда
            ВызватьИсключение "Параметрическая связь должна вести в реальный запрос со своим режимом значения";
        КонецЕсли;
        Если СтрНайти(ВРег(НаборПриемник.Запрос), ВРег("&" + Связь.Параметр)) = 0 Тогда
            ВызватьИсключение "Фактический параметр связи должен использоваться в настоящем запросе приёмника";
        КонецЕсли;
    Иначе
        Если ТипЗнч(НаборПриемник) <> Тип("НаборДанныхОбъектМакетаКомпоновкиДанных") Тогда
            ВызватьИсключение "Обычный приёмник — собственная таблица цен";
        КонецЕсли;
        Если НаборПриемник.ИмяОбъекта <> "Приемник85" Или Связь.Параметр <> "" Или Связь.РазрешенСписокПараметров Тогда
            ВызватьИсключение "В обычной объектной связи нет параметра запроса";
        КонецЕсли;
    КонецЕсли;
    Сообщить("Источник=" + Связь.НаборДанныхИсточник + "; приёмник=" + Связь.НаборДанныхПриемник);
    Сообщить("Выражения=" + Связь.ВыражениеИсточник + " / " + Связь.ВыражениеПриемник + "; условие=" + Связь.УсловиеСвязи);
    Сообщить("Тип=" + Строка(Связь.ТипСвязи) + "; параметр=" + Связь.Параметр + "; список=" + Строка(Связь.РазрешенСписокПараметров));
    Возврат Связь;
КонецФункции

Процедура ПроверитьСвойВыводСвязи(Макет, ВнешниеДанные, ОжидаетсяB02)
    Процессор = Новый ПроцессорКомпоновкиДанных;
    Процессор.Инициализировать(Макет, ВнешниеДанные);
    Вывод = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
    Приемник = Новый ТаблицаЗначений;
    Вывод.ОтображатьПроцентВывода = Ложь;
    Вывод.УстановитьОбъект(Приемник);
    Результат = Вывод.Вывести(Процессор, Ложь);
    Если ТипЗнч(Результат) <> Тип("ТаблицаЗначений") Или Результат.Количество() <> ?(ОжидаетсяB02, 2, 1)
        Или Результат.Колонки.Количество() <> 3 Тогда
        ВызватьИсключение "Не совпали реальные число продаж и три колонки детального вывода";
    КонецЕсли;
    Для Каждого Имя Из СтрРазделить("КодИсточника,КоличествоИсточника,ЦенаПриемника", ",") Цикл
        Если Результат.Колонки.Найти(Имя) = Неопределено Тогда
            ВызватьИсключение "Потеряно собственное выбранное поле " + Имя;
        КонецЕсли;
    КонецЦикла;
    ЕстьA01 = Ложь;
    ЕстьB02 = Ложь;
    Для Каждого Продажа Из Результат Цикл
        Если Продажа.КодИсточника = "A01" Тогда
            Если ЕстьA01 Или Продажа.КоличествоИсточника <> 3 Или Продажа.ЦенаПриемника <> 500 Тогда
                ВызватьИсключение "Нужна ровно одна связанная продажа A01/3/500";
            КонецЕсли;
            ЕстьA01 = Истина;
        ИначеЕсли Продажа.КодИсточника = "B02" Тогда
            Если Не ОжидаетсяB02 Или ЕстьB02 Или Продажа.КоличествоИсточника <> 2 Тогда
                ВызватьИсключение "Продажа B02/2 допускается только один раз во внешней связи";
            КонецЕсли;
            ТипЦены = ТипЗнч(Продажа.ЦенаПриемника);
            Если ТипЦены <> Тип("Неопределено") И ТипЦены <> Тип("Null") И ТипЦены <> Тип("Число") Тогда
                ВызватьИсключение "Отсутствующая цена не должна заменяться чужим типом";
            КонецЕсли;
            Если ЗначениеЗаполнено(Продажа.ЦенаПриемника) Тогда
                ВызватьИсключение "Для B02 нет строки цены: нельзя подставлять 500 от A01";
            КонецЕсли;
            ЕстьB02 = Истина;
        Иначе
            ВызватьИсключение "Лишняя продажа в реальном результате";
        КонецЕсли;
    КонецЦикла;
    Если Не ЕстьA01 Или ЕстьB02 <> ОжидаетсяB02 Или Результат.Итог("КоличествоИсточника") <> ?(ОжидаетсяB02, 5, 3) Тогда
        ВызватьИсключение "Нужен правильный состав продаж и итог количества 5 или 3";
    КонецЕсли;
    Сообщить("Настоящий вывод: A01/3/500; B02 присутствует=" + Строка(ЕстьB02) + "; количество=" + Строка(Результат.Итог("КоличествоИсточника")));
КонецПроцедуры

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

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

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

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

&НаКлиенте
Процедура Выполнить(Команда)
    ВыполнитьНаСервере();
КонецПроцедуры

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

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

  1. СвойТипПоляПараметра и ПроверитьСвоиКвалификаторыПараметра переиспользуют точные описания четырёх полей: два строковых кода, количество Число(1,0) и цена Число(3,0), оба неотрицательные. Описания передаются колонкам при добавлении и полям схемы; readonly-тип колонки не заменяется.

  2. Исходная СвязьНаборовДанныхСхемыКомпоновкиДанных сопоставляет КодИсточника и КодПриемника между собственными Источник85 и Приемник85. Условие КоличествоИсточника > 0 истинно для своих положительных продаж; пустое условие означало бы безусловное осуществление связи.

  3. После компиляции берём настоящий элемент СвязьНаборовДанныхМакетаКомпоновкиДанных. Его фактические имена разрешаются через Макет.НаборыДанных.Найти и проверяются по типам и внешним ключам. Имена генератора не угадываются и не сравниваются с именами исходной схемы вслепую.

  4. ВыражениеИсточник и ВыражениеПриемник — строки выражений, не значения кодов и не ссылки на сами таблицы. УсловиеСвязи — отдельное выражение допуска связи. Их фактические значения печатаются из настоящего макета; затем реальный состав результата подтверждает сопоставление.

  5. Вывод.Вывести возвращает настоящий результат. Проверка сверяет точные выбранные колонки, все строки без дублей, связанную A01/3/500, наличие/отсутствие B02/2 и независимый итог количества. Для отсутствующей цены B02 допускается только незаполненное число/Null/Неопределено, а не цена A01.

  6. Для Скаляр запрос использует Данные.Код = &КодыСвязи85, флаг списка Ложь; для Список — Данные.Код В (&КодыСвязи85), флаг Истина. Параметр схемы явно объявлен строковым с использованием Авто. Код берётся из реальной внешней A01, а не присваивается пользовательским значением 500.

  7. Весь стенд создаётся заново для каждого режима. Приёмник содержит A01/500 и B01/700, но результат обязан содержать только A01/3/500. Флаг разрешает передачу списка, однако один исходный код не доказывает пакетную передачу нескольких кодов.

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

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

  2. Будущий отрицательный контроль своего результата: заменить цену у B02 на 500 без изменения количества строк и суммы количества. Проверка должна отказать, хотя итог 5 сохранится. Второй контроль — дублировать A01 вместо B02: проверки состава и повторов должны отказать. Здесь контроль не запускался.

  3. В 1С опыт не выполнялся. Эти проверки — код будущего опыта в собственном стенде, не подтверждение реальной компиляции, XDTO round-trip или работы процессора. Не заменяйте настоящий Результат таблицей ожидаемых строк ради прохождения проверки.

  4. Оба реальных вывода должны дать ровно одну A01/3/500 и итог 3. B01/700 не должна попадать в результат, а параметр связи из макета должен встречаться в настоящем запросе приёмника. Здесь многокодовое пакетирование не проверялось.

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

Ожидается реальная связанная A01/3/500. Обычный внешний режим дополнительно сохраняет B02/2 без цены, итог 5; внутренний и параметрические режимы дают только A01, итог 3. Здесь в 1С не запускалось.

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

  1. runtimeVerifiedScenarios=0. Все результаты ожидаемые, статически проверенные по установленной справке, но не измеренные запуском в 1С. Рабочие конфигурации и базы не меняются.

  2. Обязательная у связи исходной схемы отвечает за обязательность включения связи при компиляции и не тождественна ТипСвязи макета. Внешняя сохраняет запись без приёмника; Внутренняя её исключает. В обычном опыте меняется именно ТипСвязи настоящего макета, остальные определения сохраняются.

  3. Параметр означает имя параметра запроса приёмника, а не пользовательское значение. РазрешенСписокПараметров согласуется с операцией В; для равенства список не разрешается. Имя параметра из макета проверяется в фактическом запросе с учётом регистра, а не предполагается равным исходному имени.

  4. НачальноеВыражение предназначено для рекурсивной связи набора с самим собой. Этот набор уроков её не демонстрирует и не засчитывает это свойство. Присваивание пустой строки в обычной связи не является обучением рекурсии.

  5. СвязиНаборовДанных макета — readonly-ссылка на редактируемую коллекцию. У неё нет метода Найти. Добавить() и Вставить(Индекс) не принимают Тип; Сдвинуть и Удалить получают настоящий элемент той же коллекции. Не исполняйте дублированные или неполные черновые связи.

  6. В пустой колонке коллекции значений представление отсутствующей цены может зависеть от установленного типа. Урок не считает нулевую цену найденной строкой: A01 проверяется как точные 500, B02 — отсутствие заполненной цены и правильное участие продажи во внешнем режиме.

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

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

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

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

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