Константа в 1С: как записать значение из кода, формы и обработки

· 9 мин

Содержание

Чтобы установить значение константы в 1С, достаточно одной строки на сервере: Константы.ИмяКонстанты.Установить(Значение);. Прочитать её обратно можно методом Получить(). Всё остальное в теме — это контекст вызова, права, обработчики записи и перенос значения в другую базу.

Частое заблуждение: константу можно «присвоить» как обычную переменную, Константы.Имя = 5. Не получится. Константа — хранимый объект метаданных, и менять её нужно через менеджер или менеджер значения. Ниже — все рабочие способы, от самого простого до сложных.

Что такое константа и когда она нужна

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

Что важно знать до записи:

  • 📌 Тип значения задаётся в конфигураторе: число, строка, дата, булево, ссылка на справочник, составной тип.
  • 📌 Константа может быть независимой или разделяться по областям данных (для сервисной модели).
  • 📌 У каждой константы есть свой менеджер: Константы.ИмяКонстанты, и свой менеджер значения: Константы.ИмяКонстанты.СоздатьМенеджерЗначения().
  • 📌 Права на запись берутся из ролей. Без права «Изменение» метод вызовет исключение.

Сравните два способа записи:

СпособКогда использоватьОсобенности
Установить(Значение)Нужно просто записать значениеОдна строка, без промежуточного объекта
Менеджер значения: Значение, Записать()Нужны проверки, режим загрузки, свойства объектаСрабатывают обработчики записи модуля менеджера значения
Форма константы или общая форма настроекМеняет пользовательЗаписывается при закрытии формы или по кнопке

Программная установка значения: метод Установить

Самый частый вариант. Выполняется в серверной процедуре или функции.

Константы.ОсновнаяОрганизация.Установить(Организация);
Константы.ПрефиксНумерации.Установить("ТД-");
Константы.ДатаНачалаУчета.Установить(Дата(2024, 1, 1));
Константы.ИспользоватьСкидки.Установить(Истина);

Чтение так же просто:

Префикс = Константы.ПрефиксНумерации.Получить();

Тип значения должен совпадать с типом константы. Строку в числовую константу система сама не превратит, если строка не приводится к числу. Для ссылок передавайте именно ссылку, а не наименование.

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

Установка через менеджер значения

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

МенеджерЗначения = Константы.ПрефиксНумерации.СоздатьМенеджерЗначения();
МенеджерЗначения.Прочитать();
МенеджерЗначения.Значение = "ТД-";
МенеджерЗначения.ОбменДанными.Загрузка = Истина;
МенеджерЗначения.Записать();

Что здесь происходит по шагам:

  1. Создаёте менеджер значения нужной константы.
  2. Читаете текущее значение: так подтягиваются служебные свойства.
  3. Присваиваете новое в свойство Значение.
  4. При необходимости включаете ОбменДанными.Загрузка, чтобы пропустить проверки в обработчиках.
  5. Вызываете Записать().

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

Запись нескольких констант в одной транзакции

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

НачатьТранзакцию();
Попытка
    Константы.ОсновнаяОрганизация.Установить(Организация);
    Константы.ПрефиксНумерации.Установить("ТД-");
    Константы.ИспользоватьСкидки.Установить(Истина);
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    ВызватьИсключение;
КонецПопытки;

Правило простое: НачатьТранзакцию и ЗафиксироватьТранзакцию ставьте парами, а в блоке исключения всегда откатывайте. Не держите транзакцию открытой во время диалога с пользователем.

Константы с разделением по областям данных

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

  • 🔹 Неразделённая константа одна на всю систему, её меняет администратор сервиса.
  • 🔹 Разделённая константа читается и пишется в контексте текущей области.
  • 🔹 Для обхода областей используют специальные методы установки разделителей сеанса, и только в служебных процедурах.

Для локальной файловой или клиент-серверной базы без разделения этот нюанс не нужен: константа одна.

Изменение значения через форму и список настроек

