Абстрактные типы, множества, очереди. Примеры использования

22.04.24

Разработка - Математика и алгоритмы

В последнем обновлении библиотеки АТДМассив появились множества и очереди. В рамках практического примера создания вычислителя выражений демонстрируется применение этих новых абстрактных типов в сочетании с уже ранее представленным абстрактным массивом.

Скачать исходный код

Наименование Файл Версия Размер
Абстрактные типы, множества, очереди. Примеры использования
.dt 472,14Mb
1
.dt 472,14Mb 1 Скачать

Содержание


Введение

Новые абстрактные типы позволяют более гибко и эффективно управлять данными и использовать их в решении различных задач. Рассмотрение примеров позволит лучше понять, как эти типы могут быть применены на практике и как они взаимодействуют между собой для решения разных задач.

В новой версии АТДМассив реализованы следующие абстрактные типы:

  • Множество
  • Очередь
  • ПриоритетнаяОчередь
  • ОчередьУникальныхЗначений
  • ПриоритетнаяОчередьУникальныхЗначений

Теория абстрактных типов давно считается фундаментом в области языков программирования общего назначения. Однако давайте не будем углубляться в теорию, предполагая, что Вы уже знакомы с ней, или, в случае отсутствия знаний, можете найти нужные материалы самостоятельно. Мой фокус направлен на тех, кто больше интересуется не теорией, а практическим применением этих типов в среде 1С.

Давайте рассмотрим конкретные примеры использования данных типов на практике, чтобы проиллюстрировать их ценность и практическое применение в реальных ситуациях.

Работа с множеством

Основная задача

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

Объекты могут принадлежать к простым типам, ссылочным или структурным. Для первых двух категорий не возникает проблем с их идентификацией. Простые типы отличаются друг от друга по значению, в то время как ссылочные типы различаются по значению ссылки, через которую они ссылаются на объект.

Более сложная ситуация возникает с объектами, относящимися к структурным или составным типам. К ним также будут относиться и ссылочные типы, если ссылка в нашей задаче не будет являться идентификатором объекта.

Составные типы представляют собой типы данных, содержащие в себе поля. Подобно структурному типу, универсальным аналогом которого является объект "Структура", составные типы могут быть использованы для описания объектов как, например, строк в таблице или ссылочных объектов на элементы справочника. Важно отметить, что каждый программный объект занимает определенное место в памяти и имеет ссылку на него. В этом контексте все структурные объекты являются уникальными по сути, поскольку они имеют различные ссылки в памяти. Однако они могут также содержать объектную информацию, которая может быть уникальной не за счёт ссылки, а за счёт ключа.

Итак, уникальность объекта структурного типа может быть определена как по самому объекту, так и по специальному ключу, используемому для его идентификации. Например, рассмотрим две структуры данных, в которых содержится один и тот же код товара. В данном случае обе структуры могут считаться уникальными, поскольку они имеют различные адреса в памяти компьютера. В то же время, эти структуры могут ссылаться на один и тот же товар, что подчеркивает важность использования ключей для корректного определения уникальности объектов структурного типа.

Рассмотри следующие примеры работы с простыми типами и составными.

Множество простых типов

Давайте рассмотрим пример работы с корзиной покупателя. Пусть у нас есть множество товаров, представленное их названиями. Создадим объект "Корзина" с абстрактным типом "Множество". Добавим в эту корзину товары "Арбуз" и "Дыня", а затем выполним проверку содержимого корзины на наличие арбуза и бананов.

Сначала мы создадим объект "Корзина" с использованием абстрактного типа "Множество", который позволит нам хранить уникальные товары. Затем добавим в эту корзину товары "Арбуз" и "Дыня". После этого, мы проверим содержимое корзины и убедимся, содержит ли она арбуз и бананы.

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

  1. Создаем объект "Корзина" с абстрактным типом "Множество".
  2. Добавляем в корзину товары: "Арбуз" и "Дыня".
  3. Проверяем содержимое корзины на наличие "Арбуза" и "Бананов".

Такой подход позволит нам продемонстрировать работу с абстрактными типами и методами их использования для управления данными в корзине покупателя.

