ИсточникиДанныхСхемыКомпоновкиДанных.Количество

Методы · Count

Получает количество элементов в коллекции.

Синтаксис

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

ИсточникиДанныхСхемыКомпоновкиДанных.Количество (DataCompositionSchemaDataSources.Count)

ИсточникиДанныхСхемыКомпоновкиДанных (DataCompositionSchemaDataSources)

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

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

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

Описание:

Получает количество элементов в коллекции.

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

Сервер, толстый клиент, внешнее соединение.

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

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

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

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

Сумма продажи: доступные значения, подписи выбора и выражение представления

На собственных продажах A01/3/500 и B02/5/700 строим вычисляемое описание суммы и реальные списки1500/3500. Заменяем список на сумму B02, снимаем и восстанавливаем его; отдельно меняем представление на Код85. Независимая модель сохраняет исходный список и формулу.

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

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

Подготовка

  1. Только НОВАЯ отдельная пустая база УчебныеЗначенияРасчета85 на платформе8.5.1.1343, не копия рабочей базы. Нет бизнес-объектов, расширений, подписок и фоновых заданий. Здесь база не создаётся и код не запускается.

  2. Создайте вручную общий модуль УчебныеЗадачи: Сервер=Да, Вызов сервера=Да; клиентские флаги, Глобальный и Привилегированный=Нет. Вставьте полный основной код целиком в модуль, не внутрь ещё одной процедуры.

  3. Своя внешняя обработка УчебныеЗначенияРасчета85 → управляемая Форма: команда Выполнить, действие Выполнить, кнопка. Отдельный полный модуль формы ниже вставьте только в модуль этой формы. До будущего разрешённого опыта сохраните собственную базу и выполните F7 вне опыта; откройте новый сеанс без расширений.

  4. Все данные готовит код: две строки таблицы, Local-источник, объектный набор Продажи85 и одно поле Сумма85. Ключ внешней структуры и ИмяОбъекта совпадают. Код85 — Строка; Количество85 — Число(1,0), Цена85 — Число(3,0), сумма — Число(6,2), всё числовое неотрицательное. Шесть разрядов ВСЕГО включают два дробных; предел9999.99.

  5. Конструктор создаёт только СписокЗначений; элементы возвращает Добавить. Числовая сумма, её строковая подпись и Булево-пометка задаются явно. Картинка не используется: необязательный аргумент пропущен, его документированное значение — пустая картинка, не Неопределено.

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

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

Функция СвояРазрядностьПродаж(Имя)
    Если Имя = "Код85" Тогда
        Возврат 0;
    ИначеЕсли Имя = "Количество85" Тогда
        Возврат 1;
    ИначеЕсли Имя = "Цена85" Тогда
        Возврат 3;
    ИначеЕсли Имя = "Сумма85" Тогда
        Возврат 6;
    КонецЕсли;
    ВызватьИсключение "В своей модели продаж только четыре заранее определённых поля";
КонецФункции

Функция СвойТипПродаж(Имя)
    Разрядность = СвояРазрядностьПродаж(Имя);
    Если Разрядность = 0 Тогда
        Возврат Новый ОписаниеТипов("Строка");
    КонецЕсли;
    ДробнаяЧасть = 0;
    Если Разрядность = 6 Тогда
        ДробнаяЧасть = 2;
    КонецЕсли;
    Возврат Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Разрядность, ДробнаяЧасть, ДопустимыйЗнак.Неотрицательный));
КонецФункции

Процедура ПроверитьСвойТипПродаж(Описание, Имя)
    Если ТипЗнч(Описание) <> Тип("ОписаниеТипов") Тогда
        ВызватьИсключение "Нужно собственное описание типа продаж";
    КонецЕсли;
    Разрядность = СвояРазрядностьПродаж(Имя);
    ТипПоля = Тип("Число");
    Если Разрядность = 0 Тогда
        ТипПоля = Тип("Строка");
    КонецЕсли;
    ПолныеТипы = Описание.Типы();
    Если ПолныеТипы.Количество() <> 1 Или ПолныеТипы[0] <> ТипПоля Тогда
        ВызватьИсключение "Не совпал полный собственный тип поля продаж";
    КонецЕсли;
    Если Разрядность = 0 Тогда
        Возврат;
    КонецЕсли;
    ДробнаяЧасть = 0;
    Если Разрядность = 6 Тогда
        ДробнаяЧасть = 2;
    КонецЕсли;
    Квалификаторы = Описание.КвалификаторыЧисла;
    Если ТипЗнч(Квалификаторы) <> Тип("КвалификаторыЧисла") Или Квалификаторы.Разрядность <> Разрядность
        Или Квалификаторы.РазрядностьДробнойЧасти <> ДробнаяЧасть
        Или Квалификаторы.ДопустимыйЗнак <> ДопустимыйЗнак.Неотрицательный Тогда
        ВызватьИсключение "Не совпали разряды, дробная часть и знак собственного поля продаж";
    КонецЕсли;
КонецПроцедуры

