Разработка и Конфигурация · 12 мин
Амперсанд в 1С: что означает символ & и где он используется
Амперсанд в 1С: что означает символ & в запросах, перед именами переменных и в директивах. Примеры использования, типичные ошибки и ответы на вопросы.
Символ амперсанда (&) в платформе 1С:Предприятие встречается в трёх разных контекстах, и в каждом он означает своё. Чаще всего разработчик видит его в тексте запроса перед именем параметра — например, &Контрагент или &Период. Реже амперсанд появляется в модуле формы как часть директив компиляции &НаКлиенте и &НаСервере, а также в операторе конкатенации строк в некоторых унаследованных решениях.
Путаница возникает из-за того, что один и тот же символ выполняет разные задачи в зависимости от места использования. В запросе амперсанд — это маркер параметра, значение которого подставляется извне. В модуле формы — часть служебной директивы, указывающей, где выполняется код. Понимание этой разницы избавляет от типичных ошибок компиляции и от вопросов «почему запрос не видит мою переменную».
Ниже разобраны все сценарии использования амперсанда в 1С: запросы, директивы форм, виртуальные таблицы, типичные ошибки и способы их диагностики. Материал ориентирован на тех, кто начинает работать с языком запросов 1С и встроенным языком платформы.
Что означает амперсанд в запросе 1С
В языке запросов 1С амперсанд перед идентификатором обозначает параметр запроса. Это именованное место, куда в момент выполнения подставляется конкретное значение — ссылка, дата, число, строка, массив или таблица значений. Сам запрос при этом остаётся неизменным текстом, а значения передаются отдельно через метод УстановитьПараметр().
Типичный фрагмент кода выглядит так:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Продажи.Номенклатура,
| СУММА(Продажи.Количество) КАК Количество
|ИЗ
| РегистрНакопления.Продажи КАК Продажи
|ГДЕ
| Продажи.Период МЕЖДУ &НачалоПериода И &КонецПериода
| И Продажи.Контрагент = &Контрагент
|СГРУППИРОВАТЬ ПО
| Продажи.Номенклатура";
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДатаСеанса()));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекущаяДатаСеанса()));
Запрос.УстановитьПараметр("Контрагент", ВыбранныйКонтрагент);
Результат = Запрос.Выполнить().Выгрузить();
Обратите внимание: в тексте запроса параметр пишется с амперсандом (&Контрагент), а в методе УстановитьПараметр имя указывается без амперсанда — просто строкой «Контрагент». Это одна из самых частых ошибок новичков.
Зачем нужны параметры и почему нельзя подставлять значения напрямую
Технически можно собрать текст запроса конкатенацией строк, вставив значения прямо в текст. Так делать не следует по нескольким причинам. Во-первых, параметризованный запрос защищён от ошибок форматирования: дата, число или ссылка передаются в своём типе, и платформа сама корректно их обрабатывает. При строковой подстановке легко получить неверный литерал — например, дату в неправильном формате.
Во-вторых, параметры позволяют передавать в запрос сложные значения: массивы для условия В (&Список) и таблицы значений для временных таблиц. Подставить массив конкатенацией строк практически невозможно без громоздкого и хрупкого кода.
В-третьих, параметризованные запросы лучше кэшируются механизмами СУБД: текст запроса не меняется, меняются только значения, что положительно влияет на повторное выполнение.
Амперсанд в директивах компиляции форм
Второй контекст — модули управляемых форм. Здесь амперсанд входит в состав директив, которые указывают платформе, где будет скомпилирован и выполнен код:
&НаКлиенте— процедура или функция выполняется на клиенте (тонкий, веб- или толстый клиент);&НаСервере— код выполняется на сервере, контекст формы доступен;&НаСервереБезКонтекста— серверный вызов без передачи данных формы, выполняется быстрее;&НаКлиентеНаСервереБезКонтекста— код компилируется в обоих окружениях, обычно используется в общих модулях форм.
Здесь амперсанд сам по себе ничего не «значит» — это просто синтаксический маркер директивы, аналогичный символу # в директивах препроцессора (#Если Сервер Тогда). Директива ставится на строку непосредственно перед объявлением процедуры или функции.
&НаКлиенте
Процедура РассчитатьСумму(Команда)
Объект.Сумма = Объект.Цена * Объект.Количество;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьЦенуНоменклатуры(Номенклатура)
// серверный код без контекста формы
КонецФункции
Ошибка «Процедура или функция с указанным именем не определена» при вызове серверной процедуры из клиентской часто связана именно с неправильной директивой: например, клиентский код не может напрямую вызвать процедуру с директивой &НаСервере из другого модуля, если та не экспортная.
Параметры виртуальных таблиц
Третий сценарий — параметры виртуальных таблиц регистров. В круглых скобках после имени виртуальной таблицы перечисляются её параметры, и значения для них тоже передаются через амперсанд:
ВЫБРАТЬ
Остатки.Номенклатура,
Остатки.КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК Остатки
Здесь &Период — момент, на который рассчитываются остатки, а &Склад — отбор по измерению. Важно понимать: параметры виртуальной таблицы применяются до выборки данных, поэтому отбор в параметрах работает быстрее, чем то же условие в секции ГДЕ. Это существенно влияет на производительность при больших объёмах данных.
Как передать в параметр массив или таблицу значений
Массив для условия В
Для отбора по списку значений параметру присваивается массив или список значений, а в запросе используется оператор В:
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Родитель В (&СписокГрупп)";
Запрос.УстановитьПараметр("СписокГрупп", МассивГрупп);
Если массив пуст, условие В (&Параметр) не вернёт ни одной записи — это логично, но часто становится неожиданностью. Когда пустой список должен означать «без отбора», добавляйте ветку: ГДЕ &БезОтбора ИЛИ Номенклатура.Родитель В (&СписокГрупп) и передавайте булев параметр.
Таблица значений как временная таблица
Таблицу значений можно передать параметром и поместить во временную таблицу запроса. Для этого нужен менеджер временных таблиц и секция ПОМЕСТИТЬ:
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст =
"ВЫБРАТЬ
| ТЗ.Номенклатура,
| ТЗ.Количество
|ПОМЕСТИТЬ ВТ_Данные
|ИЗ
| &ТаблицаДанных КАК ТЗ";
Запрос.УстановитьПараметр("ТаблицаДанных", ТаблицаЗначений);
Запрос.Выполнить();
После этого временная таблица ВТ_Данные доступна в последующих запросах пакета. Ограничение: колонки таблицы значений должны иметь явно заданные типы, иначе платформа может не построить по ним соединение или выдать ошибку типизации.
- 1Откройте консоль запросов (внешнюю обработку или встроенную в конфигурацию)
- 2Вставьте текст запроса — консоль сама найдёт все параметры по амперсандам
- 3Заполните значения каждого параметра в таблице параметров
- 4Выполните запрос и проверьте результат
- 5Перенесите проверенный текст и установку параметров в модуль
Типичные ошибки при работе с амперсандом
Большинство проблем с амперсандом сводится к нескольким повторяющимся сценариям. Знание их экономит часы отладки.
Отдельная группа ошибок — попытка использовать амперсанд в запросе как оператор конкатенации строк по привычке из других языков (например, из VBA, где & склеивает строки). Во встроенном языке 1С строки соединяются оператором +, а в языке запросов — оператором + или функцией ПОДСТРОКА в сочетании с ним. Амперсанд для конкатенации в 1С не используется.
Ещё одна ловушка — динамическая сборка текста запроса, когда имя параметра формируется в цикле. Если параметр добавлен в текст после того, как запрос уже был подготовлен, или имя не совпадает по регистру/написанию, ошибка проявится только при выполнении. Проверяйте такие запросы в консоли с реальными данными.
Как проверить результат
Все параметры из текста установлены в коде
Ошибка «Переменная не определена» — ищите неустановленный параметр
Тип значения совпадает с типом поля (ссылка к ссылке, дата к дате)
Пустой результат при заведомо существующих данных — проверьте тип параметра
Клиентская процедура вызывается с клиента, серверная — через серверный вызов
«Процедура не определена» — неверная директива или отсутствует Экспорт
Амперсанд в именах и другие граничные случаи
Иногда разработчик встречает амперсанд в неожиданных местах. Например, в текстах макетов и шаблонах СКД параметры также обозначаются амперсандом, а в схеме компоновки данных параметры могут иметь вид &Период с автоматическим созданием при описании в тексте запроса набора данных.
В обычных формах (устаревший механизм) директив компиляции не было — там амперсанд встречается только в запросах. Если вы поддерживаете старую конфигурацию на обычном приложении, весь контекст формы один, и разделения на клиент/сервер в модуле формы нет.
Также стоит помнить, что амперсанд — зарезервированный символ: имя переменной или поля запроса не может начинаться с него, кроме как в роли параметра. Попытка назвать поле выборки &МоеПоле приведёт к тому, что конструктор воспримет его как параметр.
Удобный приём: давайте параметрам говорящие имена с указанием сути (НачалоПериода, СписокСкладов), а не короткие вроде П1 или Пар. В больших запросах с десятком параметров это резко упрощает чтение и отладку, а консоль запросов покажет все параметры списком.
FAQ: частые вопросы об амперсанде в 1С
Что означает & перед словом в тексте запроса 1С?
Это параметр запроса. Значение для него задаётся из кода методом УстановитьПараметр("ИмяБезАмперсанда", Значение). Один и тот же параметр можно использовать в тексте запроса несколько раз — значение подставится везде.
Нужно ли ставить амперсанд в методе УстановитьПараметр?
Нет. В методе УстановитьПараметр имя передаётся строкой без амперсанда: УстановитьПараметр("Контрагент", Значение). Амперсанд с именем приведёт к ошибке — параметр с таким именем в запросе не найдётся.
Чем &НаКлиенте отличается от &НаСервере?
Это директивы компиляции модуля формы. &НаКлиенте выполняется на компьютере пользователя и имеет доступ к интерфейсу, но не к базе данных напрямую. &НаСервере выполняется на сервере, может обращаться к данным, но не к элементам интерфейса напрямую. Вызов сервера из клиентского кода — это сетевое обращение, поэтому частые вызовы стоит объединять.
Можно ли использовать амперсанд для склейки строк в 1С?
Нет. Для конкатенации строк во встроенном языке используется оператор +, а в запросах — также +. Амперсанд в 1С зарезервирован под параметры запросов и директивы компиляции. Привычка из VBA или SQL Server здесь не работает.
Что произойдёт, если не установить параметр запроса?
При выполнении запроса возникнет ошибка вида «Переменная не определена (&ИмяПараметра)». Запрос не выполнится, поэтому все параметры, встречающиеся в тексте, должны быть установлены до вызова Выполнить().
Как передать в запрос список значений через параметр?
Передайте параметру массив или список значений и используйте оператор В: ГДЕ Поле В (&Список). Учтите, что пустой массив даст пустой результат отбора — при необходимости добавляйте отдельный булев параметр-флаг «без отбора».
Что важно запомнить
Амперсанд в 1С имеет два основных смысла: параметр запроса (&Имя, значение задаётся через УстановитьПараметр без символа &) и часть директив компиляции форм (&НаКлиенте, &НаСервере). Для склейки строк амперсанд не используется. Проверяйте соответствие параметров в тексте запроса и в коде — большинство ошибок связано именно с этим.