Корзина = РаботаСМножеством.Множество();
РаботаСМножеством.Добавить(Корзина, "Арбуз");
РаботаСМножеством.Добавить(Корзина, "Дыня");
Если РаботаСМножеством.Содержит(Корзина, "Арбуз") Тогда
    Сообщить("Корзина уже содержит Арбуз");
КонецЕсли;
Если РаботаСМножеством.Содержит(Корзина, "Бананы") Тогда
    Сообщить("Корзина уже содержит Бананы");
КонецЕсли;
> Корзина уже содержит Арбуз

Множество составных типов

Отлично! Теперь давайте представим наши товары в виде структурных объектов. Мы будем использовать код каждого товара как его уникальный идентификатор. Это позволит нам более гибко управлять товарами и обращаться к ним по их уникальным идентификаторам.

Создание товаров в виде структурных объектов с использованием кодов позволит нам легко добавлять новые товары, проверять наличие уже добавленных, удалять ненужные. Каждый товар будет представлен как отдельная структура с набором характеристик и уникальным идентификатором.

Корзина = РаботаСМножеством.Множество("Код");//  создание множества с ключем "Код"
Арбуз = Новый Структура("Код, Наименование", "1", "Арбуз");
Дыня = Новый Структура("Код, Наименование", "2", "Дыня");
Бананы = Новый Структура("Код, Наименование", "3", "Бананы");
РаботаСМножеством.Добавить(Корзина, Арбуз);
РаботаСМножеством.Добавить(Корзина, Дыня);
Если РаботаСМножеством.Содержит(Корзина, Арбуз) Тогда
    Сообщить(СтрШаблон("Корзина уже содержит товар %1 - %2", Арбуз.Код, Арбуз.Наименование));
КонецЕсли;
Если РаботаСМножеством.Содержит(Корзина, Бананы) Тогда
    Сообщить(СтрШаблон("Корзина уже содержит товар %1 - %2", Бананы.Код, Бананы.Наименование));
КонецЕсли;
> Корзина уже содержит товар 1 - Арбуз

В следующем примере мы можем увидеть работу с разными структурными объектами, которые ссылаются на один и тот же объект. Использование идентификации объекта по ключу позволяет системе однозначно идентифицировать объект, что затем позволяет проводить операции с этим объектом в рамках множества.

НаборТоваров = РаботаСМассивом.АТДМассив()
    .Положить(Новый Структура("Код, Наименование", "1", "Арбуз"))
    .Положить(Новый Структура("Код, Наименование", "2", "Ананас"))
    .Положить(Новый Структура("Код, Наименование", "3", "Бананы"))
    .ВМассив()
;
Корзина = РаботаСМножеством.Множество("Код");//  создание множества с ключем "Код"
РаботаСМножеством.Дополнить(Корзина, НаборТоваров);
Арбуз = Новый Структура("Код, Наименование", "1", "Арбуз");//  новый структурный объект, ссылающийся на добавленный ранее в составе набора товар
Если РаботаСМножеством.Содержит(Корзина, Арбуз) Тогда
    Сообщить(СтрШаблон("Корзина уже содержит товар %1 - %2", Арбуз.Код, Арбуз.Наименование));
КонецЕсли;

РаботаСМножеством.Удалить(Корзина, Арбуз);

Если НЕ РаботаСМножеством.Содержит(Корзина, Арбуз) Тогда
    Сообщить(СтрШаблон("Товар %1 - %2 был удален из корзины", Арбуз.Код, Арбуз.Наименование));
КонецЕсли;
> Корзина уже содержит товар 1 - Арбуз
> Товар 1 - Арбуз был удален из корзины

Работа с очередью

Название "Очередь" уже само по себе несет в себе определение задачи, для которой этот тип данных был создан: упорядочивание множества объектов в определенном порядке. В простом случае этот порядок определяется последовательностью добавления объектов в очередь. В таком случае использование очереди не представляет собой особого интереса по сравнению с использованием массива.

Однако ситуация меняется, когда в очереди действует определенный порядок объектов. Кроме того, помимо порядка, в очереди может быть наложено ограничение на уникальность объектов. Таким образом, основное различие между Очередью и Множеством состоит в том, что в очереди есть определенный порядок объектов.

