Заинтересовала небольшая теоретическая задачка на алгоритмизацию и работу с матрицами (читай циклами). И захотелось реализовать ее на языке 1С. Заодно вспомнить основы работы с сортировкой.
Используемая версия платформы 8.3.18.1336.
Решила написать внешнюю обработку и весь код сделать в модуле формы.
Добавила реквизиты: Размерность матрицы, диапазон заполнения: верхняя и нижняя границы и поле ввода для ограничивающего параметра.
Кнопка "Сгенерировать" для генерации матрицы по заданным условиям. И кнопка "Найти число" для поиска первого удовлетворяющего заданным условиям числа.
Ничего хитрого тут нет. Все операции проводятся на серверной стороне.
1. СгенерироватьНаСервере()
&НаСервере
Процедура СгенерироватьНаСервере()
ТЗМодуль = Новый ТаблицаЗначений;
х = 0;
у = 0;
ИмяКолонки = "";
// Создание пустой ТЗ размером М*Н
ОписаниеСтроки = Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(10));
Пока х < ЧислоСтолбцов Цикл
ИмяКолонки = "л"+х+"";
ТЗМодуль.Колонки.Добавить(ИмяКолонки, ОписаниеСтроки);
х = х + 1;
КонецЦикла;
Пока у < ЧислоСтрок Цикл
ТЗМодуль.Добавить();
у = у + 1;
КонецЦикла;
// Заполнение ТЗ случайными числами
ГСЧ = Новый ГенераторСлучайныхЧисел();
х = 0;
у = 0;
Пока х < ЧислоСтрок Цикл
Пока у < ЧислоСтолбцов Цикл
ТЗМодуль[х][у] = ГСЧ.СлучайноеЧисло(НижняяГраница, ВерхняяГраница);
у = у + 1;
КонецЦикла;
у = 0;
х = х + 1;
КонецЦикла;
Для Каждого Колонка Из ТЗМодуль.Колонки Цикл
Инфо = Инфо + " " +Колонка.Имя+ " Тип значения: " +Колонка.ТипЗначения + ". ";
КонецЦикла;
// Собирается инофрмация по добавленным ранее элементам формы и реквизитам, на которые элементы формы ссылаются.
УдаляемыеРеквизиты = Новый Массив;
УдаляемыеЭлементы = Новый Массив;
Для каждого Эл Из Элементы.ТЗ.ПодчиненныеЭлементы Цикл
УдаляемыеРеквизиты.Добавить(Эл.ПутьКДанным);
УдаляемыеЭлементы.Добавить(Эл);
КонецЦикла;
Для каждого Эл Из УдаляемыеЭлементы Цикл
Элементы.Удалить(Эл);
КонецЦикла;
// Добавляются колонки из ТаблицыЗначений ТЗМодуль в реквизит формы ТЗ
НовыеРеквизиты = Новый Массив;
Для Каждого Колонка Из ТЗМодуль.Колонки Цикл
НовыйРеквизит = Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, "ТЗ", Колонка.Заголовок);
НовыеРеквизиты.Добавить(НовыйРеквизит);
КонецЦикла;
//Удаляются старые и устанавливаются новые реквизиты
ИзменитьРеквизиты(НовыеРеквизиты, УдаляемыеРеквизиты);
// Динамически добавить на форму элемент формы ТЗ со всеми колонками
// Добавляются колонки из ТаблицыЗначений в элементы ТабЭлементФормы со ссылкой на колонки в ТабРеквизит
Для Каждого Колонка Из ТЗМодуль.Колонки Цикл
НовыйЭлемент = Элементы.Добавить(Колонка.Имя, Тип("ПолеФормы"), Элементы.ТЗ);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода; //Или ПолеВвода, или что-то другое;
ПутьКДанным = "ТЗ." + Колонка.Имя;
НовыйЭлемент.ПутьКДанным = ПутьКДанным;
КонецЦикла;
// В созданный реквизит загружается ТЗ
ЗначениеВРеквизитФормы(ТЗМодуль, "ТЗ");
КонецПроцедуры
Здесь сначала происходит создание пустой таблицы значений. с описанием типов для колонок. Потом заполнение таблицы случайными значениями через объект встроенного языка ГенераторСлучайныхЧисел().
Потом динамически добавляем на форму колонки для таблицы значений. Вызываем стандартную процедуру глобального контекста ИзменитьРеквизиты().
И вторая команда: Найти число. Здесь происходит поиск первого наибольшего числа, но не большего, чем задано в ограничении.
&НаСервере
Процедура НайтиЧислоНаСервере()
ТЗРасчет = РеквизитФормыВЗначение("ТЗ");
х = 0;
у = 0;
к = 0;
СчетчикИзмененияК = 0;
МассивПодходящихЧисел = Новый Массив();
МассивКоординатНайденных = Новый Массив();
МассивКоординатНайденных.Добавить(Новый Массив());
МассивКоординатНайденных.Добавить(Новый Массив());
// 1. найти, а есть ли вообще хоть одно число, удовлетворяющее условию?
Пока х < ЧислоСтрок Цикл
Пока у < ЧислоСтолбцов Цикл
Если Число(ТЗРасчет[х][у]) < МеньшеЭтогоЧисла Тогда
к = Число(ТЗРасчет[х][у]);
МассивПодходящихЧисел.Добавить(к);
МассивКоординатНайденных[0].Добавить(х);
МассивКоординатНайденных[1].Добавить(у);
СчетчикИзмененияК = СчетчикИзмененияК + 1;
Иначе
//
КонецЕсли;
у = у + 1;
КонецЦикла;
у = 0;
х = х + 1;
КонецЦикла;
Если СчетчикИзмененияК > 0 Тогда
Результат = к;
Иначе
Результат = "Нет числа, удовлетворяющего условию."
КонецЕсли;
// 2. Имея массив отобранных чисел, надо найти максимальный элемент в массиве.
// Если такое число вообще есть
Если Результат <> "Нет числа, удовлетворяющего условию." Тогда
х = 0;
ПоследняяПозицияИзмененияК = 0;
ЗнакПредыдущегоШага = NULL;
ЗнакТекущегоШага = NULL;
МахЭлемент = МассивПодходящихЧисел[0];
Пока х < МассивПодходящихЧисел.Количество() Цикл
Если МахЭлемент < МассивПодходящихЧисел[х] Тогда
МахЭлемент = МассивПодходящихЧисел[х];
ПоследняяПозицияИзмененияК = ПоследняяПозицияИзмененияК + 1;
ЗнакТекущегоШага = ИСТИНА;
Иначе
ЗнакТекущегоШага = ЛОЖЬ;
КонецЕсли;
х = х + 1;
КонецЦикла;
Результат = МахЭлемент;
Иначе
//
КонецЕсли;
КонецПроцедуры