К статье
Практический материал

Разработка и Конфигурация · 12 мин

Амперсанд в 1С: что означает символ & и где он используется

Амперсанд в 1С: что означает символ & в запросах, перед именами переменных и в директивах. Примеры использования, типичные ошибки и ответы на вопросы.

Символ амперсанда (&) в платформе 1С:Предприятие встречается в трёх разных контекстах, и в каждом он означает своё. Чаще всего разработчик видит его в тексте запроса перед именем параметра — например, &Контрагент или &Период. Реже амперсанд появляется в модуле формы как часть директив компиляции &НаКлиенте и &НаСервере, а также в операторе конкатенации строк в некоторых унаследованных решениях.

Путаница возникает из-за того, что один и тот же символ выполняет разные задачи в зависимости от места использования. В запросе амперсанд — это маркер параметра, значение которого подставляется извне. В модуле формы — часть служебной директивы, указывающей, где выполняется код. Понимание этой разницы избавляет от типичных ошибок компиляции и от вопросов «почему запрос не видит мою переменную».

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

Что означает амперсанд в запросе 1С

В языке запросов 1С амперсанд перед идентификатором обозначает параметр запроса. Это именованное место, куда в момент выполнения подставляется конкретное значение — ссылка, дата, число, строка, массив или таблица значений. Сам запрос при этом остаётся неизменным текстом, а значения передаются отдельно через метод УстановитьПараметр().

Типичный фрагмент кода выглядит так:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Продажи.Номенклатура,

| СУММА(Продажи.Количество) КАК Количество

|ИЗ

| РегистрНакопления.Продажи КАК Продажи

|ГДЕ

| Продажи.Период МЕЖДУ &НачалоПериода И &КонецПериода

| И Продажи.Контрагент = &Контрагент

|СГРУППИРОВАТЬ ПО

| Продажи.Номенклатура";

Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДатаСеанса()));

Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекущаяДатаСеанса()));

Запрос.УстановитьПараметр("Контрагент", ВыбранныйКонтрагент);

Результат = Запрос.Выполнить().Выгрузить();

Обратите внимание: в тексте запроса параметр пишется с амперсандом (&Контрагент), а в методе УстановитьПараметр имя указывается без амперсанда — просто строкой «Контрагент». Это одна из самых частых ошибок новичков.

Зачем нужны параметры и почему нельзя подставлять значения напрямую

Технически можно собрать текст запроса конкатенацией строк, вставив значения прямо в текст. Так делать не следует по нескольким причинам. Во-первых, параметризованный запрос защищён от ошибок форматирования: дата, число или ссылка передаются в своём типе, и платформа сама корректно их обрабатывает. При строковой подстановке легко получить неверный литерал — например, дату в неправильном формате.

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

В-третьих, параметризованные запросы лучше кэшируются механизмами СУБД: текст запроса не меняется, меняются только значения, что положительно влияет на повторное выполнение.

Амперсанд в директивах компиляции форм

Второй контекст — модули управляемых форм. Здесь амперсанд входит в состав директив, которые указывают платформе, где будет скомпилирован и выполнен код:

  • &НаКлиенте — процедура или функция выполняется на клиенте (тонкий, веб- или толстый клиент);
  • &НаСервере — код выполняется на сервере, контекст формы доступен;
  • &НаСервереБезКонтекста — серверный вызов без передачи данных формы, выполняется быстрее;
  • &НаКлиентеНаСервереБезКонтекста — код компилируется в обоих окружениях, обычно используется в общих модулях форм.

Здесь амперсанд сам по себе ничего не «значит» — это просто синтаксический маркер директивы, аналогичный символу # в директивах препроцессора (#Если Сервер Тогда). Директива ставится на строку непосредственно перед объявлением процедуры или функции.

&НаКлиенте

Процедура РассчитатьСумму(Команда)

Объект.Сумма = Объект.Цена * Объект.Количество;

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

&НаСервереБезКонтекста

Функция ПолучитьЦенуНоменклатуры(Номенклатура)

// серверный код без контекста формы

КонецФункции

Ошибка «Процедура или функция с указанным именем не определена» при вызове серверной процедуры из клиентской часто связана именно с неправильной директивой: например, клиентский код не может напрямую вызвать процедуру с директивой &НаСервере из другого модуля, если та не экспортная.

Параметры виртуальных таблиц

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

ВЫБРАТЬ

Остатки.Номенклатура,

Остатки.КоличествоОстаток

ИЗ

РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК Остатки

Здесь &Период — момент, на который рассчитываются остатки, а &Склад — отбор по измерению. Важно понимать: параметры виртуальной таблицы применяются до выборки данных, поэтому отбор в параметрах работает быстрее, чем то же условие в секции ГДЕ. Это существенно влияет на производительность при больших объёмах данных.

Как передать в параметр массив или таблицу значений

Массив для условия В

Для отбора по списку значений параметру присваивается массив или список значений, а в запросе используется оператор В:

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Родитель В (&СписокГрупп)";

Запрос.УстановитьПараметр("СписокГрупп", МассивГрупп);

Если массив пуст, условие В (&Параметр) не вернёт ни одной записи — это логично, но часто становится неожиданностью. Когда пустой список должен означать «без отбора», добавляйте ветку: ГДЕ &БезОтбора ИЛИ Номенклатура.Родитель В (&СписокГрупп) и передавайте булев параметр.

Таблица значений как временная таблица

Таблицу значений можно передать параметром и поместить во временную таблицу запроса. Для этого нужен менеджер временных таблиц и секция ПОМЕСТИТЬ:

Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

Запрос.Текст =

"ВЫБРАТЬ

| ТЗ.Номенклатура,

| ТЗ.Количество