Использование очереди становится более ценным в случаях, когда важно сохранить порядок элементов или обеспечить уникальность объектов в очереди. Очередь предоставляет гарантии относительно порядка и уникальности элементов, что делает ее удобным инструментом для работы с данными в определенных условиях.

Таким образом, Очередь может использоваться для эффективной организации данных, когда порядок объектов имеет значение, в отличие от простого массива или множества, где это свойство не задано.

В примере с простой очередью порядок действий аналогичен работе с массивом:

Очередь = РаботаСОчередью.Очередь();
РаботаСОчередью.Положить(Очередь, "Арбуз");
РаботаСОчередью.Положить(Очередь, "Ананас");
РаботаСОчередью.Положить(Очередь, "Бананы");
РаботаСОчередью.Положить(Очередь, "Бананы");
Пока НЕ РаботаСОчередью.Пустая(Очередь) Цикл
    Товар = РаботаСОчередью.Взять(Очередь);
    Сообщить(Товар);
КонецЦикла;
> Бананы
> Бананы
> Ананас
> Арбуз

Очередь уникальных значений уже имеет признаки множества:

Очередь = РаботаСОчередью.ОчередьУникальныхЗначений();
РаботаСОчередью.Положить(Очередь, "Арбуз");
РаботаСОчередью.Положить(Очередь, "Ананас");
РаботаСОчередью.Положить(Очередь, "Бананы");
РаботаСОчередью.Положить(Очередь, "Бананы");
Пока НЕ РаботаСОчередью.Пустая(Очередь) Цикл
    Товар = РаботаСОчередью.Взять(Очередь);
    Сообщить(Товар);
КонецЦикла;
> Бананы
> Ананас
> Арбуз

Та же очередь с определенным порядком уже содержит упорядоченный набор товаров:

Очередь = РаботаСОчередью.ПриоритетнаяОчередь("Сравнить(Б, А)");
РаботаСОчередью.Положить(Очередь, "Арбуз");
РаботаСОчередью.Положить(Очередь, "Ананас");
РаботаСОчередью.Положить(Очередь, "Бананы");
РаботаСОчередью.Положить(Очередь, "Бананы");
Пока НЕ РаботаСОчередью.Пустая(Очередь) Цикл
    Товар = РаботаСОчередью.Взять(Очередь);
    Сообщить(Товар);
КонецЦикла;
> Арбуз
> Ананас
> Бананы
> Бананы

Для очереди уникальных значений:

Очередь = РаботаСОчередью.ПриоритетнаяОчередьУникальныхЗначений("Сравнить(Б, А)");
РаботаСОчередью.Положить(Очередь, "Арбуз");
РаботаСОчередью.Положить(Очередь, "Ананас");
РаботаСОчередью.Положить(Очередь, "Бананы");
РаботаСОчередью.Положить(Очередь, "Бананы");
Пока НЕ РаботаСОчередью.Пустая(Очередь) Цикл
    Товар = РаботаСОчередью.Взять(Очередь);
    Сообщить(Товар);
КонецЦикла;
> Арбуз
> Ананас
> Бананы

То же самое, но со структурными объектами:

Очередь = РаботаСОчередью.ПриоритетнаяОчередьУникальныхЗначений("Сравнить(Б.Наименование, А.Наименование)", "Код");//  задана функция сравнения и ключ по полю "Код"
РаботаСОчередью.Положить(Очередь, Новый Структура("Код, Наименование", 1, "Арбуз"));
РаботаСОчередью.Положить(Очередь, Новый Структура("Код, Наименование", 2, "Ананас"));
РаботаСОчередью.Положить(Очередь, Новый Структура("Код, Наименование", 3, "Бананы"));
РаботаСОчередью.Положить(Очередь, Новый Структура("Код, Наименование", 3, "Бананы"));
Пока НЕ РаботаСОчередью.Пустая(Очередь) Цикл
    Товар = РаботаСОчередью.Взять(Очередь);
    Сообщить(СтрШаблон("%1) %2", Товар.Код, Товар.Наименование));
КонецЦикла;
> 2) Ананас
> 1) Арбуз
> 3) Бананы

Вычислитель

Постановка задачи

