МодельПрогнозаПоискПоследовательностей

Типы · PredictionModelSequentialPatterns

Модель, прогнозирующая последующие события. Колонки модели: <Имя колонки - время> - время; <Имя колонки - последовательности> - последовательность; <Имя колонки - элемента> - элемент.

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

МодельПрогнозаПоискПоследовательностей (PredictionModelSequentialPatterns)

МодельПрогнозаПоискПоследовательностей (PredictionModelSequentialPatterns)

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

Свойства:
ИсточникДанных (DataSource)
Колонки (Columns)
КолонкиРезультата (ResultColumns)
НастройкаВходныхКолонок (InputColumnsSetting)
ШаблоныПоследовательностей (SequentialPatterns)

Методы:
Выполнить (Execute)

Описание:

Модель, прогнозирующая последующие события.
Колонки модели:
<Имя колонки - время> - время;

<Имя колонки - последовательности> - последовательность;

<Имя колонки - элемента> - элемент.

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

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

См. также:
РезультатАнализаДанныхПоискПоследовательностей, метод СоздатьМодельПрогноза

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

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

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

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

Найти шаблоны собственных событий, разобрать интервалы и выполнить прогноз отдельной истории

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

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

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

Подготовка

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

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

  3. Собственная внешняя обработка → управляемая Форма → команда/кнопка Выполнить, действие Выполнить. Полный отдельный модуль формы ниже возвращает только текст собственного серверного расчета; таблицы и модель на клиент не передаются.

  4. Журнал в памяти имеет типизированные Серия (Строка), Момент (Дата), Событие (Строка). Четыре own-stream-1…4 дают A 01.01.2025 → B 02.01.2025; пятая A→C, шестая C→A с теми же датами. Это 12 событий, шесть серий, три символических значения A/B/C, не история реальных клиентов.

  5. Роли: Серия=Последовательность с дискретным видом, Момент=Время с непрерывным видом, Событие=Элемент с дискретным видом. МинимальнаяДлина=2; ПоискПоИерархии, МинимальныйИнтервал, МаксимальныйИнтервал и ИнтервалЭквивалентностиВремени выключены. Поэтому не создаются неподтвержденные единицы/кратности выключенных ограничений.

  6. Параметр с native-именем МинимальныйПроцентСлучаев получает небольшой учебный порог 1. В установленной справке название говорит о проценте, а описание о минимальном числе последовательностей. Урок прямо фиксирует противоречие и не утверждает единицу порога; значение реально ищется, проверяется по типу и перечитывается.

  7. Отдельный НовыйВход создается без будущих ответов: own-future-A с A и own-future-C с C, обе записи 01.02.2025. События и даты результата не заполняются заранее. Никаких рабочих таблиц, файлов или сети не нужно.

