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

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

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

Базовая структура и синтаксис запроса

Любой запрос в начинается с ключевого слова ВЫБРАТЬ, за которым следует перечень полей, которые необходимо получить в результат. Далее указывается источник данных через ключевое слово ИЗ. Синтаксис языка 1С имеет русскоязычные ключевые слова, что делает код читаемым, но требует строгого соблюдения порядка следования блоков.

Для фильтрации получаемых данных используется блок ГДЕ. Именно здесь прописываются условия отбора, которые существенно влияют на скорость выполнения. Если вы не укажете условия отбора по периоду или конкретному элементу, система может попытаться выгрузить всю таблицу в оперативную память.

Рассмотрим простой пример получения списка номенклатуры. В этом запросе мы обращаемся к справочнику и выбираем только те позиции, которые помечены как используемые.

ВЫБРАТЬ

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

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

Номенклатура.Артикул

ИЗ

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

ГДЕ

Номенклатура.ЭтоГруппа = ЛОЖЬ

И Номенклатура.ПометкаУдаления = ЛОЖЬ

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

⚠️ Внимание: Никогда не используйте ВЫБРАТЬ * в рабочей конфигурации 1С. Выборка всех полей без разбора создает излишнюю нагрузку на сеть и память, особенно если в таблице есть поля с большими текстами или хранилищами.

💡

Используйте автоподстановку полей в конфигураторе (Ctrl+Space), чтобы избежать опечаток в именах полей и быстро получить список доступных реквизитов таблицы.

Работа с виртуальными таблицами и срезами

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

Срез последних значений позволяет получить актуальное состояние остатков или цен на конкретную дату. Это избавляет разработчика от необходимости писать сложные подзапросы для поиска максимальной даты движения. Синтаксис обращения к таким таблицам имеет специфический вид с параметрами в скобках.

Например, чтобы получить остаток товара на складе на конец дня, используется конструкция РегистрНакопления.ОстаткиТоваров.ОстаткиНа(Дата, Условие). Параметры передаются через точку с запятой. Это мощный механизм, который СУБД оптимизирует автоматически.

ВЫБРАТЬ

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

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

ИЗ

РегистрНакопления.ОстаткиТоваров.ОстаткиНа(

&КонецДня,

Склад = &НашСклад

) КАК Остатки

ГДЕ

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

Использование виртуальных таблиц требует понимания их внутренней логики. Некоторые таблицы, например ИсторияИзменений, могут работать медленно на больших объемах, если не ограничены жесткими условиями отбора. Всегда проверяйте план выполнения запроса в режиме отладки.

Почему виртуальные таблицы быстрее?

Виртуальные таблицы используют заранее построенные индексы и агрегированные данные, хранящиеся в отдельных служебных таблицах, что позволяет СУБД не сканировать весь лог движений, а брать готовый результат.

Соединения таблиц (JOIN) в запросах 1С

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

Внутреннее соединение (ВНУТРЕННЕЕ СОЕДИНЕНИЕ) возвращает только те записи, для которых нашлась пара в обеих таблицах. Если в одной из таблиц нет соответствия, строка исключается из результата. Это самый распространенный тип соединения для отчетов, где нужны только полные данные.

Левое соединение (ЛЕВОЕ СОЕДИНЕНИЕ) возвращает все записи из левой таблицы, даже если для них нет соответствия в правой. В полях правой таблицы в таком случае будет установлено значение NULL (или ПУСТО в терминах 1С). Это полезно, когда нужно найти документы, по которым еще не проведены оплаты.

  • 🔗 ВНУТРЕННЕЕ СОЕДИНЕНИЕ: Только совпадающие записи из обеих таблиц.
  • ⬅️ ЛЕВОЕ СОЕДИНЕНИЕ: Все записи левой таблицы + совпадения правой.
  • ➡️ ПРАВОЕ СОЕДИНЕНИЕ: Все записи правой таблицы + совпадения левой (используется редко).
  • 🔄 ПОЛНОЕ СОЕДИНЕНИЕ: Все записи из обеих таблиц независимо от совпадений.

При построении сложных запросов с тремя и более таблицами порядок соединений может влиять на производительность. Конструктор запросов обычно справляется с оптимизацией, но в спорных случаях стоит экспериментировать с порядком таблиц в блоке ИЗ.

📊 Какой тип соединения вы используете чаще всего?
ВНУТРЕННЕЕ
ЛЕВОЕ
ПРАВОЕ
ПОЛНОЕ

Группировка и агрегатные функции

Для формирования итоговых отчетов недостаточно просто выбрать данные, их нужно сгруппировать. Блок СГРУППИРОВАТЬ ПО определяет, по каким полям строки будут объединены в одну запись результата. Все остальные поля в блоке ВЫБРАТЬ должны быть обернуты в агрегатные функции.

Самые популярные функции — это СУММА, КОЛИЧЕСТВО, МИНИМУМ и МАКСИМУМ. Они позволяют получать обороты, средние цены или количество документов за период. Без правильной группировки запрос вернет ошибку выполнения или некорректные данные.

Рассмотрим пример отчета по продажам менеджеров. Нам нужно сгруппировать данные по менеджеру и посчитать общую сумму продаж.