Функция СоздатьСвоюОсновуПродаж()
    Данные = Новый ТаблицаЗначений;
    Имена = СтрРазделить("Код85,Количество85,Цена85", ",");
    Для Каждого Имя Из Имена Цикл
        Данные.Колонки.Добавить(Имя, СвойТипПродаж(Имя));
    КонецЦикла;
    СтрокаПродажи = Данные.Добавить();
    СтрокаПродажи.Код85 = "A01";
    СтрокаПродажи.Количество85 = 3;
    СтрокаПродажи.Цена85 = 500;
    СтрокаПродажи = Данные.Добавить();
    СтрокаПродажи.Код85 = "B02";
    СтрокаПродажи.Количество85 = 5;
    СтрокаПродажи.Цена85 = 700;
    Схема = Новый СхемаКомпоновкиДанных;
    Источник = Схема.ИсточникиДанных.Добавить();
    Источник.Имя = "СвоиПродажи85";
    Источник.ТипИсточникаДанных = "Local";
    Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
    Если ТипЗнч(Набор) <> Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Тогда
        ВызватьИсключение "Нужен собственный объектный набор продаж";
    КонецЕсли;
    Набор.Имя = "Продажи85";
    Набор.ИмяОбъекта = "Продажи85";
    Набор.ИсточникДанных = "СвоиПродажи85";
    Для Каждого Имя Из Имена Цикл
        Поле = Набор.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
        Если ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда
            ВызватьИсключение "Нужно собственное простое поле исходных продаж";
        КонецЕсли;
        Поле.Поле = Имя;
        Поле.ПутьКДанным = Имя;
        Поле.ТипЗначения = СвойТипПродаж(Имя);
    КонецЦикла;
    ВнешниеДанные = Новый Структура;
    ВнешниеДанные.Вставить("Продажи85", Данные);
    Стенд = Новый Структура;
    Стенд.Вставить("Схема", Схема);
    Стенд.Вставить("ВнешниеДанные", ВнешниеДанные);
    Возврат Стенд;
КонецФункции

Процедура ПроверитьСвоюОсновуПродаж(Стенд)
    Если ТипЗнч(Стенд) <> Тип("Структура") Или Стенд.Количество() <> 2 Тогда
        ВызватьИсключение "Нужна собственная структура схемы и внешних продаж";
    КонецЕсли;
    Схема = Неопределено;
    ВнешниеДанные = Неопределено;
    Если Не Стенд.Свойство("Схема", Схема) Или Не Стенд.Свойство("ВнешниеДанные", ВнешниеДанные) Тогда
        ВызватьИсключение "Не совпали оба собственных ключа стенда продаж";
    КонецЕсли;
    Если ТипЗнч(Схема) <> Тип("СхемаКомпоновкиДанных") Или Схема.ИсточникиДанных.Количество() <> 1
        Или Схема.НаборыДанных.Количество() <> 1 Тогда
        ВызватьИсключение "Нужен единственный собственный источник и объектный набор";
    КонецЕсли;
    Если ТипЗнч(ВнешниеДанные) <> Тип("Структура") Или ВнешниеДанные.Количество() <> 1 Тогда
        ВызватьИсключение "Нужен единственный собственный внешний объект продаж";
    КонецЕсли;
    Данные = Неопределено;
    Если Не ВнешниеДанные.Свойство("Продажи85", Данные) Тогда
        ВызватьИсключение "Внешний ключ обязан содержать настоящую собственную таблицу";
    КонецЕсли;
    Если ТипЗнч(Данные) <> Тип("ТаблицаЗначений") Или Данные.Количество() <> 2 Или Данные.Колонки.Количество() <> 3 Тогда
        ВызватьИсключение "Нужны две собственные продажи и три колонки";
    КонецЕсли;
    Источник = Схема.ИсточникиДанных.Получить(0);
    Если ТипЗнч(Источник) <> Тип("ИсточникДанныхСхемыКомпоновкиДанных")
        Или Источник.Имя <> "СвоиПродажи85" Или Источник.ТипИсточникаДанных <> "Local" Тогда
        ВызватьИсключение "Не совпал собственный логический источник";
    КонецЕсли;
    Набор = Схема.НаборыДанных.Получить(0);
    Если ТипЗнч(Набор) <> Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Или Набор.Имя <> "Продажи85"
        Или Набор.ИмяОбъекта <> "Продажи85" Или Набор.ИсточникДанных <> "СвоиПродажи85"
        Или Схема.НаборыДанных.Найти("Продажи85") <> Набор Или Набор.Поля.Количество() <> 3 Тогда
        ВызватьИсключение "Не совпал полный собственный набор и его три исходных поля";
    КонецЕсли;
    Имена = СтрРазделить("Код85,Количество85,Цена85", ",");
    Для Индекс = 0 По 2 Цикл
        Колонка = Данные.Колонки.Получить(Индекс);
        Поле = Набор.Поля.Получить(Индекс);
        Если ТипЗнч(Колонка) <> Тип("КолонкаТаблицыЗначений") Или Колонка.Имя <> Имена[Индекс]
            Или ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")
            Или Поле.Поле <> Имена[Индекс] Или Поле.ПутьКДанным <> Имена[Индекс] Тогда
            ВызватьИсключение "Не совпали все имена, порядок и пути исходных колонок и полей";
        КонецЕсли;
        ПроверитьСвойТипПродаж(Колонка.ТипЗначения, Имена[Индекс]);
        ПроверитьСвойТипПродаж(Поле.ТипЗначения, Имена[Индекс]);
    КонецЦикла;
    Коды = СтрРазделить("A01,B02", ",");
    Количества = Новый Массив;
    Количества.Добавить(3);
    Количества.Добавить(5);
    Цены = Новый Массив;
    Цены.Добавить(500);
    Цены.Добавить(700);
    Суммы = Новый Массив;
    Суммы.Добавить(1500);
    Суммы.Добавить(3500);
    Для Индекс = 0 По 1 Цикл
        СтрокаПродажи = Данные.Получить(Индекс);
        Если ТипЗнч(СтрокаПродажи) <> Тип("СтрокаТаблицыЗначений")
            Или ТипЗнч(СтрокаПродажи.Код85) <> Тип("Строка") Или СтрокаПродажи.Код85 <> Коды[Индекс]
            Или ТипЗнч(СтрокаПродажи.Количество85) <> Тип("Число") Или СтрокаПродажи.Количество85 <> Количества[Индекс]
            Или ТипЗнч(СтрокаПродажи.Цена85) <> Тип("Число") Или СтрокаПродажи.Цена85 <> Цены[Индекс]
            Или СтрокаПродажи.Количество85 * СтрокаПродажи.Цена85 <> Суммы[Индекс] Тогда
            ВызватьИсключение "Не совпали все собственные ячейки и отдельный арифметический эталон BSL";
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Функция СвоеПолеСуммы(Стенд)
    ПроверитьСвоюОсновуПродаж(Стенд);
    Каталог = Стенд.Схема.ВычисляемыеПоля;
    Если ТипЗнч(Каталог) <> Тип("ВычисляемыеПоляСхемыКомпоновкиДанных") Или Каталог.Количество() <> 1 Тогда
        ВызватьИсключение "Нужен единственный собственный расчёт суммы";
    КонецЕсли;
    Поле = Каталог[0];
    Если ТипЗнч(Поле) <> Тип("ВычисляемоеПолеСхемыКомпоновкиДанных")
        Или Поле.ПутьКДанным <> "Сумма85" Или Поле.Заголовок <> "Сумма продажи"
        Или Поле.Выражение <> "Количество85 * Цена85" Тогда
        ВызватьИсключение "Не совпало полное собственное описание расчёта суммы";
    КонецЕсли;
    ПроверитьСвойТипПродаж(Поле.ТипЗначения, "Сумма85");
    Возврат Поле;