Для программы "Вычислитель", которая выполняет вычисление параметров с использованием математических выражений, важно определить правильный порядок вычисления параметров. Если часть параметров задана через использование значений других параметров, необходимо обеспечить такой порядок вычислений, чтобы каждый следующий параметр вычислялся после всех параметров, от которых он зависит.

Один из способов решения данной задачи - использование топологической сортировки. Этот метод позволяет упорядочить вершины графа таким образом, чтобы каждое ребро указывало на вершину, зависящую только от вершин, с которыми она соединена.

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

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

Примеры параметров и их выражений:

Параметры.Ставка = Параметры.СтавкаЗаЭскроу * Параметры.ДоляКредитаПокрытогоЭскроу + Параметры.БазоваяСтавка * (1 - Параметры.ДоляКредитаПокрытогоЭскроу)
Параметры.СтавкаЗаЭскроу = Параметры.МинЛьготнаяСтавка + Параметры.СтавкаАСВ / 100 / (1 Параметры.СтавкаФОР / 100)
Параметры.ДоляКредитаПокрытогоЭскроу = Параметры.СуммаЭскроуНачальныйОстаток * (1 - Параметры.СтавкаФОР / 100) / Параметры.ОсновнойДолгНачальныйОстаток
Параметры.БазоваяСтавка = Параметры.МинБазоваяСтавка + Параметры.КлючеваяСтавка / 100

Исходные параметры, которые задаются значением:

Параметры.МинЛьготнаяСтавка
Параметры.СтавкаАСВ
Параметры.СтавкаФОР
Параметры.СуммаЭскроуНачальныйОстаток
Параметры.ОсновнойДолгНачальныйОстаток
Параметры.МинБазоваяСтавка
Параметры.КлючеваяСтавка

Для решения этой задачи потребуется:

  1. определить порядок расчета параметров
  2. рассчитать параметры в установленном порядке

Топологическая сортировка графа зависимостей

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

Топологическая сортировка предполагает упорядочивание вершин в ориентированном ациклическом графе таким образом, чтобы все ребра шли от вершин с более ранними номерами к вершинам с более поздними номерами.

Этот подход позволяет избежать циклических зависимостей и обеспечить правильный порядок вычислений параметров в задаче вычислителя. После успешной топологической сортировки вершин графа можно гарантировать, что каждый параметр будет вычислен после всех параметров, от которых он зависит.

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

Исходно по связям зависимостей для параметров из примера получается примерно такой граф:

 

Модель расчета

 

И его упорядоченный вид будет уже таким:

 

Модель расчета

 

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

В общем виде алгоритм может быть таким:

//  Элементы - массив - все вершины графа, где связи описаны через массив параметров (свойство элемента "Параметры")
//  Порядок - число - начальное значение порядка. Порядок увеличивается при выходе из "глубины" поиска
Функция ОпределитьПорядок(Элементы, Знач Порядок = 0)
    Для Каждого Элемент Из Элементы Цикл
        ПорядокЭлемента = Элемент.Порядок;
        Если ПорядокЭлемента <> -1 Тогда //  если порядок для вершины уже определен
            Порядок = Макс(Порядок, ПорядокЭлемента);
            Продолжить;
        КонецЕсли;
        //  Рекурсивный спуск в глубину
        Порядок = ОпределитьПорядок(Элемент.Параметры, Порядок);
        //  Порядок при выходе из спуска
        Порядок = Порядок + 1;
        Элемент.Порядок = Порядок;
    КонецЦикла;
    Возврат Порядок;
КонецФункции

Код "Вычислителя"

