Введение: Суть вопроса
Представим ситуацию, когда разработчик 1С сталкивается с нестандартным подходом к написанию запросов, который выглядит компактно, но вызывает вопросы о его целесообразности. Например, можно встретить такой синтаксис:
Выборка = НовыйЗапрос("Выбрать А а, В в, Г г
|Из Справочник.УУУ
|Где Усл1 и Усл2 и Усл3",
Новый Структура("Парам", Парам)).Выполнить().Выбрать();
У нас возникает закономерный вопрос: действительно ли такой подход дает какие-либо преимущества? Ускоряет ли он написание кода, улучшает читаемость или имеет другие неочевидные плюсы? Давайте разберем эту ситуацию подробнее, опираясь на мнения опытных разработчиков и стандарты платформы 1С:Предприятие.
Прежде чем анализировать нестандартный синтаксис, рассмотрим, как рекомендуется и принято работать с запросами в 1С:Предприятие. Стандартный подход обеспечивает высокую читаемость, удобство отладки и соответствие официальным стандартам разработки.
Создание объекта Запрос. Мы начинаем с создания нового экземпляра объекта Запрос.
Запрос = Новый Запрос;
Установка текста запроса. Далее мы присваиваем тексту запроса соответствующее свойство объекта Запрос. Важно использовать многострочные литералы для улучшения читаемости сложных запросов.
Запрос.Текст =
"ВЫБРАТЬ
| СправочникУУУ.А КАК А,
| СправочникУУУ.В КАК В,
| СправочникУУУ.Г КАК Г
|ИЗ
| Справочник.УУУ КАК СправочникУУУ
|ГДЕ
| СправочникУУУ.Поле1 = &Парам1
| И СправочникУУУ.Поле2 = &Парам2";
Установка параметров запроса. Для передачи значений в запрос мы обязательно используем метод УстановитьПараметр(). Этот подход обеспечивает безопасность (предотвращает потенциальные инъекции, хотя в 1С это менее критично, чем в SQL) и правильную работу механизма кэширования запросов, что влияет на производительность.
Запрос.УстановитьПараметр("Парам1", ЗначениеПараметра1);
Запрос.УстановитьПараметр("Парам2", ЗначениеПараметра2);
Выполнение запроса и получение результатов. После настройки запроса мы выполняем его методом Выполнить(), а затем получаем выборку или таблицу значений с помощью Выбрать() или Выгрузить().
Выборка = Запрос.Выполнить().Выбрать();
Прежде всего, важно понять, что конструкция НовыйЗапрос(...), показанная в сообщении автора, не является стандартным конструктором объекта Запрос в 1С:Предприятие. Как выяснилось в ходе обсуждения на форуме (сообщения 9, 10, 13), это пользовательская функция-обертка, которую кто-то написал для инкапсуляции стандартных шагов.
Такие обертки иногда создаются разработчиками, привыкшими к другим языкам программирования, где популярны паттерны функционального программирования или цепочечные API (например, в Java, JavaScript, C# с LINQ). Они стремятся привнести этот "элегантный" и "компактный" стиль в разработку на 1С.
Основываясь на мнениях участников форума (сообщения 25, 31) и общих тенденциях в программировании, можно выделить несколько потенциальных "плюсов" такого подхода:
Скорость написания для некоторых разработчиков. Для тех, кто привык к функциональному стилю и цепочкам вызовов, написание всего в одну строку может казаться быстрее и удобнее. Это субъективный фактор, но он имеет место быть.
Компактность кода. В простых случаях, когда запрос очень короткий и имеет всего один-два параметра, вся конструкция помещается в одну строку, что выглядит более "компактно" (сообщение 31).
"Эстетическое" удовольствие. Некоторые разработчики находят такой стиль более "элегантным" или "красивым" из-за его схожести с функциональными паттернами, характерными для других языков (сообщения 10, 17, 21, 23).
Однако подавляющее большинство разработчиков на форуме категорически высказались против такого синтаксиса, указывая на множество критических недостатков. Давайте их перечислим:
Критическое снижение читаемости и сопровождаемости кода. Это главный и самый часто упоминаемый минус (сообщение 38). Даже в приведенном примере, когда запрос удлиняется или появляются более сложные условия, одна длинная строка становится "портянкой", которую крайне сложно читать, понимать и анализировать. Представьте, если запрос будет занимать не 4, а 40 строк (сообщение 42) — это делает код практически неразбираемым.
Нарушение стандартов 1С. "Система стандартов и методик разработки конфигураций для платформы 1С:Предприятие 8" (доступная на ИТС) прямо или косвенно осуждает подобные конструкции (сообщения 5, 6, 13, 43, 53). Отклонение от стандартов ведет к неоднородности кодовой базы, проблемам при работе в команде и сложностям при интеграции с типовыми решениями.
Проблемы с отладкой и рефакторингом. Отлаживать код, где вся логика запроса, его параметры, выполнение и получение результата свернуты в одну строку пользовательской функции, становится крайне трудно. Изменение или доработка такого запроса требует разворачивания всей этой логики, что увеличивает время на поддержку.
Отсутствие поддержки стандартными инструментами. Мощный "Конструктор запросов" в 1С:Предприятие, который является незаменимым инструментом для создания и анализа запросов, не сможет работать с таким нестандартным вызовом. Это лишает разработчика удобства визуальной отладки и построения запросов.
Проблемы при сравнении версий (diff). Очень длинные строки кода (сообщение 16) значительно усложняют анализ изменений при использовании систем контроля версий (например, Git) и инструментов для сравнения файлов. Любое, даже минимальное изменение в запросе может привести к изменению всей строки, делая диффы неинформативными.
Потенциальный "говнокодинг". В профессиональной среде такой подход, без должного обоснования и при ухудшении читаемости, часто расценивается как низкокачественное программирование (сообщение 43).
Ограниченность при динамическом формировании запросов. Если запрос должен динамически меняться в зависимости от условий, то передача всего текста запроса одной строкой в пользовательскую функцию сильно усложнит эту задачу. Придется использовать строковые операции, что увеличит вероятность ошибок.
Чтобы избежать описанных выше проблем и писать качественный, сопровождаемый код, мы рекомендуем придерживаться следующих практик:
Всегда используйте описанную выше стандартную схему работы с запросами: создайте объект Запрос, присвойте текст свойству Текст, установите параметры через УстановитьПараметр() и затем выполните запрос. Это золотой стандарт разработки на 1С.
// Пример правильного использования
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Номенклатура,
| ТоварыНаСкладахОстатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(
| &Дата,
| Склад = &ОсновнойСклад
| ) КАК ТоварыНаСкладахОстатки";
Запрос.УстановитьПараметр("Дата", ТекущаяДата());
Запрос.УстановитьПараметр("ОсновнойСклад", Справочники.Склады.НайтиПоНаименованию("Основной склад"));
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныхЗаписей = РезультатЗапроса.Выбрать();
СтрШаблон() для динамических запросовЕсли вам необходимо динамически формировать части запроса (например, список полей, условий или временных таблиц), используйте функцию СтрШаблон(). Она позволяет создавать шаблон строки с заполнителями и затем подставлять в них значения. Это гораздо более читабельно и безопасно, чем конкатенация строк или СтрЗаменить() для сложных случаев (сообщение 54).
ИменаПолей = "Номенклатура.Наименование КАК Товар,
|КоличествоОстаток КАК Остаток";
УсловияОтбора = "ГДЕ Склад = &Склад";
ТекстЗапросаШаблон =
"ВЫБРАТЬ
| %1
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки() КАК ТоварыНаСкладахОстатки
|%2";
ТекстЗапроса = СтрШаблон(ТекстЗапросаШаблон, ИменаПолей, УсловияОтбора);
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Склад", Справочники.Склады.НайтиПоНаименованию("Розничный склад"));
Выборка = Запрос.Выполнить().Выбрать();
СтрЗаменить()Хотя СтрШаблон() предпочтительнее для многих динамических задач, СтрЗаменить() все еще может быть полезен в специфических ситуациях. Например, для замены небольших, простых фрагментов текста, которые не являются параметрами. Как упомянуто на форуме (сообщение 55), некоторые разработчики используют СтрЗаменить() для создания "запросов-болванок", которые потом корректно открываются в конструкторе запросов 1С. Однако для передачи значений и сложных динамических вставок всегда выбирайте УстановитьПараметр() и СтрШаблон() соответственно.
Всегда форматируйте текст запроса, используя переносы строк и отступы, чтобы он был легко читаем. Каждое ключевое слово (ВЫБРАТЬ, ИЗ, ГДЕ, СОЕДИНЕНИЕ) и каждое поле или условие должны быть на новой строке с соответствующим отступом. Это значительно улучшает читаемость и облегчает поиск ошибок.
Для сложных запросов или повторяющихся операций с запросами мы рекомендуем разделять логику: выносите формирование текста запроса, установку параметров, выполнение и обработку результатов в отдельные процедуры или функции. Это делает код более модульным, тестируемым и легким для понимания (сообщение 46).
Несмотря на кажущуюся "красоту" или "компактность" нестандартного синтаксиса с использованием пользовательских функций-оберток, такой подход имеет гораздо больше минусов, чем плюсов. Он ведет к снижению читаемости, усложнению поддержки и отладки, а также противоречит устоявшимся стандартам разработки на платформе 1С:Предприятие.
Мы настоятельно рекомендуем придерживаться стандартных методов работы с запросами, использовать УстановитьПараметр() для передачи данных, СтрШаблон() для динамического формирования текста и всегда уделять внимание форматированию и структурированию кода. Такой подход обеспечит стабильность, производительность и легкость сопровождения ваших решений на долгие годы.