Функция ВыполнитьПример() Экспорт
    ПроверитьСвойПустойСтенд();
    История = СоздатьСвоюИсторию(Ложь);
    Анализатор = Новый АнализДанных;
    Анализатор.ТипАнализа = Тип("АнализДанныхПоискПоследовательностей");
    Анализатор.ИсточникДанных = История;
    НастроитьСвоиРолиИстории(Анализатор.НастройкаКолонок);
    НастроитьСвойПараметр(Анализатор.Параметры, "МинимальныйПроцентСлучаев", 1);
    НастроитьСвойПараметр(Анализатор.Параметры, "МинимальнаяДлина", 2);
    НастроитьСвойПараметр(Анализатор.Параметры, "ПоискПоИерархии", Ложь);
    НастроитьСвойПараметр(Анализатор.Параметры, "МинимальныйИнтервал", Ложь);
    НастроитьСвойПараметр(Анализатор.Параметры, "МаксимальныйИнтервал", Ложь);
    НастроитьСвойПараметр(Анализатор.Параметры, "ИнтервалЭквивалентностиВремени", Ложь);
    Результат = Анализатор.Выполнить();
    Если ТипЗнч(Результат) <> Тип("РезультатАнализаДанныхПоискПоследовательностей") Или Результат.КоличествоПоследовательностей <> 6 Тогда
        ВызватьИсключение "Нужен настоящий результат шести своих серий, не двенадцати строк";
    КонецЕсли;
    НастроитьСвоиРолиИстории(Результат.НастройкаКолонок, Истина);
    ПроверитьСвойПараметр(Результат.Параметры, "МинимальныйПроцентСлучаев", 1);
    ПроверитьСвойПараметр(Результат.Параметры, "МинимальнаяДлина", 2);
    ПроверитьСвойПараметр(Результат.Параметры, "МинимальныйИнтервал", Ложь);
    ПроверитьСвойПараметр(Результат.Параметры, "МаксимальныйИнтервал", Ложь);
    ПроверитьСвойПараметр(Результат.Параметры, "ИнтервалЭквивалентностиВремени", Ложь);
    Отчет = "СВОЙ ЖУРНАЛ В ПАМЯТИ, НЕ ПЛАН РЕАЛЬНЫХ ПОКУПОК" + Символы.ПС;
    Отчет = Отчет + "Строк событий=" + Строка(История.Количество()) + "; последовательностей=" + Строка(Результат.КоличествоПоследовательностей)
        + "; элементов по платформе=" + Строка(Результат.КоличествоЭлементов) + Символы.ПС;
    Отчет = Отчет + ОписатьСвоиШаблоны(Результат.ШаблоныПоследовательностей);
    Модель = Результат.СоздатьМодельПрогноза();
    Если ТипЗнч(Модель) <> Тип("МодельПрогнозаПоискПоследовательностей") Тогда
        ВызватьИсключение "Не создана настоящая модель по своей истории";
    КонецЕсли;
    Отчет = Отчет + "ШАБЛОНЫ СОЗДАННОЙ МОДЕЛИ" + Символы.ПС + ОписатьСвоиШаблоны(Модель.ШаблоныПоследовательностей);
    НовыйВход = СоздатьСвоюИсторию(Истина);
    Модель.ИсточникДанных = НовыйВход;
    Если ТипЗнч(Модель.ИсточникДанных) <> Тип("ТаблицаЗначений") Или Модель.ИсточникДанных.Количество() <> 2 Тогда
        ВызватьИсключение "Нужна отдельная таблица двух собственных новых начал";
    КонецЕсли;
    Колонки = Модель.Колонки;
    Входы = Модель.НастройкаВходныхКолонок;
    Если ТипЗнч(Колонки) <> Тип("КолонкиМоделиПрогноза") Или ТипЗнч(Входы) <> Тип("НастройкаВходныхКолонокМоделиПрогноза")
        Или Входы.Количество() = 0 Или Входы.Количество() > 3 Тогда
        ВызватьИсключение "Нужны настоящие входные настройки своего трехколоночного журнала";
    КонецЕсли;
    Для Каждого Настройка Из Входы Цикл
        ВходнаяКолонка = Настройка.КолонкаМоделиПрогноза;
        Если ТипЗнч(ВходнаяКолонка) <> Тип("КолонкаМоделиПрогноза") Тогда
            ВызватьИсключение "Настройка не содержит настоящего описания входа модели";
        КонецЕсли;
        Имя = ВходнаяКолонка.Имя;
        Если Имя <> "Серия" И Имя <> "Момент" И Имя <> "Событие" Тогда
            ВызватьИсключение "Свой источник не содержит требуемого моделью поля " + Имя;
        КонецЕсли;
        Источник = НайтиСвоюКолонку(Колонки, Имя, ТипКолонкиМоделиПрогноза.КолонкаИсточникаДанных);
        Настройка.КолонкаИсточникаДанных = Источник;
        Если Настройка.КолонкаИсточникаДанных.Имя <> Имя Тогда
            ВызватьИсключение "Не сохранилось собственное соответствие " + Имя;
        КонецЕсли;
    КонецЦикла;
    Отчет = Отчет + ОписатьСвоиКолонки(Колонки);
    ИсточникСерии = НайтиСвоюКолонку(Колонки, "Серия", ТипКолонкиМоделиПрогноза.КолонкаИсточникаДанных);
    ПрогнозМомента = НайтиСвоюКолонку(Колонки, "Момент", ТипКолонкиМоделиПрогноза.Прогнозируемая);
    ПрогнозСобытия = НайтиСвоюКолонку(Колонки, "Событие", ТипКолонкиМоделиПрогноза.Прогнозируемая);
    Выход = Модель.КолонкиРезультата;
    Если ТипЗнч(Выход) <> Тип("КолонкиРезультатаМоделиПрогноза") Тогда
        ВызватьИсключение "Нужны реальные настройки своего результата";
    КонецЕсли;
    Выход.Очистить();
    КолонкаСерии = Выход.Добавить(ИсточникСерии);
    КолонкаСерии.Имя = "УчебнаяСерия";
    КолонкаМомента = Выход.Добавить(ПрогнозМомента);
    КолонкаМомента.Имя = "УчебныйМомент";
    КолонкаСобытия = Выход.Добавить(ПрогнозСобытия);
    КолонкаСобытия.Имя = "УчебноеСобытие";
    Прогноз = Модель.Выполнить();
    Если ТипЗнч(Прогноз) <> Тип("ТаблицаЗначений") Или Прогноз.Количество() > 64 Или Прогноз.Колонки.Количество() <> 3 Тогда
        ВызватьИсключение "Нужна настоящая небольшая таблица ожидаемых событий со своей схемой";
    КонецЕсли;
    Для Каждого Имя Из СтрРазделить("УчебнаяСерия,УчебныйМомент,УчебноеСобытие", ",") Цикл
        Если Прогноз.Колонки.Найти(Имя) = Неопределено Тогда
            ВызватьИсключение "Нет собственной выходной колонки " + Имя;
        КонецЕсли;
    КонецЦикла;
    Отчет = Отчет + "ПРОГНОЗ; фактических строк=" + Строка(Прогноз.Количество()) + Символы.ПС;
    Для Каждого СтрокаПрогноза Из Прогноз Цикл
        Код = СтрокаПрогноза.УчебнаяСерия;
        Если ТипЗнч(Код) <> Тип("Строка") Или НовыйВход.Найти(Код, "Серия") = Неопределено Тогда
            ВызватьИсключение "Прогноз содержит чужую последовательность";
        КонецЕсли;
        Событие = СтрокаПрогноза.УчебноеСобытие;
        Если ТипЗнч(Событие) = Тип("ОбъектАнализаДанных") Тогда
            ОписаниеСобытия = ОписатьСвоеСобытие(Событие);
        Иначе
            ОписаниеСобытия = Строка(Событие);
        КонецЕсли;
        Отчет = Отчет + Код + "; момент как вернула платформа=" + Строка(СтрокаПрогноза.УчебныйМомент)
            + "; тип момента=" + Строка(ТипЗнч(СтрокаПрогноза.УчебныйМомент))
            + "; событие=" + ОписаниеСобытия + "; тип события=" + Строка(ТипЗнч(Событие)) + Символы.ПС;
    КонецЦикла;
    Если История.Количество() <> 12 Или НовыйВход.Количество() <> 2 Тогда
        ВызватьИсключение "Изменились размеры своих независимых таблиц";
    КонецЕсли;
    Возврат Отчет + "Число прогнозных строк и дата следующего события не назначались заранее; это учебная диагностика, не обещание будущего";