КонецФункции

Функция СоздатьСвойРасчетСуммы()
    Стенд = СоздатьСвоюОсновуПродаж();
    Поле = Стенд.Схема.ВычисляемыеПоля.Добавить();
    Если ТипЗнч(Поле) <> Тип("ВычисляемоеПолеСхемыКомпоновкиДанных") Тогда
        ВызватьИсключение "Добавить обязан вернуть собственное вычисляемое поле";
    КонецЕсли;
    Поле.ПутьКДанным = "Сумма85";
    Поле.Выражение = "Количество85 * Цена85";
    Поле.Заголовок = "Сумма продажи";
    Поле.ТипЗначения = СвойТипПродаж("Сумма85");
    Поле.ВыражениеПредставления = "";
    Поле.УстановитьДоступныеЗначения();
    Возврат Стенд;
КонецФункции

Функция СоздатьСвойСписокСумм(Стенд, Режим)
    ПроверитьСвоюОсновуПродаж(Стенд);
    Если Режим <> "Все" И Режим <> "ТолькоB02" Тогда
        ВызватьИсключение "В своём списке два режима: все продажи или только B02";
    КонецЕсли;
    Список = Новый СписокЗначений;
    Данные = Стенд.ВнешниеДанные.Продажи85;
    Для Индекс = 0 По Данные.Количество() - 1 Цикл
        СтрокаПродажи = Данные.Получить(Индекс);
        Если Режим = "ТолькоB02" И СтрокаПродажи.Код85 <> "B02" Тогда
            Продолжить;
        КонецЕсли;
        Сумма = СтрокаПродажи.Количество85 * СтрокаПродажи.Цена85;
        Список.Добавить(Сумма, СтрокаПродажи.Код85 + " — сумма продажи", Ложь);
    КонецЦикла;
    Возврат Список;