Следующий код вычислителя демонстрирует работу с абстрактными типами.

 
 Основной код вычислителя
    //  Определение параметров
    Параметры = Новый Массив;
    Параметры.Добавить(Новый Структура("Код, Параметры, Значение", "МинЛьготнаяСтавка", Новый Массив, 0.0242));
    Параметры.Добавить(Новый Структура("Код, Параметры, Значение", "СтавкаАСВ", Новый Массив, 0.48));
    Параметры.Добавить(Новый Структура("Код, Параметры, Значение", "СтавкаФОР", Новый Массив, 4.50));
    Параметры.Добавить(Новый Структура("Код, Параметры, Значение", "СуммаЭскроуНачальныйОстаток", Новый Массив, 100));
    Параметры.Добавить(Новый Структура("Код, Параметры, Значение", "ОсновнойДолгНачальныйОстаток", Новый Массив, 1000));
    Параметры.Добавить(Новый Структура("Код, Параметры, Значение", "МинБазоваяСтавка", Новый Массив, 0.02));
    Параметры.Добавить(Новый Структура("Код, Параметры, Значение", "КлючеваяСтавка", Новый Массив, 7.5000));
    Параметры.Добавить(Новый Структура("Код, Параметры, Значение", "БазоваяСтавка", Новый Массив));
    Параметры.Добавить(Новый Структура("Код, Параметры, Значение", "ДоляКредитаПокрытогоЭскроу", Новый Массив));
    Параметры.Добавить(Новый Структура("Код, Параметры, Значение", "СтавкаЗаЭскроу", Новый Массив));
    Параметры.Добавить(Новый Структура("Код, Параметры, Значение", "Ставка", Новый Массив));
    //  Установка выражений для расчетных параметров
    Словарь = РаботаСМассивом.Преобразовать(Параметры, "ОбщийКлиентСервер.ВставитьСвойство(Накопитель, Элемент.Код, Элемент)", Новый Структура);
    Словарь["Ставка"].Вставить("Выражение", "Параметры.СтавкаЗаЭскроу * Параметры.ДоляКредитаПокрытогоЭскроу + Параметры.БазоваяСтавка * (1 - Параметры.ДоляКредитаПокрытогоЭскроу)");
    Словарь["СтавкаЗаЭскроу"].Вставить("Выражение", "Параметры.МинЛьготнаяСтавка + Параметры.СтавкаАСВ / 100 / (1 - Параметры.СтавкаФОР / 100)");
    Словарь["ДоляКредитаПокрытогоЭскроу"].Вставить("Выражение", "Параметры.СуммаЭскроуНачальныйОстаток * (1 - Параметры.СтавкаФОР / 100) / Параметры.ОсновнойДолгНачальныйОстаток");
    //Словарь["БазоваяСтавка"].Вставить("Выражение", "Параметры.МинБазоваяСтавка + Параметры.КлючеваяСтавка / 100");
    Словарь["БазоваяСтавка"].Вставить("Выражение", "Параметры.МинБазоваяСтавка + (Параметры.КлючеваяСтавка + Параметры.Ставка)/ 100");
    //  Заполнение входящих параметров для расчетных параметров
    Для Каждого Параметр Из Параметры Цикл
        Выражение = "";
        Если НЕ Параметр.Свойство("Выражение", Выражение) ИЛИ НЕ ЗначениеЗаполнено(Выражение) Тогда
            Продолжить;
        КонецЕсли;
        НайденныеПараметры = РаботаСМножеством.Множество();
        РезультатыПоиска = СтрНайтиВсеПоРегулярномуВыражению(Выражение, "\bПараметры\.[А-Яа-яA-Za-z_]\w*\b", Истина, Истина);
        Для Каждого РезультатПоиска Из РезультатыПоиска Цикл
            ИмяВходящегоПараметра = Прав(РезультатПоиска.Значение, РезультатПоиска.Длина - СтрДлина("Параметры."));
            Если РаботаСМножеством.Содержит(НайденныеПараметры, ИмяВходящегоПараметра) Тогда
                Продолжить;
            КонецЕсли;
            ВходящийПараметр = Словарь[ИмяВходящегоПараметра];
            Если ВходящийПараметр = Неопределено Тогда
                Продолжить;
            КонецЕсли;
            Параметр.Параметры.Добавить(ИмяВходящегоПараметра);
            РаботаСМножеством.Добавить(НайденныеПараметры, ИмяВходящегоПараметра);
        КонецЦикла;
    КонецЦикла;
    //  Топологическая сортировка параметров
    РаботаСМассивом.ДляКаждого(Параметры, "Элемент.Вставить('Порядок', -1)");// Сбросим порядок по-умолчанию
    ОпределитьТопологическийПорядок(Параметры, РаботаСОчередью.ОчередьУникальныхЗначений("Код"), Словарь);
    //  Вычисление параметров в установленном порядке
    РаботаСМассивом.СортироватьПо(Параметры, "Порядок");
    Для Каждого Параметр Из Параметры Цикл
        Выражение = Неопределено;
        Если НЕ Параметр.Свойство("Выражение", Выражение) Тогда
            Продолжить;
        КонецЕсли;
        ЗначенияПараметров = РаботаСМассивом.АТДМассив(Параметр.Параметры)
            .Отобразить("Контекст[Элемент]", Словарь)
            .Преобразовать("ОбщийКлиентСервер.ВставитьСвойство(Накопитель, Элемент.Код, Элемент.Значение)", Новый Структура);
        ;
        Параметр.Значение = ВычислитьВыражение(Выражение, ЗначенияПараметров);
    КонецЦикла;
    //  Вывод результата
    Результат = ОбщийКлиентСервер.ОбъектВJSON(РаботаСМассивом.Отобразить(Параметры, "Новый Структура('Код, Выражение, Значение', Элемент.Код, ?(Элемент.Свойство('Выражение'), Элемент.Выражение, ''), Элемент.Значение)"));

 

 
 Реализация алгоритма определения топологического порядка