ВЫБРАТЬ

Продажи.Менеджер,

СУММА(Продажи.Сумма) КАК СуммаПродаж,

КОЛИЧЕСТВО(Продажи.Ссылка) КАК КоличествоЧеков

ИЗ

Документ.ЧекККМ КАК Продажи

ГДЕ

Продажи.Проведен = ИСТИНА

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

Продажи.Менеджер

Также стоит учитывать, что группировка по ссылкам на документы или элементы справочников может быть ресурсоемкой операцией, если не отфильтровать лишние записи заранее.

Функция Описание Тип возвращаемого значения
СУММА Суммирует значения числового поля Число
КОЛИЧЕСТВО Считает количество строк или не NULL значений Число
МИНИМУМ Находит наименьшее значение в группе Тип поля
ЕСТЬNULL Заменяет NULL на указанное значение Тип заменяющего значения

Оптимизация и анализ производительности

Написание работающего запроса — это только половина дела. В высоконагруженных системах 1С критически важна скорость его выполнения. Медленный запрос может "положить" работу всего предприятия в отчетный период. Поэтому анализ производительности должен стать привычкой разработчика.

Основным инструментом анализа является Консоль запросов или режим отладки с включенной технологией исполнения (ТехЖурнал). Они позволяют увидеть время выполнения, количество прочитанных строк и используемые индексы. Если запрос выполняется дольше 1-2 секунд на небольшой базе, это повод для рефакторинга.

Частой ошибкой является использование функций в условиях отбора блока ГДЕ. Например, вызов ГОД(Период) или ЛЕВЫЙ(Код, 3) внутри условия запрещает СУБД использовать индекс по этому полю. Это приводит к полному сканированию таблицы (Table Scan), что крайне медленно.

⚠️ Внимание: Избегайте конструкций вида ГДЕ Поле = ? + 1 или использования функций над полем в условии. Это ломает использование индексов и замедляет выборку в десятки раз на больших объемах данных.

Для оптимизации старайтесь сужать область выборки как можно раньше. Фильтры по дате и организации должны стоять в самом начале условия ГДЕ. Также полезно использовать временные таблицы для промежуточных результатов, если основной запрос получается слишком громоздким.

💡

Золотое правило оптимизации: Сначала отфильтруйте данные по самым селективным полям (дата, организация), и только потом выполняйте соединения и группировки.

Типичные ошибки и способы их решения

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

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

Другая частая ошибка связана с типами данных. Попытка сравнить строку с числом или дату со строкой без явного приведения типов может привести к непредсказуемым результатам или ошибкам выполнения. Всегда проверяйте типы параметров, передаваемых в запрос.

  • Отсутствие индексов: Запрос по неуникальному полю без индекса работает медленно.
  • Выборка лишних полей: Чтение больших текстовых полей, которые не используются в отчете.
  • Запросы в цикле: Выполнение запроса внутри цикла по таблице значений вместо одного общего запроса.

Исправление этих ошибок часто требует переписывания логики программы. Вместо цикла с запросами следует формировать таблицу значений параметров и передавать её в один большой запрос. Это кардинально меняет архитектуру взаимодействия с базой данных.

☑️ Проверка качества запроса

Выполнено: 0 / 1

Практические примеры сложных выборок

В реальной работе редко встречаются простые выборки из одной таблицы. Чаще всего требуется построить аналитику, сопоставляющую планы и факты, или получить иерархическую структуру данных. Рассмотрим пример запроса с вложенным подзапросом.

Подзапросы позволяют выполнять выборку внутри условия ГДЕ или в блоке ВЫБРАТЬ. Это мощный инструмент, но его следует использовать с осторожностью, так как некоторые СУБД выполняют подзапросы для каждой строки внешнего запроса, что снижает производительность.

ВЫБРАТЬ

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

(ВЫБРАТЬ

СУММА(Движения.Количество)

ИЗ

РегистрНакопления.Продажи.Обороты

КАК Движения

ГДЕ

Движения.Номенклатура = Номенклатура.Ссылка

) КАК ОбщийОборот

ИЗ

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

ГДЕ

Номенклатура.Родитель = &ВыбраннаяГруппа

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

Помните, что возможности языка запросов 1С постоянно расширяются с выходом новых версий платформы. Следите за обновлениями и изучайте новые функции, такие как полнотекстовый поиск или работа с JSON внутри запроса, чтобы писать современный и эффективный код.

Можно ли использовать переменные в тексте запроса?

Да, в 1С параметры запроса обозначаются знаком амперсанда (&), например &ДатаНачала. Значения этим параметрам присваиваются через метод УстановитьПараметр объекта запроса перед выполнением.

В чем разница между Временной таблицей и Таблицей значений?

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

Почему запрос выполняется долго только у некоторых пользователей?

Это может быть связано с блокировками данных (локами), которые устанавливают другие пользователи в момент выполнения отчета, или с различиями в правах доступа (RLS), которые усложняют план выполнения запроса.

Как отладить запрос, который выдает ошибку синтаксиса?

Скопируйте текст запроса из кода и вставьте его в внешнюю обработку "Консоль запросов". Она подсветит строку с ошибкой и позволит проверить выполнение на актуальных данных базы без компиляции модуля.