Как исправить синтаксическую ошибку при добавлении новой колонки в запрос печатной формы 1С?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей IT и автоматизация бизнеса
← На главную

При доработке внешних печатных форм часто возникает задача вывести дополнительный реквизит документа или номенклатуры — например, артикул, примечание или код по классификатору (ТН ВЭД / УКТВЭД). Однако даже простое добавление поля в текст запроса может привести к ошибке времени выполнения вида Синтаксическая ошибка при вызове метода Выполнить(). Проанализируем типичные причины таких ошибок, разберем поведение парсера запросов 1С и пошагово восстановим корректную работу печатной формы.

Почему возникает синтаксическая ошибка при добавлении поля

Платформа 1С:Предприятие при разборе текста запроса жестко контролирует синтаксис списков выборки. Выясним причину, почему ошибка указывает на корректно написанное имя поля (например, >КодУКТВЭД):

  1. Пропущенная запятая между полями. В языке запросов 1С допускается назначение псевдонима полю как с ключевым словом КАК, так и простым пробелом: конструкция вида Сумма ИмяПоля синтаксически корректна и означает назначение полю Сумма псевдонима ИмяПоля. Если разработчик забывает поставить запятую между двумя выражениями, компилятор считает следующее слово псевдонимом текущего поля, а сбой происходит на следующем за ним операторе или запятой.
  2. Ошибки динамической склейки строк. Если в тексте запроса используются переменные (например, "+ ТекстКодАртикул + "), отсутствие пробелов перед или после кавычек приводит к слипанию ключевых слов или идентификаторов реквизитов.
  3. Несоответствие колонок при объединении таблиц. При использовании конструкции ОБЪЕДИНИТЬ ВСЕ количество полей, их порядок и типы во всех объединяемых блоках ВЫБРАТЬ должны строго совпадать. Если поле добавлено в секцию Товары, но отсутствует в секции Услуги, запрос завершится аварийно.
  4. Нарушение правил группировки. Если в запросе присутствует секция СГРУППИРОВАТЬ ПО, все неагрегированные поля из списка ВЫБРАТЬ обязаны присутствовать в секции группировки.

Пошаговый разбор исправления текста запроса

Рассмотрим фрагмент исходного запроса, в котором возникла ошибка. Обратим внимание на блок формирования полей табличной части до исправления:


|ВЫБРАТЬ
|   НомерСтроки КАК НомерСтрокиТЧ,
|   Номенклатура,
|   ВЫРАЗИТЬ(Номенклатура.НаименованиеПолное КАК СТРОКА(1000)) КАК Товар,
|   Номенклатура.Код КАК Код,
|   Номенклатура."+ ТекстКодАртикул + " КАК КодАртикул,
|   Количество,
|   Номенклатура.ЕдиницаХраненияОстатков.Представление КАК ЕдиницаЦены,
|   Цена,
|   Сумма
|   ДопПрим,
|   КодУКТВЭД

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

Посмотрим на корректный текст запроса, объединяющий табличные части товаров и услуг с учетом группировок:


Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ТекущийДокумент", СсылкаНаОбъект);

