«Значение» в 1С: слово из запроса, параметр процедуры и тип данных

· 9 мин

Содержание

Многие ищут в справке отдельный тип данных «Значение» и не находят. Такого типа в языке 1С нет. Слово «Значение» встречается в трёх разных ролях, и из-за этого путаница: функция Значение() в тексте запроса, ключевое слово Знач в параметрах процедур и «значение» как общее название любых данных в переменной.

Если коротко: в запросе Значение(...) подставляет в условие предопределённый элемент или перечисление. В коде у любой переменной есть значение и тип, а тип проверяют через ТипЗнч(). Ниже по очереди разберём, где что работает и где чаще ошибаются.

Что называют типом «Значение» и где проходят границы

Язык 1С динамически типизирован. Переменная может хранить число, строку, ссылку на документ, структуру или Неопределено. Универсального контейнера под названием «Значение» нет, зато есть «произвольное значение»: так в описании типов реквизита называют допустимость любого типа.

Три значения слова, которые путают:

  • 🔹 Функция Значение() в запросе. Работает только внутри текста запроса и берёт элемент перечисления или предопределённые данные.
  • 🔹 Модификатор Знач в заголовке процедуры. Говорит, что параметр передан по значению, а не по ссылке.
  • 🔹 Значение переменной. То, что лежит в ней в данный момент. У него есть тип, и он меняется по ходу выполнения.

Граница контекста простая. Значение() нельзя вызвать в обычном коде модуля: там вместо него пишут Перечисления.ВидыНоменклатуры.Товар или Справочники.Валюты.Рубль. Обратная сторона: обращение через точку не работает внутри текста запроса.

Если видите «Значение» в списке типов в конструкторе запроса, это подсказка для вставки функции Значение(), а не отдельный тип.

Как создавать и менять значения в коде

В коде значение появляется тремя способами: присвоили литерал, получили из объекта или создали объект коллекции. Самые частые контейнеры для группы значений:

КонтейнерКогда братьЧто учесть
СтруктураФиксированный набор именованных полейКлюч должен быть допустимым идентификатором
СоответствиеПроизвольные ключи, быстрый поискПорядок обхода не гарантирован
МассивЗначений/МассивПростой списокИндексы с нуля
СписокЗначенийНужен выбор в формеХранит значение и представление
ТаблицаЗначенийМного строк с колонкамиКолонки с типами ускоряют поиск
ХранилищеЗначенияПоложить объект в реквизит базыЧитается только через Получить()

Пример: собираем параметры отбора в структуру и передаём в процедуру.

Отбор = Новый Структура;
Отбор.Вставить("Организация", Организация);
Отбор.Вставить("Период", НачалоМесяца(ТекущаяДата()));

Результат = ПолучитьДанные(Отбор);

Передача в процедуру: Знач и ссылка

По умолчанию параметр процедуры передаётся по ссылке. Изменили его внутри — изменился и внешний объект. Слово Знач отключает это поведение.

Процедура Обработать(Знач Строка, Таблица)
    Строка = СокрЛП(Строка);   // снаружи строка не изменится
    Таблица.Очистить();         // таблица снаружи очистится
КонецПроцедуры

Тонкость: для объектов-коллекций Знач копирует только ссылку. Содержимое таблицы или структуры всё равно можно испортить. Настоящую копию делают явно: Таблица.Скопировать() или ФиксированнаяСтруктура.

Не путайте Знач с копированием объекта. Для таблицы значений это копия указателя, а не данных.

Значения в запросах и параметрах

В запросе значение попадает двумя путями: через Значение() внутри текста и через параметр &Имя. Отличие в том, что Значение() фиксируется при написании запроса, а параметр подставляется при выполнении.

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|   Номенклатура.Ссылка
|ИЗ
|   Справочник.Номенклатура КАК Номенклатура
|ГДЕ
|   Номенклатура.ВидНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ВидыНоменклатуры.Товар)
|   И Номенклатура.Родитель = &Группа";
Запрос.УстановитьПараметр("Группа", Группа);
Выборка = Запрос.Выполнить().Выбрать();

