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

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

Как найти максимальный элемент массива в 1С

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

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

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

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

Поиск максимума перебором в цикле

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

Функция МаксимумМассива(Массив)

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

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

КонецЕсли;

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

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

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

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

КонецЕсли;

КонецЦикла;

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

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

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

Обратите внимание на инициализацию: начинать сравнение нужно с первого элемента массива, а не с нуля. Если все элементы отрицательные (например, температуры или корректировки сумм), стартовый ноль ошибочно станет «максимумом».

Как найти индекс максимального элемента

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

Функция ИндексМаксимума(Массив)

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

Возврат -1;

КонецЕсли;

ИндексМакс = 0;

Для Сч = 1 По Массив.Количество() - 1 Цикл

Если Массив[Сч] > Массив[ИндексМакс] Тогда

ИндексМакс = Сч;

КонецЕсли;

КонецЦикла;

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

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

Здесь используется цикл «Для…По» с явным счётчиком, поскольку конструкция «Для Каждого» индекс не предоставляет. Помните, что индексация массивов в 1С начинается с нуля, а метод Количество() возвращает число элементов, поэтому верхняя граница цикла — «Количество() - 1».

Получив индекс, легко достать и значение: Максимум = Массив[ИндексМакс]. Если максимальных элементов несколько, эта функция вернёт индекс первого из них — при строгом сравнении «>» более поздние равные элементы накопитель не перезаписывают.

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

Альтернатива ручному циклу — воспользоваться готовой сортировкой. У объекта «СписокЗначений» есть метод СортироватьПоЗначению(): после сортировки по возрастанию максимум окажется последним элементом. Массив предварительно выгружается в список значений.

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

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

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

Максимум = Список[Список.Количество() - 1].Значение;

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

Ещё один вариант — поместить данные в таблицу значений и вызвать Сортировать() по нужной колонке либо использовать итоги. Этот путь оправдан, когда вместе с числом хранятся связанные реквизиты (товар, контрагент, документ), и нужно получить всю строку с максимальным показателем, а не только само число.

Сравнение способов

Цикл с накопителем

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

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

Короткий код, удобен, когда нужен и упорядоченный список. Медленнее на больших данных, создаёт лишний объект.

Таблица значений

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

Работа с пустыми массивами и смешанными типами

Обращение к элементу пустого массива вызывает ошибку исполнения, поэтому проверка Количество() = 0 обязательна до начала перебора. Что возвращать в этом случае — решение прикладное: Неопределено, ноль или исключение с понятным текстом. Вариант с Неопределено самый безопасный, но вызывающий код должен уметь его обрабатывать.

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

Числа = Новый Массив;

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

Если ТипЗнч(Элемент) = Тип("Число") Тогда

Числа.Добавить(Элемент);

КонецЕсли;

КонецЦикла;

Аналогично стоит поступать с элементами, равными Неопределено или NULL (последние встречаются после обхода результатов запросов): сравнение с ними может дать неожиданный результат. Явно пропускайте такие значения внутри цикла через Продолжить.

Максимум по части массива и вложенные массивы

Если искать нужно не во всём массиве, а в его диапазоне, ограничьте границы цикла «Для…По»: начальный и конечный индексы задаются явно. Это полезно, например, когда массив объединяет несколько блоков данных, а анализировать требуется только один из них.

Со вложенными структурами — массивом массивов или массивом структур — сравнивать элементы напрямую нельзя. Нужно извлекать сравниваемое поле: для структуры обращаться к ключу, для вложенного массива — к конкретному индексу. Логика накопителя при этом не меняется, меняется только способ получения сравниваемого значения.

// Массив структур с полем "Сумма"

Максимум = Неопределено;

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

Если Максимум = Неопределено

Или Строка.Сумма > Максимум.Сумма Тогда

Максимум = Строка;

КонецЕсли;

КонецЦикла;

В этом примере в накопителе хранится вся структура, а не только число — так по завершении цикла доступны и остальные поля «победившей» строки. Это стандартный приём при поиске, например, документа с максимальной суммой.

Порядок действий
  1. 1
    Проверьте, что массив не пустой: Массив.Количество() > 0
  2. 2
    Убедитесь, что элементы сравнимого типа, при необходимости отфильтруйте
  3. 3
    Инициализируйте накопитель первым элементом массива
  4. 4
    Переберите элементы, обновляя накопитель при строгом сравнении
  5. 5
    Если нужна позиция — запоминайте индекс через цикл со счётчиком
  6. 6
    Проверьте результат на тестовом наборе с отрицательными и повторяющимися значениями

Типичные ошибки и проверка результата

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

Типичные ошибки
01
Инициализация максимума нулём — на массиве из отрицательных чисел результат будет неверным
02
Отсутствие проверки пустого массива — ошибка обращения к элементу по индексу 0
03
Нестрогое сравнение «>=» там, где нужен первый максимум — вернётся индекс последнего из равных
04
Сравнение разнотипных значений без фильтрации — формально код работает, но результат бессмыслен
05
Путаница между Количество() и верхним индексом — выход за границу массива на единицу
06
Сортировка исходного списка, когда порядок элементов нужен дальше по логике — данные теряют исходную последовательность

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

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

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

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

Массив из одного элемента
Норма

Функция возвращает этот элемент

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

Ошибка или Неопределено

Все элементы отрицательные
Норма

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

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

Возвращается 0

Несколько одинаковых максимумов
Норма

Возвращается значение максимума, индекс — первого вхождения

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

Индекс указывает не туда, куда ожидает логика

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

Возвращается Неопределено или контролируемое значение

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

Исключение при обращении к элементу

Итог

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

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

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

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

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

Как найти минимальный элемент массива?

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

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

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

Как найти максимум в массиве структур по числовому полю?

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

Что быстрее — цикл или сортировка списка значений?

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

Как найти несколько наибольших значений, а не одно?

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