Пользователю код не нужен. Но разработчику важно понимать, как константа попадает в форму.

Автоматическая форма константы

В управляемом приложении у константы есть собственная форма: открывается из списка констант или из раздела настроек. Платформа сама создаёт поле ввода нужного типа и записывает значение по кнопке «Записать» или при закрытии с сохранением.

Своя форма настроек

Чаще константы выводят на общую форму, где собрано сразу несколько параметров. Тогда в конфигураторе:

  1. Откройте форму, перетащите нужные константы из дерева реквизитов в элементы формы.
  2. Привяжите поле к реквизиту типа «КонстантаМенеджерЗначения.ИмяКонстанты».
  3. Проверьте, что в свойствах поля стоит автозапись или явная команда записи.

Если нужна логика (скрыть поле, пока не включена опция), добавьте серверный вызов:

&НаСервере
Процедура ЗаписатьНастройкуНаСервере(Знач НовоеЗначение)
    Константы.ИспользоватьСкидки.Установить(НовоеЗначение);
КонецПроцедуры

&НаКлиенте
Процедура ИспользоватьСкидкиПриИзменении(Элемент)
    ЗаписатьНастройкуНаСервере(ИспользоватьСкидки);
КонецПроцедуры

Не пишите значение в ПриИзменении для каждого нажатия клавиши в строковом поле. Достаточно события окончания ввода текста или явной кнопки «Применить»: так вы не нагружаете сервер лишними вызовами.

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

Серверный контекст и общие модули

Менеджер констант — серверный объект. С клиента напрямую Константы.Имя.Установить() не вызвать: нужна серверная процедура, как в примере выше.

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

// Общий модуль НастройкиСервер, флаг «Сервер»
Функция ПрефиксНумерации() Экспорт
    Возврат Константы.ПрефиксНумерации.Получить();
КонецФункции

Процедура УстановитьПрефиксНумерации(Знач Значение) Экспорт
    Если Не ПравоДоступа("Изменение", Метаданные.Константы.ПрефиксНумерации) Тогда
        ВызватьИсключение НСтр("ru = 'Недостаточно прав для изменения настройки.'");
    КонецЕсли;
    Константы.ПрефиксНумерации.Установить(Значение);
КонецПроцедуры

Что стоит учесть:

  • 🔧 Если модуль вызывается с клиента, снимите флаг «Вызов сервера» только когда уверены в безопасности: иначе любой пользователь сможет менять настройку.
  • 🔧 Для фоновых заданий и регламентных процедур права определяет пользователь, от имени которого они работают.
  • 🔧 Привилегированный режим (УстановитьПривилегированныйРежим(Истина)) снимает проверку прав. Включайте его на минимальный блок и только когда это оправдано.

Внешнее соединение и COM

Из внешнего скрипта константу тоже можно установить через соединение:

Соединение.Константы.ПрефиксНумерации.Установить("ТД-");

Это работает, если пользователь соединения обладает нужной ролью, а база не заблокирована для соединений.

Когда константа не подходит

Иногда проще отказаться от константы, чем бороться с её ограничениями. Посмотрите на задачу с другой стороны:

  • 🔸 Значение зависит от организации, склада или пользователя. Константа одна на базу, нужен регистр сведений с измерением.
  • 🔸 Значение меняется во времени, и нужна история. Тут подойдёт периодический регистр сведений.
  • 🔸 Настройка персональная, у каждого пользователя своя. Используйте хранилище настроек пользователя, а не общую константу.
  • 🔸 Список допустимых значений редактирует пользователь. Это справочник.

Если же параметр действительно один на всю базу и меняется редко, константа остаётся самым простым и быстрым вариантом. Читается она дёшево, а запись видна администратору в одном месте.

Ошибки при записи и проверка значений

Запись может упасть по понятным причинам. Разберите по таблице.

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