КонецФункции

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

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

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

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

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

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

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

  1. СвоеПолеСуммы проверяет обе строки и все типы исходной таблицы/набора, полный путь, заголовок, формулу и числовые квалификаторы единственного расчёта. Получение через Каталог[0] не требует спорного возвращаемого типа Получить вычисляемого каталога.

  2. СоздатьСвойСписокСумм берёт настоящие собственные строки, считает Количество85 * Цена85 обычной арифметикой BSL и добавляет1500/3500 с подписями «A01 — сумма продажи», «B02 — сумма продажи» и пометками Ложь. ТолькоB02 создаёт новый одноэлементный список3500, не фильтрует таблицу.

  3. УстановитьДоступныеЗначения(Список) задаёт доступные значения поля; ПолучитьДоступныеЗначения() возвращает СписокЗначений или Неопределено. Проверка читает количество и каждый ЭлементСпискаЗначений: тип/число, тип/подпись, тип/пометка и порядок. Одинакового количества недостаточно.

  4. Снятие выполняется документированным вызовом УстановитьДоступныеЗначения() без аргумента. После него ожидается Неопределено. Пустой список и явно переданное Неопределено здесь не подставляются: их эквивалентность снятию не заявляется.

  5. Выражение остаётся Количество85 * Цена85, Заголовок — Сумма продажи, ТипЗначения — числовой. ВыражениеПредставления меняется с пустой строки на Код85, реальное исходное поле, затем возвращается. По справке непустое выражение задаёт выводимое представление, пустое использует Выражение. Строковые подписи списка выбора не являются этим выражением.

  6. Девять состояний оригинала: снятый список/пустое представление; все суммы/пустое; все/Код85; толькоB02/Код85; снято/Код85; все/Код85; все/пустое; снято/пустое; восстановлено все/пустое. На каждом состоянии проверяются исходные данные и расчёт, не только список.

  7. Пять сверок копии сохраняют полный список1500/3500 и пустое представление при замене, снятии и восстановлении оригинала. Копия полностью строится заново: другая таблица, схема, источник, набор, поле и заново созданный список; ссылочная идентичность списка getter/setter не предполагается.

  8. Настоящий код КА2 КомпоновкаДанныхСервер.СкопироватьПоляНабораДанных читает ПолучитьДоступныеЗначения, проверяет Неопределено и передаёт список в УстановитьДоступныеЗначения. Там обычное поле набора, не вычисляемое: перенос доступных значений подтверждает паттерн, а точный контракт вычисляемого поля подтверждается только установленной справкой8.5.1.1343. Рабочая процедура не вызывается.

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

  1. Ожидаемый будущий итог: две исходные продажи неизменны; единственное описание Сумма85 сохраняет формулу и Число(6,2,Неотрицательный), представление снова пустое; оригинал и независимая копия имеют1500/A01 и3500/B02, пометки Ложь. Этап снятия должен вернуть Неопределено, а не пустой элемент или список.

  2. Будущий отрицательный контроль только в отдельно разрешённом стенде: заменить значениеB02 в списке3500 на3501, не меняя ожидание. Проверка должна отказать, даже когда количество элементов прежнее. Другие контроли: неправильная подпись или Истина вместо Ложь должны отказать; цена701 вместо700 должна отказать до создания списка. Здесь ничего из этого не запускалось.

  3. runtimeVerifiedScenarios=0. Подтверждён текст контрактов и статическая целостность примера, не выполненный вызов платформы, показ списка в форме или отрисованный результат отчёта. Арифметика BSL не доказывает исполнение строк Выражение/ВыражениеПредставления движком СКД.

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

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

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

  1. Доступные значения не являются правами доступа, проверкой рабочего документа или автоматически установленным отбором. ТолькоB02 не удаляет A01 из исходных данных; количество строк всегда2. Этот урок не обещает видимость/выбор/фильтрацию конкретного интерфейса.

  2. Не изменяйте список, возвращённый ПолучитьДоступныеЗначения, в расчёте на общую ссылку. Документирован контракт значения, не идентичность, глубокое копирование или владение; для каждой установки код строит новый список и сравнивает содержимое.

  3. Не путайте подпись ЭлементСпискаЗначений.Представление с ВыражениеПредставления самого вычисляемого поля и с его Заголовком. Замена представления на Код85 не меняет числовую формулу, тип суммы или исходные данные; реальный вывод и влияние настроек отчёта требуют отдельного разрешённого теста.

  4. Не используйте здесь Сумма85 внутри собственного Выражение: вычисляемый расчёт должен ссылаться на поля набора. Поле Код85 действительно подготовлено в таблице и схеме, неизвестных реквизитов нет.

  5. Не создаются настройки выбора, ресурсы, компоновщик макета или процессор; отчёт не считается готовым к исполнению. Никаких запросов, сети, записи данных или модификации конфигураций пользователя; весь опыт ограничен новой собственной моделью в памяти.

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

Вычисляемые поля продаж: сумма, скидка, редактор каталога и восстановление

Создаём настоящую собственную таблицу A01/3/500 и B02/5/700, объектный набор и два описания вычислений. Все формулы ссылаются только на исходные поля, не на другое вычисляемое поле. Отдельная арифметика BSL служит эталоном, не выдаётся за исполнение СКД.

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

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

Подготовка

  1. Только НОВАЯ отдельная пустая база УчебныеВычисляемые85 на точной платформе8.5.1.1343, не копия рабочей. Нет бизнес-объектов, расширений, подписок и заданий. Здесь база не создаётся и опыт не запускается.

  2. Создайте вручную пустой общий модуль УчебныеЗадачи: Сервер=Да, Вызов сервера=Да; клиентские флаги, Глобальный и Привилегированный=Нет. Полный основной модуль вставьте целиком, не внутрь второй процедуры.

  3. Создайте свою внешнюю обработку УчебныеВычисляемые85 с управляемой Формой, командой Выполнить, её действием Выполнить и кнопкой. Отдельный полный модуль формы ниже предназначен только для этого модуля формы. До будущего разрешённого теста сохраните и выполните F7 только собственной базы вне опыта; откройте свежий сеанс без расширений.

  4. Таблица, её строки, источник, объектный набор, поля и внешняя структура создаются самим кодом. Код85 — Строка, Количество85 — целое0–9, Цена85 — целое0–999. Два расчётных описания имеют Число(6,2,Неотрицательный): шесть разрядов ВСЕГО, два дробных, максимум9999.99, не шесть целых плюс два дробных.

  5. Справка Получить у этого каталога указывает ИсточникДанныхСхемыКомпоновкиДанных как возвращаемый тип, хотя описывает работу аналогично [] каталога вычисляемых полей. Прямые вызовы в просмотренных конфигурациях не подтвердились. Поэтому код берёт своё поле через [], проверяет его тип и отдельно требует совпадения Получить с этим же объектом. Расхождение не скрывается и runtime-подтверждения нет.

