ФиксированнаяСтруктура.Количество

Методы · Count

Получает количество свойств объекта.

Синтаксис

Количество()
Полное описание, параметры и ограничения

ФиксированнаяСтруктура.Количество (FixedStructure.Count)

ФиксированнаяСтруктура (FixedStructure)

Количество (Count)

Доступен, начиная с версии 8.2.

Синтаксис:
Количество()
Возвращаемое значение:
Тип: Число.

Описание:

Получает количество свойств объекта.

Доступность:

Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер.

Использование в версии:

Доступен, начиная с версии 8.2.

Методическая информация

Практические примеры

Передать неизменяемую копию настроек

Копия сохраняет значения настроек, даже если исходная структура затем изменена.

Где и как запускать

Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.

Подготовка

  1. Используем простые значения: число и строку.

  2. Изменяем исходную структуру после создания копии.

Настройки = Новый Структура("Таймаут,Режим", 30, "Тест");
Снимок = Новый ФиксированнаяСтруктура(Настройки);
Настройки.Таймаут = 60;
Таймаут = 0;
Если Снимок.Свойство("Таймаут", Таймаут) Тогда
    Сообщить(Таймаут);
КонецЕсли;
Сообщить(Снимок.Количество());

Разбор по шагам

  1. Конструктор сохраняет состав свойств и их значения.

  2. Свойство безопасно получает существующее поле через выходной параметр.

  3. Изменение исходной структуры не меняет сохранённый Таймаут.

Как проверить результат

  1. Вывод Таймаут=30, количество свойств 2.

  2. Настройки.Таймаут в отладчике равен 60.

Ожидаемый результат

Неизменяемая копия содержит исходные настройки.

На что обратить внимание

  1. Вложенные изменяемые объекты не получают глубокую неизменяемость.

  2. Фиксированная структура не позволяет присвоить новое значение полю.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Неизменяемый пакет товара и три профиля JSON: шесть вариантов конструкторов без неизвестных объектов

Из собственных значений A01/Книга/3/250 делаем неизменяемые снимки двумя способами. Получаем редактируемую копию, создаём версию5/270 с пустым объектом extra, затем записываем и читаем JSON со стандартными, читаемыми и компактными параметрами. Проверяем все поля, типы, независимость скалярных данных, оформление и экранирование.

Где и как запускать

Полный серверный общий модуль УчебныйПакет своей пустой конфигурации УчебныйСнимокJSON85 и отдельный модуль формы. В1С не запускался.

Подготовка

  1. НОВАЯ пустая отдельная учебная база точно8.5.1.1343, имя конфигурации УчебныйСнимокJSON85, совместимость Не использовать. Нет бизнес-объектов, расширений, подписок и фоновых заданий; модули вручную пустые, кроме своего общего модуля. Рабочие конфигурации и записи не используются.

  2. Общий модуль УчебныйПакет: Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Вставьте весь основной модуль. Своя внешняя обработка УчебныйСнимокJSON85 → управляемая Форма: команда/кнопка Выполнить с действием Выполнить; реквизиты не нужны. Полный отдельный модуль формы приведён ниже.

  3. Будущая ручная подготовка: сохранить конфигурацию, Конфигурация → Обновить конфигурацию базы данных (F7), открыть новый собственный клиент и свою обработку. Здесь F7, код, сериализация и форма не выполнялись.

  4. Все значения создаёт сам код. Четыре обязательных ключа sku/title/stock/price допустимы как имена переменных BSL. title содержит кириллицу, <>, &, одинарные кавычки, слеш и U+2028/U+2029. extra — действительно пустая ФиксированнаяСтруктура, не Неопределено и не строка с текстом {}.