Как проверить, что значение действительно записалось

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

  1. Вызовите Получить() сразу после Установить() и сравните с исходным значением.
  2. Для ссылок сравнивайте сами ссылки, а не их строковые представления.
  3. Для дат учтите, что тип «Дата» может хранить только дату или дату со временем. Если состав даты задан «только дата», время обрежется.
  4. Для строк с ограничением длины лишние символы тоже обрежутся.

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

Проверку значения лучше делать до записи, а не после:

Процедура УстановитьСтавку(Знач Значение)
    Если ТипЗнч(Значение) <> Тип("Число") Или Значение < 0 Или Значение > 100 Тогда
        ВызватьИсключение НСтр("ru = 'Ставка должна быть числом от 0 до 100.'");
    КонецЕсли;
    Константы.СтавкаПоУмолчанию.Установить(Значение);
КонецПроцедуры

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

Попытка
    Константы.СтавкаПоУмолчанию.Установить(НовоеЗначение);
Исключение
    ЗаписьЖурналаРегистрации("Настройки.СтавкаПоУмолчанию",
        УровеньЖурналаРегистрации.Ошибка, , ,
        ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
    ВызватьИсключение;
КонецПопытки;

Не глушите исключение пустым блоком. Тогда ошибка пройдёт незамеченной, а пользователь решит, что настройка применилась.

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

Перенос значений констант между базами

Константы не переезжают сами. Если вы разворачиваете копию базы , часть значений придётся перенести.

Основные способы:

  1. Выгрузка и загрузка информационной базы (.dt). Копирует всё, включая константы. Подходит для полного клона.
  2. Обмен по плану обмена или в распределённой базе. Константы попадают в состав обмена, если они включены в план обмена.
  3. Выгрузка в XML и загрузка обработкой. Для точечного переноса нескольких настроек пишут небольшую обработку: читает значения, формирует файл, на другой стороне записывает.

Отдельно про состав констант в обмене. Если база-приёмник использует свои настройки (другая организация по умолчанию, другой префикс нумерации), такие константы из обмена исключают. Иначе при каждой синхронизации локальные значения будут перезаписываться чужими.

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

// Выгрузка
Результат = Новый Структура;
Результат.Вставить("ПрефиксНумерации", Константы.ПрефиксНумерации.Получить());
Результат.Вставить("ДатаНачалаУчета", Константы.ДатаНачалаУчета.Получить());
// ... сериализуйте структуру в файл любым удобным способом

// Загрузка
Для Каждого Элемент Из ПрочитаннаяСтруктура Цикл
    Константы[Элемент.Ключ].Установить(Элемент.Значение);
КонецЦикла;

Ссылочные значения (организация, склад, контрагент) на другой базе будут иметь другие идентификаторы. Передавайте не ссылку, а естественный ключ: код, наименование, ИНН. На стороне приёмника находите объект и ставите ссылку на него.

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

Перед переносом настроек в другую базу
Выполнено: 0 / 5

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

Можно ли установить значение константы из клиентского кода?
Нет, напрямую нельзя. Менеджер констант работает на сервере, поэтому с клиента вызывайте серверную процедуру.
Чем `Установить` отличается от записи через менеджер значения?
Установить записывает значение одной командой. Менеджер значения даёт доступ к объекту записи: можно задать режим загрузки и проверить поведение обработчиков модуля менеджера значения.
Как узнать, кто и когда менял константу?
Смотрите журнал регистрации. Если для объекта включена запись изменений в конфигурации, там будут события записи по пользователю и времени.
Что вернёт `Получить()`, если значение не задано?
Пустое значение типа константы: ноль, пустая строка, Ложь, пустая дата или пустая ссылка.
Можно ли хранить в константе список или таблицу?
Прямо нельзя. Для этого есть тип «Хранилище значения», но чаще удобнее регистр сведений или справочник.
Нужно ли перезапускать клиент после изменения константы?
Обычно нет. Но если значение кешируется в модуле с повторным использованием возвращаемых значений, свежие данные появятся после сброса кеша или нового сеанса.