Развернуть дерево спецификаций быстро

23.10.18

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

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Развернуть дерево спецификаций быстро
.epf 54,40Kb ver:2018-10-25
17
17 Скачать (10 SM) Купить за 4 550 руб.

Суть метода

  Метод заключается в параллельном получении составов различных изделий по уровням дерева и помещение результата в кэш. Таким образом, к базе данных выполняется n-запросов, где <= Максимальная уровень глубины изделия.

Особенности метода

  • алгоритм позволяет получить составы в том случае, если не используются номенклатурные узлы;
  • в исходных комплектующих в полях Номенклатура, ХарактеристикаНоменклатуры должны быть значения типа СправочникСсылка.Номенклатура и СправочникСсылка.ХарактеристикиНоменклатуры соответственно, в противном случае там будет null;
  • не использует спецификации, явно указанные в исходных комплектующих (не стоит галка Использовать вид воспроизводства);
  • основные спецификации номенклатуры получаются на дату актуальных движений(параметр Период не указан);
  • используется алгоритм определения наиболее подходящих спецификаций подобно процедуре общего модуля УправлениеПроизводством.ОпределитьСпецификациюПоУмолчанию().

Описание алгоритма

  1. Сначала наполняется кэш исходных комплектующих спецификаций в процедуре ЗаполнитьКэшСпецификацийРекурсивно(). На вход поступает массив спецификаций изделий, которые необходимо развернуть, КэшСпецификаций - соответствие, которое нужно создать до вызова процедуры;
    1. Внутри выполняется получение исходных комплектующих для данного набора спецификаций. Полученные таблицы для каждой спецификации складываются в соответствие Ключ - Спецификация номенклатуры, Значение - Таблица исходных комплектующих, где для каждой строки определена основная спецификация номенклатуры. Функция ПолучитьСоставСпецификаций();
    2. На предыдущем шаге функция возвращает массив различных спецификаций исходных комплектующих и отправляет его в функцию ПолучитьСоставСпецификаций() еще раз;
    3. Цикл прекращается когда функция не возвратит ни одного элемента.
  2. Имея заполненный кэш спецификаций строим дерево состава изделия процедурой ПостроитьДеревоСпецификацийПоКэшу(). В качестве параметра функция принимает спецификацию номенклатуры, для которой нужно построить дерево состава;

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

Обработка-пример демонстрирует скорость работы данного подхода. Все процедуры алгоритма указаны в модуле обработке.

Тестировалось на платформах 8.2.13, 8.3.11. Конфигурация УПП 1.3.111.

Спецификации быстро дерево

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    183175    1020    403    

965

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

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    12979    sergey279    18    

65

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    8088    XilDen    36    

90

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    21007    skovpin_sa    15    

107

Запросы HighLoad оптимизация Программист Запросы Бесплатно (free)

Многие знают, что для ускорения работы запроса нужно «изучить план». При этом сам план обычно обескураживает: куча разноцветных иконок и стрелочек; ничего не понятно, но очень интересно! Аналитик производительности Александр Денисов на конференции Infostart Event 2021 Moscow Premiere рассказал, как выполняется план запроса и что нужно сделать, чтобы с его помощью находить проблемы производительности.

20.06.2023    35459    Филин    37    

121

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

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

1 стартмани

09.06.2023    14653    8    SpaceOfMyHead    20    

63

Запросы Инструментарий разработчика Программист Бесплатно (free)

Список всех популярных обработок.

17.03.2023    80187    kuzyara    92    

194
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. пользователь 24.10.18 11:59
Сообщение было скрыто модератором.
...
2. RustIG 1877 24.10.18 19:01 Сейчас в теме
(0) молодцы! молодцы, что используете кэширование, хеш-таблицы, рекурсию - все это стандартные методы ускорения работы алгоритмов.
молодцы, что не заморочились одним большим запросом для получения дерева. такие и подобные задачи как раз так и решаются.
разработчики, берите на заметку.
3. Red_Devil 181 25.10.18 16:24 Сейчас в теме
{ВнешняяОбработка.ПостроитьДеревоСпецификаций_кэш.МодульОбъекта(589)}: Ошибка при вызове метода контекста (Выполнить)
РезультатЗапроса = Запрос.Выполнить();
по причине:
{(15, 87)}: Поле не найдено "ОриентировочныйСрокПоставки"
ЕСТЬNULL(ВЫРАЗИТЬ(СпецИсходныеКомплектующие.Номенклатура КАК Справочник.Номенклатура)<<?>>.ОриентировочныйСрокПоставки, 0) КАК СрокИзготовления,