Процедура ВыполнитьПример() Экспорт
    ПроверитьСвойПустойСтенд();
    РабочийИсходник = Новый Структура("sku,title,stock,price", "A01", СвоеНазваниеПакета(), 3, 250);
    Снимок = Новый ФиксированнаяСтруктура(РабочийИсходник);
    Именованный = Новый ФиксированнаяСтруктура("sku,title,stock,price", "A01", СвоеНазваниеПакета(), 3, 250);
    Если ТипЗнч(Снимок) <> Тип("ФиксированнаяСтруктура") Или ТипЗнч(Именованный) <> Тип("ФиксированнаяСтруктура") Тогда
        ВызватьИсключение "Оба способа создания дают фиксированные снимки";
    КонецЕсли;
    ПустыеДополнения = Новый ФиксированнаяСтруктура;
    Если ТипЗнч(ПустыеДополнения) <> Тип("ФиксированнаяСтруктура") Или ПустыеДополнения.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен собственный пустой неизменяемый объект дополнений";
    КонецЕсли;
    ПроверитьСвоиПоляПакета(Снимок, 3, 250, Ложь);
    ПроверитьСвоиПоляПакета(Именованный, 3, 250, Ложь);
    РабочийИсходник.stock = 8;
    РабочийИсходник.price = 999;
    ПроверитьСвоиПоляПакета(РабочийИсходник, 8, 999, Ложь);
    ПроверитьСвоиПоляПакета(Снимок, 3, 250, Ложь);
    Рабочий = Новый Структура(Снимок);
    Если ТипЗнч(Рабочий) <> Тип("Структура") Тогда
        ВызватьИсключение "Рабочая копия должна быть изменяемой структурой";
    КонецЕсли;
    Рабочий.stock = 5;
    Рабочий.price = 270;
    Рабочий.Вставить("extra", ПустыеДополнения);
    Пакет = Новый ФиксированнаяСтруктура(Рабочий);
    Если ТипЗнч(Пакет) <> Тип("ФиксированнаяСтруктура") Тогда
        ВызватьИсключение "Окончательный собственный пакет фиксирован";
    КонецЕсли;
    ПроверитьСвоиПоляПакета(Пакет, 5, 270, Истина);
    Рабочий.stock = 9;
    Рабочий.price = 990;
    РабочийИсходник.Очистить();
    Если РабочийИсходник.Количество() <> 0 Тогда
        ВызватьИсключение "Собственный исходный рабочий контейнер очищен";
    КонецЕсли;
    ПроверитьСвоиПоляПакета(Рабочий, 9, 990, Истина);
    ПроверитьСвоиПоляПакета(Снимок, 3, 250, Ложь);
    ПроверитьСвоиПоляПакета(Именованный, 3, 250, Ложь);
    ПроверитьСвоиПоляПакета(Пакет, 5, 270, Истина);
    Стандартные = Новый ПараметрыЗаписиJSON;
    СтандартныйОтступ = Стандартные.СимволыОтступа;
    Если СтандартныйОтступ <> "" И СтандартныйОтступ <> " " Тогда
        ВызватьИсключение "Отступ по умолчанию не совпал ни с одним из двух описаний установленной справки";
    КонецЕсли;
    ПроверитьСвоиПараметрыПакета(Стандартные, ПереносСтрокJSON.Авто, СтандартныйОтступ, Ложь);
    Читаемые = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Unix, "  ", Истина,
        ЭкранированиеСимволовJSON.Нет, Истина, Истина, Истина, Истина, Истина);
    Компактные = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, "", Истина,
        ЭкранированиеСимволовJSON.Нет, Истина, Истина, Истина, Истина, Истина);
    Профили = Новый Массив;
    Профили.Добавить(Новый Структура("Имя,Параметры,Перенос,Отступ,Экранировать",
        "По умолчанию", Стандартные, ПереносСтрокJSON.Авто, СтандартныйОтступ, Ложь));
    Профили.Добавить(Новый Структура("Имя,Параметры,Перенос,Отступ,Экранировать",
        "Читаемый Unix", Читаемые, ПереносСтрокJSON.Unix, "  ", Истина));
    Профили.Добавить(Новый Структура("Имя,Параметры,Перенос,Отступ,Экранировать",
        "Компактный", Компактные, ПереносСтрокJSON.Нет, "", Истина));
    Для Каждого Профиль Из Профили Цикл
        Текст = ЗаписатьСвойПакетВСтроку(Пакет, Профиль.Параметры, Профиль.Перенос, Профиль.Отступ, Профиль.Экранировать);
        Восстановленный = ПрочитатьСвойПакетИзСтроки(Текст);
        ПроверитьСвоеПредставлениеПакета(Текст, Профиль.Перенос, Профиль.Экранировать);
        ПроверитьСвоиПоляПакета(Пакет, 5, 270, Истина);
        Восстановленный.stock = 7;
        ПроверитьСвоиПоляПакета(Восстановленный, 7, 270, Истина);
        ПроверитьСвоиПоляПакета(Пакет, 5, 270, Истина);
        Сообщить(Профиль.Имя);
        Сообщить(Текст);
    КонецЦикла;
    Сообщить(СтрШаблон("Пакет сохранён: stock=%1, price=%2, произведение=%3; длина стандартного отступа=%4",
        Пакет.stock, Пакет.price, Пакет.stock * Пакет.price, СтрДлина(СтандартныйОтступ)));
КонецПроцедуры

Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры

Функция СвоеНазваниеПакета()
    Возврат "Книга <учебная>& 'тест'/" + Символ(8232) + Символ(8233);
КонецФункции