Что выбрать:

  1. Перечисление, предопределённый элемент, Неопределено, Истина — пишите через Значение(). Запрос читается проще, а платформа заранее знает тип.
  2. Всё, что приходит из формы, отбора или расчёта, — через параметр.
  3. Список значений для В (&Список) передавайте массивом или таблицей значений. Склеивать идентификаторы в строку не нужно.

Пустые ссылки пишут как Значение(Справочник.Контрагенты.ПустаяСсылка). Отдельная тема — NULL. Он появляется при левом соединении, когда для строки нет пары. Сравнение Поле = NULL не сработает, нужны ПОЛЕ ЕСТЬ NULL или функция ЕСТЬNULL(Поле, 0).

Составные типы и сравнение в условии

Если поле имеет составной тип (например, регистратор), сравнивать его с конкретным значением лучше через ССЫЛКА. Условие Регистратор ССЫЛКА Документ.РасходнаяНакладная отбирает только документы нужного вида и не ломается на других типах.

Для перечислений удобно В (ЗНАЧЕНИЕ(...), ЗНАЧЕНИЕ(...)): так в условии помещается несколько значений без цепочки ИЛИ. Для дат и чисел используйте параметры с явным типом. Например, дата без времени и дата с временем сравниваются по-разному, и граница периода может «потерять» последний день.

Любое Значение() с опечаткой в имени перечисления ловится только при выполнении. Откройте конструктор запроса и вставьте значение кнопкой: так имя не ошибётся.

«Буфер значений» и производительность

Термина «буфер значений» в платформе нет. Если вы встретили его в статьях, обычно под ним имеют в виду одно из трёх: кэш обращений к реквизитам, повторно используемые модули или временное хранилище данных формы. Разберём настоящие механизмы.

  • ⚡ Модуль с повторным использованием возвращаемых значений. Результат функции запоминается на время сеанса или вызова. Годится для справочных данных, которые редко меняются.
  • ⚡ Временные таблицы запроса. Данные загружаются один раз и используются в нескольких запросах пакета.
  • ⚡ Временное хранилище. Данные кладут по адресу, например перед открытием формы, и забирают по этому адресу.
  • ⚡ Кэш в глобальной переменной модуля управляемого приложения. Простой вариант для настроек, но не для данных, которые могут меняться у других пользователей.

Что стоит знать про скорость самого кода:

  • Обращение к реквизиту через ссылку (Ссылка.Реквизит) каждый раз идёт в базу. В цикле на тысячу строк это тысяча запросов. Читайте нужные поля одним запросом.
  • ТаблицаЗначений.Найти() по колонке без индекса перебирает всё. Для частого поиска используйте Соответствие или Индексы колонок.
  • Крупные объекты в ХранилищеЗначения сжимаются и читаются целиком. Для частых выборок они неудобны.

Когда значение хранят не в коде, а в данных

Иногда задача выглядит как «положить значение куда-то до следующего запуска». Вариантов несколько, и выбирают их по сроку жизни:

  • на время работы формы — реквизит формы или временное хранилище;
  • на время сеанса — параметр сеанса или переменная модуля;
  • на постоянной основе — константа, регистр сведений или хранилище настроек пользователя.

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

Типизация и проверка содержимого

Тип значения проверяют функциями ТипЗнч() и Тип(). Первая возвращает тип конкретного значения, вторая создаёт описание типа по имени.

Если ТипЗнч(Значение) = Тип("СправочникСсылка.Контрагенты") Тогда
    // это ссылка на контрагента
ИначеЕсли ТипЗнч(Значение) = Тип("Число") Тогда
    // число
КонецЕсли;