Запрос.Текст = 
"ВЫБРАТЬ
|   ВложенныйЗапрос.НомерТЧ,
|   ВложенныйЗапрос.НомерСтрокиТЧ,
|   ВложенныйЗапрос.Номенклатура,
|   ВЫРАЗИТЬ(ВложенныйЗапрос.Номенклатура.НаименованиеПолное КАК СТРОКА(1000)) КАК Товар,
|   ВложенныйЗапрос.Номенклатура.Код КАК Код,
|   ВложенныйЗапрос.Номенклатура." + ТекстКодАртикул + " КАК КодАртикул,
|   ВложенныйЗапрос.Количество,
|   ВложенныйЗапрос.КоличествоМест,
|   ВложенныйЗапрос.ЕдиницаЦены.Представление КАК ЕдиницаЦены,
|   ВложенныйЗапрос.ЕдиницаМест.Представление КАК ЕдиницаМест,
|   ВложенныйЗапрос.ПроцентСкидкиНаценки КАК Скидка,
|   ВложенныйЗапрос.ПроцентАвтоматическихСкидок КАК АвтоматическаяСкидка,
|   ВложенныйЗапрос.Цена,
|   ВложенныйЗапрос.Сумма,
|   ВложенныйЗапрос.СуммаНДС,
|   ВложенныйЗапрос.ДопПрим,
|   ВложенныйЗапрос.КодУКТВЭД,
|   ВложенныйЗапрос.Характеристика,
|   NULL КАК Серия
|ИЗ
|   (ВЫБРАТЬ
|       1 КАК НомерТЧ,
|       МИНИМУМ(СчетНаОплатуПокупателю.НомерСтроки) КАК НомерСтрокиТЧ,
|       СчетНаОплатуПокупателю.Номенклатура КАК Номенклатура,
|       СчетНаОплатуПокупателю.ЕдиницаИзмерения КАК ЕдиницаЦены,
|       СчетНаОплатуПокупателю.ЕдиницаИзмеренияМест КАК ЕдиницаМест,
|       СчетНаОплатуПокупателю.ПроцентСкидкиНаценки КАК ПроцентСкидкиНаценки,
|       СчетНаОплатуПокупателю.ПроцентАвтоматическихСкидок КАК ПроцентАвтоматическихСкидок,
|       СчетНаОплатуПокупателю.Цена КАК Цена,
|       СУММА(СчетНаОплатуПокупателю.Количество) КАК Количество,
|       СУММА(СчетНаОплатуПокупателю.КоличествоМест) КАК КоличествоМест,
|       СУММА(СчетНаОплатуПокупателю.Сумма) КАК Сумма,
|       СУММА(СчетНаОплатуПокупателю.СуммаНДС) КАК СуммаНДС,
|       СчетНаОплатуПокупателю.ДопПрим КАК ДопПрим,
|       СчетНаОплатуПокупателю.КодУКТВЭД КАК КодУКТВЭД,
|       СчетНаОплатуПокупателю.ХарактеристикаНоменклатуры КАК Характеристика
|   ИЗ
|       Документ.СчетНаОплатуПокупателю.Товары КАК СчетНаОплатуПокупателю
|   ГДЕ
|       СчетНаОплатуПокупателю.Ссылка = &ТекущийДокумент
|   СГРУППИРОВАТЬ ПО
|       СчетНаОплатуПокупателю.Номенклатура,
|       СчетНаОплатуПокупателю.ЕдиницаИзмерения,
|       СчетНаОплатуПокупателю.ЕдиницаИзмеренияМест,
|       СчетНаОплатуПокупателю.ПроцентСкидкиНаценки,
|       СчетНаОплатуПокупателю.ПроцентАвтоматическихСкидок,
|       СчетНаОплатуПокупателю.Цена,
|       СчетНаОплатуПокупателю.ДопПрим,
|       СчетНаОплатуПокупателю.КодУКТВЭД,
|       СчетНаОплатуПокупателю.ХарактеристикаНоменклатуры) КАК ВложенныйЗапрос
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|   2,
|   СчетНаОплатуПокупателю.НомерСтроки,
|   ВЫРАЗИТЬ(СчетНаОплатуПокупателю.Содержание КАК СТРОКА(1000)),
|   ВЫРАЗИТЬ(СчетНаОплатуПокупателю.Содержание КАК СТРОКА(1000)),
|   СчетНаОплатуПокупателю.Номенклатура.Код,
|   СчетНаОплатуПокупателю.Номенклатура." + ТекстКодАртикул + ",
|   СчетНаОплатуПокупателю.Количество,
|   NULL,
|   СчетНаОплатуПокупателю.Номенклатура.ЕдиницаХраненияОстатков,
|   NULL,
|   СчетНаОплатуПокупателю.ПроцентСкидкиНаценки,
|   0,
|   СчетНаОплатуПокупателю.Цена,
|   СчетНаОплатуПокупателю.Сумма,
|   СчетНаОплатуПокупателю.СуммаНДС,
|   СчетНаОплатуПокупателю.ДопПрим,
|   СчетНаОплатуПокупателю.КодУКТВЭД,
|   NULL,
|   NULL
|ИЗ
|   Документ.СчетНаОплатуПокупателю.Услуги КАК СчетНаОплатуПокупателю
|ГДЕ
|   СчетНаОплатуПокупателю.Ссылка = &ТекущийДокумент
|
|УПОРЯДОЧИТЬ ПО
|   НомерТЧ,
|   НомерСтрокиТЧ";

Особенности работы с полями классификаторов

Разберем важные нюансы, с которыми можно столкнуться при выводе кодов классификаторов (ТН ВЭД, УКТВЭД) в табличный документ:

  1. Тип реквизита. Если поле КодУКТВЭД имеет тип ссылки (например, СправочникСсылка.КлассификаторУКТВЭД), то при прямом выводе в ячейку макета отобразится строковое представление элемента (обычно наименование). Чтобы вывести сам цифровой код, в тексте запроса следует явно обращаться к реквизиту: СчетНаОплатуПокупателю.КодУКТВЭД.Код КАК КодУКТВЭД либо использовать функцию ПРЕДСТАВЛЕНИЕ().
  2. Отсутствие реквизита в табличной части услуг. Если в табличной части Услуги классификатор не ведется, вместо обращения к несуществующему полю во второй ветке объединения необходимо передавать пустое значение соответствующего типа:
    
    "" КАК КодУКТВЭД // если реквизит выбирается строкой
    ЗНАЧЕНИЕ(Справочник.КлассификаторУКТВЭД.ПустаяСсылка) // если реквизит ссылочный
    
  3. Синхронизация с макетом. После успешного выполнения запроса убедимся, что в макете печатной формы в области строки добавлена ячейка со свойством Заполнение = Параметр и именем КодУКТВЭД. Если в модуле заполнение выполняется методом ОбластьСтрока.Параметры.Заполнить(ВыборкаСтрок), имена полей выборки запроса и параметров макета должны полностью совпадать. Не забудем также расширить области заголовка таблицы и подвала, чтобы не нарушить сетку документа.

Рекомендации по отладке сложных запросов

Чтобы избежать подобных ошибок в дальнейшем, используем следующие приемы разработки:

  1. Проверка через Конструктор запроса. Любой запрос с объединениями и вложенными таблицами перед запуском стоит открывать через контекстное меню в Конструкторе запроса платформы. Конструктор автоматически отслеживает синтаксические конструкции, проверяет расстановку запятых и соответствие полей группировки. Если в тексте есть синтаксическая ошибка, конструктор сразу укажет строку с некорректным выражением.
  2. Отладка сформированного текста. Если запрос формируется с динамической подстановкой переменных (как в случае с ТекстКодАртикул), перед выполнением установим точку останова, скопируем итоговую строку из Запрос.Текст через табло отладчика и проверим ее выполнение во внешней консоли запросов.
← На главную