Можно ли использовать оператор Новый внутри выражения для вызова методов через точку?

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

Многие разработчики, имеющие опыт работы с языками программирования вроде C#, Java или JavaScript, часто стремятся перенести привычку «цепочечного» вызова методов (method chaining) в среду 1С. В этих языках вполне естественно написать конструкцию, которая создает объект и тут же вызывает его метод. Однако во встроенном языке 1С попытка написать Результат = (Новый Запрос(Текст)).Выполнить(); приведет к синтаксической ошибке. В этой статье мы подробно разберем, почему это происходит, какие ограничения накладывает платформа и какими способами можно добиться желаемого результата для упрощения кода или быстрой отладки.

Анализируем причину синтаксического ограничения

Для начала выясним причину, по которой привычный подход не работает. В системе 1С:Предприятие 8 оператор Новый не является функцией в строгом понимании этого слова. Это именно оператор создания экземпляра типа. Грамматика встроенного языка построена таким образом, что операция разыменования (обращение к свойствам и методам через точку) может быть применена только к переменным, результатам функций или результатам других операций разыменования.

Рассмотрим стандартную ситуацию. Согласно документации «Руководство разработчика», при работе с оператором Новый (как в конструкторной, так и в функциональной форме) нельзя ставить точку непосредственно после закрывающей скобки конструктора. Платформа ожидает, что созданный объект сначала будет помещен в какую-либо переменную (стек), и только потом к этой переменной будет применено обращение. Таким образом, следующий код является синтаксически некорректным:


// ОШИБКА: Ожидается символ ';'
Результат = (Новый Запрос("ВЫБРАТЬ 1")).Выполнить(); 

Даже использование дополнительных скобок не помогает «обмануть» лексический анализатор 1С, так как он не видит в выражении (Новый ...) объекта, готового к немедленному использованию методов через точку.

Функциональная форма оператора Новый

Разберем подробнее так называемую «функциональную форму» оператора, о которой часто упоминают в документации. Она выглядит следующим образом: Новый(Тип, Параметры). Проанализируем пример, где мы пытаемся создать объект, используя тип как объект метаданных или строку:


// Использование функциональной формы
МассивПараметров = Новый Массив;
МассивПараметров.Добавить("ВЫБРАТЬ 0");
Запрос = Новый("Запрос", МассивПараметров); 
// Здесь точка после скобки также недопустима

Важный технический нюанс: если конструктор объекта принимает только один параметр (например, текст запроса), то в функцию Новый() можно передать само значение. Если же параметров несколько, их необходимо упаковать в Массив. Однако, как бы мы ни вызывали Новый, правило остается прежним: результат должен быть сначала присвоен переменной.

Решение 1: Использование функции Вычислить() для отладки

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


Результат = Вычислить("Новый Запрос(""ВЫБРАТЬ КОНЕЦПЕРИОДА(ДАТАВРЕМЯ(2020, 2, 29), МЕСЯЦ)"")").Выполнить().Выгрузить();

В данном случае функция Вычислить() принимает строку, интерпретирует её и возвращает объект в контекст выражения. Поскольку Вычислить() — это полноценная функция, система позволяет «прицепить» к её результату вызов методов через точку. Это отличный способ для использования в окне «Вычислить выражение», но мы крайне не рекомендуем использовать этот метод в промышленном коде (Production) по следующим причинам:

Решение 2: Создание функций-оберток (Fluent Interface)

Для тех, кто хочет писать элегантный и лаконичный код в рабочих модулях, существует профессиональный способ обхода ограничения — использование вспомогательных функций в общих модулях. Посмотрим на примере, как это реализовано в некоторых библиотеках, включая БСП.

Создадим в общем модуле (например, ОбщегоНазначения) простую функцию-«эхо»:


Функция ВернутьОбъект(Объект) Экспорт
    Возврат Объект;
КонецФункции

Теперь мы можем использовать эту функцию для создания «цепочки» вызовов. Рассмотрим, как изменится наш код:


Текст = "ВЫБРАТЬ 1 КАК Поле";
ТЗ = ОбщегоНазначения.ВернутьОбъект(Новый Запрос(Текст)).Выполнить().Выгрузить();

Проанализируем ситуацию: функция ВернутьОбъект принимает свежесозданный объект Запрос и возвращает его же. С точки зрения синтаксиса 1С, результатом выполнения функции является объект, к которому можно обращаться через точку. Это позволяет избавиться от промежуточных переменных, если они вам действительно не нужны.

Сравнение с COM-соединением

Интересно заметить, что при работе через COM-соединение (например, с другой базой 1С) подобные ограничения отсутствуют. Выясним почему. Рассмотрим пример:


// Работа через COM
КомЗапрос = Соединение.NewObject("Запрос", ТекстЗапроса);
Результат = КомЗапрос.Execute().Unload(); // Здесь цепочка работает!

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

Выводы и рекомендации

Подведем итог нашему исследованию. Использовать оператор Новый внутри выражения с последующим вызовом метода через точку напрямую невозможно. Однако в зависимости от ваших целей можно выбрать один из двух путей:

  1. Для отладки: используйте конструкцию с Вычислить("Новый ..."). Это позволит мгновенно увидеть результат в табло отладчика без модификации рабочего кода.
  2. Для разработки: если вы стремитесь к сокращению кода, создайте универсальную функцию в общем модуле, которая будет возвращать переданный ей объект. Это легальный и безопасный способ реализации «текучего» интерфейса в 1С.

Тем не менее, стоит помнить о «философии» программирования на 1С. Читаемость кода и возможность быстро разобраться в нем другими разработчиками зачастую важнее, чем экономия нескольких строк. Стандартное написание с явным созданием переменной Запрос делает код понятным, упрощает установку параметров и отладку каждого шага выполнения.

← На главную