Полезные проверки:

  • ✔️ ЗначениеЗаполнено(Значение) — не пусто ли. Для ссылки это не ПустаяСсылка, для числа не ноль, для даты не 00010101.
  • ✔️ Значение = Неопределено — переменная вообще ничего не получила.
  • ✔️ ТипЗнч(Значение) = Тип("Null") — значение пришло из запроса при отсутствии связи.
  • ✔️ Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)) — к какому объекту метаданных относится ссылка.

Для реквизитов и колонок тип задают заранее: Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(15, 2)). Колонка с описанием типа сама приводит присвоенное значение, а лишнее обрезает или обнуляет.

ОписаниеЧто делаетПример
ЧислоХранит число с заданной точностью15 знаков, 2 после запятой
СтрокаОграничивает длинуДля кода — 11, для имени — 150
ДатаДата или дата со временемСостав даты
Составной типНесколько типов в одномСсылка на разные документы

Если оставить колонку таблицы без типа, в неё можно записать что угодно. Потом такой набор сложно загрузить в запрос: типы колонок не выводятся однозначно.

Как проверить, что лежит в переменной?

Какие ошибки случаются чаще всего

Ошибки с «значениями» делятся на две группы: те, что падают сразу с текстом, и те, что молча дают неверный результат.

Что видитеПричинаЧто сделать
Поле объекта не обнаруженоОпечатка в имени реквизита или обращение к значению другого типаПроверьте ТипЗнч() перед обращением
Значение не является значением объектного типаВ переменной Неопределено, число или строка вместо объектаПроверьте условие, из которого получена ссылка
Неверный тип параметра запросаВ параметр пришла строка вместо ссылкиУстановите значение с нужным типом
Пустой результат запросаСравнение с Неопределено через =Используйте ЕСТЬ NULL или параметр
Изменение параметра «не доходит» наружуСтоит ЗначВерните результат функцией или уберите Знач
Неожиданное изменение данныхКопия коллекции не сделанаСкопируйте таблицу явно

Отдельный случай: Значение() с названием, которое отсутствует в конфигурации. Платформа выдаёт сообщение, что значение не найдено в метаданных. Причина обычно в том, что запрос взяли из другой конфигурации или переименовали элемент перечисления.

Диагностика: выберите симптом

Рекомендации по работе со значениями

Практика показывает несколько простых правил, которые уменьшают количество странных ошибок:

  1. ✅ Давайте переменным понятные имена и задавайте им начальное значение. Неопределено в начале цикла — частый источник сюрпризов.
  2. ✅ В запросах используйте параметры, а не склейку строк. Это быстрее, безопаснее и не ломается на кавычках.
  3. ✅ Для групп данных выбирайте подходящую коллекцию. Структура для набора полей, Соответствие для поиска, ТаблицаЗначений для строк.
  4. ✅ Типизируйте колонки и реквизиты: платформа проверит приведение за вас.
  5. ✅ Перед обращением к реквизиту через точку убедитесь, что значение — ссылка, а не пустая ссылка.
  6. ✅ Кэш делайте только для данных, которые не меняются в течение сеанса.

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

Частые вопросы

Есть ли в 1С отдельный тип данных «Значение»?
Нет. «Значение» — это общее название содержимого переменной, а также функция Значение() в запросах и модификатор Знач в параметрах процедур.
Чем `Значение()` в запросе отличается от параметра?
Функцию подставляют прямо в текст запроса для предопределённых данных и перечислений. Параметр передаётся при выполнении и подходит для любых динамических данных.
Что делает `Знач` в заголовке процедуры?
Передаёт параметр по значению. Присваивание внутри процедуры не меняет переменную снаружи. Для объектов-коллекций копируется только ссылка.
Как узнать тип значения в переменной?
Вызовите ТипЗнч(Переменная) и сравните результат с Тип("Имя типа"). Для проверки заполненности есть ЗначениеЗаполнено().
Можно ли хранить объект в реквизите?
Да, через тип ХранилищеЗначения. Положить: Новый ХранилищеЗначения(Данные), достать: Хранилище.Получить(). Запросом по содержимому оно не читается.