При разработке сложных отчетов или проведении глубокого анализа данных в платформе 1С:Предприятие разработчики часто сталкиваются с необходимостью фильтрации выборки по конкретным справочникам или планам видов характеристик. В таких случаях стандартные строковые литералы не подходят, так как система должна однозначно идентифицировать объект метаданных, а не просто текст. Именно здесь на сцену выходит предопределенное значение, которое позволяет жестко зафиксировать ссылку на элемент конфигурации непосредственно в теле запроса.
Использование этого механизма критически важно для обеспечения стабильности кода при обновлении конфигураций или переносе баз данных между различными информационными системами. Если вы просто подставите имя элемента в кавычках, запрос может выполнить поиск по наименованию, что приведет к ошибкам при наличии дублей или изменении имен объектов. Синтаксический анализатор языка запросов 1С распознает специальную конструкцию и преобразует её во внутреннее представление ссылки еще до начала выполнения.
Понимание того, как работает предопределенное значение в запросе 1С, является базовым навыком для любого программиста, работающего с СКД (Системой Компоновки Данных) или пишущего прямые текстовые запросы. Ошибки в этой области часто приводят к тому, что отчеты возвращают пустые результаты или, что хуже, выбирают не те данные, которые планировалось получить. В этой статье мы детально разберем синтаксис, особенности компиляции и практические примеры применения данной конструкции.
Синтаксическая конструкция и правила написания
Основное правило, которое необходимо запомнить навсегда: предопределенные значения в тексте запроса всегда заключаются в специальные символы & (амперсанд) в начале и в конце. Это отличает их от параметров запроса, которые также начинаются с амперсанда, но не имеют замыкающего символа, и от обычных строковых констант. Компилятор запросов видит такую конструкцию и понимает, что нужно обратиться к метаданным конфигурации для получения уникального идентификатора объекта.
Формат записи строго регламентирован и зависит от типа объекта, к которому вы обращаетесь. Для справочников, планов счетов или видов расчетов используется прямое указание имени предопределенного элемента. Важно соблюдать регистр символов, так как платформа чувствительна к написанию имен объектов метаданных в некоторых контекстах, хотя в большинстве случаев используется точное совпадение с именем в конфигураторе. Неправильное написание приведет к ошибке компиляции запроса с сообщением о том, что объект не найден.
⚠️ Внимание: Не путайте предопределенные значения с параметрами запроса. Параметр выглядит как&ПараметрДата, а предопределенное значение как&Справочник.Валюты.Рубль&. Лишний или отсутствующий амперсанд в конце полностью меняет логику работы запроса.
Рассмотрим базовую структуру обращения к объектам разных типов. Для справочников путь строится через имя справочника и имя элемента. Для планов счетов добавляется уточнение по счету. Если имя элемента содержит пробелы или специальные символы, его необходимо брать в дополнительные кавычки внутри конструкции, хотя в предопределенных значениях это требуется редко, так как имена обычно задаются программистами без пробелов.
Всегда проверяйте имя предопределенного элемента в конфигураторе (свойство"Имя"), а не используйте то название, которое видит пользователь в интерфейсе. Они могут кардинально отличаться.
Работа со справочниками и планами счетов
Наиболее частый сценарий использования — это фильтрация по валютам, организациям или конкретным статьям затрат, которые являются предопределенными в конфигурации. Например, в типовой конфигурации 1С:Бухгалтерия или 1С:Управление торговлей всегда есть предопределенный элемент"Рубль" в справочнике валют. Чтобы выбрать все документы в этой валюте, вы не должны передавать ссылку из внешнего кода, а можете жестко задать её в запросе.
Синтаксис для справочников выглядит следующим образом: &Справочник.ИмяСправочника.ИмяЭлемента&. Платформа автоматически подставит уникальную ссылку (UUID) этого элемента. Это гарантирует, что даже если в базе будет создано еще сто валют с названием"Рубль" или"USD", запрос выберет данные именно по тому элементу, который был задан разработчиком при создании конфигурации.
Аналогичный подход применяется к планам счетов. Здесь конструкция усложняется добавлением уровня счета. Вы можете обратиться к конкретному счету бухгалтерского учета, например, к счету денежных средств на расчетных счетах. Это позволяет писать универсальные отчеты по оборотно-сальдовой ведомости, не зависящие от того, как пользователь переименовал счета в своей базе, если они остаются предопределенными.
- 🔹 Справочники:
&Справочник.Валюты.Рубль&— выбирает предопределенный элемент валюты. - 🔹 Планы счетов:
&ПланСчетов.Хозрасчетный.51&— обращается к счету 51"Расчетные счета". - 🔹 Планы видов характеристик:
&ПланВидовХарактеристик.ВидыСубконто.Проекты&— используется для аналитики. - 🔹 Перечисления:
&Перечисление.СтатусыДокументов.Проведен&— фильтрация по статусу проведения.
Использование таких конструкций делает код более читаемым и самодокументируемым. Любой разработчик, открывший ваш запрос, сразу поймет, по какому именно объекту идет отбор, без необходимости изучать внешние параметры или код вызова. Это особенно важно в больших проектах, где над системой работают целые команды специалистов.
Использование в условиях отбора (ГДЕ)
Основная область применения предопределенных значений — это секция ГДЕ запроса. Здесь они выступают в роли констант для сравнения. Вы можете сравнивать поле документа с предопределенным значением, проверять вхождение в список или использовать их в логических выражениях. Платформа оптимизирует такие сравнения, превращая их в прямое сравнение уникальных идентификаторов, что обеспечивает высокую скорость выполнения.
Рассмотрим пример, где необходимо отобрать все приходные ордера, созданные в валюте"Рубль". Вместо того чтобы передавать текущую валюту сеанса или параметр отчета, мы жестко фиксируем условие. Это полезно для служебных отчетов, которые должны всегда показывать данные только в национальной валюте, независимо от настроек пользователя.
ВЫБРАТЬ
ПриходныеОрдера.Ссылка КАК Ссылка,
ПриходныеОрдера.Сумма КАК Сумма
ИЗ
Документ.ПриходныйОрден КАК ПриходныеОрдера
ГДЕ
ПриходныеОрдера.Валюта = &Справочник.Валюты.Рубль&
Также предопределенные значения активно используются в операторах В (IN), когда нужно отфильтровать выборку по списку конкретных элементов. Это позволяет избежать создания временных таблиц или сложных объединений для передачи списка значений из внешнего кода. Вы просто перечисляете нужные элементы через запятую внутри скобок.
⚠️ Внимание: Если предопределенный элемент был удален из конфигурации (снят флаг"Предопределенный"), но остался в базе данных, запрос вернет ошибку выполнения. Убедитесь, что объект существует в метаданных текущей версии конфигурации.
Еще один важный нюанс — работа с перечислениями. Часто требуется отобрать документы только с определенным статусом, например,"Проведен" или"ПомеченНаУдаление". Использование предопределенного значения перечисления в условии ГДЕ является самым надежным способом такой фильтрации, так как значения перечислений не меняются пользователем в процессе работы.
☑️ Проверка корректности условия ГДЕ
Отличия от параметров и переменных
Начинающие разработчики часто путают предопределенные значения с параметрами запроса, передаваемыми из кода 1С. Главное отличие заключается в моменте определения значения. Параметр определяется во время выполнения программы (runtime) и может меняться от запуска к запуску. Предопределенное значение определяется на этапе компиляции запроса и жестко привязано к конфигурации.
Когда вы передаете параметр, платформа должна выполнить дополнительное действие по подстановке значения в дерево запроса. В случае с предопределенным значением компилятор сразу заменяет текстовую конструкцию на внутренний идентификатор (GUID). Это делает выполнение запроса с предопределенными значениями теоретически чуть более быстрым, хотя на современных мощностях разница часто незаметна для пользователя.
С точки зрения архитектуры приложения, использование предопределенных значений снижаетность (coupling) кода. Вашему отчету не нужно знать о том, какая ссылка на"Рубль" хранится в текущей базе в переменной. Он сам находит этот элемент по имени. Это упрощает поддержку кода и снижает вероятность ошибок, связанных с передачей неправильных ссылок из вызывающего модуля.
Техническая деталь реализации
Внутри движка запросов предопределенное значение преобразуется в константу типа"Ссылка" или"ПеречислениеСсылка" еще до построения плана выполнения. Поэтому в плане выполнения вы не увидите операции подстановки параметра, только прямое сравнение констант.
Однако есть и ограничения. Вы не можете использовать предопределенное значение динамически. То есть, вы не можете сконструировать имя элемента в переменной и подставить его в запрос. Имя должно быть известно на момент написания кода. Если вам нужна динамика, придется использовать параметры и передавать ссылку из внешнего кода.
Влияние на производительность и оптимизацию
Использование предопределенных значений положительно сказывается на производительности сложных запросов, особенно тех, которые строятся динамически или используются в СКД. Поскольку значение известно заранее, оптимизатор запросов 1С может более эффективно строить план выполнения, учитывая селективность условия. Сравнение по константе (которой по сути является предопределенное значение) всегда работает быстрее, чем сравнение по параметру, значение которого неизвестно до старта.
В больших базах данных с миллионами записей в регистрах накопления или сведений, правильная индексация и использование констант в условиях отбора критически важны. Предопределенное значение позволяет СУБД (SQL Server, PostgreSQL) использовать статистические данные о распределении значений в индексе, так как конкретное значение известно заранее.
| Критерий | Предопределенное значение | Параметр запроса | Строковый литерал |
|---|---|---|---|
| Момент определения | Компиляция запроса | Выполнение запроса | Компиляция запроса |
| Тип данных | Ссылка / Перечисление | Любой поддерживаемый | Строка |
| Зависимость от БД | Зависит от наличия в метаданных | Не зависит | Не зависит |
| Скорость сравнения | Максимальная (по GUID) | Высокая | Низкая (по строке) |
Важно отметить, что злоупотребление предопределенными значениями там, где нужна гибкость, может привести к проблемам. Например, если вы жестко зашьете в отчет отбор по конкретной организации через предопределенное значение, этот отчет станет бесполезным для филиалов или других организаций, не являющихся предопределенными. Баланс между жесткостью и гибкостью — ключ к качественному коду.
Предопределенные значения обеспечивают максимальную производительность и надежность ссылок, но лишают запрос гибкости динамического изменения критериев отбора.
Типичные ошибки и способы их решения
Самая распространенная ошибка — опечатка в имени объекта или элемента. Поскольку проверка синтаксиса происходит в конфигураторе или при первой компиляции, ошибка может проявиться не сразу, если запрос формируется динамически через конкатенацию строк. Всегда используйте автоподстановку в редакторе запросов, чтобы избежать ручного ввода имен.
Вторая частая проблема возникает при обновлении конфигурации. Если разработчик снял галочку"Предопределенный" с элемента справочника, все запросы, использующие конструкцию &...& для этого элемента, перестанут работать. Система выдаст ошибку о том, что предопределенное значение не найдено. Решение — либо вернуть флаг предопределенности, либо переписать запрос на использование параметров.
Третья ошибка связана с типами данных. Попытка сравнить числовое поле с предопределенным значением справочника приведет к ошибке типов. Убедитесь, что поле в таблице, с которым вы сравниваете значение, действительно имеет тип"СправочникСсылка" или соответствующий тип перечисления.
⚠️ Внимание: В некоторых редких случаях, при использовании динамического списка или расширений конфигурации, имена предопределенных элементов могут конфликтовать. Всегда проверяйте уникальность имен в контексте вашей конкретной базы данных.
Также стоит помнить про ограничения на вложенность. Вы не можете использовать предопределенное значение внутри функций преобразования типов напрямую в некоторых версиях платформы без явного приведения. Если возникает ошибка, попробуйте сначала поместить значение в переменную запроса или использовать явное приведение типа.
Используйте обработку"Проверка конфигурации" перед выгрузкой обновления, чтобы найти все места, где используются предопределенные значения удаленных объектов.
Можно ли использовать предопределенное значение в выражениях SELECT?
Да, вы можете выводить предопределенное значение как отдельное поле в результатах запроса. Например, чтобы добавить колонку с валютой"Рубль" ко всем строкам отчета, даже если в исходных данных валюта разная. Синтаксис остается тем же: &Справочник.Валюты.Рубль& КАК ВалютаОтчета.
Что будет, если элемент с таким именем не помечен как предопределенный?
Запрос не скомпилируется. Вы получите сообщение об ошибке:"Не найдено предопределенное значение...". Система требует, чтобы объект имел соответствующий флаг в свойствах метаданных, иначе конструкция с амперсандами считается невалидной.
Как узнать имя предопределенного элемента, если я не знаю его?
Откройте конфигуратор, найдите нужный справочник или план счетов в дереве метаданных. Раскройте ветку"Предопределенные элементы". Имя, указанное в свойстве"Имя" (а не"Синоним"), и нужно использовать в запросе между амперсандами.
Работают ли предопределенные значения в расширении конфигурации?
Да, работают, но с ограничениями. Вы можете обращаться к предопределенным элементам основной конфигурации из расширения. Однако создать новое предопределенное значение в расширении и обратиться к нему по имени из основной конфигурации напрямую через запрос нельзя без специальных механизмов передачи параметров.
Влияет ли язык интерфейса на написание предопределенного значения?
Нет, абсолютно не влияет. Предопределенные значения привязаны к внутренним именам метаданных, которые не зависят от языка интерфейса (русский, английский, казахский и т.д.). Запрос будет работать одинаково на любой языковой версии платформы.