При разработке на платформе 1С:Предприятие часто возникает задача поиска экстремального (максимального или минимального) значения в наборе данных. Это может быть колонка табличной части документа, результат выборки или произвольная таблица значений. Давайте разберем, как сделать это максимально эффективно, учитывая особенности производительности и надежности кода.
Это самый универсальный и понятный способ. Его главные преимущества — отсутствие необходимости изменять порядок строк (сортировать) и корректная работа как на клиенте, так и на сервере. Однако здесь важно избегать классической ошибки с инициализацией переменной максимума.
Важное предостережение: Не инициализируйте переменную максимума нулем, если в вашей колонке могут присутствовать отрицательные числа. В таком случае алгоритм вернет ошибочный ноль. Лучше всего присвоить переменной значение из первой строки коллекции.
Разберем алгоритм по шагам:
МаксЗначение значение из первой строки.Макс() для обновления результата на каждой итерации.
Если Объект.ТабличнаяЧасть.Количество() > 0 Тогда
МаксЗначение = Объект.ТабличнаяЧасть[0].ВашаКолонка;
Для Индекс = 1 По Объект.ТабличнаяЧасть.Количество() - 1 Цикл
ТекущееЗначение = Объект.ТабличнаяЧасть[Индекс].ВашаКолонка;
МаксЗначение = Макс(МаксЗначение, ТекущееЗначение);
КонецЦикла;
КонецЕсли;
Если данные уже находятся в базе данных или объем выборки достаточно велик, использование запроса является наиболее профессиональным решением. Запрос позволяет выполнить агрегацию на стороне СУБД, что значительно быстрее, чем обработка данных средствами встроенного языка 1С.
Для реализации этого метода мы выгружаем колонку из табличной части во временную таблицу и передаем её в запрос:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ МАКСИМУМ(Т.Срок) КАК МаксСрок
|ИЗ ВременнаяТаблица КАК Т";
ТЗ_ДляЗапроса = Объект.ТабличнаяЧасть.Выгрузить(,"Срок");
Запрос.УстановитьПараметр("ТЗ", ТЗ_ДляЗапроса);
Результат = Запрос.Выполнить().Выбрать();
Если Результат.Следующий() Тогда
Максимум = Результат.МаксСрок;
КонецЕсли;
Часто программисты используют метод Сортировать() для получения максимума. Суть проста: сортируем таблицу по убыванию и берем значение из первой строки. Это кажется коротким и изящным решением, но у него есть минусы:
O(N log N), тогда как у простого цикла — O(N). Для маленьких таблиц (до 1000 строк) разница не ощутима, но для больших объемов это избыточная нагрузка на процессор и память.Если вы все же решили использовать этот метод, делайте это на копии данных:
ТЗ_Копия = Объект.ТабличнаяЧасть.Выгрузить(,"Срок");
ТЗ_Копия.Сортировать("Срок Убыв");
Если ТЗ_Копия.Количество() > 0 Тогда
МаксЗначение = ТЗ_Копия[0].Срок;
КонецЕсли;
Независимо от выбранного метода, всегда добавляйте проверку Объект.ТабличнаяЧасть.Количество() > 0 или используйте конструкцию Если ЗначениеЗаполнено(). Обращение к индексу [0] у пустой коллекции приведет к ошибке выполнения, которая остановит работу вашего кода и потребует вмешательства пользователя.
Подведем итоги:
Макс().Запрос.Следуя этим рекомендациям, вы сможете писать универсальный, быстрый и читаемый код, который будет работать стабильно в любых условиях.