Функция ОпределитьТопологическийПорядок(Элементы, Очередь, Словарь, Знач Порядок = 0)
    Для Каждого КлючИлиЗначение Из Элементы Цикл
        Если ТипЗнч(КлючИлиЗначение) = Тип("Строка") Тогда
            Элемент = Словарь[КлючИлиЗначение];
        Иначе
            Элемент = КлючИлиЗначение;
        КонецЕсли;
        ПорядокЭлемента = Элемент.Порядок;
        Если ПорядокЭлемента <> -1 Тогда
            Порядок = Макс(Порядок, ПорядокЭлемента);
            Продолжить;
        КонецЕсли;
        //  Контроль циклической ссылки
        Если РаботаСОчередью.Содержит(Очередь, Элемент) Тогда
            ЭлементыСтека = РаботаСМассивом.Отобразить(Очередь.Элементы, СтрШаблон("Элемент['%1']", Очередь.Ключ));
            ЭлементыСтека.Добавить(Элемент[Очередь.Ключ]);
            ВызватьИсключение "Циклическая ссылка: " + СтрСоединить(ЭлементыСтека, "<--");
        КонецЕсли;
        //  Контроль циклической ссылки
        РаботаСОчередью.Положить(Очередь, Элемент);
        //  Рекурсивный спуск
        Порядок = ОпределитьТопологическийПорядок(Элемент.Параметры, Очередь, Словарь, Порядок);
        //  Контроль циклической ссылки
        РаботаСОчередью.Взять(Очередь);
        //  Порядок при выходе из спуска
        Порядок = Порядок + 1;
        Элемент.Порядок = Порядок;
    КонецЦикла;
    Возврат Порядок;
КонецФункции

 

В коде определения топологического порядка есть контроль на наличие циклических ссылок. Вот пример ошибка, которая будет сгенерирована при запуске текущего примера:

Модель расчета

 

Действительно, в выражении вычисления параметра "Ставка" присутствует параметр БазоваяСтавка и в то же время сама БазоваяСтавка вычисляется через значение параметра "Ставка". Вот фрагмент этого кода:

    Словарь["Ставка"].Вставить("Выражение", "Параметры.СтавкаЗаЭскроу * Параметры.ДоляКредитаПокрытогоЭскроу + Параметры.БазоваяСтавка * (1 - Параметры.ДоляКредитаПокрытогоЭскроу)");
    Словарь["БазоваяСтавка"].Вставить("Выражение", "Параметры.МинБазоваяСтавка + (Параметры.КлючеваяСтавка + Параметры.Ставка)/ 100");

Уберем из выражения параметра "БазоваяСтавка" параметр "Ставка". Теперь никаких ошибок нет.

 
 Результат работы вычислителя

 

Заключение

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

Однако использование абстракций может значительно повысить читаемость и семантическую понятность кода. Если это приводит к увеличению производительности, снижению затрат на сопровождение и действительно дает положительный результат, то стоит рассмотреть и такой подход.

