Как в 1С 7.7 передать в функцию произвольное (динамическое) количество аргументов?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

В процессе разработки на платформе 1С:Предприятие 7.7 часто возникает задача передать в процедуру или функцию набор параметров, количество которых заранее неизвестно. В отличие от других языков программирования, например PHP с его функцией func_get_args, в 1С 7.7 нет встроенного механизма для получения всех переданных аргументов в виде единой коллекции. При объявлении процедуры или функции необходимо явно указывать все принимаемые ею параметры.

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

Решение 1: Использование объекта "СписокЗначений"

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

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


Функция Дебаг(я1=,я2=,я3=,я4=,я5=,я6=,я7=,я8=,я9=,я0=) Экспорт
    Сп = СоздатьОбъект("СписокЗначений");
    Сп.ДобавитьЗначение(я1);
    Сп.ДобавитьЗначение(я2);
    // ... и так далее для всех 10 аргументов
    Сп.ДобавитьЗначение(я0);
    
    Стр = "";
    Для н=1 По Сп.РазмерСписка() Цикл
        зн = Сп.ПолучитьЗначение(н);
        Если ТипЗначения(зн) <> 0 Тогда
            Стр=Стр+"("+ТипЗначенияСтр(зн)+")"+СокрЛП(зн)+"    ";
        КонецЕсли;
    КонецЦикла;
    Сообщить(Стр,"");
КонецФункции

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

Порядок действий:

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

Посмотрим на пример. Вместо неудобного вызова:

Дебаг(Логин, СпрСотр.Login, КакаяТоПеременная, ...);

Код будет выглядеть так:


// Создаем и заполняем список перед вызовом
СпПараметров = СоздатьОбъект("СписокЗначений");
СпПараметров.ДобавитьЗначение(Логин, "Имя переменной: Логин");
СпПараметров.ДобавитьЗначение(СпрСотр.Login, "Имя переменной: СпрСотр.Login");
// ... добавляем столько значений, сколько нужно

// Вызываем функцию с одним аргументом
Дебаг(СпПараметров);

Сама функция при этом значительно упрощается и становится универсальной:


Процедура Дебаг(Параметры) Экспорт
    Если ТипЗначенияСтр(Параметры) <> "СписокЗначений" Тогда
        Сообщить("В функцию Дебаг должен передаваться СписокЗначений!", "!");
        Возврат;
    КонецЕсли;
    
    СтрВывода = "";
    Для Индекс = 1 По Параметры.РазмерСписка() Цикл
        Значение = Параметры.ПолучитьЗначение(Индекс);
        Представление = Параметры.ПолучитьПредставление(Индекс);
        
        // Если представление (имя) не задано, выводим просто значение
        Если ПустаяСтрока(Представление) = 1 Тогда
            СтрВывода = СтрВывода + "(" + ТипЗначенияСтр(Значение) + ") " + СокрЛП(Значение) + "; ";
        Иначе // Иначе выводим и имя, и значение
            СтрВывода = СтрВывода + Представление + " = (" + ТипЗначенияСтр(Значение) + ") " + СокрЛП(Значение) + "; ";
        КонецЕсли;
    КонецЦикла;
    
    Сообщить(СтрВывода);
КонецПроцедуры

Важный момент: у метода ДобавитьЗначение() есть второй, необязательный параметр — представление (или имя) значения. Его использование делает отладочный вывод гораздо более информативным, так как мы видим не только значение переменной, но и ее "имя" или контекст.

Решение 2: Формирование строки для вывода

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

Сообщить(ЧтоТо, ГдеТо, КогдаТо); // Так делать нельзя!

Самое простое решение для этой конкретной задачи — предварительно собрать все значения в одну строку. В 1С 7.7 значения разных типов автоматически преобразуются в строку при конкатенации (сложении со строкой).

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


Процедура ПримерВывода()
    Товар = "Сковородка Tefal";
    Количество = 2;
    Цена = 1250.25;
    
    // Собираем все переменные в одну строку с разделителями
    СтрокаДляСообщения = "Товар: " + Товар + ", Количество: " + Количество + ", Сумма: " + (Цена * Количество);
    
    Сообщить(СтрокаДляСообщения);
КонецПроцедуры

Этот способ очень прост и эффективен, когда нужно быстро вывести 2-3 переменные. Однако для большого количества переменных или сложного форматирования он становится громоздким.

Решение 3: Продвинутое форматирование с помощью функции Шаблон()

Для более сложного и гибкого форматирования строк в 1С 7.7 существует мощный инструмент — функция Шаблон(). Она заменяет выражения, заключенные в квадратные скобки [], их вычисленными значениями в контексте текущего модуля.

Рассмотрим пример, который был предложен на форуме:


Процедура Сформировать()
    Товар = "Сковородка Tefal";
    Кол = 2;
    Цена = 1250.25;
    
    // Передаем строку с именами переменных и выражениями
    Тест("Товар,Кол,Цена,Цена*Кол");
КонецПроцедуры

Процедура Тест(СтрокаВыражений)
    // Разбираем строку на отдельные выражения
    Выражения = СтрЗаменить(СтрокаВыражений, ",", РазделительСтрок);
    
    Для i = 1 По СтрКоличествоСтрок(Выражения) Цикл
        Выражение = СтрПолучитьСтроку(Выражения, i);
        
        // Формируем шаблон и вычисляем его
        // Важно: Шаблон() вычислит выражение в контексте того модуля, где он вызывается.
        // В данном примере Тест() и Сформировать() должны быть в одном модуле,
        // а переменные Товар, Кол, Цена - видны в процедуре Тест().
        // Например, они могут быть переменными модуля.
        Сообщить(Шаблон("[" + Выражение + "]"));
    КонецЦикла;
КонецПроцедуры

Важно понимать: функция Шаблон() не передает контекст переменных "волшебным" образом. Она работает с теми переменными, которые доступны в месте ее вызова. Если переменные Товар, Кол, Цена были локальными в процедуре Сформировать(), то в процедуре Тест() они будут недоступны, и Шаблон() выдаст ошибку. Чтобы этот код работал, переменные должны быть объявлены на уровне модуля.

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

Итоги

Мы рассмотрели несколько способов для решения задачи передачи произвольного числа аргументов в 1С 7.7:

  1. Передача СпискаЗначений — это наиболее универсальный, гибкий и правильный метод. Он позволяет передавать любое количество разнотипных данных и является стандартом в разработке на 1С 7.7.
  2. Простая конкатенация строк — быстрый и легкий способ для простого вывода нескольких переменных в Сообщить().
  3. Использование функции Шаблон() — мощный инструмент для сложного форматирования строк, но требует понимания области видимости переменных.

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

← На главную