Полный собственный редактор коллекции настроек с проверкой исходных объектов, индексов, независимости и настоящего вывода диаграммы.
Где и как запускать
Полный серверный общий модуль УчебныеКоллекцииНастроек85; полный отдельный модуль своей формы ниже.
Подготовка
НОВАЯ пустая файловая база 8.5.1.1343: Имя=УчебныеКоллекцииНастроек85, совместимость НеИспользовать, управляемое приложение. Без бизнес-метаданных, расширений и заданий. Не рабочая КА2/УНФ/УТ/БП. Здесь не запускалось: runtimeVerifiedScenarios=0.
Общий модуль УчебныеКоллекцииНастроек85: Сервер=Да, Клиент=Нет, Вызов сервера=Нет, Глобальный=Нет, Привилегированный=Нет. Вставьте весь код одного урока целиком. Все схемы, настройки и источники включены; неизвестных входных объектов нет.
Обработка УчебныеНастройкиПродаж85 → управляемая форма Пульт → команда Выполнить с одноименным действием и кнопкой. Полный отдельный модуль формы ниже. F7 и обновление только своего нового стенда перед будущим отдельно разрешенным запуском.
Три константные продажи: Север/Книга/3/750, Север/Ручка/1/50, Юг/Книга/2/500. Серии по Магазин, точки по Наименование, ресурс Сумма. Источник всегда имеет три строки, шесть единиц и сумму 1300; Юг/Ручка отсутствует.
СоздатьСвоюСхемуПродаж каждый раз создает ВСЕ объекты заново. Это не Массив ссылок и не частичная копия настроек. Оригинал защищается ссылками владельцев и полной сериализацией схемы в строку памяти, без записи файла.
Базовый отбор Сумма>=0 пропускает все свои положительные продажи; порядок магазинных серий задан по Магазин Возр. Поэтому каждая редактируемая коллекция изначально непуста и проверка Получить(0) не читает отсутствующий элемент.
Процедура ВыполнитьПример() Экспорт
ПроверитьСвойПустойСтенд();
Если ПривилегированныйРежим() Тогда
ВызватьИсключение "Привилегированный режим не нужен";
КонецЕсли;
Схема = СоздатьСвоюСхемуПродаж();
Настройки = Схема.НастройкиПоУмолчанию;
ИсходнаяДиаграмма = ПолучитьСвоюДиаграммуНастроек(Настройки);
ИсходнаяГруппа = ПолучитьСвоюМагазиннуюГруппуНастроек(Настройки);
ТекстИсходнойСхемы = СвояСхемаВСтроку(Схема);
ПроверитьСвоюДиаграммуПродаж(СкомпоноватьСвоиПродажи(Схема));
СхемаЧерновика = СоздатьСвоюСхемуПродаж();
НастройкиЧерновика = СхемаЧерновика.НастройкиПоУмолчанию;
ГруппаЧерновика = ПолучитьСвоюМагазиннуюГруппуНастроек(НастройкиЧерновика);
Каталог = ГруппаЧерновика.ПоляГруппировки.Элементы;
ИсходноеКоличество = Каталог.Количество();
Если ИсходноеКоличество < 1 Тогда
ВызватьИсключение "В собственной исходной коллекции должен быть реальный элемент";
КонецЕсли;
Первичные = Новый Массив;
Для Каждого Элемент Из Каталог Цикл
Первичные.Добавить(Элемент);
КонецЦикла;
ПроверитьСвоиПервичныеЭлементы(Каталог, Первичные, 0);
Первый = Каталог.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
ЗаполнитьСвойЭлементНастройки(Первый, Истина);
Второй = Каталог.Вставить(0, Тип("ПолеГруппировкиКомпоновкиДанных"));
ЗаполнитьСвойЭлементНастройки(Второй, Ложь);
Если Каталог.Количество() <> ИсходноеКоличество + 2
Или Каталог.Индекс(Первый) <> ИсходноеКоличество + 1 Или Каталог.Индекс(Второй) <> 0
Или Каталог.Получить(0) <> Второй Тогда
ВызватьИсключение "Не совпали размер, индексы и реальные элементы настроек";
КонецЕсли;
ПроверитьСвоиПервичныеЭлементы(Каталог, Первичные, 1);
Каталог.Сдвинуть(Первый, -(ИсходноеКоличество + 1));
Если Каталог.Получить(0) <> Первый Или Каталог.Индекс(Второй) <> 1 Тогда
ВызватьИсключение "Переместился не тот собственный элемент настройки";
КонецЕсли;
ПроверитьСвоиПервичныеЭлементы(Каталог, Первичные, 2);
Каталог.Удалить(Второй);
Если Каталог.Количество() <> ИсходноеКоличество + 1 Или Каталог.Получить(0) <> Первый Тогда
ВызватьИсключение "Удалить должен убрать лишь вторую собственную настройку";
КонецЕсли;
ПроверитьСвоиПервичныеЭлементы(Каталог, Первичные, 1);
Каталог.Очистить();
Если Каталог.Количество() <> 0 Тогда
ВызватьИсключение "Не очищен каталог черновика";
КонецЕсли;
Если ПолучитьСвоюДиаграммуНастроек(Настройки) <> ИсходнаяДиаграмма
Или ПолучитьСвоюМагазиннуюГруппуНастроек(Настройки) <> ИсходнаяГруппа
Или СвояСхемаВСтроку(Схема) <> ТекстИсходнойСхемы Тогда
ВызватьИсключение "Правка независимо созданного черновика затронула исходную схему";
КонецЕсли;
ВосстановленнаяСхема = СоздатьСвоюСхемуПродаж();
ВосстановленныеНастройки = ВосстановленнаяСхема.НастройкиПоУмолчанию;
ВосстановленнаяГруппа = ПолучитьСвоюМагазиннуюГруппуНастроек(ВосстановленныеНастройки);
ВосстановленныйКаталог = ВосстановленнаяГруппа.ПоляГруппировки.Элементы;
Если ВосстановленныйКаталог.Количество() <> ИсходноеКоличество Тогда
ВызватьИсключение "Фабрика не вернула полные исходные настройки задачи";
КонецЕсли;
ПроверитьСвоюДиаграммуПродаж(СкомпоноватьСвоиПродажи(ВосстановленнаяСхема));
ПроверитьСвоюДиаграммуПродаж(СкомпоноватьСвоиПродажи(Схема));
Сообщить("Самостоятельные настройки и полный вывод проверены; исходные продажи 750/50/500, сумма 1300.");
КонецПроцедуры
Функция СоздатьСвоюСхемуПродаж()
Схема = Новый СхемаКомпоновкиДанных;
Источник = Схема.ИсточникиДанных.Добавить();
Источник.Имя = "УчебныеПродажи";
Источник.ТипИсточникаДанных = "Local";
Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
Набор.Имя = "СвоиТриСтроки";
Набор.ИсточникДанных = Источник.Имя;
Набор.АвтоЗаполнениеДоступныхПолей = Истина;
Набор.Запрос = "ВЫБРАТЬ
| ""Север"" КАК Магазин,
| ""Книга"" КАК Наименование,
| 3 КАК Количество,
| 750 КАК Сумма
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ ""Север"", ""Ручка"", 1, 50
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ ""Юг"", ""Книга"", 2, 500";
Для Каждого ИмяРесурса Из СтрРазделить("Сумма,Количество", ",") Цикл
Ресурс = Схема.ПоляИтога.Добавить();
Ресурс.ПутьКДанным = ИмяРесурса;
Ресурс.Выражение = "Сумма(" + ИмяРесурса + ")";
КонецЦикла;
Настройки = Схема.НастройкиПоУмолчанию;
Диаграмма = Настройки.Структура.Добавить(Тип("ДиаграммаКомпоновкиДанных"));
Диаграмма.Имя = "УчебныеПродажиПоМагазинам";
Диаграмма.Использование = Истина;
Выбранное = Диаграмма.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
Выбранное.Поле = Новый ПолеКомпоновкиДанных("Сумма");
Выбранное.Использование = Истина;
Серия = Диаграмма.Серии.Добавить();
Серия.Имя = "Магазины";
Серия.Использование = Истина;
ПолеСерии = Серия.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
ПолеСерии.Поле = Новый ПолеКомпоновкиДанных("Магазин");
ПолеСерии.ТипГруппировки = ТипГруппировкиКомпоновкиДанных.Элементы;
ПолеСерии.Использование = Истина;
Точка = Диаграмма.Точки.Добавить();
Точка.Имя = "Товары";
Точка.Использование = Истина;
ПолеТочки = Точка.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
ПолеТочки.Поле = Новый ПолеКомпоновкиДанных("Наименование");
ПолеТочки.ТипГруппировки = ТипГруппировкиКомпоновкиДанных.Элементы;
ПолеТочки.Использование = Истина;
Диаграмма.ПараметрыВывода.УстановитьЗначениеПараметра("ТипДиаграммы", ТипДиаграммы.Гистограмма);
Диаграмма.ПараметрыВывода.УстановитьЗначениеПараметра("Заголовок", "Свои продажи: магазины и товары");
БазовыйОтбор = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
БазовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Сумма");
БазовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.БольшеИлиРавно;
БазовыйОтбор.ПравоеЗначение = 0;
БазовыйОтбор.Использование = Истина;
БазовыйПорядок = Серия.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
БазовыйПорядок.Поле = Новый ПолеКомпоновкиДанных("Магазин");
БазовыйПорядок.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
БазовыйПорядок.Использование = Истина;
Возврат Схема;
КонецФункции
Функция ПолучитьСвоюДиаграммуНастроек(Настройки)
Найденные = Новый Массив;
Для Каждого Элемент Из Настройки.Структура Цикл
Если ТипЗнч(Элемент) = Тип("ДиаграммаКомпоновкиДанных") Тогда
Найденные.Добавить(Элемент);
КонецЕсли;
КонецЦикла;
Если Найденные.Количество() <> 1 Тогда
ВызватьИсключение "Нужна одна собственная диаграмма настроек";
КонецЕсли;
Возврат Найденные[0];
КонецФункции
Функция ПолучитьСвоюМагазиннуюГруппуНастроек(Настройки)
Диаграмма = ПолучитьСвоюДиаграммуНастроек(Настройки);
Если Диаграмма.Серии.Количество() <> 1 Тогда
ВызватьИсключение "В этой собственной диаграмме одна настройка магазинной группы серий";
КонецЕсли;
Группа = Диаграмма.Серии.Получить(0);
Если ТипЗнч(Группа) <> Тип("ГруппировкаДиаграммыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужна группа из настроек, не из скомпилированного макета";
КонецЕсли;
Возврат Группа;
КонецФункции
Функция СкомпоноватьСвоиПродажи(Схема)
Если Схема.НаборыДанных.Количество() <> 1 Тогда
ВызватьИсключение "Ожидается один собственный Local-запрос";
КонецЕсли;
Набор = Схема.НаборыДанных.Получить(0);
КонтрольныйЗапрос = Новый Запрос;
КонтрольныйЗапрос.Текст = Набор.Запрос;
Источник = КонтрольныйЗапрос.Выполнить().Выгрузить();
Если Источник.Количество() <> 3 Или Источник.Итог("Количество") <> 6 Или Источник.Итог("Сумма") <> 1300 Тогда
ВызватьИсключение "Изменился собственный источник трех продаж";
КонецЕсли;
Компоновщик = Новый КомпоновщикМакетаКомпоновкиДанных;
Возврат Компоновщик.Выполнить(Схема, Схема.НастройкиПоУмолчанию);
КонецФункции
Функция СвояСхемаВСтроку(Схема)
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(Запись, Схема);
Возврат Запись.Закрыть();
КонецФункции
Процедура ПроверитьСвоиПервичныеЭлементы(Каталог, Первичные, Смещение)
Для Номер = 0 По Первичные.Количество() - 1 Цикл
Если Каталог.Получить(Номер + Смещение) <> Первичные[Номер] Тогда
ВызватьИсключение "Изменились объекты или взаимный порядок исходных элементов копии";
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ЗаполнитьСвойЭлементНастройки(Элемент, ЭтоПервый)
Если ТипЗнч(Элемент) <> Тип("ПолеГруппировкиКомпоновкиДанных") Тогда
ВызватьИсключение "Нужно явное поле настройки группировки";
КонецЕсли;
Элемент.Поле = Новый ПолеКомпоновкиДанных(?(ЭтоПервый, "Магазин", "Наименование"));
Элемент.ТипГруппировки = ТипГруппировкиКомпоновкиДанных.Элементы;
Элемент.Использование = Истина;
КонецПроцедуры
Функция СформироватьСвойДокумент(СвойМакет)
Процессор = Новый ПроцессорКомпоновкиДанных;
Процессор.Инициализировать(СвойМакет);
Документ = Новый ТабличныйДокумент;
Вывод = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
Вывод.ОтображатьПроцентВывода = Ложь;
Вывод.УстановитьДокумент(Документ);
РезультатВывода = Вывод.Вывести(Процессор, Ложь);
Если ТипЗнч(РезультатВывода) <> Тип("ТабличныйДокумент") Тогда
ВызватьИсключение "Не получен собственный табличный документ";
КонецЕсли;
Возврат РезультатВывода;
КонецФункции
Процедура ПроверитьСвоюДиаграммуПродаж(Макет)
Документ = СформироватьСвойДокумент(Макет);
Найденные = Новый Массив;
Для Каждого Рисунок Из Документ.Рисунки Цикл
Если Рисунок.ТипРисунка = ТипРисункаТабличногоДокумента.Диаграмма Тогда
ГотоваяДиаграмма = Рисунок.Объект;
Если ТипЗнч(ГотоваяДиаграмма) <> Тип("Диаграмма") Тогда
ВызватьИсключение "Рисунок не содержит обычную готовую диаграмму";
КонецЕсли;
Найденные.Добавить(ГотоваяДиаграмма);
КонецЕсли;
КонецЦикла;
Если Найденные.Количество() <> 1 Тогда
ВызватьИсключение "Нужен один фактически выведенный рисунок диаграммы";
КонецЕсли;
ГотоваяДиаграмма = Найденные[0];
Если ГотоваяДиаграмма.Серии.Количество() <> 2 Или ГотоваяДиаграмма.Точки.Количество() <> 2 Тогда
ВызватьИсключение "Не получены две магазинные серии и две товарные точки";
КонецЕсли;
Север = Неопределено;
Юг = Неопределено;
Для Каждого Серия Из ГотоваяДиаграмма.Серии Цикл
Если Серия.Текст = "Север" Тогда
Север = Серия;
ИначеЕсли Серия.Текст = "Юг" Тогда
Юг = Серия;
КонецЕсли;
КонецЦикла;
Книга = Неопределено;
Ручка = Неопределено;
Для Каждого Точка Из ГотоваяДиаграмма.Точки Цикл
Если Точка.Текст = "Книга" Тогда
Книга = Точка;
ИначеЕсли Точка.Текст = "Ручка" Тогда
Ручка = Точка;
КонецЕсли;
КонецЦикла;
Если Север = Неопределено Или Юг = Неопределено Или Книга = Неопределено Или Ручка = Неопределено Тогда
ВызватьИсключение "Проверьте реальные подписи осей своей простой диаграммы";
КонецЕсли;
СеверКнига = ГотоваяДиаграмма.ПолучитьЗначение(Книга, Север).Значение;
СеверРучка = ГотоваяДиаграмма.ПолучитьЗначение(Ручка, Север).Значение;
ЮгКнига = ГотоваяДиаграмма.ПолучитьЗначение(Книга, Юг).Значение;
Если ТипЗнч(СеверКнига) <> Тип("Число") Или ТипЗнч(СеверРучка) <> Тип("Число")
Или ТипЗнч(ЮгКнига) <> Тип("Число") Тогда
ВызватьИсключение "Три настоящие продажи должны быть числовыми значениями рисунка";
КонецЕсли;
Если СеверКнига <> 750 Или СеверРучка <> 50 Или ЮгКнига <> 500
Или СеверКнига + СеверРучка + ЮгКнига <> 1300 Тогда
ВызватьИсключение "Изменились настоящие значения выведенной диаграммы";
КонецЕсли;
ЮгРучка = ГотоваяДиаграмма.ПолучитьЗначение(Ручка, Юг).Значение;
Если ЗначениеЗаполнено(ЮгРучка) Тогда
ВызватьИсключение "В исходном запросе нет продажи Юг/Ручка";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедурыУчебныеНастройкиПродаж85.Пульт
УчебныеКоллекцииНастроек85 → Обработки → УчебныеНастройкиПродаж85 → Формы → Пульт → Модуль
Полный модуль собственной управляемой формы; здесь не выполнялся.
&НаКлиенте
Процедура Выполнить(Команда)
ВыполнитьНаСервере();
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
УчебныеКоллекцииНастроек85.ВыполнитьПример();
КонецПроцедурыРазбор по шагам
Фабрика собирает свою схему, Local-запрос, ресурсы и диаграмму. Отбор и порядок настроек — настоящие владельцы коллекций, не параметры выдуманного универсального примера.
Компоновщик получает схему и ее реальные настройки. Новый процессор выводит диаграмму, после чего проверяются тип рисунка, число осей, фактические подписи и значения 750/50/500.
Независимый черновик создается той же полной фабрикой. Массив Первичные сохраняет каждый прежний объект только своего каталога для проверки идентичности и относительного порядка.
Первая вставленная настройка задает Магазин, вторая Наименование, обе явные Элементы. Это редактор многопольного ключа группы, не переименование готовой серии. Дублированный/очищенный ключ не выводится; фабрика восстановления возвращает исходный единственный Магазин.
Добавить(Тип) создает первый новый элемент в конце, Вставить(0,Тип) — второй в начале. Заполнение зависит от точного типа: структура, поля, группы условий и сортировки не подменяют друг друга.
Индекс получает реальный элемент. После вставок размер N+2, индексы второго 0 и первого N+1; старые объекты идут с позиции 1. Получить(0) возвращает тот же второй объект.
Сдвинуть(Первый,-(N+1)) переносит тот же объект в начало. Старые элементы начинаются с позиции 2. Удалить(Второй) сохраняет первого и все старые элементы; их смещение снова 1.
Очистить меняет лишь каталог своей отдельно созданной схемы. Очистка структуры убирает весь вывод; очистка полей убирает ключ группировки; очистка отбора снимает ограничения; очистка порядка не задает сортировку. Эти действия имеют разный смысл.
Идентичность владельцев и сериализация всего оригинала должны остаться прежними. Для полного возврата заново создаются схема, настройки, поля, отбор, порядок и диаграмма; старые ссылки очищенного каталога не используются.
Сам оригинал и полностью восстановленная схема компонуются заново, каждый вывод использует новый процессор. Проверяется настоящий рисунок, а не заранее заполненная ожидаемыми числами таблица.
Как проверить результат
Размеры N → N+2 → N+2 → N+1 → 0. На каждом этапе каждый прежний объект каталога сохранен в прежнем относительном порядке.
Сам оригинал не изменяется по владельцам и полной сериализации схемы. После полного восстановления в каталоге снова N исходных настроек.
Исходный и восстановленный полные результаты имеют Север/Юг, Книга/Ручка, реальные 750/50/500 и сумму 1300. Подписи ищутся без предположения порядка индексов.
Ожидаемый результат
Получен полный собственный учебный редактор настроек; сохранены оригинал и полный восстановленный результат. Черновые изменения этой коллекции не исполняются; реальные значения проверяются у оригинала и полного восстановления. Здесь не запускалось в 1С.
На что обратить внимание
Изменяются коллекции НАСТРОЕК, не коллекции скомпилированного макета и не серии готового рисунка. Тот же глагол Добавить в этих уровнях имеет разные сигнатуры и возвращаемые типы.
Тип для Добавить/Вставить здесь обязателен. Получить требует допустимого индекса; Сдвинуть/Удалить принимают реальный фабричный элемент собственного каталога. Имя поля или элемент другой схемы не заменяют его.
ПоляГруппировки, Порядок, Отбор и их Элементы — readonly-ссылки; методы меняют полученные коллекции, а не присваивают вместо них новый Массив.
Отборы на верхнем уровне объединяются по И, внутри созданной группы — по Или. Два отдельных условия Магазин=Север И Магазин=Юг дали бы пустой результат; первая группа содержит оба магазина через Или.
В native-параметре Вставить отбора упомянут элемент условного оформления, но в возвращаемых типах — элемент отбора. Здесь вставляется ГруппаЭлементовОтбораКомпоновкиДанных, согласованная в обеих декларациях. Ошибочный вариант не используется.
Черновые дополнительные поля/критерии сортировки нужны для изучения редактора, не обещают прежнюю структуру рисунка. Неполная структура и очищенные поля не компонуются. Урок отбора отдельно исполняет только полностью заполненные допустимые настройки.
Три свойства пользовательского отображения структуры здесь не засчитываются: этот урок не создает пользовательскую настройку компоновщика. Они остаются в общей задаче заполнения.
Статические проверки не подтверждают запуск в 1С. Здесь не выполняются бизнес-записи, работа в production, сеть, печать или файловая запись. Полная задача в справочнике остается открытой до проверки всего покрытия.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.