ВычисляемыеПоляСхемыКомпоновкиДанных.Найти

Методы · Find

Осуществляет поиск элемента коллекции по имени.

Синтаксис

Найти(<Имя>)
Полное описание, параметры и ограничения

ВычисляемыеПоляСхемыКомпоновкиДанных.Найти (DataCompositionSchemaCalculatedFields.Find)

ВычисляемыеПоляСхемыКомпоновкиДанных (DataCompositionSchemaCalculatedFields)

Найти (Find)

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

Синтаксис:
Найти(<Имя>)
Параметры:

<Имя> (обязательный)
Тип: Строка.
Имя искомого элемента.
Возвращаемое значение:
Тип: ВычисляемоеПолеСхемыКомпоновкиДанных, Неопределено.
Если элемент не найден, будет возвращено значение Неопределено.
Описание:

Осуществляет поиск элемента коллекции по имени.

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

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

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

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

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

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

Рассчитать сумму Количество × Цена в списке

Вычисляемое поле принадлежит схеме списка. Для расчёта суммы не добавляем реквизит справочника и не записываем данные.

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

Модуль собственной управляемой формы внешней обработки. Вставляйте готовые процедуры с директивами на уровне модуля; каждый урок — в отдельной копии формы.

Подготовка

  1. В учебной базе 8.5.1.1343 создайте новую внешнюю обработку УчебныйСписок85, пустую управляемую основную форму. Режим совместимости — 8.3.19 или выше. Не переделывайте список рабочей конфигурации.

  2. В реквизитах формы добавьте Список типа ДинамическийСписок. Создайте один элемент ТаблицаФормы с именем ТаблицаТоваров и путём к данным Список. Колонки вручную не добавляйте: их создаёт код. Это не ТаблицаЗначений и не коллекция строк для Добавить().

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

  4. При открытии код задаёт произвольный запрос из четырёх константных строк. Основная таблица не указана; таблицы базы, файлы и внешние сервисы не используются. Запись данных отсутствует.

  5. Каждый раз открывайте отдельную копию формы. Автоматическое сохранение настроек отключено: старый пользовательский отбор не должен вмешиваться в упражнение.

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

    Список.ПоляКлюча = Новый ФиксированныйМассив(КлючевыеПоля);
    Список.ТекстЗапроса = "ВЫБРАТЬ
|    1 КАК УчебныйНомер,
|    ""Книга"" КАК Наименование,
|    ""Канцелярия"" КАК Категория,
|    3 КАК Количество,
|    250 КАК Цена
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ 2, ""Ручка"", ""Канцелярия"", 1, 30
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ 3, ""Чай"", ""Продукты"", 2, 150
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ 4, ""Вода"", ""Продукты"", 0, 70";
    Элементы.ТаблицаТоваров.ТолькоПросмотр = Истина;
    Сумма = Список.ВычисляемыеПоля.Добавить();
    Сумма.ПутьКДанным = "УчебнаяСумма";
    Сумма.Заголовок = "Сумма, руб.";
    Сумма.Выражение = "Количество * Цена";
    Сумма.ТипЗначения = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));
    Сумма.Оформление.УстановитьЗначениеПараметра("Формат", "ЧДЦ=2; ЧН=0");
    Сообщить(Список.ВычисляемыеПоля.Найти("УчебнаяСумма") = Сумма);
    Сообщить(Список.ВычисляемыеПоля.Количество() = 1);
    Контроль = Новый Запрос(Список.ТекстЗапроса);
    Данные = Контроль.Выполнить().Выгрузить();
    Сообщить(Данные.Найти(1, "УчебныйНомер").Количество * Данные.Найти(1, "УчебныйНомер").Цена = 750);

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

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

  1. У вычисляемого поля задаём уникальный путь УчебнаяСумма. Это имя понадобится в ПутьКДанным колонки формы.

  2. Выражение использует поля запроса, не переменные модуля формы. Количество и Цена числовые в собственном запросе.

  3. Формат меняет отображение, а не арифметику. Дополнительная проверка исходных данных подтверждает сумму Книги 750.

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

  1. Три проверки дают Истина.

  2. В новой колонке суммы: Книга 750,00; Ручка 30,00; Чай 300,00; Вода 0,00.

  3. В исходном запросе нет колонки УчебнаяСумма: вычисление относится к схеме списка.

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

Наглядная расчётная колонка без изменения структуры базы.

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

  1. ВыражениеПредставления вычисляемого поля не поддерживается в динамическом списке.

  2. Не складывайте строки количества/цены как числа без определения их типа; здесь типы заданы самим запросом.

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

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

Создаём настоящую собственную таблицу 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С» и не аффилирован с ней.