Разработка и Конфигурация · 14 мин
Как передавать параметры в 1С
Как передавать параметры в 1С: между процедурами и функциями, при открытии форм, в командах и запросах. Примеры кода, типичные ошибки и проверка результата.
Передача параметров — базовый приём разработки в 1С, без которого невозможно написать ни одну обработку, отчёт или доработку типовой конфигурации. Параметры передаются между процедурами и функциями, при открытии форм, в командах интерфейса, в запросах и при программном вызове веб-сервисов. У каждого сценария есть свой синтаксис и свои подводные камни.
Основная сложность для начинающего разработчика — понять, когда параметр передаётся по значению, а когда по ссылке, как правильно сформировать структуру параметров формы и почему запрос «не видит» переданное значение. Ниже разобраны все ключевые сценарии с примерами кода на встроенном языке.
Материал ориентирован на платформу 1С:Предприятие 8.3 с управляемыми формами, но большинство принципов применимо и к обычным формам, и к внешним обработкам.
Как передавать параметры в процедуры и функции
Самый частый случай — вызов собственной процедуры или функции с аргументами. Параметры объявляются в заголовке через запятую, при вызове значения перечисляются в том же порядке:
Функция РассчитатьСуммуСНДС(Сумма, СтавкаНДС = 20)
Возврат Сумма + Сумма * СтавкаНДС / 100;
КонецФункции
// Вызов:
Итог = РассчитатьСуммуСНДС(10000); // СтавкаНДС = 20 по умолчанию
Итог = РассчитатьСуммуСНДС(10000, 10); // явное значение ставки
Параметры со значением по умолчанию всегда ставятся в конец списка. Если пропустить необязательный параметр в середине, оставьте на его месте запятую: МояПроцедура(Значение1, , Значение3).
По умолчанию параметры передаются «по ссылке»: если внутри процедуры изменить значение параметра, изменится и переменная в вызывающем коде. Чтобы запретить это, используйте ключевое слово Знач — тогда внутрь попадёт копия:
Процедура ОбработатьСписок(Знач СписокТоваров)
// изменения СписокТоваров не затронут переменную вызывающего кода
КонецПроцедуры
Передача по ссылке работает только в пределах одного контекста. При вызове серверной процедуры с клиента параметры всё равно сериализуются, поэтому полагаться на изменение переданной переменной через границу «клиент–сервер» нельзя — серверная процедура должна возвращать результат явно.
Как передать параметры при открытии формы
Управляемые формы открываются функцией ОткрытьФорму(), вторым аргументом которой идёт структура параметров. Ключи структуры становятся свойствами объекта Параметры в модуле формы:
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Организация", ТекущаяОрганизация);
ПараметрыФормы.Вставить("ДатаНачала", НачалоМесяца(ТекущаяДата()));
ПараметрыФормы.Вставить("РежимВыбора", Истина);
ОткрытьФорму("Обработка.ПечатьАктов.Форма.ФормаНастройки", ПараметрыФормы, ЭтотОбъект);
В открываемой форме значения читаются в обработчике ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("Организация") Тогда
Организация = Параметры.Организация;
КонецЕсли;
КонецПроцедуры
Обязательно проверяйте наличие ключа через Параметры.Свойство() — обращение к несуществующему параметру вызовет ошибку. Это особенно важно, если форма открывается из нескольких мест с разным набором параметров.
Для форм списков и выбора есть зарезервированные параметры платформы: Отбор (структура отбора), РежимВыбора, МножественныйВыбор, ЗакрыватьПриВыборе, ТекущаяСтрока. Их не нужно объявлять — платформа обработает автоматически.
- 1Сформируйте структуру Новый Структура и добавьте нужные ключи
- 2Вызовите ОткрытьФорму() с этой структурой вторым аргументом
- 3В модуле открываемой формы прочитайте значения через Параметры.ИмяКлюча в ПриСозданииНаСервере
- 4Проверьте наличие ключа через Параметры.Свойство() перед использованием
- 5Запустите открытие и убедитесь, что поля формы заполнились переданными значениями
Как вернуть результат из формы: оповещения и закрытие с параметром
Передача данных обратно — из открытой формы в вызвавшую — делается двумя способами. Первый: форма при закрытии возвращает значение через Закрыть(Результат), а вызывающий код получает его в обработчике оповещения:
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораКонтрагента", ЭтотОбъект);
ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", , ЭтотОбъект, , , , ОписаниеОповещения);
&НаКлиенте
Процедура ПослеВыбораКонтрагента(Результат, ДопПараметры) Экспорт
Если Результат <> Неопределено Тогда
Контрагент = Результат;
КонецЕсли;
КонецПроцедуры
Второй способ — метод Оповестить("ИмяСобытия", Параметр, Источник) внутри формы и обработчик ОбработкаОповещения в форме-получателе. Этот вариант удобен, когда форма не закрывается, а данные должны обновляться многократно, например при подборе товаров в документ.
Выбирайте оповещение о закрытии, если результат нужен один раз, и Оповестить() — если форма живёт параллельно с основной и обмен данными продолжается.
Как передавать параметры в запросы
В запросах параметры объявляются через символ & в тексте и заполняются методом УстановитьПараметр() до выполнения:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Продажи.Номенклатура,
| СУММА(Продажи.Количество) КАК Количество
|ИЗ
| РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Продажи
|ГДЕ
| Продажи.Номенклатура В (&СписокНоменклатуры)
|СГРУППИРОВАТЬ ПО
| Продажи.Номенклатура";
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ДатаОтчета));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ДатаОтчета));
Запрос.УстановитьПараметр("СписокНоменклатуры", СписокТоваров);
Результат = Запрос.Выполнить();
Тип значения должен соответствовать контексту: в оператор В передавайте массив или список значений, в сравнение — одиночное значение нужного типа. Передача NULL или несовместимого типа не всегда вызывает явную ошибку, но даёт пустой результат — это одна из самых коварных причин «запрос ничего не вернул».
Для виртуальных таблиц регистров параметры указываются прямо в тексте в скобках. Помните, что не все параметры виртуальных таблиц можно опустить — порядок и количество фиксированы, пропуск обозначается запятой.
Как передавать параметры в команды и обработчики событий
У команд формы и глобальных команд параметры передаются через коллекцию ПараметрыКоманды в обработчике ОбработкаКоманды. Для команд, привязанных к объекту (например, печатная форма документа), платформа сама передаёт массив ссылок на выбранные объекты:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
// ПараметрКоманды — массив ссылок на выбранные документы
ПараметрыФормы = Новый Структура("ОбъектыПечати", ПараметрКоманды);
ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыФормы);
КонецПроцедуры
Тип параметра команды настраивается в свойстве «Тип параметра команды» в конфигураторе. Если тип не задан, команда не появится в интерфейсе объектов нужного вида — частая причина «команда не отображается в документе».
В обработчиках событий элементов формы (ПриИзменении, НачалоВыбора и т.п.) параметры передаются платформой: ссылка на элемент, выбранное значение, стандартная обработка. Состав фиксирован для каждого события — смотрите синтакс-помощник, а не добавляйте свои аргументы: лишние параметры в обработчике события приведут к ошибке вызова.
Как передать параметры между клиентом и сервером
В управляемом приложении код делится на клиентский и серверный. При вызове серверной процедуры с клиента параметры сериализуются: платформа упаковывает их, передаёт на сервер и распаковывает. Отсюда ограничения — передавать можно только сериализуемые типы.
Безопасно передавать: примитивные типы (строка, число, дата, булево), ссылки на объекты базы, структуры, массивы, таблицы значений (через реквизит формы), хранилище значений. Нельзя передавать: объекты типа ДокументОбъект, СправочникОбъект, Запрос, ТабличныйДокумент — используйте ссылки и создавайте объекты уже на сервере.
&НаКлиенте
Процедура СформироватьОтчет(Команда)
Результат = СформироватьНаСервере(Организация, Период);
// дальше работаем с результатом на клиенте
КонецПроцедуры
&НаСервере
Функция СформироватьНаСервере(Организация, Период)
// здесь можно создавать запросы и объекты
Возврат ТаблицаРезультата;
КонецФункции
Директивы компиляции определяют контекст: &НаКлиенте, &НаСервере, &НаСервереБезКонтекста. Вариант «без контекста» быстрее (не передаётся вся форма), но не имеет доступа к данным формы — передавайте нужные значения явными параметрами.
Как проверить, что параметры переданы правильно
Поля заполнены переданными значениями
Поля пустые — ключ структуры не совпадает с читаемым именем
Возвращаются ожидаемые строки
Пустая выборка при заведомо существующих данных — проверьте тип и значение параметра
Код выполняется без исключений
Ошибка сериализации — в параметрах несериализуемый тип
В табло видны переданные значения на входе в процедуру
Параметр = Неопределено — значение не установлено в вызывающем коде
Передача параметров через структуру: когда много аргументов
Когда у процедуры больше трёх-четырёх параметров, список аргументов становится хрупким: перепутанный порядок даёт трудноотлаживаемые ошибки. Практичное решение — упаковать параметры в структуру:
Функция СоздатьЗаказ(ПараметрыЗаказа)
// ПараметрыЗаказа.Контрагент, ПараметрыЗаказа.ДатаДоставки и т.д.
КонецФункции
Плюсы подхода: порядок не важен, добавление нового параметра не ломает существующие вызовы, вызов читается самодокументированно. Минус — нет контроля типов и обязательности на этапе компиляции, поэтому внутри функции проверяйте наличие ключей через Свойство() и задавайте значения по умолчанию.
Этот же приём используется при передаче параметров в фоновые задания (ФоновыеЗадания.Выполнить принимает массив параметров), при вызове внешних обработок и в механизмах БСП вроде ДлительныеОперации.ВыполнитьВФоне, где параметры процедуры передаются структурой.
Как выбрать способ передачи
Частые ошибки и как их избежать
Первая группа ошибок — несовпадение имён. Ключ структуры при открытии формы, имя параметра запроса, имя свойства в Параметры.Свойство() должны совпадать посимвольно. Встроенный язык нечувствителен к регистру, но чувствителен к опечаткам, а ошибка проявится только в момент выполнения.
Вторая группа — работа с изменяемыми параметрами. Если процедура меняет параметр, переданный по ссылке, вызывающий код получит изменённое значение — это источник неочевидных побочных эффектов. Если изменение не входит в контракт процедуры, объявляйте параметр через Знач.
Третья группа — передача несериализуемых типов между клиентом и сервером. Ошибка «Ошибка передачи данных между клиентом и сервером» почти всегда означает, что в параметрах или возвращаемом значении оказался объект, который платформа не умеет упаковывать. Замените объект ссылкой и пересоздайте его на нужной стороне.
Что важно запомнить
В процедуры параметры передаются списком (Знач — защита от изменений), в формы — структурой через ОткрытьФорму() с чтением в ПриСозданииНаСервере, в запросы — через УстановитьПараметр() до выполнения, результат из формы возвращается оповещением. Между клиентом и сервером передавайте только сериализуемые типы, а при большом числе аргументов упаковывайте их в структуру.
Частые вопросы
Чем передача по значению (Знач) отличается от передачи по ссылке?
При передаче по ссылке процедура работает с той же переменной, что и вызывающий код: её изменения видны снаружи. Ключевое слово Знач создаёт копию — изменения внутри процедуры не затрагивают исходную переменную. Для массивов и структур Знач копирует саму структуру, но вложенные объекты-ссылки остаются общими.
Как передать таблицу значений на клиент?
Напрямую таблица значений на тонком клиенте недоступна. Варианты: хранить её как реквизит формы типа «ТаблицаЗначений» — платформа сама синхронизирует данные; либо преобразовать в массив структур и передать его. Обратно на сервер массив структур собирается в таблицу вручную.
Почему Параметры.ИмяКлюча выдаёт ошибку в форме?
Объект Параметры содержит только те ключи, которые были переданы при открытии, плюс стандартные параметры формы. Обращение к отсутствующему ключу вызывает исключение. Всегда используйте конструкцию «Если Параметры.Свойство("Ключ") Тогда ...» перед чтением значения.
Как передать параметры в фоновое задание?
Метод ФоновыеЗадания.Выполнить(ИмяМетода, Параметры, Ключ, Наименование) принимает массив параметров — элементы массива подставляются в процедуру по порядку. Все значения должны быть сериализуемыми, так как фоновое задание выполняется в отдельном сеансе на сервере. Результат передаётся через помещение данных во временное хранилище.
Можно ли передать параметры в отчёт на СКД?
Да. Параметры компоновки данных задаются через коллекцию Настройки.ПараметрыДанных: находите параметр по имени и устанавливаете Значение и Использование = Истина. В типовых конфигурациях на БСП удобнее использовать КомпоновщикНастроек отчёта и метод УстановитьПараметр пользовательских настроек.
Что делать, если параметров у процедуры очень много?
Объедините их в структуру с понятными именами ключей и передавайте одним аргументом. Это устраняет зависимость от порядка, упрощает добавление новых параметров и делает вызов читаемым. Внутри процедуры проверяйте наличие обязательных ключей и задавайте значения по умолчанию для необязательных.