Как в 1С написать функцию для сложения произвольного количества чисел и почему возникает ошибка "Слишком много фактических параметров"?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Анализ исходной проблемы и кода

Представим ситуацию: начинающему разработчику дали тестовое задание — написать функцию для суммирования чисел. Он предоставил следующий код и столкнулся с проблемой.

Исходный код функции:


Функция ДобавитьЭлементыВМассив(Массив, Элементы)Экспорт
	
	Для Каждого Элемент из Элементы Цикл 
		МойМассив.Добавить(Элемент);
	КонецЦикла;	
	
	МойМассив = Новый Массив();
	
	Результат = 0;
	Для Каждого Элемент из МойМассив Цикл
		Результат = Результат + Элемент;
	КонецЦикла;
		Возврат Результат;
		
КонецФункции

А вот так он пытался ее вызвать:


&НаКлиенте
Процедура ПриНачалеРаботыСистемы() 	

	Результат = ЛогикаБизнесПроцесса.ДобавитьЭлементыВМассив(1, 2, 3);
	Сообщить(Результат);

КонецПроцедуры

При запуске этого кода система выдает ошибку: "Слишком много фактических параметров". Проанализируем, почему это происходит и какие еще ошибки скрыты в этом коде.

  1. Ошибка "Слишком много фактических параметров". Это ключевая проблема. Функция ДобавитьЭлементыВМассив объявлена с двумя параметрами: Массив и Элементы. Однако при вызове ей пытаются передать три значения: ДобавитьЭлементыВМассив(1, 2, 3). Система 1С не может сопоставить три переданных значения с двумя ожидаемыми параметрами и справедливо сообщает об ошибке.

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

  2. Логическая ошибка в порядке операций. Посмотрим на логику внутри функции. Сначала идет цикл, который пытается добавить элементы в массив МойМассив. Но сам массив инициализируется строкой МойМассив = Новый Массив(); только ПОСЛЕ этого цикла. На момент первой итерации цикла переменная МойМассив не определена, что привело бы к другой ошибке — "Переменная не определена", если бы не ошибка с параметрами.
  3. Неиспользуемый параметр и некорректная логика. Функция принимает параметр Массив, но нигде в коде его не использует. Кроме того, название функции ДобавитьЭлементыВМассив предполагает, что она должна модифицировать массив, а по факту она пытается посчитать сумму. Это нарушает принцип единственной ответственности: функция должна делать что-то одно и делать это хорошо. В данном случае она пытается делать две вещи, причем обе неправильно.
  4. Обнуление массива перед подсчетом. Даже если бы код дошел до подсчета суммы, он бы всегда возвращал 0. Почему? Потому что после гипотетического наполнения массива МойМассив, он тут же пересоздается пустым: МойМассив = Новый Массив();. Следующий цикл проходит по пустому массиву, и итоговый результат остается равным 0.

Решение 1: Правильная реализация через Массив

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

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

Шаг 1. Создаем правильную функцию.

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


Функция СуммаЭлементовМассива(ЧисловойМассив)
    
    // Инициализируем переменную для хранения суммы
    Переменная Результат = 0;
    
    // Проходим в цикле по всем элементам переданного массива
    Для Каждого Элемент Из ЧисловойМассив Цикл
        // Складываем текущий элемент с накопленной суммой
        Результат = Результат + Элемент;
    КонецЦикла;
    
    // Возвращаем итоговую сумму
    Возврат Результат;
    
КонецФункции

Шаг 2. Правильно вызываем функцию.

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


// Создаем пустой массив
МоиЧисла = Новый Массив;

// Добавляем в него наши числа
МоиЧисла.Добавить(10);
МоиЧисла.Добавить(20);
МоиЧисла.Добавить(50);
МоиЧисла.Добавить(120);

// Вызываем нашу функцию, передавая ей ВЕСЬ массив как один параметр
ИтоговаяСумма = СуммаЭлементовМассива(МоиЧисла); // Результат будет 200

Сообщить("Сумма чисел равна: " + ИтоговаяСумма);

Улучшение: в реальных задачах в массив могут попасть не только числа. Чтобы избежать ошибок, стоит добавить проверку типа элемента перед сложением.


Функция СуммаЭлементовМассива(ЧисловойМассив)
    
    Переменная Результат = 0;
    
    Для Каждого Элемент Из ЧисловойМассив Цикл
        // Проверяем, что текущий элемент является числом
        Если ТипЗнч(Элемент) = Тип("Число") Тогда
            Результат = Результат + Элемент;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Результат;
    
КонецФункции

Решение 2: Использование ТаблицыЗначений

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

Посмотрим на пример.


// 1. Создаем ТаблицуЗначений и добавляем в нее колонку для чисел
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("ЧислоДляСуммы");

// 2. Наполняем таблицу данными (например, из массива)
ЧислаДляСложения = Новый Массив;
ЧислаДляСложения.Добавить(15);
ЧислаДляСложения.Добавить(25);
ЧислаДляСложения.Добавить(100);

Для Каждого Число Из ЧислаДляСложения Цикл
    НоваяСтрока = ТЗ.Добавить();
    НоваяСтрока.ЧислоДляСуммы = Число;
КонецЦикла;

// 3. Получаем сумму с помощью метода Итог()
ИтоговаяСумма = ТЗ.Итог("ЧислоДляСуммы"); // Результат будет 140

Сообщить("Сумма чисел из таблицы равна: " + ИтоговаяСумма);

Этот метод может быть даже производительнее цикла, если речь идет о большом объеме данных.

Выводы и рекомендации

Подведем итог разбора. Чтобы успешно решать подобные задачи в 1С, запомним несколько ключевых правил:

  1. Фиксированное число параметров: Пользовательские функции в 1С всегда имеют строго определенное количество параметров. Если нужно передать "произвольное количество" элементов, их следует объединить в одну коллекцию (Массив, СписокЗначений, ТаблицаЗначений) и передать эту коллекцию как один параметр.
  2. Логика и порядок действий: Всегда инициализируйте переменные (например, Новый Массив()) до их использования. Внимательно следите за порядком операций в коде.
  3. "Говорящие" имена: Называйте функции и переменные так, чтобы их назначение было очевидно. Функция СуммаЭлементовМассива гораздо понятнее, чем ДобавитьЭлементыВМассив, если она считает сумму.
  4. Одна функция — одна задача: Старайтесь, чтобы ваша процедура или функция выполняла одну конкретную задачу. Это делает код более читаемым, простым для отладки и повторного использования.

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

← На главную