«Значение» в 1С: слово из запроса, параметр процедуры и тип данных
Содержание
Многие ищут в справке отдельный тип данных «Значение» и не находят. Такого типа в языке 1С нет. Слово «Значение» встречается в трёх разных ролях, и из-за этого путаница: функция Значение() в тексте запроса, ключевое слово Знач в параметрах процедур и «значение» как общее название любых данных в переменной.
Если коротко: в запросе Значение(...) подставляет в условие предопределённый элемент или перечисление. В коде у любой переменной есть значение и тип, а тип проверяют через ТипЗнч(). Ниже по очереди разберём, где что работает и где чаще ошибаются.
Что называют типом «Значение» и где проходят границы
Язык 1С динамически типизирован. Переменная может хранить число, строку, ссылку на документ, структуру или Неопределено. Универсального контейнера под названием «Значение» нет, зато есть «произвольное значение»: так в описании типов реквизита называют допустимость любого типа.
Три значения слова, которые путают:
- 🔹 Функция
Значение()в запросе. Работает только внутри текста запроса и берёт элемент перечисления или предопределённые данные. - 🔹 Модификатор
Значв заголовке процедуры. Говорит, что параметр передан по значению, а не по ссылке. - 🔹 Значение переменной. То, что лежит в ней в данный момент. У него есть тип, и он меняется по ходу выполнения.
Граница контекста простая. Значение() нельзя вызвать в обычном коде модуля: там вместо него пишут Перечисления.ВидыНоменклатуры.Товар или Справочники.Валюты.Рубль. Обратная сторона: обращение через точку не работает
внутри текста запроса.
Если видите «Значение» в списке типов в конструкторе запроса, это подсказка для вставки функции Значение(), а не отдельный тип.
Как создавать и менять значения в коде
В коде значение появляется тремя способами: присвоили литерал, получили из объекта или создали объект коллекции. Самые частые контейнеры для группы значений:
| Контейнер | Когда брать | Что учесть |
|---|---|---|
Структура | Фиксированный набор именованных полей | Ключ должен быть допустимым идентификатором |
Соответствие | Произвольные ключи, быстрый поиск | Порядок обхода не гарантирован |
МассивЗначений/Массив | Простой список | Индексы с нуля |
СписокЗначений | Нужен выбор в форме | Хранит значение и представление |
ТаблицаЗначений | Много строк с колонками | Колонки с типами ускоряют поиск |
ХранилищеЗначения | Положить объект в реквизит базы | Читается только через Получить() |
Пример: собираем параметры отбора в структуру и передаём в процедуру.
Отбор = Новый Структура;
Отбор.Вставить("Организация", Организация);
Отбор.Вставить("Период", НачалоМесяца(ТекущаяДата()));
Результат = ПолучитьДанные(Отбор);
Передача в процедуру: Знач и ссылка
По умолчанию параметр процедуры передаётся по ссылке. Изменили его внутри — изменился и внешний объект. Слово Знач отключает это поведение.
Процедура Обработать(Знач Строка, Таблица)
Строка = СокрЛП(Строка); // снаружи строка не изменится
Таблица.Очистить(); // таблица снаружи очистится
КонецПроцедуры
Тонкость: для объектов-коллекций Знач копирует только ссылку. Содержимое таблицы или структуры всё равно можно испортить. Настоящую копию делают явно: Таблица.Скопировать() или ФиксированнаяСтруктура.
Не путайте Знач с копированием объекта. Для таблицы значений это копия указателя, а не данных.
Значения в запросах и параметрах
В запросе значение попадает двумя путями: через Значение() внутри текста и через параметр &Имя. Отличие в том, что Значение() фиксируется при написании запроса, а параметр подставляется при выполнении.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ВидНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ВидыНоменклатуры.Товар)
| И Номенклатура.Родитель = &Группа";
Запрос.УстановитьПараметр("Группа", Группа);
Выборка = Запрос.Выполнить().Выбрать();
Что выбрать:
- Перечисление, предопределённый элемент,
Неопределено,Истина— пишите черезЗначение(). Запрос читается проще, а платформа заранее знает тип. - Всё, что приходит из формы, отбора или расчёта, — через параметр.
- Список значений для
В (&Список)передавайте массивом или таблицей значений. Склеивать идентификаторы в строку не нужно.
Пустые ссылки пишут как Значение(Справочник.Контрагенты.ПустаяСсылка). Отдельная тема — NULL. Он появляется при левом соединении, когда для строки нет пары. Сравнение Поле = NULL не сработает, нужны ПОЛЕ ЕСТЬ NULL или функция ЕСТЬNULL(Поле, 0).
Составные типы и сравнение в условии
Если поле имеет составной тип (например, регистратор), сравнивать его с конкретным значением лучше через ССЫЛКА. Условие Регистратор ССЫЛКА Документ.РасходнаяНакладная отбирает только документы нужного вида и не ломается на других типах.
Для перечислений удобно В (ЗНАЧЕНИЕ(...), ЗНАЧЕНИЕ(...)): так в условии помещается несколько значений без цепочки ИЛИ. Для дат и чисел используйте параметры с явным типом. Например, дата без времени и дата с временем сравниваются по-разному, и граница периода может «потерять» последний день.
Любое Значение() с опечаткой в имени перечисления ловится только при выполнении. Откройте конструктор запроса и вставьте значение кнопкой: так имя не ошибётся.
«Буфер значений» и производительность
Термина «буфер значений» в платформе нет. Если вы встретили его в статьях, обычно под ним имеют в виду одно из трёх: кэш обращений к реквизитам, повторно используемые модули или временное хранилище данных формы. Разберём настоящие механизмы.
- ⚡ Модуль с повторным использованием возвращаемых значений. Результат функции запоминается на время сеанса или вызова. Годится для справочных данных, которые редко меняются.
- ⚡ Временные таблицы запроса. Данные загружаются один раз и используются в нескольких запросах пакета.
- ⚡ Временное хранилище. Данные кладут по адресу, например перед открытием формы, и забирают по этому адресу.
- ⚡ Кэш в глобальной переменной модуля управляемого приложения. Простой вариант для настроек, но не для данных, которые могут меняться у других пользователей.
Что стоит знать про скорость самого кода:
- Обращение к реквизиту через ссылку (
Ссылка.Реквизит) каждый раз идёт в базу. В цикле на тысячу строк это тысяча запросов. Читайте нужные поля одним запросом. ТаблицаЗначений.Найти()по колонке без индекса перебирает всё. Для частого поиска используйтеСоответствиеилиИндексыколонок.- Крупные объекты в
ХранилищеЗначениясжимаются и читаются целиком. Для частых выборок они неудобны.
Когда значение хранят не в коде, а в данных
Иногда задача выглядит как «положить значение куда-то до следующего запуска». Вариантов несколько, и выбирают их по сроку жизни:
- на время работы формы — реквизит формы или временное хранилище;
- на время сеанса — параметр сеанса или переменная модуля;
- на постоянной основе — константа, регистр сведений или хранилище настроек пользователя.
Параметры сеанса удобны для текущего пользователя или организации, но их нужно инициализировать при запуске. Если забыть, при первом обращении платформа сообщит, что параметр не установлен. Константы читаются быстро, но подходят для одиночных настроек. Для списка значений по периодам заводят регистр сведений.
Типизация и проверка содержимого
Тип значения проверяют функциями ТипЗнч() и Тип(). Первая возвращает тип конкретного значения, вторая создаёт описание типа по имени.
Если ТипЗнч(Значение) = Тип("СправочникСсылка.Контрагенты") Тогда
// это ссылка на контрагента
ИначеЕсли ТипЗнч(Значение) = Тип("Число") Тогда
// число
КонецЕсли;
Полезные проверки:
- ✔️
ЗначениеЗаполнено(Значение)— не пусто ли. Для ссылки это неПустаяСсылка, для числа не ноль, для даты не00010101. - ✔️
Значение = Неопределено— переменная вообще ничего не получила. - ✔️
ТипЗнч(Значение) = Тип("Null")— значение пришло из запроса при отсутствии связи. - ✔️
Метаданные.НайтиПоТипу(ТипЗнч(Ссылка))— к какому объекту метаданных относится ссылка.
Для реквизитов и колонок тип задают заранее: Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(15, 2)). Колонка с описанием типа сама приводит присвоенное значение, а лишнее обрезает или обнуляет.
| Описание | Что делает | Пример |
|---|---|---|
Число | Хранит число с заданной точностью | 15 знаков, 2 после запятой |
Строка | Ограничивает длину | Для кода — 11, для имени — 150 |
Дата | Дата или дата со временем | Состав даты |
| Составной тип | Несколько типов в одном | Ссылка на разные документы |
Если оставить колонку таблицы без типа, в неё можно записать что угодно. Потом такой набор сложно загрузить в запрос: типы колонок не выводятся однозначно.
ЗначениеЗаполнено(Переменная): единая проверка для ссылок, чисел, дат и строк.ТипЗнч(Переменная) = Тип("..."): сравнение с описанием типа.Переменная = Неопределено, затем ЗначениеЗаполнено().Null отдельно, а в самом запросе используйте ЕСТЬNULL(Поле, Значение).Какие ошибки случаются чаще всего
Ошибки с «значениями» делятся на две группы: те, что падают сразу с текстом, и те, что молча дают неверный результат.
| Что видите | Причина | Что сделать |
|---|---|---|
Поле объекта не обнаружено | Опечатка в имени реквизита или обращение к значению другого типа | Проверьте ТипЗнч() перед обращением |
Значение не является значением объектного типа | В переменной Неопределено, число или строка вместо объекта | Проверьте условие, из которого получена ссылка |
Неверный тип параметра запроса | В параметр пришла строка вместо ссылки | Установите значение с нужным типом |
| Пустой результат запроса | Сравнение с Неопределено через = | Используйте ЕСТЬ NULL или параметр |
| Изменение параметра «не доходит» наружу | Стоит Знач | Верните результат функцией или уберите Знач |
| Неожиданное изменение данных | Копия коллекции не сделана | Скопируйте таблицу явно |
Отдельный случай: Значение() с названием, которое отсутствует в конфигурации. Платформа выдаёт сообщение, что значение не найдено в метаданных. Причина обычно в том, что запрос взяли из другой конфигурации или переименовали элемент перечисления.
Неопределено, значит выше по коду поиск ничего не нашёл. Исправляйте условие поиска, а не сам вызов.Знач содержимое не защищает, нужна явная копия.Рекомендации по работе со значениями
Практика показывает несколько простых правил, которые уменьшают количество странных ошибок:
- ✅ Давайте переменным понятные имена и задавайте им начальное значение.
Неопределенов начале цикла — частый источник сюрпризов. - ✅ В запросах используйте параметры, а не склейку строк. Это быстрее, безопаснее и не ломается на кавычках.
- ✅ Для групп данных выбирайте подходящую коллекцию.
Структурадля набора полей,Соответствиедля поиска,ТаблицаЗначенийдля строк. - ✅ Типизируйте колонки и реквизиты: платформа проверит приведение за вас.
- ✅ Перед обращением к реквизиту через точку убедитесь, что значение — ссылка, а не пустая ссылка.
- ✅ Кэш делайте только для данных, которые не меняются в течение сеанса.
Хранилище значения не заменяет таблицу в базе. Достать из него отдельное поле запросом нельзя, поэтому данные для отчётов держите в нормальных реквизитах и регистрах.
Частые вопросы
Есть ли в 1С отдельный тип данных «Значение»?
Значение() в запросах и модификатор Знач в параметрах процедур.Чем `Значение()` в запросе отличается от параметра?
Что делает `Знач` в заголовке процедуры?
Как узнать тип значения в переменной?
ТипЗнч(Переменная) и сравните результат с Тип("Имя типа"). Для проверки заполненности есть ЗначениеЗаполнено().Можно ли хранить объект в реквизите?
ХранилищеЗначения. Положить: Новый ХранилищеЗначения(Данные), достать: Хранилище.Получить(). Запросом по содержимому оно не читается.