Процедура ПроверитьСвоиПоляПакета(Объект, Запас, Цена, СДополнениями)
    Если ТипЗнч(Объект) <> Тип("Структура") И ТипЗнч(Объект) <> Тип("ФиксированнаяСтруктура") Тогда
        ВызватьИсключение "Нужен только собственный подготовленный пакет";
    КонецЕсли;
    Ожидание = Новый Структура("sku,title,stock,price", "A01", СвоеНазваниеПакета(), Запас, Цена);
    Если Объект.Количество() <> ?(СДополнениями, 5, 4) Тогда
        ВызватьИсключение "Не совпал полный набор собственных полей пакета";
    КонецЕсли;
    Для Каждого Имя Из СтрРазделить("sku,title,stock,price", ",") Цикл
        Если Не Объект.Свойство(Имя, Факт) Тогда
            ВызватьИсключение "Отсутствует собственное обязательное поле " + Имя;
        КонецЕсли;
        Ожидание.Свойство(Имя, Эталон);
        Если ТипЗнч(Факт) <> ТипЗнч(Эталон) Или Факт <> Эталон Тогда
            ВызватьИсключение "Не совпали тип и полное собственное значение поля " + Имя;
        КонецЕсли;
    КонецЦикла;
    Если СДополнениями Тогда
        Если Не Объект.Свойство("extra", Дополнения) Тогда
            ВызватьИсключение "Пустой объект дополнений не должен исчезнуть";
        КонецЕсли;
        Если ТипЗнч(Дополнения) <> Тип("Структура") И ТипЗнч(Дополнения) <> Тип("ФиксированнаяСтруктура") Тогда
            ВызватьИсключение "Дополнения должны быть объектом, не строкой, массивом или null";
        КонецЕсли;
        Если Дополнения.Количество() <> 0 Тогда
            ВызватьИсключение "Собственный extra должен быть именно пустым объектом";
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

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

Функция ЗаписатьСвойПакетВСтроку(Пакет, Параметры, Перенос, Отступ, Экранировать)
    ПроверитьСвоиПоляПакета(Пакет, 5, 270, Истина);
    ПроверитьСвоиПараметрыПакета(Параметры, Перенос, Отступ, Экранировать);
    Запись = Новый ЗаписьJSON;
    Запись.УстановитьСтроку(Параметры);
    Попытка
        ПроверитьСвоиПараметрыПакета(Запись.Параметры, Перенос, Отступ, Экранировать);
        ЗаписатьJSON(Запись, Пакет);
        Возврат Запись.Закрыть();
    Исключение
        Запись.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
КонецФункции

Функция ПрочитатьСвойПакетИзСтроки(Текст)
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(Текст);
    Попытка
        Пакет = ПрочитатьJSON(Чтение, Ложь);
    Исключение
        Чтение.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Чтение.Закрыть();
    Если ТипЗнч(Пакет) <> Тип("Структура") Тогда
        ВызватьИсключение "Верхний JSON-объект восстановлен как обычная Структура";
    КонецЕсли;
    ПроверитьСвоиПоляПакета(Пакет, 5, 270, Истина);
    Возврат Пакет;
КонецФункции

Процедура ПроверитьСвоеПредставлениеПакета(Текст, Режим, Экранировать)
    Если Режим = ПереносСтрокJSON.Unix Тогда
        Если СтрНайти(Текст, Символ(10)) = 0 Или СтрНайти(Текст, Символ(13)) <> 0 Тогда
            ВызватьИсключение "Читаемый профиль должен использовать только перенос Unix";
        КонецЕсли;
    ИначеЕсли Режим = ПереносСтрокJSON.Нет Тогда
        Если СтрНайти(Текст, Символ(10)) <> 0 Или СтрНайти(Текст, Символ(13)) <> 0 Тогда
            ВызватьИсключение "Компактный профиль не содержит переводов строк";
        КонецЕсли;
    КонецЕсли;
    Если Экранировать Тогда
        Если СтрНайти(Текст, "<") <> 0 Или СтрНайти(Текст, ">") <> 0 Или СтрНайти(Текст, "&") <> 0
            Или СтрНайти(Текст, "'") <> 0 Или СтрНайти(Текст, "/") <> 0
            Или СтрНайти(Текст, Символ(8232)) <> 0 Или СтрНайти(Текст, Символ(8233)) <> 0 Тогда
            ВызватьИсключение "Не совпало заданное экранирование собственной строки";
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры
УчебныйСнимокJSON85.Форма

Своя внешняя обработка УчебныйСнимокJSON85 → управляемая Форма → Модуль

Полный отдельный модуль формы с вызовом своего серверного общего модуля; не выполнялся.

&НаКлиенте
Процедура Выполнить(Команда)
    ВыполнитьНаСервере();
    Сообщить("Снимки, редактируемая копия и три обратных преобразования собственного пакета проверены");
КонецПроцедуры

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

