Разработка и Конфигурация · 11 мин
Как найти максимальный элемент массива в 1С
Как найти максимальный элемент массива в 1С: перебор в цикле, сортировка, список значений, работа с индексами и типичные ошибки. Примеры кода на встроенном языке.
Встроенный язык 1С не содержит готовой функции вида «МаксимумМассива», поэтому поиск максимального элемента реализуется вручную — чаще всего простым перебором в цикле. Задача возникает регулярно: при поиске максимальной цены в подборке товаров, при анализе числовых показателей, при обработке результатов запросов, выгруженных в массивы.
Существует несколько рабочих подходов: классический цикл с запоминанием текущего максимума, сортировка массива или списка значений с последующим чтением крайнего элемента, а также обход таблицы значений, если данные удобнее держать в ней. У каждого способа есть свои ограничения по скорости, типам данных и сохранению исходного порядка элементов.
Ниже разобраны основные методы с готовыми примерами кода, пояснения по работе с индексами, обработкой пустых массивов и смешанных типов, а также типичные ошибки, которые приводят к неверному результату или падению кода.
Поиск максимума перебором в цикле
Базовый и самый надёжный приём — завести переменную, записать в неё первый элемент массива, а затем последовательно сравнивать с ней остальные. Если текущий элемент больше накопителя, значение обновляется. После завершения цикла в переменной окажется максимальный элемент.
Функция МаксимумМассива(Массив)
Если Массив.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Максимум = Массив[0];
Для Каждого Элемент Из Массив Цикл
Если Элемент > Максимум Тогда
Максимум = Элемент;
КонецЕсли;
КонецЦикла;
Возврат Максимум;
КонецФункции
Такой подход работает с любыми сравнимыми типами — числами, датами, строками (строки сравниваются по алфавитному порядку). Сложность алгоритма линейная: один проход по массиву, что оптимально для этой задачи. На больших массивах из сотен тысяч элементов разница с другими методами заметна именно в пользу цикла.
Обратите внимание на инициализацию: начинать сравнение нужно с первого элемента массива, а не с нуля. Если все элементы отрицательные (например, температуры или корректировки сумм), стартовый ноль ошибочно станет «максимумом».
Как найти индекс максимального элемента
Часто нужен не сам максимум, а его позиция — например, чтобы потом удалить элемент, заменить его или получить связанные данные из параллельной структуры. Для этого в цикле запоминают не значение, а индекс.
Функция ИндексМаксимума(Массив)
Если Массив.Количество() = 0 Тогда
Возврат -1;
КонецЕсли;
ИндексМакс = 0;
Для Сч = 1 По Массив.Количество() - 1 Цикл
Если Массив[Сч] > Массив[ИндексМакс] Тогда
ИндексМакс = Сч;
КонецЕсли;
КонецЦикла;
Возврат ИндексМакс;
КонецФункции
Здесь используется цикл «Для…По» с явным счётчиком, поскольку конструкция «Для Каждого» индекс не предоставляет. Помните, что индексация массивов в 1С начинается с нуля, а метод Количество() возвращает число элементов, поэтому верхняя граница цикла — «Количество() - 1».
Получив индекс, легко достать и значение: Максимум = Массив[ИндексМакс]. Если максимальных элементов несколько, эта функция вернёт индекс первого из них — при строгом сравнении «>» более поздние равные элементы накопитель не перезаписывают.
Поиск максимума через сортировку и список значений
Альтернатива ручному циклу — воспользоваться готовой сортировкой. У объекта «СписокЗначений» есть метод СортироватьПоЗначению(): после сортировки по возрастанию максимум окажется последним элементом. Массив предварительно выгружается в список значений.
Список = Новый СписокЗначений;
Список.ЗагрузитьЗначения(Массив);
Список.СортироватьПоЗначению(НаправлениеСортировки.Возр);
Максимум = Список[Список.Количество() - 1].Значение;
Метод удобен, когда сортировка и так нужна по логике задачи — например, требуется не только максимум, но и топ-5 значений. Если же нужен только один максимальный элемент, сортировка избыточна: она требует больше вычислений, чем один проход циклом, и создаёт промежуточный объект.
Ещё один вариант — поместить данные в таблицу значений и вызвать Сортировать() по нужной колонке либо использовать итоги. Этот путь оправдан, когда вместе с числом хранятся связанные реквизиты (товар, контрагент, документ), и нужно получить всю строку с максимальным показателем, а не только само число.
Сравнение способов
Универсально, быстро, не меняет исходный массив. Требует аккуратной инициализации и проверки на пустоту.
Короткий код, удобен, когда нужен и упорядоченный список. Медленнее на больших данных, создаёт лишний объект.
Подходит, когда с числом связаны другие поля и нужна вся строка. Избыточен для простого числового массива.
Работа с пустыми массивами и смешанными типами
Обращение к элементу пустого массива вызывает ошибку исполнения, поэтому проверка Количество() = 0 обязательна до начала перебора. Что возвращать в этом случае — решение прикладное: Неопределено, ноль или исключение с понятным текстом. Вариант с Неопределено самый безопасный, но вызывающий код должен уметь его обрабатывать.
Отдельная проблема — массивы со смешанными типами. Сравнение числа со строкой в 1С не вызывает ошибки, но выполняется по внутренним правилам упорядочивания типов, и результат для прикладной логики обычно бессмыслен. Если тип элементов не гарантирован, фильтруйте массив перед поиском.
Числа = Новый Массив;
Для Каждого Элемент Из ИсходныйМассив Цикл
Если ТипЗнч(Элемент) = Тип("Число") Тогда
Числа.Добавить(Элемент);
КонецЕсли;
КонецЦикла;
Аналогично стоит поступать с элементами, равными Неопределено или NULL (последние встречаются после обхода результатов запросов): сравнение с ними может дать неожиданный результат. Явно пропускайте такие значения внутри цикла через Продолжить.
Максимум по части массива и вложенные массивы
Если искать нужно не во всём массиве, а в его диапазоне, ограничьте границы цикла «Для…По»: начальный и конечный индексы задаются явно. Это полезно, например, когда массив объединяет несколько блоков данных, а анализировать требуется только один из них.
Со вложенными структурами — массивом массивов или массивом структур — сравнивать элементы напрямую нельзя. Нужно извлекать сравниваемое поле: для структуры обращаться к ключу, для вложенного массива — к конкретному индексу. Логика накопителя при этом не меняется, меняется только способ получения сравниваемого значения.
// Массив структур с полем "Сумма"
Максимум = Неопределено;
Для Каждого Строка Из МассивСтруктур Цикл
Если Максимум = Неопределено
Или Строка.Сумма > Максимум.Сумма Тогда
Максимум = Строка;
КонецЕсли;
КонецЦикла;
В этом примере в накопителе хранится вся структура, а не только число — так по завершении цикла доступны и остальные поля «победившей» строки. Это стандартный приём при поиске, например, документа с максимальной суммой.
- 1Проверьте, что массив не пустой: Массив.Количество() > 0
- 2Убедитесь, что элементы сравнимого типа, при необходимости отфильтруйте
- 3Инициализируйте накопитель первым элементом массива
- 4Переберите элементы, обновляя накопитель при строгом сравнении
- 5Если нужна позиция — запоминайте индекс через цикл со счётчиком
- 6Проверьте результат на тестовом наборе с отрицательными и повторяющимися значениями
Типичные ошибки и проверка результата
Большинство дефектов в этой, казалось бы, простой задаче связано с граничными случаями. Проверять код стоит на специально подобранных наборах: пустой массив, массив из одного элемента, все элементы равны, все отрицательные, максимум на первой и на последней позиции.
Для самопроверки удобно временно выводить отладочные сообщения через Сообщить() или смотреть значения в отладчике конфигуратора, поставив точку останова внутри цикла. Убедитесь, что накопитель меняется ожидаемое число раз и итоговое значение совпадает с ручным подсчётом на контрольном примере.
Если функция поиска максимума используется в нескольких местах конфигурации, вынесите её в общий модуль с признаком «Сервер» (или «Клиент», если вызывается из клиентского кода) — это исключит расхождение реализаций и упростит исправление ошибок в одном месте.
Как проверить результат
Функция возвращает этот элемент
Ошибка или Неопределено
Возвращается наибольшее из отрицательных чисел
Возвращается 0
Возвращается значение максимума, индекс — первого вхождения
Индекс указывает не туда, куда ожидает логика
Возвращается Неопределено или контролируемое значение
Исключение при обращении к элементу
Что важно запомнить
Оптимальный способ найти максимум массива в 1С — один проход циклом с накопителем, инициализированным первым элементом. Обязательны проверка на пустой массив и контроль типов. Сортировка списка значений оправдана, только когда упорядоченные данные нужны сами по себе.
Частые вопросы
Есть ли в 1С встроенная функция поиска максимума массива?
Нет, встроенный язык не предоставляет готовой функции для поиска максимального элемента массива. Используется ручной перебор в цикле либо обходной путь через сортировку списка значений. Для таблиц значений часть задач решают итоги и сортировка по колонке.
Как найти минимальный элемент массива?
Точно так же, как максимальный, но с обратным знаком сравнения: накопитель обновляется, когда текущий элемент меньше сохранённого. Инициализация первым элементом и проверка на пустоту остаются обязательными.
Что вернуть, если массив пустой?
Чаще всего возвращают Неопределено — это явный сигнал вызывающему коду, что результата нет. Вариант с нулём допустим, только если по логике задачи ноль не может быть ошибочно принят за найденное значение. Генерировать исключение стоит лишь тогда, когда пустой массив — гарантированно ошибочная ситуация.
Как найти максимум в массиве структур по числовому полю?
В цикле сравнивайте не сами структуры, а значения нужного ключа, а в накопителе храните всю структуру целиком — тогда после цикла доступны все её поля. Начальное значение накопителя можно задать как Неопределено и обработать первую итерацию отдельным условием.
Что быстрее — цикл или сортировка списка значений?
Цикл с накопителем быстрее: он делает один проход по данным, тогда как сортировка выполняет больше операций и создаёт промежуточный объект. На небольших массивах разница незаметна, но при обработке крупных выгрузок в регламентных заданиях предпочтителен цикл.
Как найти несколько наибольших значений, а не одно?
Для топ-N удобнее сортировка: выгрузите массив в список значений, отсортируйте по убыванию и возьмите первые N элементов. Альтернатива без сортировки — поддерживать в цикле отдельный небольшой массив лидеров, но код заметно усложняется и оправдан только при очень больших объёмах данных.