Добавляет колонку в конец коллекции колонок таблицы.
Синтаксис
Добавить(<Имя>, <Тип>, <Заголовок>, <Ширина>)Полное описание, параметры и ограничения
КоллекцияКолонокТаблицыЗначений.Добавить (ValueTableColumnCollection.Add)
КоллекцияКолонокТаблицыЗначений (ValueTableColumnCollection)
Добавить (Add)
Доступен, начиная с версии 8.0.
Синтаксис:
Добавить(<Имя>, <Тип>, <Заголовок>, <Ширина>)
Параметры:
<Имя> (необязательный)
Тип: Строка.
Имя колонки.
Значение по умолчанию: Пустая строка.
<Тип> (необязательный)
Тип: ОписаниеТипов.
Объект, описывающий допустимые типы значений для колонки. Если параметр не указан, в колонке можно будет хранить значение любого типа.
<Заголовок> (необязательный)
Тип: Строка.
Заголовок колонки таблицы значений. Используется при визуальном отображении таблицы значений.
Значение по умолчанию: Пустая строка.
<Ширина> (необязательный)
Тип: Число.
Ширина колонки в символах. Используется при визуальном отображении таблицы значений.
Значение по умолчанию: 0.
Возвращаемое значение:
Тип: КолонкаТаблицыЗначений.
Описание:
Добавляет колонку в конец коллекции колонок таблицы.
Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение (сервер), мобильный автономный сервер.
Использование в версии:
Доступен, начиная с версии 8.0.
Методическая информация
Практические примеры
Разобрать ассоциации шести собственных корзин и получить настоящий прогноз для двух новых входов
Самодостаточный серверный модуль отделяет десять событий от шести транзакций, обучает поиск ассоциаций, показывает реальные частые группы и правила ЕСЛИ/ТО, выгружает их в дерево и применяет созданную модель к отдельному источнику. Ни состав рекомендаций, ни количество строк выхода заранее не подставляются.
Где и как запускать
Полный серверный общий модуль УчебныеСвоиАссоциации85 собственной пустой конфигурации; подготовка, разбор и модель включены. Не запускался в 1С.
Подготовка
НОВАЯ отдельная пустая файловая база точно 8.5.1.1343: конфигурация УчебныеСвоиАссоциации85, совместимость Не использовать, Русский. Без прикладных объектов, расширений, подписок, заданий и рабочих данных; модули конфигурации вручную пустые. Не использовать БП/КА2/УТ/УНФ.
Общие → Общие модули → УчебныеСвоиАссоциации85: Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Вставить весь основной модуль. Будущая ручная подготовка: сохранить и обновить только свой стенд F7. Все функции подготовки и разбора включены.
Создать собственную внешнюю обработку → управляемая Форма → команду/кнопку Выполнить с действием Выполнить. Весь отдельный модуль формы ниже вызывает только свой серверный общий модуль; на клиент возвращается текст, не объекты анализа.
Таблица событий имеет Корзина/Товар. Четыре own-basket-1…4 содержат A+B, пятая только A, шестая только C: десять строк событий, шесть объектов, три различных вымышленных товара. Это не продажи, документы или рабочий справочник.
Корзина — Объект, Товар — Элемент; обе колонки дискретные. ТипИсточникаДанных=Событийный. МинимальныйПроцентСлучаев=25 исключает одиночный C из частых сочетаний. МинимальнаяДостоверность/МинимальнаяЗначимость=0 специально не вводят дополнительный порог этих показателей в маленьком учебном опыте.
ПоискПоИерархии=Ложь, ИгнорироватьНезаполненныеЗначения=Истина, ТипОтсеченияПравил=Избыточные. Числовые значения как товары не используются; настройки числовой интерпретации не придумываются. Достоверность вывода не переводится в проценты без подтвержденной единицы.
Отдельный прогнозный источник создается заново: own-future-A содержит только A, own-future-C только C. Готовых следствий и вероятностей в источнике нет; для C отсутствие рекомендации допустимо.
Функция ВыполнитьПример() Экспорт
ПроверитьСвойПустойСтенд();
События = СоздатьСвоиКорзины(Ложь);
Анализатор = Новый АнализДанных;
Анализатор.ТипАнализа = Тип("АнализДанныхПоискАссоциаций");
Анализатор.ИсточникДанных = События;
НастроитьСвоиРолиКорзины(Анализатор.НастройкаКолонок);
НастроитьСвойПараметр(Анализатор.Параметры, "ТипИсточникаДанных", ТипИсточникаДанныхПоискаАссоциаций.Событийный);
НастроитьСвойПараметр(Анализатор.Параметры, "МинимальныйПроцентСлучаев", 25);
НастроитьСвойПараметр(Анализатор.Параметры, "МинимальнаяДостоверность", 0);
НастроитьСвойПараметр(Анализатор.Параметры, "МинимальнаяЗначимость", 0);
НастроитьСвойПараметр(Анализатор.Параметры, "ПоискПоИерархии", Ложь);
НастроитьСвойПараметр(Анализатор.Параметры, "ИгнорироватьНезаполненныеЗначения", Истина);
НастроитьСвойПараметр(Анализатор.Параметры, "ТипОтсеченияПравил", ТипОтсеченияПравилАссоциации.Избыточные);
Результат = Анализатор.Выполнить();
Если ТипЗнч(Результат) <> Тип("РезультатАнализаДанныхПоискАссоциаций") Или Результат.КоличествоОбъектов <> 6 Тогда
ВызватьИсключение "Нужен настоящий результат по шести собственным корзинам, не по десяти строкам событий";
КонецЕсли;
НастроитьСвоиРолиКорзины(Результат.НастройкаКолонок, Истина);
ПроверитьСвойПараметр(Результат.Параметры, "ТипИсточникаДанных", ТипИсточникаДанныхПоискаАссоциаций.Событийный);
ПроверитьСвойПараметр(Результат.Параметры, "МинимальныйПроцентСлучаев", 25);
ПроверитьСвойПараметр(Результат.Параметры, "МинимальнаяДостоверность", 0);
Отчет = "СВОИ ВЫМЫШЛЕННЫЕ КОРЗИНЫ, НЕ РЕАЛЬНЫЕ РЕКОМЕНДАЦИИ" + Символы.ПС;
Отчет = Отчет + "Строк событий=" + Строка(События.Количество()) + "; объектов-корзин=" + Строка(Результат.КоличествоОбъектов)
+ "; элементов по платформе=" + Строка(Результат.КоличествоЭлементов)
+ "; средний размер по платформе=" + Строка(Результат.СреднийРазмерОбъекта) + Символы.ПС;
Группы = Результат.Группы;
Если ТипЗнч(Группы) <> Тип("ФиксированныйМассив") Или Группы.Количество() > 128 Тогда
ВызватьИсключение "Нужны настоящие небольшие группы собственного расчета";
КонецЕсли;
Отчет = Отчет + "Найдено групп=" + Строка(Группы.Количество()) + Символы.ПС;
Для Каждого Группа Из Группы Цикл
Если ТипЗнч(Группа) <> Тип("АссоциированнаяГруппа") Или Группа.КоличествоСлучаев < 0
Или Группа.КоличествоСлучаев > 6 Или Группа.ПроцентСлучаев < 0 Или Группа.ПроцентСлучаев > 100 Тогда
ВызватьИсключение "Некорректные случаи или процент настоящей своей группы";
КонецЕсли;
Отчет = Отчет + "Группа " + ОписатьСвойНаборТоваров(Группа.Элементы)
+ "; случаев=" + Строка(Группа.КоличествоСлучаев) + "; процент=" + Строка(Группа.ПроцентСлучаев) + Символы.ПС;
КонецЦикла;
Отчет = Отчет + ОписатьСвоиПравила(Результат.Правила);
Дерево = Результат.ВыгрузитьПравила();
Отчет = Отчет + ОписатьСвоеДеревоПравил(Дерево);
Модель = Результат.СоздатьМодельПрогноза();
Если ТипЗнч(Модель) <> Тип("МодельПрогнозаПоискАссоциаций") Тогда
ВызватьИсключение "Не создана собственная настоящая модель ассоциаций";
КонецЕсли;
Отчет = Отчет + "ПРАВИЛА СОЗДАННОЙ МОДЕЛИ" + Символы.ПС + ОписатьСвоиПравила(Модель.Правила);
НовыеКорзины = СоздатьСвоиКорзины(Истина);
Модель.ИсточникДанных = НовыеКорзины;
Если ТипЗнч(Модель.ИсточникДанных) <> Тип("ТаблицаЗначений") Или Модель.ИсточникДанных.Количество() <> 2 Тогда
ВызватьИсключение "Нужен отдельный собственный источник двух новых одиночных корзин";
КонецЕсли;
Колонки = Модель.Колонки;
Входы = Модель.НастройкаВходныхКолонок;
Если ТипЗнч(Колонки) <> Тип("КолонкиМоделиПрогноза") Или ТипЗнч(Входы) <> Тип("НастройкаВходныхКолонокМоделиПрогноза")
Или Входы.Количество() = 0 Или Входы.Количество() > 2 Тогда
ВызватьИсключение "Нужны настоящие входные соответствия своей двухколоночной модели";
КонецЕсли;
Для Каждого Настройка Из Входы Цикл
Имя = Настройка.КолонкаМоделиПрогноза.Имя;
Если Имя <> "Корзина" И Имя <> "Товар" Тогда
ВызватьИсключение "Модель требует непредусмотренное собственным источником поле " + Имя;
КонецЕсли;
СвязатьСвоюВходнуюКолонку(Входы, Колонки, Имя);
КонецЦикла;
Отчет = Отчет + ОписатьСвоиКолонки(Колонки);
ИсточникКорзины = НайтиСвоюКолонку(Колонки, "Корзина", ТипКолонкиМоделиПрогноза.КолонкаИсточникаДанных);
Следствие = НайтиСвоюКолонку(Колонки, "Следствие", ТипКолонкиМоделиПрогноза.Прогнозируемая);
Достоверность = НайтиСвоюКолонку(Колонки, "Достоверность", ТипКолонкиМоделиПрогноза.Прогнозируемая);
Выход = Модель.КолонкиРезультата;
Если ТипЗнч(Выход) <> Тип("КолонкиРезультатаМоделиПрогноза") Тогда
ВызватьИсключение "Нужна собственная реальная коллекция выхода ассоциаций";
КонецЕсли;
Выход.Очистить();
КолонкаКорзины = Выход.Добавить(ИсточникКорзины);
КолонкаКорзины.Имя = "УчебнаяКорзина";
КолонкаСледствия = Выход.Добавить(Следствие);
КолонкаСледствия.Имя = "УчебноеСледствие";
КолонкаДостоверности = Выход.Добавить(Достоверность);
КолонкаДостоверности.Имя = "УчебнаяДостоверность";
Прогноз = Модель.Выполнить();
Если ТипЗнч(Прогноз) <> Тип("ТаблицаЗначений") Или Прогноз.Количество() > 32 Или Прогноз.Колонки.Количество() <> 3 Тогда
ВызватьИсключение "Нужна настоящая небольшая выходная таблица со своей схемой";
КонецЕсли;
Для Каждого Имя Из СтрРазделить("УчебнаяКорзина,УчебноеСледствие,УчебнаяДостоверность", ",") Цикл
Если Прогноз.Колонки.Найти(Имя) = Неопределено Тогда
ВызватьИсключение "Нет собственной выходной колонки " + Имя;
КонецЕсли;
КонецЦикла;
Отчет = Отчет + "РЕКОМЕНДАЦИИ ПО ДВУМ НОВЫМ КОРЗИНАМ; строк=" + Строка(Прогноз.Количество()) + Символы.ПС;
Для Каждого СтрокаПрогноза Из Прогноз Цикл
Код = СтрокаПрогноза.УчебнаяКорзина;
Если ТипЗнч(Код) <> Тип("Строка") Или НовыеКорзины.Найти(Код, "Корзина") = Неопределено Тогда
ВызватьИсключение "Результат содержит чужую корзину";
КонецЕсли;
ЗначениеСледствия = СтрокаПрогноза.УчебноеСледствие;
Если ТипЗнч(ЗначениеСледствия) = Тип("ОбъектАнализаДанных") Тогда
ОписаниеСледствия = ОписатьСвойТовар(ЗначениеСледствия);
Иначе
ОписаниеСледствия = Строка(ЗначениеСледствия);
КонецЕсли;
Отчет = Отчет + Код + "; следствие=" + ОписаниеСледствия + "; тип следствия=" + Строка(ТипЗнч(ЗначениеСледствия))
+ "; достоверность как вернула платформа=" + Строка(СтрокаПрогноза.УчебнаяДостоверность)
+ "; тип достоверности=" + Строка(ТипЗнч(СтрокаПрогноза.УчебнаяДостоверность)) + Символы.ПС;
КонецЦикла;
Если События.Количество() <> 10 Или НовыеКорзины.Количество() <> 2 Тогда
ВызватьИсключение "Изменились свои независимые таблицы памяти";
КонецЕсли;
Возврат Отчет + "Для C связь с другим товаром не заложена; отсутствие рекомендации допустимо. Не ожидается ровно две строки выхода";
КонецФункции
Функция СоздатьСвоиКорзины(ДляПрогноза)
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Корзина", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("Товар", Новый ОписаниеТипов("Строка"));
Если ДляПрогноза Тогда
ДобавитьСвойТовар(Таблица, "own-future-A", "A");
ДобавитьСвойТовар(Таблица, "own-future-C", "C");
Ожидается = 2;
Иначе
Для Номер = 1 По 4 Цикл
Код = "own-basket-" + Строка(Номер);
ДобавитьСвойТовар(Таблица, Код, "A");
ДобавитьСвойТовар(Таблица, Код, "B");
КонецЦикла;
ДобавитьСвойТовар(Таблица, "own-basket-5", "A");
ДобавитьСвойТовар(Таблица, "own-basket-6", "C");
Ожидается = 10;
КонецЕсли;
Если Таблица.Количество() <> Ожидается Или Таблица.Колонки.Количество() <> 2 Тогда
ВызватьИсключение "Нарушен размер собственного списка событий";
КонецЕсли;
Возврат Таблица;
КонецФункции
Процедура ДобавитьСвойТовар(Таблица, Код, Товар)
СтрокаКорзины = Таблица.Добавить();
СтрокаКорзины.Корзина = Код;
СтрокаКорзины.Товар = Товар;
КонецПроцедуры
Процедура НастроитьСвоиРолиКорзины(Настройки, ТолькоПроверка = Ложь)
Если ТипЗнч(Настройки) <> Тип("КолонкиАнализаДанных") Или Настройки.Количество() <> 2 Тогда
ВызватьИсключение "Нужны две настоящие настройки Корзина и Товар";
КонецЕсли;
Корзина = Настройки.Найти("Корзина");
Товар = Настройки.Найти("Товар");
Если Корзина = Неопределено Или Товар = Неопределено Тогда
ВызватьИсключение "Нет собственных настроек объект/элемент";
КонецЕсли;
Если Не ТолькоПроверка Тогда
Корзина.ТипКолонки = ТипКолонкиАнализаДанныхПоискАссоциаций.Объект;
Корзина.ВидДанных = ВидДанныхАнализа.Дискретные;
Товар.ТипКолонки = ТипКолонкиАнализаДанныхПоискАссоциаций.Элемент;
Товар.ВидДанных = ВидДанныхАнализа.Дискретные;
КонецЕсли;
Если Корзина.ТипКолонки <> ТипКолонкиАнализаДанныхПоискАссоциаций.Объект Или Товар.ТипКолонки <> ТипКолонкиАнализаДанныхПоискАссоциаций.Элемент
Или Корзина.ВидДанных <> ВидДанныхАнализа.Дискретные Или Товар.ВидДанных <> ВидДанныхАнализа.Дискретные Тогда
ВызватьИсключение "Перепутаны собственная корзина и товар события";
КонецЕсли;
КонецПроцедуры
Функция ОписатьСвойТовар(Объект)
Если ТипЗнч(Объект) <> Тип("ОбъектАнализаДанных") Тогда
ВызватьИсключение "Нужен настоящий объект элемента группы или правила";
КонецЕсли;
Свойства = Новый Структура("Товар", Неопределено);
ЗаполнитьЗначенияСвойств(Свойства, Объект);
Описание = Свойства.Товар;
Если ТипЗнч(Описание) <> Тип("СвойствоОбъектаАнализаДанных") Или Описание.Имя <> "Товар"
Или Описание.ВидСравнения <> ВидСравнения.Равно Или ТипЗнч(Описание.Значение) <> Тип("Строка")
Или (Описание.Значение <> "A" И Описание.Значение <> "B" И Описание.Значение <> "C") Тогда
ВызватьИсключение "Элемент не описывает один из трех собственных товаров";
КонецЕсли;
Возврат Описание.Значение;
КонецФункции
Функция ОписатьСвойНаборТоваров(Элементы)
Если ТипЗнч(Элементы) <> Тип("ФиксированныйМассив") Или Элементы.Количество() > 3 Тогда
ВызватьИсключение "Нужен настоящий небольшой набор своих объектов анализа";
КонецЕсли;
Имена = Новый Массив;
Для Каждого Элемент Из Элементы Цикл
Имена.Добавить(ОписатьСвойТовар(Элемент));
КонецЦикла;
Возврат "[" + СтрСоединить(Имена, ", ") + "]";
КонецФункции
Функция ОписатьСвоиПравила(Правила)
Если ТипЗнч(Правила) <> Тип("ФиксированныйМассив") Или Правила.Количество() > 128 Тогда
ВызватьИсключение "Нужен настоящий небольшой набор своих правил";
КонецЕсли;
Отчет = "Найдено правил=" + Строка(Правила.Количество()) + Символы.ПС;
Для Каждого Правило Из Правила Цикл
Если ТипЗнч(Правило) <> Тип("ПравилоАссоциации") Или Правило.КоличествоСлучаев < 0 Или Правило.КоличествоСлучаев > 6
Или Правило.ПроцентСлучаев < 0 Или Правило.ПроцентСлучаев > 100 Тогда
ВызватьИсключение "Нужны настоящие правила по своим шести корзинам";
КонецЕсли;
Отчет = Отчет + "ЕСЛИ " + ОписатьСвойНаборТоваров(Правило.Предпосылка) + " ТО " + ОписатьСвойНаборТоваров(Правило.Следствие)
+ "; случаев=" + Строка(Правило.КоличествоСлучаев) + "; процент=" + Строка(Правило.ПроцентСлучаев)
+ "; достоверность=" + Строка(Правило.Достоверность) + "; значимость=" + Строка(Правило.Значимость) + Символы.ПС;
КонецЦикла;
Возврат Отчет;
КонецФункции
Функция ОписатьСвоеДеревоПравил(Дерево)
Если ТипЗнч(Дерево) <> Тип("ДеревоЗначений") Или Дерево.Строки.Количество() > 128 Или Дерево.Колонки.Количество() > 32 Тогда
ВызватьИсключение "Нужна настоящая небольшая выгрузка правил в дерево";
КонецЕсли;
Отчет = "ВЫГРУЗКА ПРАВИЛ: корневых строк=" + Строка(Дерево.Строки.Количество()) + Символы.ПС;
Для Каждого Колонка Из Дерево.Колонки Цикл
Отчет = Отчет + "Колонка выгрузки=" + Колонка.Имя + Символы.ПС;
КонецЦикла;
Для Каждого СтрокаДерева Из Дерево.Строки Цикл
Для Каждого Колонка Из Дерево.Колонки Цикл
Отчет = Отчет + Колонка.Имя + "=" + Строка(СтрокаДерева[Колонка.Имя]) + "; ";
КонецЦикла;
Отчет = Отчет + "дочерних строк=" + Строка(СтрокаДерева.Строки.Количество()) + Символы.ПС;
КонецЦикла;
Возврат Отчет;
КонецФункции
Функция НайтиСвойПараметр(Параметры, Имя)
Параметр = Параметры.Найти(Имя);
Если Параметр = Неопределено Или ТипЗнч(Параметр) <> Тип("ПараметрАнализаДанных") Тогда
ВызватьИсключение "Не найден собственный параметр алгоритма " + Имя;
КонецЕсли;
Индекс = Параметры.Индекс(Параметр);
Если Индекс < 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.ВыполнитьПример();
КонецФункцииРазбор по шагам
Собственный guard проверяет пустую конфигурацию до алгоритма. СоздатьСвоиКорзины строит типизированные таблицы только в памяти. Один объект-корзина состоит из нескольких событий: десять строк не означают десять транзакций.
АнализДанных.ТипАнализа получает настоящий Тип("АнализДанныхПоискАссоциаций"). Роли Объект/Элемент и виды данных задаются реальным настройкам колонок. Параметры ищутся по установленным native-именам, тип значения проверяется до присваивания; ключевые настройки результата перечитываются.
КоличествоОбъектов сопоставляется с шестью своими корзинами, КоличествоЭлементов и СреднийРазмерОбъекта выводятся фактически. В исходной таблице различны количество событий 10 и число товаров 3; неоднозначное слово «элементы» в короткой справке не заменяет проверку реального результата.
Группы содержат настоящие АссоциированнаяГруппа. КоличествоСлучаев — число корзин, где группа встречается, а ПроцентСлучаев — процент. Элементы — фиксированный массив ОбъектАнализаДанных, не список готовых строк товара.
ОписатьСвойТовар копирует пересечение имен в свою структуру и разбирает настоящее динамическое свойство Товар как СвойствоОбъектаАнализаДанных. Проверяются имя, сравнение Равно, строка и один из A/B/C. Объект источника readonly и не меняется.
ПравилоАссоциации разделяет Предпосылка (ЕСЛИ) и Следствие (ТО); обе части — массивы объектов анализа. КоличествоСлучаев/ПроцентСлучаев показывают поддержку, Достоверность — условную вероятность, Значимость — отдельную native-характеристику. Последние два числа выводятся как вернула платформа, не объявляются автоматически процентами.
ВыгрузитьПравила возвращает реальное ДеревоЗначений. Урок показывает действительные имена его колонок, значения корневых строк и количество детей, не угадывает схему выгрузки. Это текстовая диагностика дерева, не показ GUI и не запись файла.
СоздатьМодельПрогноза вызывается у настоящего своего результата. Модель.Правила также разбирается тем же полным помощником; источник прогноза — отдельные новые корзины, не обучающая таблица.
Существующие входные соответствия модели обходятся фактически. Допустимы только собственные Корзина/Товар; каждое реальное имя связывается с настоящими колонками Входная/КолонкаИсточникаДанных. Не создаем произвольную настройку или ожидаем безусловно два входа.
Native-модель описывает прогнозируемые колонки Следствие и Достоверность. Их реальные дескрипторы и колонка источника Корзина добавляются в собственный выход: УчебнаяКорзина, УчебноеСледствие, УчебнаяДостоверность. Иерархия и пути выводятся фактически.
Модель.Выполнить вызывается после настройки. Таблица выхода может иметь ноль, одну или несколько строк на собственную корзину: по правилам рекомендации отсутствуют или множественны. Не требуем одну строку на событие и не запрещаем повторный код корзины. Проверяем принадлежность каждого кода своему входу и свою схему колонок.
Следствие разбирается как ОбъектАнализаДанных только при фактическом таком типе; иначе выводится значение и его реальный тип. Короткая модельная справка не объявляет точный тип ячейки. Достоверность также выводится с типом и без выдуманного коэффициента 100. Никаких заранее назначенных B или чисел вероятности нет.
Как проверить результат
Будущий положительный опыт: отчет должен подтвердить шесть объектов и десять событий, реальные роли/параметры, найденные группы/правила, actual-дерево и actual-прогноз по двум новым кодам. Количество правил, порядок и строки рекомендаций не фиксируются статическими тестами.
Ручной эталон собственной таблицы, не результат 1С: A встречается в 5 из 6 корзин, B в 4 из 6, C в 1 из 6, пара A+B в 4 из 6. Для направления A→B условная доля 4/5, для B→A 4/4. Это разные знаменатели; отсечение может убрать часть правил из конечного вывода.
Будущий отрицательный контроль ролей: только присваивание Корзина.ТипКолонки заменить с Объект на Элемент. Независимая проверка ролей должна остановиться до анализа. Вернуть Объект.
Будущий отрицательный контроль событий: только границу заполнения четырех корзин заменить с 4 на 3. Проверка собственной таблицы должна отвергнуть восемь вместо десяти событий до алгоритма. Вернуть 4.
Будущий отрицательный контроль прогноза: сразу после Прогноз = Модель.Выполнить() временно присвоить Прогноз = Неопределено. Проверка типа должна остановиться до строк; затем вернуть полный исходник.
runtimeVerifiedScenarios=0: 1С, BSL, алгоритм, модель, форма, база и прогноз здесь не запускались. Статические проверки не доказывают состав найденных правил и успешное выполнение native-модели. Все будущие ручные проверки — только собственный отдельный стенд.
Ожидаемый результат
Разобраны события/транзакции, реальные группы, обе части правил и показатели, собственное дерево и отдельный прогнозный источник. Модель действительно вызывается в полном коде; рекомендации и их количество не сфабрикованы.
На что обратить внимание
Ассоциация — наблюдаемая связь вымышленных товаров, а не причинность и не разрешение навязывать реальные покупки. Качество рекомендаций на реальных данных этим опытом не установлено.
Поддержка пары и достоверность направленного правила имеют разные знаменатели. Число событий/число корзин/число уникальных товаров различны; не использовать один счетчик вместо всех трех.
Нет обещания конкретного числа правил: пороги, отсечение и алгоритм влияют на результат. Пустой прогноз для корзины C допустим; результат не обязан повторять количество строк источника.
У НастройкаВходныхКолонок проверяются реальные полученные имена. Если installed-модель потребует иное имя или роль, урок остановится с диагностикой до прогноза; это место требует будущей ручной проверки, а не заполнения неизвестных параметров.
В native-описании модели не указан точный тип ячейки Следствие. Поэтому он не придумывается: факт типа проверяется, object-ветка разбирает descriptor, остальная ветка показывает значение/тип. Достоверность не масштабируется автоматически.
Readonly свойства результатов, групп, правил и модели не присваиваются. Меняются только разрешенные настройки созданных объектов; источник, дерево и нормализованные карты не выдаются за рабочие данные.
У КолонкиМоделиПрогноза.Получить противоречивый declared-тип; помощник использует только общее Имя возврата. Остальные свойства читаются у настоящего объекта Найти. Нет исправления native-справки на основании догадки.
Нет запросов к конфигурациям пользователя, записей базы, файлов, сети, почты, печати и GUI расчетов. Собственная внешняя форма лишь получает текст своего сервера.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Взвесить X/Y, разобрать настоящую нормализацию и спрогнозировать кластеры двух новых точек
Полный самостоятельный серверный модуль обучается на шести собственных точках, задает веса 2/1 реальным дополнительным параметрам, читает карту нормализации и выполняет прогноз отдельной таблицы. Координаты и ключи результата сопоставляются с собственным источником, номера групп не выдумываются.
Где и как запускать
Полный серверный общий модуль УчебныйНовыйКластер85 собственной пустой конфигурации; все помощники включены. Не запускался в 1С.
Подготовка
НОВАЯ отдельная пустая файловая база точно 8.5.1.1343: конфигурация УчебныйНовыйКластер85, совместимость Не использовать, Русский. Нет прикладных объектов, расширений, подписок и заданий; модули конфигурации вручную пустые. Не использовать БП/КА2/УТ/УНФ.
Общие → Общие модули → УчебныйНовыйКластер85. Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Вставить весь основной модуль, включая собственную подготовку, все помощники и защиту. Будущая ручная подготовка: сохранить и обновить только свою базу F7.
Создать свою внешнюю обработку и управляемую Форма: команда/кнопка Выполнить, действие Выполнить. Полный модуль формы ниже вызывает только собственный общий модуль и получает текст отчета; модель и таблицы на клиент не передаются.
Собственная обучающая таблица содержит шесть координат: (0,0), (0,1), (1,0), (10,10), (10,11), (11,10), с отдельными own-training-point-кодами. Код — дискретный ключ, X/Y — непрерывные входы. Таблицы и модель создаются только в памяти. Данные вымышленные, не клиенты и не географические координаты.
Код отдельно создает две новые точки (0.5,0.5) и (10.5,10.5) с другими own-new-point-кодами. В них нет готового номера кластера. Обучение не повторяется на новых строках.
Вес X=2 и Y=1 — выбранный учебный профиль влияния входных координат. КоличествоКластеров=2, МетодКластеризации=ДальняяСвязь, ТипЗаполненияТаблицы=ВсеПоля. Имена параметров и readonly/RW сверены с installed-справкой; значение стандартизации не выдумывается и формула нормализации не обещается.
Функция ВыполнитьПример() Экспорт
ПроверитьСвойПустойСтенд();
Обучение = СоздатьСвоиТочки(Ложь);
Анализатор = Новый АнализДанных;
Анализатор.ТипАнализа = Тип("АнализДанныхКластеризация");
Анализатор.ИсточникДанных = Обучение;
Настройки = Анализатор.НастройкаКолонок;
Ключ = Настройки.Найти("Код");
X = Настройки.Найти("X");
Y = Настройки.Найти("Y");
Если Ключ = Неопределено Или X = Неопределено Или Y = Неопределено Или Настройки.Количество() <> 3 Тогда
ВызватьИсключение "Нужны три настройки собственных исходных колонок";
КонецЕсли;
Ключ.ТипКолонки = ТипКолонкиАнализаДанныхКластеризация.Ключ;
Ключ.ВидДанных = ВидДанныхАнализа.Дискретные;
X.ТипКолонки = ТипКолонкиАнализаДанныхКластеризация.Входная;
X.ВидДанных = ВидДанныхАнализа.Непрерывные;
Y.ТипКолонки = ТипКолонкиАнализаДанныхКластеризация.Входная;
Y.ВидДанных = ВидДанныхАнализа.Непрерывные;
УстановитьСвойВес(X.ДополнительныеПараметры, 2);
УстановитьСвойВес(Y.ДополнительныеПараметры, 1);
НастроитьСвойПараметр(Анализатор.Параметры, "КоличествоКластеров", 2);
НастроитьСвойПараметр(Анализатор.Параметры, "МетодКластеризации", МетодКластеризации.ДальняяСвязь);
НастроитьСвойПараметр(Анализатор.Параметры, "ТипЗаполненияТаблицы", ТипЗаполненияТаблицыРезультатаАнализаДанных.ВсеПоля);
Результат = Анализатор.Выполнить();
Если ТипЗнч(Результат) <> Тип("РезультатАнализаДанныхКластеризация") Или Результат.КоличествоОбъектов <> 6 Тогда
ВызватьИсключение "Нужен настоящий расчет собственных шести точек";
КонецЕсли;
Модель = Результат.СоздатьМодельПрогноза();
Если ТипЗнч(Модель) <> Тип("МодельПрогнозаКластеризация") Или Модель.Кластеры.Количество() <> 2 Тогда
ВызватьИсключение "Не создана собственная модель с двумя кластерами";
КонецЕсли;
НовыеТочки = СоздатьСвоиТочки(Истина);
Модель.ИсточникДанных = НовыеТочки;
Если ТипЗнч(Модель.ИсточникДанных) <> Тип("ТаблицаЗначений") Или Модель.ИсточникДанных.Количество() <> 2 Тогда
ВызватьИсключение "Нужна отдельная собственная таблица двух новых точек";
КонецЕсли;
Колонки = Модель.Колонки;
Входы = Модель.НастройкаВходныхКолонок;
Если ТипЗнч(Колонки) <> Тип("КолонкиМоделиПрогноза") Или ТипЗнч(Входы) <> Тип("НастройкаВходныхКолонокМоделиПрогноза") Или Входы.Количество() <> 2 Тогда
ВызватьИсключение "Нужны настоящие два соответствия X и Y";
КонецЕсли;
СвязатьСвоюВходнуюКолонку(Входы, Колонки, "X");
СвязатьСвоюВходнуюКолонку(Входы, Колонки, "Y");
ИсточникКода = НайтиСвоюКолонку(Колонки, "Код", ТипКолонкиМоделиПрогноза.КолонкаИсточникаДанных);
ИсточникX = НайтиСвоюКолонку(Колонки, "X", ТипКолонкиМоделиПрогноза.КолонкаИсточникаДанных);
ИсточникY = НайтиСвоюКолонку(Колонки, "Y", ТипКолонкиМоделиПрогноза.КолонкаИсточникаДанных);
Кластер = НайтиСвоюКолонку(Колонки, "Кластер", ТипКолонкиМоделиПрогноза.Прогнозируемая);
Выход = Модель.КолонкиРезультата;
Выход.Очистить();
НастройкаКода = Выход.Добавить(ИсточникКода);
НастройкаКода.Имя = "УчебныйКод";
НастройкаX = Выход.Добавить(ИсточникX);
НастройкаX.Имя = "УчебныйX";
НастройкаY = Выход.Добавить(ИсточникY);
НастройкаY.Имя = "УчебныйY";
НастройкаКластера = Выход.Добавить(Кластер);
НастройкаКластера.Имя = "УчебныйКластер";
Отчет = "СВОИ КЛАСТЕРЫ, НЕ СЕГМЕНТАЦИЯ РЕАЛЬНЫХ КЛИЕНТОВ" + Символы.ПС;
Отчет = Отчет + ОписатьСвоиДополнительныеПараметры(Результат.НастройкаКолонок.Найти("X"), 2)
+ ОписатьСвоиДополнительныеПараметры(Результат.НастройкаКолонок.Найти("Y"), 1);
Отчет = Отчет + ОписатьСвоиКолонки(Колонки);
Прогноз = Модель.Выполнить();
Если ТипЗнч(Прогноз) <> Тип("ТаблицаЗначений") Или Прогноз.Количество() <> 2 Или Прогноз.Колонки.Количество() <> 4 Тогда
ВызватьИсключение "Нужна действительная таблица по двум новым точкам и четырем своим колонкам";
КонецЕсли;
Для Каждого Имя Из СтрРазделить("УчебныйКод,УчебныйX,УчебныйY,УчебныйКластер", ",") Цикл
Если Прогноз.Колонки.Найти(Имя) = Неопределено Тогда
ВызватьИсключение "Нет собственной выходной колонки " + Имя;
КонецЕсли;
КонецЦикла;
ВиденныеКоды = Новый Соответствие;
Для Каждого СтрокаПрогноза Из Прогноз Цикл
Код = СтрокаПрогноза.УчебныйКод;
Источник = НовыеТочки.Найти(Код, "Код");
Если Источник = Неопределено Или ВиденныеКоды.Получить(Код) <> Неопределено Тогда
ВызватьИсключение "Чужой или повторный собственный ключ прогноза";
КонецЕсли;
Если СтрокаПрогноза.УчебныйX <> Источник.X Или СтрокаПрогноза.УчебныйY <> Источник.Y Или ТипЗнч(СтрокаПрогноза.УчебныйКластер) <> Тип("Число") Тогда
ВызватьИсключение "Не сохранены входные координаты или не получен числовой номер кластера";
КонецЕсли;
ВиденныеКоды.Вставить(Код, Истина);
Отчет = Отчет + Код + "; X=" + Строка(Источник.X) + "; Y=" + Строка(Источник.Y)
+ "; ближайший кластер как вернула платформа=" + Строка(СтрокаПрогноза.УчебныйКластер) + Символы.ПС;
КонецЦикла;
Если ВиденныеКоды.Количество() <> 2 Или Обучение.Количество() <> 6 Или НовыеТочки.Количество() <> 2 Тогда
ВызватьИсключение "Не совпали собственные размеры и ключи независимых таблиц";
КонецЕсли;
Возврат Отчет + "Номера кластеров не являются постоянными бизнес-кодами; качество на двух точках не доказано";
КонецФункции
Функция СоздатьСвоиТочки(ДляПрогноза)
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Код", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("X", Новый ОписаниеТипов("Число"));
Таблица.Колонки.Добавить("Y", Новый ОписаниеТипов("Число"));
Координаты = Новый Массив;
Если ДляПрогноза Тогда
Координаты.Добавить(Новый Структура("X,Y", 0.5, 0.5));
Координаты.Добавить(Новый Структура("X,Y", 10.5, 10.5));
Префикс = "own-new-point-";
Ожидается = 2;
Иначе
Координаты.Добавить(Новый Структура("X,Y", 0, 0));
Координаты.Добавить(Новый Структура("X,Y", 0, 1));
Координаты.Добавить(Новый Структура("X,Y", 1, 0));
Координаты.Добавить(Новый Структура("X,Y", 10, 10));
Координаты.Добавить(Новый Структура("X,Y", 10, 11));
Координаты.Добавить(Новый Структура("X,Y", 11, 10));
Префикс = "own-training-point-";
Ожидается = 6;
КонецЕсли;
Номер = 0;
Для Каждого Координата Из Координаты Цикл
Номер = Номер + 1;
Точка = Таблица.Добавить();
Точка.Код = Префикс + Строка(Номер);
Точка.X = Координата.X;
Точка.Y = Координата.Y;
КонецЦикла;
Если Таблица.Количество() <> Ожидается Тогда
ВызватьИсключение "Нарушен размер собственной таблицы точек";
КонецЕсли;
Возврат Таблица;
КонецФункции
Процедура УстановитьСвойВес(Параметры, Вес)
Если ТипЗнч(Параметры) <> Тип("ПараметрыКолонкиКластерногоАнализа") Или ТипЗнч(Вес) <> Тип("Число") Или Вес <= 0 Тогда
ВызватьИсключение "Нужны настоящие дополнительные параметры и положительный свой вес";
КонецЕсли;
Параметры.Вес = Вес;
Если Параметры.Вес <> Вес Тогда
ВызватьИсключение "Свой вес колонки не сохранился";
КонецЕсли;
КонецПроцедуры
Функция ОписатьСвоиДополнительныеПараметры(Колонка, ОжидаемыйВес)
Если Колонка = Неопределено Тогда
ВызватьИсключение "Исчезла собственная колонка результата";
КонецЕсли;
Параметры = Колонка.ДополнительныеПараметры;
Если ТипЗнч(Параметры) <> Тип("ПараметрыКолонкиКластерногоАнализа") Или Параметры.Вес <> ОжидаемыйВес Тогда
ВызватьИсключение "Результат не сохранил настоящие свои дополнительные параметры";
КонецЕсли;
Нормализация = Параметры.ЗначенияНормализации;
Если ТипЗнч(Нормализация) <> Тип("Соответствие") Или Нормализация.Количество() > 64 Тогда
ВызватьИсключение "Нужна небольшая настоящая карта нормализации собственной колонки";
КонецЕсли;
Отчет = Колонка.Имя + "; вес=" + Строка(Параметры.Вес) + "; записей нормализации=" + Строка(Нормализация.Количество()) + Символы.ПС;
Для Каждого Пара Из Нормализация Цикл
Отчет = Отчет + "ключ=" + Строка(Пара.Ключ) + "; тип ключа=" + Строка(ТипЗнч(Пара.Ключ))
+ "; значение=" + Строка(Пара.Значение) + "; тип значения=" + Строка(ТипЗнч(Пара.Значение)) + Символы.ПС;
КонецЦикла;
Возврат Отчет;
КонецФункции
Функция НайтиСвойПараметр(Параметры, Имя)
Параметр = Параметры.Найти(Имя);
Если Параметр = Неопределено Или ТипЗнч(Параметр) <> Тип("ПараметрАнализаДанных") Тогда
ВызватьИсключение "Не найден собственный параметр алгоритма " + Имя;
КонецЕсли;
Индекс = Параметры.Индекс(Параметр);
Если Индекс < 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.ВыполнитьПример();
КонецФункцииРазбор по шагам
Защита стенда выполняется до расчетов. Настройки трех исходных колонок получают у реального АнализДанных, назначают ключ/входы и реальные виды данных. ДополнительныеПараметры X/Y проверяются как ПараметрыКолонкиКластерногоАнализа до записи Вес.
УстановитьСвойВес принимает только положительное числовое значение; запись Вес перечитывается. Вес влияет на анализ входной колонки, но урок не утверждает неподтвержденную конкретную формулу расстояния или порядок номеров кластеров.
Каждый параметр алгоритма ищется в настоящей коллекции, его индекс и разрешенный тип проверяются, значение задается и перечитывается. Выполнить возвращает реальный кластерный результат по шести обучающим объектам; модель создается из этого результата.
У параметров колонок результата читаются фактические Вес и ЗначенияНормализации. Последнее — readonly-свойство типа Соответствие: ничего в нем не записываем. Для каждого реального ключа/значения выводятся значение и тип; пустая карта допустима и не заменяется вымышленной формулой.
Модель.ИсточникДанных получает отдельную таблицу двух новых точек. НастройкаВходныхКолонок должна содержать два реальных соответствия. X/Y связываются через объекты КолонкаМоделиПрогноза правильных ролей Входная/КолонкаИсточникаДанных, не через колонки таблицы.
Кластер ищется как настоящая Прогнозируемая колонка, описанная в native-модели. Выходная схема явно содержит собственные имена УчебныйКод, УчебныйX, УчебныйY, УчебныйКластер. Код показывает фактическую иерархию колонок, пути и типы дополнительных параметров без придуманного вложенного пути.
Модель.Выполнить находится после настройки и возвращает реальную ТаблицаЗначений. Проверяются две строки, четыре имени, уникальные свои коды, сохранение X/Y и числовой тип кластера. Исходная строка ищется по коду, не по предполагаемому порядку результата.
Номер кластера выводится как вернула платформа. Не предполагаем нумерацию с нуля/единицы, конкретные 0/1 или устойчивость между другими расчетами. Обе таблицы памяти остаются независимыми, размеры 6/2 проверяются.
Как проверить результат
Будущий положительный опыт: отчет показывает свои веса 2/1, фактическую карту нормализации X/Y, реальную иерархию и по одному кластерному результату для двух новых кодов. Входные координаты в выводе должны совпасть с 0.5/0.5 и 10.5/10.5.
Будущий отрицательный контроль веса: только значение первого вызова УстановитьСвойВес заменить с 2 на 0. Проверка положительного веса должна остановиться до анализа. Затем вернуть 2.
Будущий отрицательный контроль входа: только вызов СвязатьСвоюВходнуюКолонку для Y заменить именем ЧужаяКоордината. Проверка наличия настоящей настройки должна остановиться до прогноза. Вернуть Y.
Будущий отрицательный контроль результата: сразу после Прогноз = Модель.Выполнить() временно присвоить Прогноз = Неопределено. Проверка типа должна остановиться до чтения строк; затем вернуть исходный код.
runtimeVerifiedScenarios=0: 1С, BSL, алгоритм, модель, форма и база здесь не запускались. Статические проверки не доказывают фактическое распределение новых точек или формулу нормализации. Все ручные опыты — только будущие, на собственном отдельном стенде.
Ожидаемый результат
Есть реальный самостоятельный конвейер обучения, дополнительных параметров и прогноза; карта нормализации и ближайшие кластеры берутся из настоящих результатов, не из заранее написанных ответов.
На что обратить внимание
ЗначенияНормализации не присваиваются, полученное Соответствие не меняется. Для непрерывной колонки карта может быть пустой; это не разрешение придумать преобразование значений.
Номера кластеров не служат постоянными кодами бизнес-сегментов. Две вымышленные новые точки не доказывают качество сегментации реальных клиентов.
Колонки/КолонкиРезультата/НастройкаВходныхКолонок модели — readonly-свойства; редактируются только разрешенные реальные элементы возвращенных настроек.
У КолонкиМоделиПрогноза.Получить в installed-справке противоречивый возвращаемый тип. Общий помощник проверяет только доступное Имя его результата и использует настоящий объект Найти для остальных свойств, не утверждая runtime-исправление документации.
Нет записи базовых данных, файлов, запросов к рабочей конфигурации, сети или GUI расчета. На клиент приходит только текст.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.