В процессе разработки на платформе 1С:Предприятие 7.7 часто возникает задача передать в процедуру или функцию набор параметров, количество которых заранее неизвестно. В отличие от других языков программирования, например PHP с его функцией func_get_args, в 1С 7.7 нет встроенного механизма для получения всех переданных аргументов в виде единой коллекции. При объявлении процедуры или функции необходимо явно указывать все принимаемые ею параметры.
Рассмотрим, как обойти это ограничение и реализовать передачу динамического числа аргументов. Проанализируем стандартные подходы и разберем примеры кода, чтобы создать универсальные и удобные функции.
Наиболее правильный и распространенный способ решения этой задачи — передача всех необходимых параметров в виде одного аргумента, который представляет собой коллекцию. В 1С 7.7 для этих целей идеально подходит объект СписокЗначений.
Проанализируем исходную проблему. Разработчик хотел создать универсальную функцию для отладки, которая выводила бы значения любых переданных переменных. Первоначальная реализация выглядела так:
Функция Дебаг(я1=,я2=,я3=,я4=,я5=,я6=,я7=,я8=,я9=,я0=) Экспорт
Сп = СоздатьОбъект("СписокЗначений");
Сп.ДобавитьЗначение(я1);
Сп.ДобавитьЗначение(я2);
// ... и так далее для всех 10 аргументов
Сп.ДобавитьЗначение(я0);
Стр = "";
Для н=1 По Сп.РазмерСписка() Цикл
зн = Сп.ПолучитьЗначение(н);
Если ТипЗначения(зн) <> 0 Тогда
Стр=Стр+"("+ТипЗначенияСтр(зн)+")"+СокрЛП(зн)+" ";
КонецЕсли;
КонецЦикла;
Сообщить(Стр,"");
КонецФункции
Основной недостаток этого подхода — жестко заданное количество аргументов. Если нужно передать 11 переменных, придется изменять саму функцию. Чтобы сделать ее динамической, изменим логику: функция будет принимать один параметр — уже готовый СписокЗначений.
Порядок действий:
СписокЗначений.ДобавитьЗначение() наполняем его всеми переменными, которые хотим передать.Посмотрим на пример. Вместо неудобного вызова:
Дебаг(Логин, СпрСотр.Login, КакаяТоПеременная, ...);
Код будет выглядеть так:
// Создаем и заполняем список перед вызовом
СпПараметров = СоздатьОбъект("СписокЗначений");
СпПараметров.ДобавитьЗначение(Логин, "Имя переменной: Логин");
СпПараметров.ДобавитьЗначение(СпрСотр.Login, "Имя переменной: СпрСотр.Login");
// ... добавляем столько значений, сколько нужно
// Вызываем функцию с одним аргументом
Дебаг(СпПараметров);
Сама функция при этом значительно упрощается и становится универсальной:
Процедура Дебаг(Параметры) Экспорт
Если ТипЗначенияСтр(Параметры) <> "СписокЗначений" Тогда
Сообщить("В функцию Дебаг должен передаваться СписокЗначений!", "!");
Возврат;
КонецЕсли;
СтрВывода = "";
Для Индекс = 1 По Параметры.РазмерСписка() Цикл
Значение = Параметры.ПолучитьЗначение(Индекс);
Представление = Параметры.ПолучитьПредставление(Индекс);
// Если представление (имя) не задано, выводим просто значение
Если ПустаяСтрока(Представление) = 1 Тогда
СтрВывода = СтрВывода + "(" + ТипЗначенияСтр(Значение) + ") " + СокрЛП(Значение) + "; ";
Иначе // Иначе выводим и имя, и значение
СтрВывода = СтрВывода + Представление + " = (" + ТипЗначенияСтр(Значение) + ") " + СокрЛП(Значение) + "; ";
КонецЕсли;
КонецЦикла;
Сообщить(СтрВывода);
КонецПроцедуры
Важный момент: у метода ДобавитьЗначение() есть второй, необязательный параметр — представление (или имя) значения. Его использование делает отладочный вывод гораздо более информативным, так как мы видим не только значение переменной, но и ее "имя" или контекст.
В ходе обсуждения выяснилось, что конечная цель автора — удобный вывод нескольких переменных в окно сообщений, так как функция Сообщить() принимает только один аргумент и не умеет работать так:
Сообщить(ЧтоТо, ГдеТо, КогдаТо); // Так делать нельзя!
Самое простое решение для этой конкретной задачи — предварительно собрать все значения в одну строку. В 1С 7.7 значения разных типов автоматически преобразуются в строку при конкатенации (сложении со строкой).
Посмотрим на пример:
Процедура ПримерВывода()
Товар = "Сковородка Tefal";
Количество = 2;
Цена = 1250.25;
// Собираем все переменные в одну строку с разделителями
СтрокаДляСообщения = "Товар: " + Товар + ", Количество: " + Количество + ", Сумма: " + (Цена * Количество);
Сообщить(СтрокаДляСообщения);
КонецПроцедуры
Этот способ очень прост и эффективен, когда нужно быстро вывести 2-3 переменные. Однако для большого количества переменных или сложного форматирования он становится громоздким.
Для более сложного и гибкого форматирования строк в 1С 7.7 существует мощный инструмент — функция Шаблон(). Она заменяет выражения, заключенные в квадратные скобки [], их вычисленными значениями в контексте текущего модуля.
Рассмотрим пример, который был предложен на форуме:
Процедура Сформировать()
Товар = "Сковородка Tefal";
Кол = 2;
Цена = 1250.25;
// Передаем строку с именами переменных и выражениями
Тест("Товар,Кол,Цена,Цена*Кол");
КонецПроцедуры
Процедура Тест(СтрокаВыражений)
// Разбираем строку на отдельные выражения
Выражения = СтрЗаменить(СтрокаВыражений, ",", РазделительСтрок);
Для i = 1 По СтрКоличествоСтрок(Выражения) Цикл
Выражение = СтрПолучитьСтроку(Выражения, i);
// Формируем шаблон и вычисляем его
// Важно: Шаблон() вычислит выражение в контексте того модуля, где он вызывается.
// В данном примере Тест() и Сформировать() должны быть в одном модуле,
// а переменные Товар, Кол, Цена - видны в процедуре Тест().
// Например, они могут быть переменными модуля.
Сообщить(Шаблон("[" + Выражение + "]"));
КонецЦикла;
КонецПроцедуры
Важно понимать: функция Шаблон() не передает контекст переменных "волшебным" образом. Она работает с теми переменными, которые доступны в месте ее вызова. Если переменные Товар, Кол, Цена были локальными в процедуре Сформировать(), то в процедуре Тест() они будут недоступны, и Шаблон() выдаст ошибку. Чтобы этот код работал, переменные должны быть объявлены на уровне модуля.
Этот метод подходит для создания сложных динамических отчетов или логов, но требует аккуратной работы с областью видимости переменных.
Мы рассмотрели несколько способов для решения задачи передачи произвольного числа аргументов в 1С 7.7:
СпискаЗначений — это наиболее универсальный, гибкий и правильный метод. Он позволяет передавать любое количество разнотипных данных и является стандартом в разработке на 1С 7.7.Сообщить().Шаблон() — мощный инструмент для сложного форматирования строк, но требует понимания области видимости переменных.Выбор конкретного метода зависит от вашей задачи. Для создания универсальных функций, принимающих динамический набор параметров, настоятельно рекомендуется использовать СписокЗначений.