Процедура ВыполнитьПример() Экспорт
    ПроверитьСвойПустойСтенд();
    Если ПривилегированныйРежим() Тогда
        ВызватьИсключение "Привилегированный режим не нужен";
    КонецЕсли;
    Пусто = Новый Массив;
    Имена = СтрРазделить("Сумма85,СуммаПослеСкидки85", ",");
    Стенд = СоздатьСвоюОсновуПродаж();
    Каталог = Стенд.Схема.ВычисляемыеПоля;
    ПроверитьСвоиРасчеты(Стенд, Пусто, 9);
    Сумма = Каталог.Добавить();
    ЗаполнитьСвойРасчет(Сумма, "Сумма85", 9);
    ПроверитьСвоиРасчеты(Стенд, СтрРазделить("Сумма85", ","), 9);
    Скидка = Каталог.Вставить(0);
    ЗаполнитьСвойРасчет(Скидка, "СуммаПослеСкидки85", 9);
    ПроверитьСвоиРасчеты(Стенд, СтрРазделить("СуммаПослеСкидки85,Сумма85", ","), 9);
    Каталог.Сдвинуть(Скидка, 1);
    ПроверитьСвоиРасчеты(Стенд, Имена, 9);
    Копия = СоздатьСвоюОсновуПродаж();
    ВосстановитьСвоиРасчеты(Копия);
    ПроверитьСвоиРасчеты(Копия, Имена, 9);
    Скидка.Выражение = СвойТекстРасчета("СуммаПослеСкидки85", 8);
    ПроверитьСвоиРасчеты(Стенд, Имена, 8);
    ПроверитьСвоиРасчеты(Копия, Имена, 9);
    Скидка.Выражение = СвойТекстРасчета("СуммаПослеСкидки85", 9);
    ПроверитьСвоиРасчеты(Стенд, Имена, 9);
    Каталог.Удалить(Сумма);
    ПроверитьСвоиРасчеты(Стенд, СтрРазделить("СуммаПослеСкидки85", ","), 9);
    ПроверитьСвоиРасчеты(Копия, Имена, 9);
    НоваяСумма = Каталог.Вставить(0);
    ЗаполнитьСвойРасчет(НоваяСумма, "Сумма85", 9);
    ПроверитьСвоиРасчеты(Стенд, Имена, 9);
    Каталог.Очистить();
    ПроверитьСвоиРасчеты(Стенд, Пусто, 9);
    ПроверитьСвоиРасчеты(Копия, Имена, 9);
    ВосстановитьСвоиРасчеты(Стенд);
    ПроверитьСвоиРасчеты(Стенд, Имена, 9);
    ПроверитьСвоиРасчеты(Копия, Имена, 9);
КонецПроцедуры

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

Функция СвояРазрядностьПродаж(Имя)
    Если Имя = "Код85" Тогда
        Возврат 0;
    ИначеЕсли Имя = "Количество85" Тогда
        Возврат 1;
    ИначеЕсли Имя = "Цена85" Тогда
        Возврат 3;
    ИначеЕсли Имя = "Сумма85" Или Имя = "СуммаПослеСкидки85" Тогда
        Возврат 6;
    КонецЕсли;
    ВызватьИсключение "В своей модели продаж только пять заранее определённых полей";
КонецФункции

Функция СвойТипПродаж(Имя)
    Разрядность = СвояРазрядностьПродаж(Имя);
    Если Разрядность = 0 Тогда
        Возврат Новый ОписаниеТипов("Строка");
    КонецЕсли;
    ДробнаяЧасть = 0;
    Если Разрядность = 6 Тогда
        ДробнаяЧасть = 2;
    КонецЕсли;
    Возврат Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Разрядность, ДробнаяЧасть, ДопустимыйЗнак.Неотрицательный));
КонецФункции

Процедура ПроверитьСвойТипПродаж(Описание, Имя)
    Если ТипЗнч(Описание) <> Тип("ОписаниеТипов") Тогда
        ВызватьИсключение "Нужно собственное описание типа продаж";
    КонецЕсли;
    Разрядность = СвояРазрядностьПродаж(Имя);
    ТипПоля = Тип("Число");
    Если Разрядность = 0 Тогда
        ТипПоля = Тип("Строка");
    КонецЕсли;
    ПолныеТипы = Описание.Типы();
    Если ПолныеТипы.Количество() <> 1 Или ПолныеТипы[0] <> ТипПоля Тогда
        ВызватьИсключение "Не совпал полный собственный тип поля продаж";
    КонецЕсли;
    Если Разрядность = 0 Тогда
        Возврат;
    КонецЕсли;
    ДробнаяЧасть = 0;
    Если Разрядность = 6 Тогда
        ДробнаяЧасть = 2;
    КонецЕсли;
    Квалификаторы = Описание.КвалификаторыЧисла;
    Если ТипЗнч(Квалификаторы) <> Тип("КвалификаторыЧисла") Или Квалификаторы.Разрядность <> Разрядность
        Или Квалификаторы.РазрядностьДробнойЧасти <> ДробнаяЧасть
        Или Квалификаторы.ДопустимыйЗнак <> ДопустимыйЗнак.Неотрицательный Тогда
        ВызватьИсключение "Не совпали разряды, дробная часть и знак собственного поля продаж";
    КонецЕсли;