КонецФункции

Функция СоздатьСвоюИсторию(ДляПрогноза)
    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Серия", Новый ОписаниеТипов("Строка"));
    Таблица.Колонки.Добавить("Момент", Новый ОписаниеТипов("Дата"));
    Таблица.Колонки.Добавить("Событие", Новый ОписаниеТипов("Строка"));
    Если ДляПрогноза Тогда
        ДобавитьСвоеСобытие(Таблица, "own-future-A", Дата(2025, 2, 1), "A");
        ДобавитьСвоеСобытие(Таблица, "own-future-C", Дата(2025, 2, 1), "C");
        Ожидается = 2;
    Иначе
        Для Номер = 1 По 4 Цикл
            Код = "own-stream-" + Строка(Номер);
            ДобавитьСвоеСобытие(Таблица, Код, Дата(2025, 1, 1), "A");
            ДобавитьСвоеСобытие(Таблица, Код, Дата(2025, 1, 2), "B");
        КонецЦикла;
        ДобавитьСвоеСобытие(Таблица, "own-stream-5", Дата(2025, 1, 1), "A");
        ДобавитьСвоеСобытие(Таблица, "own-stream-5", Дата(2025, 1, 2), "C");
        ДобавитьСвоеСобытие(Таблица, "own-stream-6", Дата(2025, 1, 1), "C");
        ДобавитьСвоеСобытие(Таблица, "own-stream-6", Дата(2025, 1, 2), "A");
        Ожидается = 12;
    КонецЕсли;
    Если Таблица.Количество() <> Ожидается Или Таблица.Колонки.Количество() <> 3 Тогда
        ВызватьИсключение "Нарушен размер своего журнала событий";
    КонецЕсли;
    Возврат Таблица;
