К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как найти максимальное значение в массиве в 1С

Как найти максимальное значение в массиве в 1С: перебор элементов, сортировка, запрос к таблице значений. Готовые примеры кода, типичные ошибки и ответы на вопросы.

Встроенной функции «Максимум» для массивов во встроенном языке 1С нет, поэтому задача решается одним из нескольких рабочих подходов: классическим перебором элементов, сортировкой массива или переносом данных в таблицу значений с последующей свёрткой. Каждый способ имеет свои условия применения, ограничения по производительности и типичные подводные камни.

Ниже разобраны конкретные варианты кода на встроенном языке 1С, которые можно переносить в свою конфигурацию практически без доработки. Отдельно рассмотрены случаи с массивом чисел, массивом структур, пустым массивом и ситуацией, когда данные изначально лежат в таблице значений или результате запроса.

Базовый способ: перебор массива с сравнением

Самый универсальный и быстрый метод — пройти по массиву циклом и запоминать наибольшее встреченное значение. Алгоритм работает за один проход и не требует дополнительной памяти, поэтому подходит для массивов любого размера.

Функция НайтиМаксимум(МассивЧисел)

Если МассивЧисел.Количество() = 0 Тогда

Возврат Неопределено;

КонецЕсли;

Максимум = МассивЧисел[0];

Для Каждого Элемент Из МассивЧисел Цикл

Если Элемент > Максимум Тогда

Максимум = Элемент;

КонецЕсли;

КонецЦикла;

Возврат Максимум;

КонецФункции

Обратите внимание на первый блок: перед перебором обязательно проверяется, что массив не пустой. Если пропустить эту проверку, обращение к элементу с индексом 0 вызовет ошибку «Индекс находится за границами массива». Возврат значения Неопределено для пустого массива — понятный контракт, который вызывающий код легко обрабатывает.

Начальное значение максимума берётся из первого элемента массива, а не из нуля. Это важно: если все числа в массиве отрицательные и инициализировать переменную нулём, функция вернёт 0, которого в массиве вообще нет.

Типичные ошибки
01
Инициализация максимума нулём — при отрицательных значениях в массиве функция вернёт 0, которого там нет
02
Отсутствие проверки на пустой массив — обращение к МассивЧисел[0] вызывает ошибку индекса
03
Сравнение значений разных типов — число со строкой в 1С сравнивается, но результат часто неожиданный и приводит к неверному максимуму

Поиск максимума через сортировку массива

Второй подход — отсортировать массив по возрастанию и взять последний элемент. В 1С для этого используется объект СписокЗначений, у которого есть метод сортировки, либо данные переносятся в таблицу значений.

Функция МаксимумЧерезСписок(МассивЧисел)

Если МассивЧисел.Количество() = 0 Тогда

Возврат Неопределено;

КонецЕсли;

Список = Новый СписокЗначений;

Список.ЗагрузитьЗначения(МассивЧисел);

Список.СортироватьПоЗначению(НаправлениеСортировки.Возр);

Возврат Список[Список.Количество() - 1].Значение;

КонецФункции

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

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

Максимум в массиве структур или по значению реквизита

На практике массив часто содержит не числа, а структуры, строки таблицы значений или ссылки на объекты, а максимум нужно найти по одному из полей. Тогда в цикле сравнивается конкретное свойство элемента.

Функция НайтиМаксимальнуюЦену(МассивТоваров)

Если МассивТоваров.Количество() = 0 Тогда

Возврат Неопределено;

КонецЕсли;

МаксЦена = МассивТоваров[0].Цена;

Для Каждого Товар Из МассивТоваров Цикл

Если Товар.Цена > МаксЦена Тогда

МаксЦена = Товар.Цена;

КонецЕсли;

КонецЦикла;

Возврат МаксЦена;

КонецФункции

Если нужен не сам максимум, а элемент с максимальным значением (например, товар с наивысшей ценой целиком), запоминайте в переменной сам элемент, а не только значение поля. Для этого внутри условия присваивайте переменной-результату текущий элемент массива.

Максимум через таблицу значений и запрос

Когда данные уже находятся в таблице значений или их удобно туда выгрузить, задачу решают штатными средствами: методом Свернуть() с функцией Максимум или запросом с агрегатной функцией МАКСИМУМ().

// Вариант 1: свёртка таблицы значений

ТЗ.Свернуть("", "Сумма");

Максимум = ТЗ[0].Сумма;

// Вариант 2: запрос

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| МАКСИМУМ(Таблица.Сумма) КАК МаксСумма

|ПОМЕСТИТЬ ВТ

|ИЗ &Таблица КАК Таблица

|;

|ВЫБРАТЬ МаксСумма ИЗ ВТ";

Запрос.УстановитьПараметр("Таблица", ТЗ);

Результат = Запрос.Выполнить().Выбрать();

Результат.Следующий();

Максимум = Результат.МаксСумма;

Запрос с функцией МАКСИМУМ() особенно эффективен, когда данные изначально хранятся в базе: не нужно выгружать тысячи строк в массив, достаточно одного запроса к регистру или справочнику. Это самый производительный вариант для больших объёмов.

