СвязиНаборовДанныхМакетаКомпоновкиДанных.Количество

Методы · Count

Получает количество элементов в коллекции.

Синтаксис

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

СвязиНаборовДанныхМакетаКомпоновкиДанных.Количество (DataCompositionTemplateDataSetLinks.Count)

СвязиНаборовДанныхМакетаКомпоновкиДанных (DataCompositionTemplateDataSetLinks)

Количество (Count)

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

Синтаксис:
Количество()
Возвращаемое значение:
Тип: Число.

Описание:

Получает количество элементов в коллекции.

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

Сервер, толстый клиент, внешнее соединение.

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

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

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

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

Каталог связей макета: добавить, вставить, переставить, удалить и восстановить

На независимом XDTO-черновике своей связи продаж и цен проверяем жизненный цикл настоящих элементов. После очистки копии восстанавливаем весь макет и проверяем полный реальный вывод.

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

Полный серверный общий модуль УчебныеСвязиМакета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", СоздатьСвоиДанныеСвязи(Ложь, Ложь));
    ДобавитьСвоиНастройкиИСвязь(Схема, Ложь, Ложь);
    Макет = СкомпилироватьСвоюСвязь(Схема);
    Связь = ПроверитьСвоюСвязьМакета(Макет, Ложь, Ложь);
    Связь.ТипСвязи = ТипСвязиНаборовДанныхКомпоновкиДанных.Внешняя;
    ПроверитьСвойВыводСвязи(Макет, Стенд.ВнешниеДанные, Истина);
    ТекстМакета = СвойМакетВСтроку(Макет);
    Черновик = СвойМакетИзСтроки(ТекстМакета);
    Скопированная = ПроверитьСвоюСвязьМакета(Черновик, Ложь, Ложь);
    Каталог = Черновик.СвязиНаборовДанных;
    Первый = Каталог.Добавить();
    СкопироватьСвоюСвязьВЧерновик(Первый, Скопированная);
    Второй = Каталог.Вставить(0);
    СкопироватьСвоюСвязьВЧерновик(Второй, Скопированная);
    Если Каталог.Количество() <> 3 Или Каталог.Индекс(Первый) <> 2 Или Каталог.Получить(0) <> Второй
        Или Каталог.Получить(1) <> Скопированная Тогда
        ВызватьИсключение "Добавление и вставка сохраняют заданный порядок собственных связей";
    КонецЕсли;
    Каталог.Сдвинуть(Первый, -2);
    Если Каталог.Индекс(Первый) <> 0 Или Каталог.Получить(0) <> Первый Или Каталог.Получить(1) <> Второй
        Или Каталог.Получить(2) <> Скопированная Тогда
        ВызватьИсключение "Сдвигается тот же собственный элемент на две позиции назад";
    КонецЕсли;
    Каталог.Удалить(Второй);
    Если Каталог.Количество() <> 2 Или Каталог.Получить(0) <> Первый Или Каталог.Получить(1) <> Скопированная Тогда
        ВызватьИсключение "После удаления остаются свой первый черновик и первоначальная связь копии";
    КонецЕсли;
    Каталог.Очистить();
    Если Каталог.Количество() <> 0 Или ПроверитьСвоюСвязьМакета(Макет, Ложь, Ложь) <> Связь Тогда
        ВызватьИсключение "Очищается только каталог копии, исходная связь не меняется";
    КонецЕсли;
    Восстановленный = СвойМакетИзСтроки(ТекстМакета);
    Восстановленная = ПроверитьСвоюСвязьМакета(Восстановленный, Ложь, Ложь);
    Если Восстановленная.ТипСвязи <> ТипСвязиНаборовДанныхКомпоновкиДанных.Внешняя Тогда
        ВызватьИсключение "Полное восстановление должно сохранить внешний тип связи";
    КонецЕсли;
    ПроверитьСвойВыводСвязи(Восстановленный, Стенд.ВнешниеДанные, Истина);
    ПроверитьСвойВыводСвязи(Макет, Стенд.ВнешниеДанные, Истина);
    Сообщить("Черновые связи очищены только в копии; оба полных макета сохранили A01/3/500 и B02/2 без цены.");
КонецПроцедуры

Функция СвойТипПоляПараметра(ИмяПоля)
    Если ИмяПоля = "КодИсточника" Или ИмяПоля = "КодПриемника" Тогда
        Возврат Новый ОписаниеТипов("Строка");
    ИначеЕсли ИмяПоля = "КоличествоИсточника" Тогда
        Возврат Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(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) + "; количество=" + Строка(Результат.Итог("КоличествоИсточника")));
КонецПроцедуры

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

Функция СвойМакетВСтроку(Макет)
    Запись = Новый ЗаписьXML;
    Запись.УстановитьСтроку();
    СериализаторXDTO.ЗаписатьXML(Запись, Макет);
    Возврат Запись.Закрыть();
КонецФункции

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

Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 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. Первый добавляется в конец, Второй вставляется в нулевую позицию. Черновики получают только реальные имена и выражения своей существующей связи, не случайные внешние параметры. Порядок Второй/Скопированная/Первый и Индекс(Первый)=2 проверяются явно.

  7. Сдвинуть(Первый,-2) даёт Первый/Второй/Скопированная; Удалить(Второй) оставляет Первый/Скопированная. Очистить удаляет только связи черновика. После удаления/очистки старые ссылки не используются. Оригинальная связь остаётся тем же объектом своего полного макета.

  8. СвойМакетИзСтроки восстанавливает новый полный макет из собственной исходной XML-строки и закрывает читатель при исключении. Исходный и полностью восстановленный макеты заново дают две продажи и итог 5; сам дублированный или очищенный черновик не выводится.

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

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

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

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

  4. Размеры чернового каталога: 1 → 3 → 3 → 2 → 0. На каждом этапе проверяются точный индекс и настоящие элементы, а не только размер. После восстановления одна внешняя связь и настоящие A01/3/500, B02/2 без цены.

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

Ожидается реальная связанная 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С» и не аффилирован с ней.