КонецФункции

Процедура ДобавитьСвоеСобытие(Таблица, Код, Момент, Событие)
    СтрокаСобытия = Таблица.Добавить();
    СтрокаСобытия.Серия = Код;
    СтрокаСобытия.Момент = Момент;
    СтрокаСобытия.Событие = Событие;
КонецПроцедуры

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

Функция ОписатьСвоеСобытие(Объект)
    Если ТипЗнч(Объект) <> Тип("ОбъектАнализаДанных") Тогда
        ВызватьИсключение "Нужен настоящий объект элемента найденного шаблона";
    КонецЕсли;
    Свойства = Новый Структура("Событие", Неопределено);
    ЗаполнитьЗначенияСвойств(Свойства, Объект);
    Описание = Свойства.Событие;
    Если ТипЗнч(Описание) <> Тип("СвойствоОбъектаАнализаДанных") Или Описание.Имя <> "Событие"
        Или Описание.ВидСравнения <> ВидСравнения.Равно Или ТипЗнч(Описание.Значение) <> Тип("Строка")
        Или (Описание.Значение <> "A" И Описание.Значение <> "B" И Описание.Значение <> "C") Тогда
        ВызватьИсключение "Элемент шаблона не описывает одно из собственных событий A/B/C";
    КонецЕсли;
    Возврат Описание.Значение;
КонецФункции

Функция ОписатьСвоиШаблоны(Шаблоны)
    Если ТипЗнч(Шаблоны) <> Тип("ФиксированныйМассив") Или Шаблоны.Количество() > 128 Тогда
        ВызватьИсключение "Нужны настоящие небольшие шаблоны собственной истории";
    КонецЕсли;
    Отчет = "Найдено шаблонов=" + Строка(Шаблоны.Количество()) + Символы.ПС;
    Для Каждого Шаблон Из Шаблоны Цикл
        Если ТипЗнч(Шаблон) <> Тип("ШаблонПоследовательностиАнализаДанных") Или Шаблон.КоличествоСлучаев < 0
            Или Шаблон.КоличествоСлучаев > 6 Или Шаблон.ПроцентСлучаев < 0 Или Шаблон.ПроцентСлучаев > 100 Тогда
            ВызватьИсключение "Некорректные случаи или процент настоящего своего шаблона";
        КонецЕсли;
        Группы = Шаблон.Элементы;
        Если ТипЗнч(Группы) <> Тип("ФиксированныйМассив") Или Группы.Количество() > 32 Тогда
            ВызватьИсключение "Нужен настоящий ограниченный массив временных групп";
        КонецЕсли;
        Шаги = Новый Массив;
        Для Каждого Группа Из Группы Цикл
            Если ТипЗнч(Группа) <> Тип("ФиксированныйМассив") Или Группа.Количество() > 3 Тогда
                ВызватьИсключение "Каждый шаг содержит фиксированный массив объектов, не строку";
            КонецЕсли;
            Имена = Новый Массив;
            Для Каждого Элемент Из Группа Цикл
                Имена.Добавить(ОписатьСвоеСобытие(Элемент));
            КонецЦикла;
            Шаги.Добавить("[" + СтрСоединить(Имена, ", ") + "]");
        КонецЦикла;
        Отчет = Отчет + СтрСоединить(Шаги, " → ") + "; случаев=" + Строка(Шаблон.КоличествоСлучаев)
            + "; процент=" + Строка(Шаблон.ПроцентСлучаев) + Символы.ПС;
        Отчет = Отчет + ОписатьСвоиИнтервалы(Шаблон.МинимальныеИнтервалы, Шаблон.СредниеИнтервалы, Шаблон.МаксимальныеИнтервалы);
    КонецЦикла;
    Возврат Отчет;
КонецФункции

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

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

Процедура НастроитьСвойПараметр(Параметры, Имя, Значение)
    Параметр = НайтиСвойПараметр(Параметры, Имя);
    Если Не Параметр.ТипЗначения.СодержитТип(ТипЗнч(Значение)) Тогда
        ВызватьИсключение "Тип значения не разрешен реальным параметром " + Имя;
    КонецЕсли;
    Параметр.Значение = Значение;
    ПроверитьСвойПараметр(Параметры, Имя, Значение);