Критика использования абстракций в коде также имеет место быть: это требует дополнительного изучения библиотеки, не все члены команды могут быть готовы к такому подходу, возможно снижение производительности выполнения на встроенном языке 1С, лишний расход памяти и другие возможные проблемы.

Важно найти баланс между применением абстракций и особенностями встроенного языка 1С. Каждая ситуация уникальна, и не всегда концепция абстракций будет оптимальным решением. Но экспериментировать, разрабатывать собственные подходы и находить пути для оптимизации и повышения эффективности разработки важно для продвижения вперед.

 

Поставка

Пример вычислителя можно посмотреть в демо базе в разделе "Библиотека подсистем КА Демо". Примеры кода можно запустить в консоли выполнения из раздела "Инструменты" (расширение "Универсальные инструменты").

 

Модель расчета


Проект подсистемы АТДМассив разрабатывается в EDT и выложен в репозиторий.
Версия платформы для демо базы: 8.3.23

 

Смотрите также

Познакомиться с бОльшим количеством примеров работы с абстрактными типами можно и в других моих статьях:
Какой взять кредит, чтобы не платить проценты?
Работа с абстрактным массивом

Статьи других авторов на эту же тему:
Реализуем Стек, Очередь и Приоритетную очередь в 1С

абстрактные типы очередь множество массив алгоритм

См. также

Метод Дугласа-Пойкера для эффективного хранения метрик

Математика и алгоритмы Платформа 1C v8.2 Конфигурации 1cv8 Россия Абонемент ($m)

На написание данной работы меня вдохновила работа @glassman «Переход на ClickHouse для анализа метрик». Автор анализирует большой объем данных, много миллионов строк, и убедительно доказывает, что ClickHouse справляется лучше PostgreSQL. Я же покажу как можно сократить объем данных в 49.9 раз при этом: 1. Сохранить значения локальных экстремумов 2. Отклонения от реальных значений имеют наперед заданную допустимую погрешность.

1 стартмани

30.01.2024    1951    stopa85    12    

34

Алгоритм симплекс-метода для решения задачи раскроя

Математика и алгоритмы Бесплатно (free)

Разработка алгоритма, построенного на модели симплекс-метода, для нахождения оптимального раскроя.

19.10.2023    4868    user1959478    50    

34

Регулярные выражения на 1С

Математика и алгоритмы Инструментарий разработчика Платформа 1С v8.3 Мобильная платформа Россия Абонемент ($m)

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

1 стартмани

09.06.2023    7923    5    SpaceOfMyHead    17    

56

Мини-обзор разных решений задач

Математика и алгоритмы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Три задачи - три идеи - три решения. Мало кода, много смысла. Мини-статья.

03.04.2023    3183    RustIG    6    

25

Модель распределения суммы по базе

Математика и алгоритмы Платформа 1С v8.3 Россия Абонемент ($m)

Обычно под распределением понимают определение сумм пропорционально коэффициентам. Предлагаю включить сюда также распределение по порядку (FIFO, LIFO) и повысить уровень размерности до 2-х. 1-ое означает, что распределение может быть не только пропорциональным, но и по порядку, а 2-ое - это вариант реализации матричного распределения: по строкам и столбцам. Возможно вас заинтересует также необычное решение этой задачи через создание DSL на базе реализации текучего интерфейса

1 стартмани

21.03.2022    8019    7    kalyaka    11    

44

Изменения формата файлов конфигурации (CF) в 8.3.16

Математика и алгоритмы Платформа 1С v8.3 Бесплатно (free)

Дополнение по формату файлов конфигурации (*.cf) в версии 8.3.16.

16.12.2021    4633    fishca    13    

37

Интересная задача на Yandex cup 2021

Математика и алгоритмы Бесплатно (free)

Мое решение задачи на Yandex cup 2021 (frontend). Лабиринт. JavaScript.

12.10.2021    9060    John_d    73    

46
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. BackinSoda 22.04.24 10:06 Сейчас в теме
У кого еще флешбеки с расчетом себестоимости ?
2. kembrik 10 22.04.24 14:27 Сейчас в теме
Наверное будет не лишним упомянуть, что в исполнителе/элементе это есть в "коробке"
Оставьте свое сообщение