Добавляем константу в конфигурацию 1С 8.3 и работаем с ней в коде
Содержание
Константу добавляют в дереве конфигурации: ветка Константы → Добавить, задать имя и тип значения. В коде значение читают методом Получить() и пишут методом Установить(). Это весь каркас — дальше детали, в которых обычно и путаются.
Частое заблуждение: раз константа хранит «одно значение», её можно завести под любую настройку и писать в неё из каждой процедуры. На деле каждое обращение к константе — это запрос к отдельной таблице базы, и бесконтрольное чтение в цикле или в проведении документов заметно тормозит систему. Поэтому важно не только создать константу , но и правильно её читать.
Пути и кнопки ниже даны для Конфигуратора на платформе 1С:Предприятие 8.3 (интерфейс «Такси», версия платформы не ниже 8.3.2x). В 1C:EDT набор свойств тот же, отличается только расположение панелей.
Что хранит константа и когда её заводить
Константа — это объект метаданных, который хранит ровно одно значение на всю информационную базу. Не список, не таблицу, а один реквизит: строку, число, дату, ссылку на элемент справочника.
Типичные кандидаты в константы:
- 🏢 основная организация или склад по умолчанию в простой самописной базе;
- 💱 валюта регламентированного учёта;
- 📅 дата запрета редактирования или дата старта учёта;
- 🔧 флажки режимов работы: «вести партионный учёт», «использовать скидки»;
- 🔗 ссылка на справочник с расширенными настройками.
Когда константу заводить не стоит. Если значений много и они логически связаны (адрес, ИНН, КПП, банковские реквизиты организации) — это реквизиты справочника, а не десяток констант. Если значение меняется для каждого пользователя — это настройка в регистре сведений с измерением «Пользователь», а не одна общая константа.
В типовых конфигурациях (БП 3.0, ЗУП 3.1, УТ 11) почти все настройки давно вынесены не в отдельные константы, а в регистры сведений и наборы настроек. Создавать новые константы обычно приходится при доработке своей или расширенной конфигурации.
Добавляем константу в конфигураторе
Порядок действий короткий.
- Откройте конфигурацию:
Конфигурация→Открыть конфигурацию. - В дереве найдите ветку Константы, встаньте на неё и нажмите
Добавить(клавишаInsили кнопка со значком «плюс» в командной панели дерева). - В палитре свойств задайте Имя — латиницей без пробелов, по которому к константе обращаются в коде (например,
ВалютаРегламентированногоУчета). Синоним заполнится автоматически — это то, что увидит пользователь. - Выберите Тип значения (о типах — в следующем разделе).
- При необходимости заполните комментарий — он виден только разработчику и помогает не забыть назначение константы.
Сохраните конфигурацию (Файл → Сохранить) и обновите конфигурацию базы данных: Конфигурация → Обновить конфигурацию базы данных (F7).
Добавление новой таблицы для константы меняет структуру базы, поэтому обновление идёт в монопольном режиме — на время этой операции все сеансы пользователей должны быть завершены. Планируйте такое обновление на нерабочее время и предупреждайте коллег.
После обновления константа существует, но пустая. Её значение задают либо вручную — через форму констант, либо программно (см. раздел про код).
Какой тип значения выбрать для константы
Тип определяет, что константа сможет хранить, и менять его у заполненной константы в рабочей базе рискованно. Поэтому тип продумывают заранее.
Доступны те же типы, что и у любого реквизита:
- примитивные —
Строка,Число,Дата,Булево; - ссылочные — ссылка на элемент конкретного справочника, документа, на значение перечисления;
- составной тип — когда в константе может лежать значение одного из нескольких типов.
Пара практических правил по примитивным типам:
- для строки без крайней нужды не ставьте флажок «Неограниченная длина» — фиксированная длина (например, 150 символов) экономит место и ускоряет запросы;
- для числа заранее задайте разрядность и точность (знаки после запятой), чтобы не обрезать значение;
- дату выбирайте составом «Дата» или «Дата и время» осознанно: для даты запрета достаточно «Дата».
Составной тип включается флажком Составной тип данных в окне выбора типа. Тогда в константе можно хранить, например, либо ссылку на организацию, либо пустое значение. Расплата — усложняется код: перед использованием значение приходится проверять на тип и на заполненность.
Пока константе не задали значение, Получить() вернёт пустое значение её типа: для числа — 0, для строки — пустую строку, для даты — пустую дату, для ссылочного типа — пустую ссылку. Отдельного состояния «значение не задано» у константы нет. Поэтому для булевой константы-флага имейте в виду: до первой записи она равна Ложь, и логику стройте от этого, а не рассчитывайте на «не установлено».
Читаем и записываем значение константы в коде
Обращение к константе идёт через объект Константы и имя константы.
Прочитать значение:
ВалютаУчета = Константы.ВалютаРегламентированногоУчета.Получить();
Записать значение:
Константы.ВалютаРегламентированногоУчета.Установить(НужнаяВалюта);
Метод Установить() сразу пишет значение в базу. Если нужно перехватить запись или установить несколько констант одной операцией, используют менеджер значения:
МенеджерЗначения = Константы.ВалютаРегламентированногоУчета.СоздатьМенеджерЗначения();
МенеджерЗначения.Значение = НужнаяВалюта;
МенеджерЗначения.Записать();
У менеджера значения есть собственный модуль с событиями ПередЗаписью и ПриЗаписи — туда вешают проверки и связанную логику (об этом в разделе про защиту).
Если одной операцией нужно изменить и константу, и другие данные (например, при изменении валюты учёта пересчитать связанные документы), оберните запись в транзакцию НачатьТранзакцию() … ЗафиксироватьТранзакцию(). Тогда либо запишется всё, либо, при ошибке, не изменится ничего. Это защищает от состояния, когда константа уже новая, а зависимые данные остались старыми.
Запись в константу — это изменение данных базы. Не вызывайте Установить() или Записать() в модулях форм при каждом открытии или в обработчиках, которые срабатывают часто: вы создадите лишнюю блокировку и нагрузку.
Набор констант: несколько значений одной записью
Когда надо прочитать или записать сразу несколько констант (например, при сохранении формы настроек), читать их по одной расточительно. Для этого есть набор:
НаборКонстант = Константы.СоздатьНабор("ВалютаРегламентированногоУчета, ВестиПартионныйУчет");
НаборКонстант.Прочитать();
НаборКонстант.ВалютаРегламентированногоУчета = НужнаяВалюта;
НаборКонстант.ВестиПартионныйУчет = Истина;
НаборКонстант.Записать();
Один вызов Прочитать() и один Записать() вместо нескольких обращений к базе. Это и есть «лучшая практика» работы с группой взаимосвязанных констант.
Форма констант для ручного ввода значений
Чтобы пользователь (или вы сами) могли задать значения без кода, константам нужна форма.
Если константа одна и к ней достаточно разового доступа, значение можно задать прямо из конфигуратора в пользовательском режиме — но на практике делают общую форму констант:
- В дереве конфигурации встаньте на ветку Общие формы →
Добавить. - В конструкторе выберите тип формы Форма констант.
- Отметьте константы, которые должны попасть на форму, и разместите их реквизиты.
- Пропишите команду открытия этой формы в подсистеме или в разделе интерфейса, чтобы пользователь мог её найти.
На форме констант менеджер записи уже встроен — платформа сама читает значения при открытии и пишет при сохранении, отдельный код для этого не нужен. На одной форме можно собрать сразу несколько констант: пользователь задаёт их вместе и сохраняет одной кнопкой, а платформа запишет весь набор. Это удобнее, чем отдельная форма под каждую константу.
Если нужно, на форму добавляют собственные обработчики — например, проверить заполнение перед записью или подставить значение по умолчанию при первом открытии. Но базовый ввод значений работает и без единой строки кода.
Если константы логически относятся к настройкам программы, выносите форму в раздел Администрирование (или в тот раздел интерфейса, где пользователь ищет настройки), а не прячьте в отдельный пункт меню.
Как ускорить частое чтение констант
Каждый Получить() — это запрос к базе. В большой конфигурации, где константу с настройкой читают из проведения документов, из форм списков и из регламентных заданий, такие обращения складываются в заметную нагрузку.
Приём, который используют практики: читать константу не напрямую, а через функцию общего модуля с повторным использованием возвращаемых значений.
// Общий модуль «НастройкиУчетаПовтИсп», свойство
// «Повторное использование возвращаемых значений» = «На время сеанса»
Функция ВалютаРегламентированногоУчета() Экспорт
Возврат Константы.ВалютаРегламентированногоУчета.Получить();
КонецФункции
Первый вызов за сеанс сходит в базу, остальные вернут закешированное значение без запроса. Режим кеширования выбирают по смыслу:
- На время вызова — кеш живёт в пределах одного серверного вызова;
- На время сеанса — кеш живёт весь сеанс пользователя.
У кеша «На время сеанса» есть обратная сторона: если значение константы изменят в базе, старые сеансы будут какое-то время видеть прежнее значение, пока кеш не сбросится. Для констант-настроек, которые меняют редко, это обычно приемлемо; для часто меняющихся данных кеш не подходит.
Второе правило оптимизации — не читать константу в цикле. Прочитайте её один раз в переменную до начала цикла и используйте переменную внутри:
ВалютаУчета = Константы.ВалютаРегламентированногоУчета.Получить();
Для Каждого СтрокаТаблицы Из ТаблицаДокументов Цикл
// используем переменную ВалютаУчета, а не читаем константу заново
ОбработатьСтроку(СтрокаТаблицы, ВалютаУчета);
КонецЦикла;
Разница между тысячей обращений к базе и одним особенно заметна в проведении документов и в регламентных заданиях, где такой код выполняется массово.
Права на константу и защита от случайного изменения
Доступ к константам управляется ролями, как и у остальных объектов.
- Откройте нужную роль (ветка
Роли), в таблице прав найдите свою константу и снимите право Изменение у тех ролей, которым менять её не положено. Право Чтение обычно оставляют — иначе код, читающий константу, упадёт на проверке прав. - Если значение должно задаваться один раз при внедрении, удобно оставить изменение только у роли администратора или у специальной роли настройки.
Логические проверки вешают на событие ПередЗаписью в модуле менеджера значения константы. Например, запретить очистку обязательной константы:
Процедура ПередЗаписью(Отказ)
Если Не ЗначениеЗаполнено(Значение) Тогда
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Так пустое значение просто не запишется, независимо от того, кто и откуда пытается его стереть.
Для совсем критичных настроек (дата запрета, параметры учётной политики) в типовых конфигурациях предусмотрены отдельные защищённые механизмы — свою константу для такого заводить не нужно, используйте штатный.
Ещё один слой защиты — отделить изменение значения от пользовательского интерфейса. Если константа задаётся один раз при внедрении и дальше меняться не должна, не выносите её на общую форму настроек вовсе. Тогда у рядового пользователя просто не будет способа её тронуть, даже имея право на изменение.
Частые ошибки при работе с константами
Короткий список того, на чём обычно спотыкаются.
- ❌ Хранят в константе то, что зависит от пользователя или организации. Константа одна на базу. Если нужно разное значение по пользователям или организациям — это регистр сведений с измерениями, а не константа.
- ❌ Пишут в константу при каждом открытии формы. Запись меняет базу и держит блокировку. Пишите только когда значение реально изменилось.
- ❌ Меняют тип заполненной константы в рабочей базе. Платформа попытается привести старое значение к новому типу; при несовместимости значение потеряется. Меняйте тип только осознанно и с резервной копией.
- ❌ Читают константу десятки раз подряд без кеширования. Для часто читаемых настроек оборачивайте чтение в функцию с повторным использованием значений.
- ❌ Путают
Установить()и форму констант.Установить()пишет сразу и молча; форма даёт пользователю проверить и сохранить осознанно. Для пользовательских настроек делайте форму.
Частые вопросы
Чем константа отличается от реквизита справочника?
Можно ли узнать, кто и когда изменил константу?
ПриЗаписи менеджера значения или заведите регистр сведений для хранения истории.Почему значение константы не меняется в коде, хотя `Установить()` выполнился?
Получить().