КонецПроцедуры

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

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

Функция ОписатьСвоиКолонки(Колонки)
    Стек = Новый Массив;
    Для Каждого Колонка Из Колонки Цикл
        Стек.Добавить(Новый Структура("Колонка,Уровень", Колонка, 0));
    КонецЦикла;
    Обработано = 0;
    Отчет = "ДЕЙСТВИТЕЛЬНАЯ ИЕРАРХИЯ КОЛОНОК" + Символы.ПС;
    Пока Стек.Количество() > 0 Цикл
        Индекс = Стек.Количество() - 1;
        Кадр = Стек[Индекс];
        Стек.Удалить(Индекс);
        Если Кадр.Уровень > 16 Или Обработано >= 128 Тогда
            ВызватьИсключение "Своя диагностика превысила учебный предел 128 колонок или 16 уровней";
        КонецЕсли;
        Колонка = Кадр.Колонка;
        Если ТипЗнч(Колонка) <> Тип("КолонкаМоделиПрогноза") Тогда
            ВызватьИсключение "В иерархии нет настоящего описания колонки";
        КонецЕсли;
        Обработано = Обработано + 1;
        Отчет = Отчет + "Уровень=" + Строка(Кадр.Уровень) + "; имя=" + Колонка.Имя
            + "; путь=" + Колонка.ПутьКДанным + "; роль=" + Строка(Колонка.ТипКолонки)
            + "; тип дополнительных параметров=" + Строка(ТипЗнч(Колонка.ДополнительныеПараметры)) + Символы.ПС;
        Дети = Колонка.Колонки;
        Если ТипЗнч(Дети) <> Тип("ФиксированныйМассив") Тогда
            ВызватьИсключение "Вложенные описания должны быть настоящим фиксированным массивом";
        КонецЕсли;
        Для Каждого Дочерняя Из Дети Цикл
            Стек.Добавить(Новый Структура("Колонка,Уровень", Дочерняя, Кадр.Уровень + 1));
        КонецЦикла;
    КонецЦикла;
    Возврат Отчет;
КонецФункции

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