КонецПроцедуры

Функция СоздатьСвоюОсновуПродаж()
    Данные = Новый ТаблицаЗначений;
    Имена = СтрРазделить("Код85,Количество85,Цена85", ",");
    Для Каждого Имя Из Имена Цикл
        Данные.Колонки.Добавить(Имя, СвойТипПродаж(Имя));
    КонецЦикла;
    СтрокаПродажи = Данные.Добавить();
    СтрокаПродажи.Код85 = "A01";
    СтрокаПродажи.Количество85 = 3;
    СтрокаПродажи.Цена85 = 500;
    СтрокаПродажи = Данные.Добавить();
    СтрокаПродажи.Код85 = "B02";
    СтрокаПродажи.Количество85 = 5;
    СтрокаПродажи.Цена85 = 700;
    Схема = Новый СхемаКомпоновкиДанных;
    Источник = Схема.ИсточникиДанных.Добавить();
    Источник.Имя = "СвоиПродажи85";
    Источник.ТипИсточникаДанных = "Local";
    Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
    Если ТипЗнч(Набор) <> Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Тогда
        ВызватьИсключение "Нужен собственный объектный набор продаж";
    КонецЕсли;
    Набор.Имя = "Продажи85";
    Набор.ИмяОбъекта = "Продажи85";
    Набор.ИсточникДанных = "СвоиПродажи85";
    Для Каждого Имя Из Имена Цикл
        Поле = Набор.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
        Если ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда
            ВызватьИсключение "Нужно собственное простое поле исходных продаж";
        КонецЕсли;
        Поле.Поле = Имя;
        Поле.ПутьКДанным = Имя;
        Поле.ТипЗначения = СвойТипПродаж(Имя);
    КонецЦикла;
    ВнешниеДанные = Новый Структура;
    ВнешниеДанные.Вставить("Продажи85", Данные);
    Стенд = Новый Структура;
    Стенд.Вставить("Схема", Схема);
    Стенд.Вставить("ВнешниеДанные", ВнешниеДанные);
    Возврат Стенд;
КонецФункции

