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