Собственная внешняя обработка → управляемая Форма → Модуль

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

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

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

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

  1. Собственный guard проверяет точную версию и пустой стенд до расчета. АнализДанных получает настоящий тип анализа и созданную таблицу. Роли и виды назначаются реальным элементам НастройкаКолонок; после расчета та же схема перечитывается без записи readonly-результата.

  2. Параметры находятся в реальной коллекции, индекс и разрешенный тип проверяются, присваивание перечитывается. Тип анализа задается значением Тип("АнализДанныхПоискПоследовательностей"), не выдуманным конструктором.

  3. КоличествоПоследовательностей сопоставляется с шестью своими кодами, а число исходных событий равно 12. КоличествоЭлементов выводится как вернула платформа; короткое слово «элементы» не заменяет различие строк/серий/уникальных значений.

  4. ШаблоныПоследовательностей — фиксированный массив настоящих ШаблонПоследовательностиАнализаДанных. КоличествоСлучаев и ПроцентСлучаев берутся из каждого шаблона, а не назначаются по ожидаемому тексту A→B.

  5. Шаблон.Элементы имеет два уровня: фиксированный массив фиксированных массивов ОбъектАнализаДанных. Один внутренний массив — набор элементов одного шага. Разбор сохраняет границы шагов [A] → [B], а не превращает всю вложенность в плоскую строку.

  6. Динамическое Событие у ОбъектАнализаДанных содержит отдельное СвойствоОбъектаАнализаДанных. Через пересечение имен копируется значение в собственную структуру, затем проверяются native-тип, имя, сравнение Равно и собственное A/B/C. Readonly-объект не меняется.

  7. МинимальныеИнтервалы, СредниеИнтервалы и МаксимальныеИнтервалы — массивы чисел секунд, что прямо сказано в installed-справке. Проверяются типы, согласованность размеров и порядок минимум ≤ среднее ≤ максимум; отчёт выводит фактические секунды. Не угадывается длина массивов как количество шагов минус один.

  8. СоздатьМодельПрогноза вызывается у настоящего результата своего расчета. Ее ШаблоныПоследовательностей также полностью разбираются. Только потом назначается отдельный источник новых начал, а не та же обучающая таблица.

  9. Входные настройки обходятся как реально созданные моделью элементы. Их КолонкаМоделиПрогноза проверяется, имя разрешено только Серия/Момент/Событие; соответствующая настоящая колонка источника ищется с обязательной ролью КолонкаИсточникаДанных и присваивается разрешенному свойству настройки. Не предполагаем безусловно три входа.

  10. Native-модель описывает выходные имена по исходным колонкам времени/последовательности/элемента. Реальные прогнозируемые Момент/Событие и источник Серия формируют свои УчебнаяСерия, УчебныйМомент, УчебноеСобытие. Фактическая иерархия колонок и пути выводятся, не составляются выдуманным строковым путем.

  11. Модель.Выполнить действительно находится после настройки и возвращает ТаблицаЗначений ожидаемых элементов. Проверяются свой тип, три имени и принадлежность каждой серии новому входу. Пустой результат и несколько ожидаемых событий на серию не превращаются искусственно в две обязательные строки.

  12. Короткая модельная справка не объявляет точные типы прогнозных ячеек времени/элемента. Поэтому в отчёте выводятся реальные значения и типы; объект элемента разбирается только при фактическом ОбъектАнализаДанных. Ни B, ни дата 02.02.2025 в результат не записываются.

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

  1. Будущий положительный опыт: отчёт подтверждает 12 исходных событий и шесть серий, свои роли/параметры, реальные вложенные шаблоны, секунды интервалов, модель и действительный прогноз новых кодов. Состав шаблонов, порядок и число прогнозных строк не обещаются статическими проверками.

  2. Ручной эталон собственной истории, не результат 1С: A→B встречается в четырех из шести серий, A→C в одной, C→A в одной. Между двумя датами каждой серии 86400 секунд. Этот эталон помогает понять направление и единицы, но не означает, что любой native-шаблон обязан содержать именно один интервал или только эти три вывода.

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

  4. Будущий отрицательный контроль ролей: только Момент.ТипКолонки изменить с Время на Элемент. Независимая проверка ролей должна остановиться до расчета; затем вернуть Время.

  5. Будущий отрицательный контроль прогноза: сразу после Прогноз = Модель.Выполнить() временно присвоить Прогноз = Неопределено. Проверка типа должна остановиться до чтения строк. Затем вернуть полный код.

  6. runtimeVerifiedScenarios=0: 1С, BSL, алгоритм, модель, форма, база и прогноз здесь не запускались. Статические тесты не доказывают успешный поиск, определенную дату будущего события или точный формат ячеек. Ручные опыты — только будущие, в собственном отдельном стенде.

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

Есть полный собственный журнал с датами и проверенный по установленной справке учебный конвейер: вложенные шаблоны, реальные интервалы и модель с отдельным прогнозным входом; будущие ответы не сфабрикованы.

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

  1. Последовательность учитывает порядок и время; ассоциация совместных товаров — другая задача. A→C и C→A здесь специально различны. Нельзя просто сортировать все символы одного журнала и объявлять найденным шаблоном.

  2. МинимальныйПроцентСлучаев имеет противоречивое название/описание в installed-справке. Порог 1 не объявляется ни 1%, ни требованием ровно одной серии без будущего подтверждения поведения платформы.

  3. Интервалы в найденном шаблоне измеряются в секундах. 86400 — разница собственных двух дат, а не заранее назначенное значение readonly-массивов и не обещанная дата следующего события.

  4. Вложенные Элементы не являются плоским массивом строк. Длина массивов интервалов не подменяется количеством событий входного журнала; выводится реальная длина.

  5. Если модель потребует непредусмотренное имя входа или не создаст описанные собственные прогнозные колонки, урок остановится до выполнения прогноза с диагностикой. Это требует будущей ручной проверки native-модели, а не подставленных неизвестных параметров.

  6. Прогноз не обязательно дает одну строку на каждый вход. Не обещаются конкретные B, время 02.02.2025, порядок строк или доказанное качество; типы ячеек не угадываются из краткой справки.

  7. Readonly свойства результата, шаблона и модели не присваиваются. Меняются только реальные настройки созданных объектов. У противоречивого КолонкиМоделиПрогноза.Получить используется лишь общее Имя; остальные свойства читаются у настоящего Найти.

  8. Нет записи базы, файлов, запросов к рабочим конфигурациям, сети, почты, печати или GUI расчета. Таблицы, даты, шаблоны и модель живут только в памяти; на клиент возвращается текст.

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

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

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

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

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