ОриентировочныйСрокПоставки это типовой реквизит?
4. SITR-utyos 1434 25.10.18 17:00 Сейчас в теме
(3) Боюсь, что нет. Исправил этот момент
Функция теперь выглядит следующим образом:
// Функция заполняет кэш исходных комплектующих указанного перечня спецификаций
//
// Параметры:
//  КэшСпецификаций  - Соответствие - 
//                 <продолжение описания параметра>
//  МассивСпецификаций  - Массив, СписокЗначений - содержит в себе перечень Спецификаций,
// 							для которых необходимо получить исходные комплектующие
//  ВключатьПустые  - Булево - Определяет, необходимо ли фиксировать Спецификации без исходных комплектующих
//
// Возвращаемое значение:
//   Массив   - Массив спецификаций исходных комплектующих. Используется чтобы вызвать эту функцию повторно
//
Функция ПолучитьСоставСпецификаций(КэшСпецификаций, МассивСпецификаций, ВключатьПустые = Ложь) Экспорт
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	СпецификацииНоменклатуры.Ссылка КАК СпецификацияПродукции,
	|	СпецИсходныеКомплектующие.НомерСтроки КАК НомерСтроки,
	|	ВЫРАЗИТЬ(СпецИсходныеКомплектующие.Номенклатура КАК Справочник.Номенклатура) КАК Номенклатура,
	|	ВЫРАЗИТЬ(СпецИсходныеКомплектующие.Номенклатура КАК Справочник.Номенклатура).ВидВоспроизводства КАК НоменклатураВидВоспроизводства,
	|	ВЫРАЗИТЬ(СпецИсходныеКомплектующие.Номенклатура КАК Справочник.Номенклатура).ВидНоменклатуры КАК НоменклатураВидНоменклатуры,
	|	ВЫРАЗИТЬ(СпецИсходныеКомплектующие.ХарактеристикаНоменклатуры КАК Справочник.ХарактеристикиНоменклатуры) КАК ХарактеристикаНоменклатуры,
	|	СпецИсходныеКомплектующие.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
	|	ВЫБОР
	|		КОГДА СпецИсходныеКомплектующие.Номенклатура ССЫЛКА Справочник.Номенклатура
	|				И СпецИсходныеКомплектующие.ЕдиницаИзмерения <> ЗНАЧЕНИЕ(Справочник.ЕдиницыИзмерения.ПустаяСсылка)
	|			ТОГДА СпецИсходныеКомплектующие.Количество * СпецИсходныеКомплектующие.ЕдиницаИзмерения.Коэффициент / СпецИсходныеКомплектующие.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент
	|		ИНАЧЕ СпецИсходныеКомплектующие.Количество
	|	КОНЕЦ КАК Количество,
	|	ВЫБОР
	|		КОГДА СпецИсходныеКомплектующие.Ссылка ЕСТЬ NULL
	|			ТОГДА ИСТИНА
	|		ИНАЧЕ ЛОЖЬ
	|	КОНЕЦ КАК СпецификацияПустая
	|ПОМЕСТИТЬ ВТИсходныеКомплектующиеСпц
	|ИЗ
	|	Справочник.СпецификацииНоменклатуры КАК СпецификацииНоменклатуры
	|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.СпецификацииНоменклатуры.ИсходныеКомплектующие КАК СпецИсходныеКомплектующие
	|		ПО СпецификацииНоменклатуры.Ссылка = СпецИсходныеКомплектующие.Ссылка
	|ГДЕ
	|	СпецификацииНоменклатуры.Ссылка В(&МассивСпецификаций)
	|	И ВЫБОР
	|			КОГДА &ВключатьПустые
	|				ТОГДА ИСТИНА
	|			ИНАЧЕ НЕ СпецИсходныеКомплектующие.Ссылка ЕСТЬ NULL
	|		КОНЕЦ
	|;
	|
	|////////////////////////////////////////////////////////////­////////////////////
	|ВЫБРАТЬ РАЗЛИЧНЫЕ
	|	ВЫРАЗИТЬ(ВТИсходныеКомплектующиеСпц.Номенклатура КАК Справочник.Номенклатура) КАК Номенклатура,
	|	ВТИсходныеКомплектующиеСпц.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры
	|ПОМЕСТИТЬ ВТНоменклатураХарактеристики
	|ИЗ
	|	ВТИсходныеКомплектующиеСпц КАК ВТИсходныеКомплектующиеСпц
	|;
	|
	|////////////////////////////////////////////////////////////­////////////////////
	|ВЫБРАТЬ
	|	ОсновныеСпецификацииНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура,
	|	ОсновныеСпецификацииНоменклатурыСрезПоследних.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
	|	ОсновныеСпецификацииНоменклатурыСрезПоследних.СпецификацияНоменклатуры КАК СпецификацияНоменклатуры,
	|	3 КАК Приоритет
	|ПОМЕСТИТЬ ВТСпецификации
	|ИЗ
	|	ВТНоменклатураХарактеристики КАК ВТНоменклатураХарактеристики
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ОсновныеСпецификацииНоменклатуры.СрезПоследних(
	|				,
	|				(Номенклатура, ХарактеристикаНоменклатуры) В
	|					(ВЫБРАТЬ
	|						Таблица.Номенклатура,
	|						Таблица.ХарактеристикаНоменклатуры
	|					ИЗ
	|						ВТНоменклатураХарактеристики КАК Таблица)) КАК ОсновныеСпецификацииНоменклатурыСрезПоследних
	|		ПО ВТНоменклатураХарактеристики.Номенклатура = ОсновныеСпецификацииНоменклатурыСрезПоследних.Номенклатура
	|			И ВТНоменклатураХарактеристики.ХарактеристикаНоменклатуры = ОсновныеСпецификацииНоменклатурыСрезПоследних.ХарактеристикаНоменклатуры
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	ОсновныеСпецификацииНоменклатурыСрезПоследних.Номенклатура,
	|	ВТНоменклатураХарактеристики.ХарактеристикаНоменклатуры,
	|	ОсновныеСпецификацииНоменклатурыСрезПоследних.СпецификацияНоменклатуры,
	|	4
	|ИЗ
	|	ВТНоменклатураХарактеристики КАК ВТНоменклатураХарактеристики
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ОсновныеСпецификацииНоменклатуры.СрезПоследних(
	|				,
	|				Номенклатура В
	|						(ВЫБРАТЬ
	|							Таблица.Номенклатура
	|						ИЗ
	|							ВТНоменклатураХарактеристики КАК Таблица)
	|					И ХарактеристикаНоменклатуры = ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка)) КАК ОсновныеСпецификацииНоменклатурыСрезПоследних
	|		ПО ВТНоменклатураХарактеристики.Номенклатура = ОсновныеСпецификацииНоменклатурыСрезПоследних.Номенклатура
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	ОсновныеСпецификацииНоменклатурыСрезПоследних.Номенклатура,
	|	ВТНоменклатураХарактеристики.ХарактеристикаНоменклатуры,
	|	ОсновныеСпецификацииНоменклатурыСрезПоследних.СпецификацияНоменклатуры,
	|	5
	|ИЗ
	|	ВТНоменклатураХарактеристики КАК ВТНоменклатураХарактеристики
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ОсновныеСпецификацииНоменклатуры.СрезПоследних(
	|				,
	|				Номенклатура В
	|					(ВЫБРАТЬ
	|						Таблица.Номенклатура
	|					ИЗ
	|						ВТНоменклатураХарактеристики КАК Таблица)) КАК ОсновныеСпецификацииНоменклатурыСрезПоследних
	|		ПО ВТНоменклатураХарактеристики.Номенклатура = ОсновныеСпецификацииНоменклатурыСрезПоследних.Номенклатура
	|;
	|
	|////////////////////////////////////////////////////////////­////////////////////
	|ВЫБРАТЬ
	|	ВТСпецификации.Номенклатура,
	|	ВТСпецификации.ХарактеристикаНоменклатуры,
	|	ВТСпецификации.СпецификацияНоменклатуры
	|ПОМЕСТИТЬ ВТСпецификацииПоУмолчанию
	|ИЗ
	|	ВТСпецификации КАК ВТСпецификации
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
	|			ВТСпецификации.Номенклатура КАК Номенклатура,
	|			ВТСпецификации.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
	|			МИНИМУМ(ВТСпецификации.Приоритет) КАК Приоритет
	|		ИЗ
	|			ВТСпецификации КАК ВТСпецификации
	|		
	|		СГРУППИРОВАТЬ ПО
	|			ВТСпецификации.Номенклатура,
	|			ВТСпецификации.ХарактеристикаНоменклатуры) КАК МинимальныйПриоритет
	|		ПО ВТСпецификации.Номенклатура = МинимальныйПриоритет.Номенклатура
	|			И ВТСпецификации.ХарактеристикаНоменклатуры = МинимальныйПриоритет.ХарактеристикаНоменклатуры
	|			И ВТСпецификации.Приоритет = МинимальныйПриоритет.Приоритет
	|;
	|
	|////////////////////////////////////////////////////////////­////////////////////
	|ВЫБРАТЬ
	|	ВТИсходныеКомплектующиеСпц.СпецификацияПродукции КАК СпецификацияПродукции,
	|	ВТИсходныеКомплектующиеСпц.НомерСтроки,
	|	ВТИсходныеКомплектующиеСпц.Номенклатура,
	|	ВТИсходныеКомплектующиеСпц.НоменклатураВидВоспроизводства,
	|	ВТИсходныеКомплектующиеСпц.НоменклатураВидНоменклатуры,
	|	ВТИсходныеКомплектующиеСпц.ХарактеристикаНоменклатуры,
	|	ВТИсходныеКомплектующиеСпц.ЕдиницаИзмерения,
	|	ВТИсходныеКомплектующиеСпц.Количество,
	|	ВТИсходныеКомплектующиеСпц.СпецификацияПустая,
	|	ВТСпецификацииПоУмолчанию.СпецификацияНоменклатуры,
	|	ВЫБОР
	|		КОГДА ВТИсходныеКомплектующиеСпц.СпецификацияПродукции = ВТСпецификацииПоУмолчанию.СпецификацияНоменклатуры
	|			ТОГДА ИСТИНА
	|		ИНАЧЕ ЛОЖЬ
	|	КОНЕЦ КАК ЗацикливаниеСпецификации,
	|	ЕСТЬNULL(СпецВыходныеИзделия.ТочкаМаршрута.Подразделение, ЗНАЧЕНИЕ(Справочник.Подразделения.ПустаяСсылка)) КАК ЦехИзготовитель,
	|	СпецВыходныеИзделия.ТочкаМаршрута КАК ТочкаМаршрута
	|ИЗ
	|	ВТИсходныеКомплектующиеСпц КАК ВТИсходныеКомплектующиеСпц
	|		ЛЕВОЕ СОЕДИНЕНИЕ ВТСпецификацииПоУмолчанию КАК ВТСпецификацииПоУмолчанию
	|			ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.СпецификацииНоменклатуры.ВыходныеИзделия КАК СпецВыходныеИзделия
	|			ПО ВТСпецификацииПоУмолчанию.СпецификацияНоменклатуры = СпецВыходныеИзделия.Ссылка
	|				И ВТСпецификацииПоУмолчанию.Номенклатура = СпецВыходныеИзделия.Номенклатура
	|		ПО ВТИсходныеКомплектующиеСпц.Номенклатура = ВТСпецификацииПоУмолчанию.Номенклатура
	|			И ВТИсходныеКомплектующиеСпц.ХарактеристикаНоменклатуры = ВТСпецификацииПоУмолчанию.ХарактеристикаНоменклатуры
	|
	|УПОРЯДОЧИТЬ ПО
	|	ВТИсходныеКомплектующиеСпц.СпецификацияПродукции,
	|	ВТИсходныеКомплектующиеСпц.НомерСтроки
	|ИТОГИ ПО
	|	СпецификацияПродукции";
	// Устанавливаем параметры
	Запрос.УстановитьПараметр("МассивСпецификаций", МассивСпецификаций);
	Запрос.УстановитьПараметр("ВключатьПустые",		ВключатьПустые);
	РезультатЗапроса = Запрос.Выполнить();
	ВыборкаПоСпецификациям = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
	
	// Создадим таблицу такую же как колонки выборки
	СтруктураТаблицы = Новый ТаблицаЗначений;
	Для Каждого Колонка Из РезультатЗапроса.Колонки Цикл
		Если Колонка.Имя = "СпецификацияПродукции" Тогда
			Продолжить;
		КонецЕсли;
		
		ЗаполнитьЗначенияСвойств(СтруктураТаблицы.Колонки.Добавить(), Колонка);
		
	КонецЦикла;
	
	// Здесь будем хранить различные спецификации исходных комплектующих
	СпецификацииИсходныхКомплектующих = Новый ТаблицаЗначений;
	СпецификацииИсходныхКомплектующих.Колонки.Добавить("СпецификацияНоменклатуры");
	
	// Пройдемся по спецификациям и добавим их в кэш
	Пока ВыборкаПоСпецификациям.Следующий() Цикл
		
		Выборка = ВыборкаПоСпецификациям.Выбрать();
		ИсходныеКомплектующие = СтруктураТаблицы.СкопироватьКолонки();// Создаем Таблицу исходных комплетующих текущей специфиикации. Создаем НОВУЮ таблицу, это очень важно
		Пока Выборка.Следующий() Цикл
			// Спецификация пустая - прерываемся, чтобы таблица исходных комплектующих была пустой
			Если Выборка.СпецификацияПустая Тогда
				Прервать;
			КонецЕсли;
			
		    НоваяСтрока = ИсходныеКомплектующие.Добавить();
		    ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
			
			// Если обнаружено зацикливание - очищаем Спецификацию, чтобы это не обрабатывалось
			Если Выборка.ЗацикливаниеСпецификации Тогда
				Сообщить("Обнаружено зацикливание спецификации на изделие " + Выборка.Номенклатура, СтатусСообщения.Важное);
				НоваяСтрока.СпецификацияНоменклатуры = Справочники.СпецификацииНоменклатуры.ПустаяСсылка();
				Продолжить;
			КонецЕсли;
			
			// Если спецификацию еще не получали - добавим в список
			Если КэшСпецификаций.Получить(Выборка.СпецификацияНоменклатуры) = Неопределено Тогда
				НоваяСтрока = СпецификацииИсходныхКомплектующих.Добавить();
				НоваяСтрока.СпецификацияНоменклатуры = Выборка.СпецификацияНоменклатуры; 
			КонецЕсли;
		КонецЦикла;
		
		// Добавляем в кэш Спецификацию и еще исходные комплектующие в виде ТаблицыЗначений
		КэшСпецификаций.Вставить(ВыборкаПоСпецификациям.СпецификацияПродукции, ИсходныеКомплектующие);
		
	КонецЦикла;
	
	СпецификацииИсходныхКомплектующих.Свернуть("СпецификацияНоменклатуры");
	
	Возврат СпецификацииИсходныхКомплектующих.ВыгрузитьКолонку("СпецификацияНоменклатуры");
	
КонецФункции
Показать
Светлый ум; +1 Ответить
5. triviumfan 99 25.10.18 21:11 Сейчас в теме
(4) В ВТ "ВТИсходныеКомплектующиеСпц" и "ВТНоменклатураХарактеристики" в качестве поля "Номенклатура" после "Выразить()" могут быть NULL.
6. SITR-utyos 1434 26.10.18 07:37 Сейчас в теме
(5)
В ВТ "ВТИсходныеКомплектующиеСпц" и "ВТНоменклатураХарактеристики" в качестве поля "Номенклатура" после "Выразить()" могут быть NULL.

Согласен. Добавлено описание в раздел Особенности метода.
9. Светлый ум 454 22.07.22 08:22 Сейчас в теме
(4) + 1 Потестим в выходные
7. AlexDidenko 21.12.19 15:47 Сейчас в теме
В ERP 2.4 будет работать?
8. echo77 1921 21.12.19 15:50 Сейчас в теме
(7) Вряд ли, но реализованный подход думаю, можно будет использовать
10. user1572191 01.05.23 18:56 Сейчас в теме
Добрый день, может кто-нибудь обработку продать не за стартмани?
Оставьте свое сообщение