Процедура ПроверитьСвоюОсновуПродаж(Стенд)
    Если ТипЗнч(Стенд) <> Тип("Структура") Или Стенд.Количество() <> 2 Тогда
        ВызватьИсключение "Нужна собственная структура схемы и внешних продаж";
    КонецЕсли;
    Схема = Неопределено;
    ВнешниеДанные = Неопределено;
    Если Не Стенд.Свойство("Схема", Схема) Или Не Стенд.Свойство("ВнешниеДанные", ВнешниеДанные) Тогда
        ВызватьИсключение "Не совпали оба собственных ключа стенда продаж";
    КонецЕсли;
    Если ТипЗнч(Схема) <> Тип("СхемаКомпоновкиДанных") Или Схема.ИсточникиДанных.Количество() <> 1
        Или Схема.НаборыДанных.Количество() <> 1 Тогда
        ВызватьИсключение "Нужен единственный собственный источник и объектный набор";
    КонецЕсли;
    Если ТипЗнч(ВнешниеДанные) <> Тип("Структура") Или ВнешниеДанные.Количество() <> 1 Тогда
        ВызватьИсключение "Нужен единственный собственный внешний объект продаж";
    КонецЕсли;
    Данные = Неопределено;
    Если Не ВнешниеДанные.Свойство("Продажи85", Данные) Тогда
        ВызватьИсключение "Внешний ключ обязан содержать настоящую собственную таблицу";
    КонецЕсли;
    Если ТипЗнч(Данные) <> Тип("ТаблицаЗначений") Или Данные.Количество() <> 2 Или Данные.Колонки.Количество() <> 3 Тогда
        ВызватьИсключение "Нужны две собственные продажи и три колонки";
    КонецЕсли;
    Источник = Схема.ИсточникиДанных.Получить(0);
    Если ТипЗнч(Источник) <> Тип("ИсточникДанныхСхемыКомпоновкиДанных")
        Или Источник.Имя <> "СвоиПродажи85" Или Источник.ТипИсточникаДанных <> "Local" Тогда
        ВызватьИсключение "Не совпал собственный логический источник";
    КонецЕсли;
    Набор = Схема.НаборыДанных.Получить(0);
    Если ТипЗнч(Набор) <> Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Или Набор.Имя <> "Продажи85"
        Или Набор.ИмяОбъекта <> "Продажи85" Или Набор.ИсточникДанных <> "СвоиПродажи85"
        Или Схема.НаборыДанных.Найти("Продажи85") <> Набор Или Набор.Поля.Количество() <> 3 Тогда
        ВызватьИсключение "Не совпал полный собственный набор и его три исходных поля";
    КонецЕсли;
    Имена = СтрРазделить("Код85,Количество85,Цена85", ",");
    Для Индекс = 0 По 2 Цикл
        Колонка = Данные.Колонки.Получить(Индекс);
        Поле = Набор.Поля.Получить(Индекс);
        Если ТипЗнч(Колонка) <> Тип("КолонкаТаблицыЗначений") Или Колонка.Имя <> Имена[Индекс]
            Или ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")
            Или Поле.Поле <> Имена[Индекс] Или Поле.ПутьКДанным <> Имена[Индекс] Тогда
            ВызватьИсключение "Не совпали все имена, порядок и пути исходных колонок и полей";
        КонецЕсли;
        ПроверитьСвойТипПродаж(Колонка.ТипЗначения, Имена[Индекс]);
        ПроверитьСвойТипПродаж(Поле.ТипЗначения, Имена[Индекс]);
    КонецЦикла;
    Коды = СтрРазделить("A01,B02", ",");
    Количества = Новый Массив;
    Количества.Добавить(3);
    Количества.Добавить(5);
    Цены = Новый Массив;
    Цены.Добавить(500);
    Цены.Добавить(700);
    Суммы = Новый Массив;
    Суммы.Добавить(1500);
    Суммы.Добавить(3500);
    Для Индекс = 0 По 1 Цикл
        СтрокаПродажи = Данные.Получить(Индекс);
        Если ТипЗнч(СтрокаПродажи) <> Тип("СтрокаТаблицыЗначений")
            Или ТипЗнч(СтрокаПродажи.Код85) <> Тип("Строка") Или СтрокаПродажи.Код85 <> Коды[Индекс]
            Или ТипЗнч(СтрокаПродажи.Количество85) <> Тип("Число") Или СтрокаПродажи.Количество85 <> Количества[Индекс]
            Или ТипЗнч(СтрокаПродажи.Цена85) <> Тип("Число") Или СтрокаПродажи.Цена85 <> Цены[Индекс]
            Или СтрокаПродажи.Количество85 * СтрокаПродажи.Цена85 <> Суммы[Индекс] Тогда
            ВызватьИсключение "Не совпали все собственные ячейки и отдельный арифметический эталон BSL";
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Функция СвойТекстРасчета(Имя, Множитель)
    Если Множитель <> 9 И Множитель <> 8 Тогда
        ВызватьИсключение "В своём опыте только скидки десять или двадцать процентов";
    КонецЕсли;
    Если Имя = "Сумма85" Тогда
        Возврат "Количество85 * Цена85";
    ИначеЕсли Имя = "СуммаПослеСкидки85" Тогда
        Если Множитель = 9 Тогда
            Возврат "Количество85 * Цена85 * 9 / 10";
        КонецЕсли;
        Возврат "Количество85 * Цена85 * 8 / 10";
    КонецЕсли;
    ВызватьИсключение "Нужен один из двух собственных путей вычисляемых полей";
КонецФункции

Функция СвойЗаголовокРасчета(Имя)
    Если Имя = "Сумма85" Тогда
        Возврат "Сумма продажи";
    ИначеЕсли Имя = "СуммаПослеСкидки85" Тогда
        Возврат "Сумма со скидкой";
    КонецЕсли;
    ВызватьИсключение "В своём каталоге только два собственных заголовка";
КонецФункции

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

Процедура ПроверитьСвоиРасчеты(Стенд, Имена, Множитель)
    ПроверитьСвоюОсновуПродаж(Стенд);
    Каталог = Стенд.Схема.ВычисляемыеПоля;
    Если ТипЗнч(Каталог) <> Тип("ВычисляемыеПоляСхемыКомпоновкиДанных") Или Каталог.Количество() <> Имена.Количество() Тогда
        ВызватьИсключение "Не совпал полный собственный каталог вычислений";
    КонецЕсли;
    Если Каталог.Найти("НетТакогоРасчета85") <> Неопределено Тогда
        ВызватьИсключение "Отсутствующий собственный расчёт не должен находиться";
    КонецЕсли;
    Для Индекс = 0 По Имена.Количество() - 1 Цикл
        Имя = Имена[Индекс];
        Поле = Каталог[Индекс];
        Если ТипЗнч(Поле) <> Тип("ВычисляемоеПолеСхемыКомпоновкиДанных") Тогда
            ВызватьИсключение "По индексу должен находиться собственный элемент вычисляемого каталога";
        КонецЕсли;
        Если Каталог.Получить(Индекс) <> Поле Или Каталог[Имя] <> Поле
            Или Каталог.Найти(Имя) <> Поле Или Каталог.Индекс(Поле) <> Индекс Тогда
            ВызватьИсключение "Не совпали Получить, числовой и именной индекс, поиск и положение своего расчёта";
        КонецЕсли;
        Если Поле.ПутьКДанным <> Имя Или Поле.Выражение <> СвойТекстРасчета(Имя, Множитель)
            Или Поле.Заголовок <> СвойЗаголовокРасчета(Имя) Тогда
            ВызватьИсключение "Не совпали полный путь, выражение и заголовок собственного расчёта";
        КонецЕсли;
        ПроверитьСвойТипПродаж(Поле.ТипЗначения, Имя);
    КонецЦикла;
    Если Каталог.Найти("СуммаПослеСкидки85") <> Неопределено Тогда
        Данные = Стенд.ВнешниеДанные.Продажи85;
        Эталон = Новый Массив;
        Если Множитель = 9 Тогда
            Эталон.Добавить(1350);
            Эталон.Добавить(3150);
        Иначе
            Эталон.Добавить(1200);
            Эталон.Добавить(2800);
        КонецЕсли;
        Для Индекс = 0 По 1 Цикл
            СтрокаПродажи = Данные.Получить(Индекс);
            Если СтрокаПродажи.Количество85 * СтрокаПродажи.Цена85 * Множитель / 10 <> Эталон[Индекс] Тогда
                ВызватьИсключение "Не совпал отдельный арифметический эталон скидки в BSL";
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Процедура ВосстановитьСвоиРасчеты(Стенд)
    Пусто = Новый Массив;
    ПроверитьСвоиРасчеты(Стенд, Пусто, 9);
    Каталог = Стенд.Схема.ВычисляемыеПоля;
    Поле = Каталог.Добавить();
    ЗаполнитьСвойРасчет(Поле, "Сумма85", 9);
    Поле = Каталог.Добавить();
    ЗаполнитьСвойРасчет(Поле, "СуммаПослеСкидки85", 9);