|ПОМЕСТИТЬ ВТ_Данные

|ИЗ

| &ТаблицаДанных КАК ТЗ";

Запрос.УстановитьПараметр("ТаблицаДанных", ТаблицаЗначений);

Запрос.Выполнить();

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

Как проверить параметры запроса
  1. 1
    Откройте консоль запросов (внешнюю обработку или встроенную в конфигурацию)
  2. 2
    Вставьте текст запроса — консоль сама найдёт все параметры по амперсандам
  3. 3
    Заполните значения каждого параметра в таблице параметров
  4. 4
    Выполните запрос и проверьте результат
  5. 5
    Перенесите проверенный текст и установку параметров в модуль

Типичные ошибки при работе с амперсандом

Большинство проблем с амперсандом сводится к нескольким повторяющимся сценариям. Знание их экономит часы отладки.

Типичные ошибки
01
УстановитьПараметр("&Контрагент", ...) с амперсандом в имени — параметр не найдётся, имя указывается без символа &
02
Параметр описан в тексте запроса, но не установлен в коде — получите ошибку «Переменная не определена» при выполнении
03
Опечатка в имени: в запросе &Период, в коде «Переод» — платформа не подскажет, ошибка всплывёт только в рантайме
04
Передача значения несовместимого типа: строка вместо ссылки — условие равенства молча не вернёт записей
05
Передача таблицы значений без типизированных колонок — ошибка при помещении во временную таблицу

Отдельная группа ошибок — попытка использовать амперсанд в запросе как оператор конкатенации строк по привычке из других языков (например, из VBA, где & склеивает строки). Во встроенном языке 1С строки соединяются оператором +, а в языке запросов — оператором + или функцией ПОДСТРОКА в сочетании с ним. Амперсанд для конкатенации в 1С не используется.

Ещё одна ловушка — динамическая сборка текста запроса, когда имя параметра формируется в цикле. Если параметр добавлен в текст после того, как запрос уже был подготовлен, или имя не совпадает по регистру/написанию, ошибка проявится только при выполнении. Проверяйте такие запросы в консоли с реальными данными.

Контрольные точки

Как проверить результат

Запрос выполняется без ошибок
Норма

Все параметры из текста установлены в коде

Тревожный признак

Ошибка «Переменная не определена» — ищите неустановленный параметр

Условие по параметру отбирает записи
Норма

Тип значения совпадает с типом поля (ссылка к ссылке, дата к дате)

Тревожный признак

Пустой результат при заведомо существующих данных — проверьте тип параметра

Директива формы работает
Норма

Клиентская процедура вызывается с клиента, серверная — через серверный вызов

Тревожный признак

«Процедура не определена» — неверная директива или отсутствует Экспорт

Амперсанд в именах и другие граничные случаи

Иногда разработчик встречает амперсанд в неожиданных местах. Например, в текстах макетов и шаблонах СКД параметры также обозначаются амперсандом, а в схеме компоновки данных параметры могут иметь вид &Период с автоматическим созданием при описании в тексте запроса набора данных.

В обычных формах (устаревший механизм) директив компиляции не было — там амперсанд встречается только в запросах. Если вы поддерживаете старую конфигурацию на обычном приложении, весь контекст формы один, и разделения на клиент/сервер в модуле формы нет.

Также стоит помнить, что амперсанд — зарезервированный символ: имя переменной или поля запроса не может начинаться с него, кроме как в роли параметра. Попытка назвать поле выборки &МоеПоле приведёт к тому, что конструктор воспримет его как параметр.

Удобный приём: давайте параметрам говорящие имена с указанием сути (НачалоПериода, СписокСкладов), а не короткие вроде П1 или Пар. В больших запросах с десятком параметров это резко упрощает чтение и отладку, а консоль запросов покажет все параметры списком.
ПЗ
Практическое замечание

FAQ: частые вопросы об амперсанде в 1С

Что означает & перед словом в тексте запроса 1С?

Это параметр запроса. Значение для него задаётся из кода методом УстановитьПараметр("ИмяБезАмперсанда", Значение). Один и тот же параметр можно использовать в тексте запроса несколько раз — значение подставится везде.

Нужно ли ставить амперсанд в методе УстановитьПараметр?

Нет. В методе УстановитьПараметр имя передаётся строкой без амперсанда: УстановитьПараметр("Контрагент", Значение). Амперсанд с именем приведёт к ошибке — параметр с таким именем в запросе не найдётся.

Чем &НаКлиенте отличается от &НаСервере?

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

Можно ли использовать амперсанд для склейки строк в 1С?

Нет. Для конкатенации строк во встроенном языке используется оператор +, а в запросах — также +. Амперсанд в 1С зарезервирован под параметры запросов и директивы компиляции. Привычка из VBA или SQL Server здесь не работает.

Что произойдёт, если не установить параметр запроса?

При выполнении запроса возникнет ошибка вида «Переменная не определена (&ИмяПараметра)». Запрос не выполнится, поэтому все параметры, встречающиеся в тексте, должны быть установлены до вызова Выполнить().

Как передать в запрос список значений через параметр?

Передайте параметру массив или список значений и используйте оператор В: ГДЕ Поле В (&Список). Учтите, что пустой массив даст пустой результат отбора — при необходимости добавляйте отдельный булев параметр-флаг «без отбора».

Итог

Что важно запомнить

Амперсанд в 1С имеет два основных смысла: параметр запроса (&Имя, значение задаётся через УстановитьПараметр без символа &) и часть директив компиляции форм (&НаКлиенте, &НаСервере). Для склейки строк амперсанд не используется. Проверяйте соответствие параметров в тексте запроса и в коде — большинство ошибок связано именно с этим.