Разработка и Конфигурация · 11 мин
Как создать фиксированную структуру в 1С
Как создать фиксированную структуру в 1С: синтаксис, отличия от обычной структуры, типовые сценарии использования, ограничения и частые ошибки разработчиков.
Фиксированная структура в 1С — это объект встроенного языка, который по составу ключей и значениям совпадает с обычной структурой, но не позволяет изменять себя после создания. Любая попытка добавить новое свойство, изменить значение существующего или удалить элемент приведёт к ошибке времени выполнения. Такой объект нужен там, где набор параметров должен оставаться неизменным на протяжении всей работы программы.
Типичные сценарии применения — передача настроек между методами, хранение константных наборов значений, кэширование параметров, защита данных от случайной модификации в длинных цепочках вызовов. Платформа сама активно использует фиксированные структуры: например, параметры формы, доступные в обработчике ПриСозданииНаСервере, часто представлены именно в фиксированном виде.
Важно понимать: фиксированность распространяется только на сам объект, а не на вложенные изменяемые значения. Если значением ключа является массив или обычная структура, их содержимое по-прежнему можно менять. Это ограничение часто становится источником ошибок у разработчиков, которые ожидают «глубокой» неизменяемости.
Что такое фиксированная структура и чем она отличается от обычной
Обычная структура (Структура) — изменяемая коллекция пар «ключ — значение». В неё можно в любой момент добавить свойство через Вставить(), изменить значение через присваивание или удалить ключ. Это удобно для накопления данных, но опасно, когда объект передаётся через несколько процедур: любая из них может незаметно поменять содержимое.
Фиксированная структура (ФиксированнаяСтруктура) наследует способ чтения данных — обращение по ключу, метод Свойство(), перебор в цикле Для Каждого. Но все модифицирующие операции запрещены. Попытка выполнить ФиксСтруктура.Вставить("Ключ", Значение) или ФиксСтруктура.Ключ = Значение завершится ошибкой «Недопустимое значение» или аналогичным сообщением о невозможности изменения.
Проверить тип объекта можно функцией ТипЗнч() и сравнением с Тип("ФиксированнаяСтруктура"). Это полезно в универсальных процедурах, которые принимают параметры и должны понимать, можно ли их дополнять или нужно сначала скопировать.
Как создать фиксированную структуру: синтаксис конструктора
Существует два основных способа создания. Первый — на основе уже заполненной обычной структуры. Вы формируете обычную структуру любым удобным способом, а затем «замораживаете» её:
ОбычнаяСтруктура = Новый Структура;
ОбычнаяСтруктура.Вставить("Организация", ТекущаяОрганизация);
ОбычнаяСтруктура.Вставить("Период", НачалоМесяца(ТекущаяДатаСеанса()));
ПараметрыОтчета = Новый ФиксированнаяСтруктура(ОбычнаяСтруктура);
Второй способ — передать ключи и значения прямо в конструктор, как и у обычной структуры. Строка параметров имеет вид: имя ключа, значение, имя следующего ключа, значение и так далее:
Настройки = Новый ФиксированнаяСтруктура("РежимОтладки, СкладПоУмолчанию", Истина, СкладСсылка);
Если вызвать конструктор без параметров — Новый ФиксированнаяСтруктура() — будет создана пустая фиксированная структура. Практической пользы от неё немного, потому что наполнить её уже нельзя, но такой объект корректен и может использоваться как заглушка «пустых настроек».
- 1Сформируйте обычную структуру с нужными ключами и значениями
- 2Убедитесь, что все значения корректны — исправить их после фиксации нельзя
- 3Вызовите Новый ФиксированнаяСтруктура(ОбычнаяСтруктура)
- 4Сохраните результат в переменную или свойство объекта
- 5Проверьте чтение: обратитесь к ключам и убедитесь, что значения возвращаются
Чтение данных и проверка наличия ключей
Чтение из фиксированной структуры работает точно так же, как из обычной. Доступны обращение через точку (Настройки.РежимОтладки), через строковый ключ в квадратных скобках и безопасный метод Свойство(), который позволяет проверить существование ключа без генерации ошибки:
Значение = Неопределено;
Если Настройки.Свойство("РежимОтладки", Значение) Тогда
// ключ существует, Значение заполнено
КонецЕсли;
Перебор в цикле также поддерживается: Для Каждого Элемент Из Настройки Цикл даёт доступ к Элемент.Ключ и Элемент.Значение. Это удобно для универсального логирования параметров или построения представлений настроек.
Обращение к несуществующему ключу через точку вызовет ошибку «Поле объекта не обнаружено», как и у обычной структуры. Поэтому в защищённом коде всегда используйте Свойство(), если набор ключей не гарантирован.
Как «изменить» фиксированную структуру: приём с копированием
Прямого способа изменить фиксированную структуру нет — это её главное свойство. Если нужна версия с дополненными или изменёнными значениями, создайте новую обычную структуру, скопируйте в неё содержимое фиксированной, внесите правки и зафиксируйте заново:
Функция ДобавитьПараметр(ИсходныеПараметры, ИмяКлюча, ЗначениеКлюча)
Копия = Новый Структура;
Для Каждого Элемент Из ИсходныеПараметры Цикл
Копия.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
Копия.Вставить(ИмяКлюча, ЗначениеКлюча);
Возврат Новый ФиксированнаяСтруктура(Копия);
КонецФункции
Такой приём безопасен: исходный объект остаётся нетронутым, а все места, где он уже используется, продолжают работать с прежними данными. Это соответствует идеологии неизменяемых объектов — вместо мутации создаётся новая версия.
Где фиксированные структуры встречаются в типовых механизмах
Платформа и типовые конфигурации используют фиксированные структуры повсеместно. Наиболее частые точки контакта: параметры управляемой формы (объект Параметры в обработчиках формы часто имеет фиксированный вид), свойства описаний оповещений, параметры открытия форм, возвращаемые значения некоторых методов глобального контекста.
Из этого следует практическое правило: если вы получили структуру из платформы или из чужого метода, не пытайтесь сразу в неё писать. Сначала проверьте тип. Если объект фиксированный — применяйте приём с копированием из предыдущего раздела.
В собственных API фиксированные структуры стоит возвращать из функций, которые формируют настройки или результат сложной операции. Это сигнал вызывающему коду: набор данных финальный, менять его не нужно. Такой контракт снижает количество скрытых зависимостей между модулями.
Что выбрать
Подходит для накопления данных, промежуточных результатов, объектов, которые дополняются по ходу алгоритма. Не защищена от случайных изменений.
Подходит для итоговых настроек, параметров, передаваемых через цепочку вызовов, константных наборов. Требует копирования для любой модификации.
Ограничения и типичные ошибки
Главное ограничение — «поверхностная» фиксация. Вложенные изменяемые объекты остаются изменяемыми. Если в фиксированную структуру помещён массив, вызов Настройки.Список.Добавить(НовоеЗначение) выполнится успешно. Чтобы добиться полной неизменяемости, вкладывайте фиксированные массивы (ФиксированныйМассив) и фиксированные структуры на каждом уровне.
Вторая частая проблема — сериализация. Фиксированная структура не всегда удобна при передаче между сеансами или сохранении в хранилище значений: в ряде сценариев проще работать с обычной структурой, а фиксировать её только в оперативной памяти. Перед проектированием обмена проверьте, поддерживает ли выбранный механизм этот тип.
Третья ошибка — попытка использовать фиксированную структуру как накапливаемый кэш. Например, кэш соответствий «ключ — вычисленное значение» требует постоянного дополнения, поэтому для него нужна обычная структура или соответствие, а фиксацию применяйте только к финальному снимку данных.
Как проверить результат и отладить код
Минимальная проверка — убедиться, что объект имеет нужный тип и содержит ожидаемые ключи. В отладчике фиксированная структура отображается с указанием типа, а её содержимое доступно для просмотра, но не для редактирования через табло переменных.
Полезный приём при разработке — написать небольшой тестовый фрагмент, который пытается изменить объект. Если изменение проходит без ошибки, значит, объект не зафиксирован, и стоит проверить место его создания. Если возникает ожидаемая ошибка модификации — контракт неизменяемости соблюдён.
Как проверить результат
ТипЗнч(Объект) = Тип("ФиксированнаяСтруктура")
Возвращается тип Структура — объект изменяемый
Возникает ошибка модификации
Значение меняется молча — фиксация не выполнена
Метод Свойство() возвращает Истина для каждого ключа
Часть ключей отсутствует — ошибка в формировании исходной структуры
В журнале регистрации ошибки модификации фиксированных структур выглядят как ошибки выполнения встроенного языка с указанием строки модуля. Если такая ошибка возникает в рабочей базе, ищите место, где фиксированный объект передаётся в процедуру, рассчитанную на обычную структуру.
Что важно запомнить
Фиксированная структура создаётся конструктором Новый ФиксированнаяСтруктура() из обычной структуры или списка ключей и значений. Изменить её нельзя — для модификации копируйте содержимое в обычную структуру, правьте и фиксируйте заново. Фиксация не распространяется на вложенные изменяемые объекты.
Частые вопросы
Можно ли удалить ключ из фиксированной структуры?
Нет, методы удаления и очистки недоступны. Чтобы получить структуру без лишнего ключа, скопируйте нужные элементы в новую обычную структуру, пропустив удаляемый ключ, и создайте из неё новую фиксированную структуру.
Чем фиксированная структура отличается от фиксированного соответствия?
Структура использует строковые ключи, являющиеся допустимыми идентификаторами, и позволяет обращение через точку. Соответствие допускает ключи любого типа, но обращение возможно только через квадратные скобки. Выбор зависит от того, какие ключи нужны: для произвольных значений-ключей подходит соответствие.
Можно ли передать фиксированную структуру между клиентом и сервером?
Да, тип сериализуется платформой при клиент-серверных вызовах в управляемом приложении. Однако для длительного хранения или обмена с внешними системами надёжнее преобразовать данные в обычную структуру или формат обмена.
Как проверить, что два фиксированных набора параметров совпадают?
Сравнение через знак равенства для структур не сравнивает содержимое. Нужно перебрать ключи одного объекта, проверить их наличие во втором через Свойство() и сравнить значения попарно, не забыв сверить и количество элементов.
Влияет ли фиксированная структура на производительность?
Чтение работает с той же скоростью, что и у обычной структуры. Затраты возникают только при «изменении» через копирование: создаётся новый объект и копируются все ссылки на значения. При частых доработках набора данных выгоднее держать обычную структуру и фиксировать её один раз в конце.
Можно ли создать фиксированную структуру с вложенной фиксированной структурой?
Да, и это рекомендуемый способ добиться многоуровневой неизменяемости. Сначала зафиксируйте вложенные структуры, затем используйте их как значения при создании внешней. Тогда попытка изменить данные на любом уровне будет заблокирована.