КонецПроцедуры
УчебныеВычисляемые85.Форма

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

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

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

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

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

  1. Свой стенд содержит две целиком проверяемые продажи и соответствующий внешний ключ Продажи85. Имя набора и ИмяОбъекта также Продажи85 намеренно: сопоставление разных имён не заявляется. Local не означает другую реальную базу.

  2. Простая сумма: Количество85 * Цена85. Скидка10%: Количество85 * Цена85 * 9 / 10. Нельзя заменить её на Сумма85 * 9 / 10: установленная справка запрещает использовать вычисляемые поля в выражениях вычисляемых полей. Обе формулы намеренно напрямую используют поля набора.

  3. Вычисляемое поле получают через Добавить() или Вставить(индекс), без Type-аргумента и неизвестного конструктора. ПутьКДанным — его имя в настройках; Заголовок — понятная подпись. У элемента не выдумывается отдельное свойство Имя. Readonly Схема.ВычисляемыеПоля не заменяется новым объектом.

  4. Десять состояний оригинала: пусто, только сумма, скидка перед суммой, исходный порядок, скидка20%, возвращённые10%, удалённая сумма, новая сумма на0, очищенный каталог, восстановленные два описания. Индекс/полный порядок, поиск, оба оператора [] и Получить сверяются вместе; Сдвинуть принимает объект и относительное смещение, Удалить — объект.

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

  6. Удаление Сумма85 не оставляет сломанной ссылки в формуле скидки, потому что та использует исходные поля напрямую. Настройки выбора и итоговые ресурсы с ссылками на вычисления здесь вообще не создаются. Это редактор модели, не готовый к выводу отчёт.

  7. В BSL проверяется отдельный арифметический эталон: 1500/3500 и для скидки10%1350/3150, для20%1200/2800. Совпадение обычной арифметики не подтверждает выполнение строк Выражение движком СКД. Запросы, компоновщик макета и процессор не запускаются.

  8. В настоящем модуле КА2 БюджетированиеСервер используются СхемаКомпоновкиДанных.ВычисляемыеПоля, Добавить(), ПутьКДанным, Выражение и ТипЗначения. Его рабочие аналитики, настройки и данные не заимствуются и не выполняются. Подтверждено создание описаний, не работа Получить в1С.

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

  1. Ожидаемый будущий итог проверки собственной модели: прежние A01/3/500 и B02/5/700, один источник/набор и два вычисляемых описания Сумма85, СуммаПослеСкидки85; скидка снова10%, оба описания Число(6,2,Неотрицательный). Копия остаётся исходной при всех изменениях оригинала.

  2. Будущий отрицательный контроль в отдельно разрешённом стенде: заменить только формулу скидки на Сумма85 * 9 / 10 без изменения эталона. Проверка полного текста должна отказать при прежних размерах и именах. Другой контроль: изменить ценуB02 с700 на701 — должна отказать проверка исходной ячейки. Здесь эти контроли не выполнялись.

  3. runtimeVerifiedScenarios=0. Статическая сверка сигнатур, типов, контекстов и текста не подтверждает реальные значения СКД, округление, сумму отчёта, порядок вывода или эффективность. Ни рабочие базы, ни конфигурации пользователя не изменяются.

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

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

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

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

  2. В документации Получить есть противоречивая строка возвращаемого типа. Проверка будущего соответствия [] и Получить не является доказательством уже выполненного вызова и не исправляет оригинальную справку. Любое несовпадение должно остановить опыт.

  3. ТипЗначения задаёт описание типа, не формат отображения. Для сумм шесть разрядов включают дробные два. Квалификаторы явно передаются вторым аргументом ОписаниеТипов и проверяются отдельно у каждой колонки, исходного поля и вычисляемого описания.

  4. После Удалить старый объект Сумма не используется; после Очистить не используются прежние Скидка и НоваяСумма. Восстановление создаёт новые описания. Сами строки продаж и независимая копия должны сохраниться.

  5. Пример принимает только собственный конечный эталон; он не является универсальным расчётом продаж, правилами рабочего округления, гарантией валютной точности или исполненным отчётом. Для вывода и проверки движка нужна отдельная разрешённая runtime-работа.

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

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

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

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

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