Учтите, что агрегатная функция МАКСИМУМ() в запросе игнорирует значения NULL. Если все значения в колонке NULL, результатом будет NULL, а не 0 — обработайте этот случай через ЕСТЬNULL().

Сравнение вариантов

Перебор с сравнением

Универсально и быстро, один проход по массиву. Подходит для любых типов и больших массивов

Сортировка списка значений

Короткий код, но медленнее перебора. Оправдан, если нужен не только максимум, но и ранжирование

Свернуть() таблицы значений

Удобно, когда данные уже в ТЗ. Требует предварительной выгрузки массива в таблицу

Запрос с МАКСИМУМ()

Лучший выбор для данных в базе: не нужно загружать строки в память

Как выбрать способ под свою задачу

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

Маршрут решения

Как выбрать действие

У вас обычный массив чисел или датИспользуйте перебор с сравнением — это самый быстрый и понятный вариант
Массив содержит структуры или объекты, а максимум нужен по полюПеребирайте массив и сравнивайте конкретное свойство элемента
Данные находятся в таблице значенийПримените Свернуть() или запрос с МАКСИМУМ()
Данные хранятся в базе (регистр, справочник)Сразу пишите запрос с МАКСИМУМ(), не выгружая данные в массив
Нужны несколько наибольших значенийОтсортируйте список значений или таблицу по убыванию и возьмите первые элементы

Проверка результата и контрольные точки

После написания функции проверьте её на граничных случаях: пустой массив, массив из одного элемента, все элементы одинаковые, все значения отрицательные. Эти четыре теста выявляют большинство ошибок в логике поиска максимума.

Для отладки удобно выводить промежуточные значения через Сообщить() или смотреть переменные в конфигураторе на точке останова. Убедитесь, что тип возвращаемого значения совпадает с ожиданием вызывающего кода — например, что функция не возвращает строку там, где дальше ожидается число.

Контрольные точки

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

Пустой массив
Норма

Функция возвращает Неопределено без ошибки

Тревожный признак

Ошибка «Индекс находится за границами массива»

Все значения отрицательные
Норма

Возвращается наибольшее из отрицательных чисел

Тревожный признак

Возвращается 0, которого нет в массиве

Один элемент в массиве
Норма

Возвращается этот элемент

Тревожный признак

Функция возвращает Неопределено или начальное значение

Запрос по колонке с NULL
Норма

NULL обработан через ЕСТЬNULL()

Тревожный признак

Результат NULL попадает в дальнейшие вычисления

Производительность и ограничения

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

Если массив формируется выборкой из запроса только ради поиска максимума, это лишняя работа: замените выгрузку на запрос с МАКСИМУМ(). Вы сократите и код, и нагрузку на память, особенно при больших таблицах.

Частая ситуация: разработчик выгружает в массив тысячи строк из регистра, чтобы найти максимальную дату или сумму. Один запрос с МАКСИМУМ() решает ту же задачу без загрузки данных в память и работает заметно быстрее.
ПЗ
Практическое замечание
Итог

Что важно запомнить

Готовой функции максимума для массива в 1С нет. Для обычного массива используйте перебор с сравнением и обязательной проверкой на пустоту. Для данных в таблице значений или в базе применяйте Свернуть() или запрос с МАКСИМУМ(). Не инициализируйте максимум нулём — берите первый элемент массива.

Частые вопросы

Есть ли в 1С встроенная функция Макс() для массива?

Нет, во встроенном языке 1С нет функции, которая напрямую возвращает максимальный элемент массива. Задачу решают перебором элементов, сортировкой списка значений или агрегатной функцией МАКСИМУМ() в запросе.

Что вернуть из функции, если массив пустой?

Общепринятый вариант — возвращать Неопределено. Это позволяет вызывающему коду явно отличить ситуацию «массив пуст» от любого реального значения, включая 0. Главное — задокументировать такое поведение в комментарии к функции.

Как найти максимум в массиве с элементами разных типов?

Лучше не допускать смешанных типов: перед поиском приведите элементы к одному типу или отфильтруйте лишние. Сравнение числа со строкой в 1С формально выполняется, но результат определяется правилами сравнения разнотипных значений и часто не совпадает с ожиданием разработчика.

Как найти не максимум, а элемент с максимальным значением поля?

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

Что быстрее: перебор, сортировка или запрос?

Для массива в памяти быстрее всего перебор — один проход без дополнительных структур. Сортировка медленнее, но полезна, если нужен ранжированный список. Если данные ещё в базе, запрос с МАКСИМУМ() выигрывает у обоих, так как не требует выгрузки строк в память.

Почему запрос с МАКСИМУМ() вернул NULL вместо числа?

Агрегатная функция МАКСИМУМ() игнорирует NULL, но если все значения в колонке NULL или выборка пуста, результатом будет NULL. Оберните агрегат в ЕСТЬNULL(МАКСИМУМ(Поле), 0), чтобы гарантированно получить число.