Разбор по шагам

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

  2. Новый ФиксированнаяСтруктура без параметров создаёт пустой объект дополнительных свойств. Его тип и количество0 проверены. Пустой объект полезен для явного extra:{}, когда контракт учебного сообщения требует само поле, но необязательные сведения отсутствуют.

  3. Новый Структура(Снимок) возвращает редактируемый контейнер. Меняем stock/price на5/270, добавляем extra и снова фиксируем окончательный пакет. Затем изменяем рабочий контейнер на9/990 и очищаем исходный: старые снимки остаются3/250, отправляемый учебный пакет5/270.

  4. ПараметрыЗаписиJSON без аргументов применяются в первом реальном преобразовании. В справке есть противоречие отступа по умолчанию: свойство СимволыОтступа говорит о пустой строке, аргумент конструктора — об одном пробеле. Код фиксирует фактическое значение, допускает только эти два описанных варианта и не заявляет, какой подтвердился в1С.

  5. Именованный конструктор параметров используется для двух явных профилей: Unix с двумя пробелами и Нет с пустым отступом. Все девять свойств readonly: не присваиваем их после создания. Двойные кавычки включены; специальные символы экранируются явными пятью флагами.

  6. Писатель и читатель работают только со строками памяти. ЗаписатьJSON прямо поддерживает ФиксированнаяСтруктура; ПрочитатьJSON(...,Ложь) возвращает обычную Структура. Все пять ключей, четыре полных значения/типа и пустой extra сверяются после каждого из трёх преобразований.

  7. Отдельно проверяем LF без CR для Unix, отсутствие LF/CR для компактного профиля и отсутствие сырых заданных специальных символов при явном экранировании. Для стандартного профиля не требуем ту же побайтовую раскладку. Порядок JSON-свойств не принимается за контракт.

  8. Восстановленному сообщению задаём stock=7: исходный фиксированный пакет остаётся5/270. Итоговое произведение5×270=1350 — арифметика учебных чисел, не реальная цена, сумма сделки или отправка сообщения.

Как проверить результат

  1. Будущий результат: три восстановленных объекта имеют исходные sku/title, stock5, price270 и пустой объект extra. После локального изменения восстановленной копии на7 пакет по-прежнему содержит5. Старые снимки сохраняют3/250, исходный контейнер очищен.

  2. Будущий отрицательный контроль: в ПрочитатьСвойПакетИзСтроки сразу перед ПроверитьСвоиПоляПакета(Пакет,5,270,Истина) вставьте Пакет.stock = "5";. При тех же пяти ключах проверка должна отклонить строковый stock по типу. Не меняйте эталон и общий проверяющий код; после опыта верните весь исходный модуль и откройте новый свой сеанс.

  3. Сверяйте восстановленные поля, не равенство трёх текстов JSON. У default-профиля показана фактическая длина отступа0 или1; это диагностическая граница противоречивой справки, а не подтверждённое в1С значение по умолчанию.

  4. runtimeVerifiedScenarios=0. Здесь не запускались BSL, JSON-писатель/читатель или форма, не выполнялись HTTP-запросы, запись файлов, изменение параметров сеанса или базы. Исходный формат специально учебный: это не заявленный контракт Avito или другого внешнего API.

Ожидаемый результат

Шесть конструкторов решают одну задачу подготовки и проверки собственной версии сообщения: источник, снимки, редактируемая копия, пустой объект дополнений и три различающихся представления JSON.

На что обратить внимание

  1. ФиксированнаяСтруктура не даёт универсального глубокого клонирования произвольного графа. Здесь значения скалярные, а вложенный extra сам фиксирован и пуст. Не заменяйте его неизвестной изменяемой структурой и не обещайте полную независимость чужих вложенных объектов.

  2. Порядок обхода ФиксированнаяСтруктура неопределён. Проверка названа по известным ключам и полным значениям, не по номерам пар. Ключи должны удовлетворять именованию переменных BSL; произвольные ключи внешнего JSON могут потребовать Соответствие.

  3. Свойства ПараметрыЗаписиJSON readonly. Все необходимые значения задаются конструктором; ПереносСтрокJSON и ЭкранированиеСимволовJSON — enum, не строки. Авто зависит от ОС, поэтому только явному Unix задаётся проверка LF без CR.

  4. Отступ по умолчанию в установленной справке описан противоречиво. Не подменяйте наблюдаемый стандартный отступ единственным догаданным эталоном; явные профили имеют однозначно заданные два пробела и пустую строку.

  5. ПрочитатьJSON не сохраняет фиксированность структуры. После чтения получаем редактируемую структуру и проверяем типы значений. Строка "5" не равна числу5 для нашего контракта, даже если внешне они похожи.

  6. Корректное экранирование и обратное чтение не являются универсальной защитой XSS. Не вставляйте default-JSON в HTML/JavaScript произвольным способом. Этот урок показывает конкретное представление данных, не проверенный сценарий веб-встраивания или интеграции.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.