Транзитивное замыкание запросом

Публикация № 158512 29.10.12

Приемы и методы разработки - Практика программирования

В частности, показывается, как одним пакетным запросом найти ВСЕХ предков (потомков) в иерархическом справочнике. Аналогично можно определять входимость деталей в узлы и готовые изделия по их спецификациям, определять подмножества аналогичных запчастей по цепочке аналогов, решать другие подобные задачи. Приложен файл с примером отчета для замыкания иерархии произвольного справочника, позволяющий протестировать быстродействие запроса в разных условиях.

Несмотря на определенную «заумность» термина, транзитивное замыкание – это простое и часто встречающееся на практике понятие. Вот примеры:

  1. Если известно, что пункт А связан с пунктом Б, а пункт Б с пунктом В, то делая вывод о том, что пункт А в итоге связан и с пунктом В, мы «транзитивно замыкаем» отношение «связанность». 
  2. Если группа 1-1-1 входит в отдел 1-1, а тот, в свою очередь является частью департамента 1, то группа 1-1-1 также входит и в департамент 1 в результате «транзитивного замыкания» отношения «вхождение». 
  3. Если рядовой Иванов подчиняется лейтенанту Петрову, лейтенант Петров – капитану Сидорову, капитан Сидоров – майору Пронину, майор Пронин – полковнику Хитрову, а полковник Хитров – генералу Дурову, то рядовой Иванов, хотя и закончил мехмат, также подчиняется генералу Дурову в результате транзитивного замыкания отношения «подчинение».

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

Вопрос о том, как решать и можно ли вообще решить подобную задачу, встречается довольно часто. Можно упомянуть публикации "Получение родителя верхнего уровня с помощью СКД"[//infostart.ru/public/84547/], "Соединение в запросе, сравнение (В ИЕРАРХИИ)"[//infostart.ru/public/102086/], "Пример получения в запросе всех подразделений с учётом иерархии (неограниченный уровень вложенности подразделений)" [//infostart.ru/public/117349/], недавнее обсуждение на форуме "Запрос из справочника с выборкой подчиненных элементов" [http://forum.infostart.ru/forum26/topic72977/message781790/#message781790]. Решение, описываемое в статье, появилось в ходе обсуждения  "Реально написать хитрый запрос" [http://forum.infostart.ru/forum14/topic35991/message395140/#message395140], и было там же опубликовано [(103)], однако осталось почти незамеченным. Данная публикация восполняет этот пробел. 

Очевидная трудность решения данной задачи заключается в природе табличного представления отношений в реляционных СУБД. Допустим, отношения связанности (например) хранятся в таблице, которая имеет следующий вид:

Пункт ... связан с пунктом ...
1 2
2 3
3 4
... ...
99 100

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

Тем не менее, решение есть. Оно довольно простое, хотя и не очевидное. Решение опирается на кое-какую математику. Вот она:

Если А – матрица смежности графа исходного отношения, то ее элемент aij равен 1, если i связан с j и 0, если связи нет. Таким образом, ненулевые элементы матрицы А фактически отмечают существование в отношении путей длины 1, А2 (А в степени 2) – путей длины 2, А3 – путей длины 3 и так далее. Если Е – единичная матрица, то

 (А + Е)n = Аn + … + A3 + A2 + A + E.

Это специфическое биноминальное разложение представляет собой матрицу смежности графа, содержащего пути длины 0, 1, 2, 3, … , n. Здесь нет биноминальных коэффициентов, потому что операции умножения и сложения выполняются по правилам алгебры логики: 0+0=0, 0+1=1, 1+0=1, 1+1=1. Ну и поскольку в графе из N вершин нет путей длины больше N, то (A + E)N и будет матрицей смежности транзитивного замыкания исходного отношения.
Во всем, что говорилось до настоящего момента, ничего нового нет. Формулы выражают общеизвестный способ, когда мы по шагам накапливаем замыкание, добавляя на каждом шаге более длинные пути. То есть, в случае отношения иерархического подчинения, сначала находим и добавляем к итоговой таблице таблицу потомков уровня 1, потом уровня 2, потом уровня 3 и так далее.

Новое заключается в том, что:

  1. Замечено, что если M > N, где N – максимальная длина пути, то (A + E)N = (A + E)M. То есть, можно не бояться возведения в степень «с запасом», которая больше, чем максимальная длина пути (глубина иерархии). Результат от этого не изменится.
  2. Предлагается вычислять (A+E)M следующим быстрым и эффективным способом: (А+E)2 = (А+E)(А+E), (А+E)4 = (А+E)2 (А+E)2 , (А+E)8 = (А+E)4( А+E)4, (А+E)16 = (А+E)8( А+E)8 и так далее, пока степень не станет больше требуемой.

Если попытаться объяснить прием словами, без формул, то получится следующее:
На первом этапе объединяем (UNION) с исходной таблицей путей длины 1 таблицу путей длины 0 (каждый элемент связан с самим собой). Далее соединяем (JOIN) эту таблицу с собой, чтобы получить в результирующей таблице пути длины 0, 1 и 2. Снова соединяем полученную таблицу с собой и получаем в результирующей таблице пути длины 0, 1, 2, 3, 4. Уже в следующем соединении получим пути длины 0, 1, 2, 3, 4, 5, 6, 7, 8. Далее максимальная длина пути будет быстро расти и очень скоро преодолеет любой заданный предел.

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


Функция ТранзитивноеЗамыкание(ИмяСправочника, МаксимальнаяДлинаПути) Экспорт

    Пролог = "ВЫБРАТЬ Родитель НачалоДуги, Ссылка КонецДуги ПОМЕСТИТЬ ЗамыканияДлины1 ИЗ Справочник.Номенклатура

            | ГДЕ Родитель <> Значение(Справочник.Номенклатура.ПустаяСсылка)

            | ОБЪЕДИНИТЬ ВЫБРАТЬ Ссылка, Ссылка ИЗ Справочник.Номенклатура;"
;

    Рефрен = "ВЫБРАТЬ РАЗЛИЧНЫЕ ПерваяДуга.НачалоДуги, ВтораяДуга.КонецДуги ПОМЕСТИТЬ ЗамыканияДлины#2 ИЗ ЗамыканияДлины#1 КАК ПерваяДуга

            | ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины#1 КАК ВтораяДуга ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги;

            | УНИЧТОЖИТЬ ЗамыканияДлины#1;"
;

    Эпилог = "ВЫБРАТЬ НачалоДуги Предок, КонецДуги Потомок ИЗ ЗамыканияДлины#2 ГДЕ НачалоДуги <> КонецДуги";

    Запрос = Новый Запрос(СтрЗаменить(Пролог, "Номенклатура", ИмяСправочника));

    МаксимальнаяДлинаЗамыканий = 1;

    Пока МаксимальнаяДлинаЗамыканий < МаксимальнаяДлинаПути Цикл

        Запрос.Текст = Запрос.Текст + СтрЗаменить(СтрЗаменить(Рефрен, "#1", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")), "#2", Формат(2 * МаксимальнаяДлинаЗамыканий, "ЧГ=0"));

        МаксимальнаяДлинаЗамыканий = 2 * МаксимальнаяДлинаЗамыканий

    КонецЦикла;

    Запрос.Текст = Запрос.Текст + СтрЗаменить(Эпилог, "#2", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0"));

    Возврат Запрос.Выполнить().Выгрузить()

КонецФункции

В теле функции сначала собирается текст запроса. Он состоит из «пролога», который извлекает из базы данных исходное отношение, дополняет его путями нулевой длины и помещает результат во временную таблицу путей длины 1 и 0. Это единственная часть функции, которая зависит от структуры данных и типа исходного отношения. Далее следует «рефрен» - повторяемая часть запроса, в которой короткие пути соединяются в более длинные пути для новой временной таблицы, а также удаляется временная таблица, полученная на предыдущем шаге. Завершает текст запроса «эпилог», в котором извлекается итоговая временная таблица. После сборки полученный пакетный запрос единожды выполняется.

На первый взгляд может показаться, что текст запроса будет очень длинным. На самом деле, даже если справочник содержит миллион элементов в цепочке подчинения (мегаматрешка!), понадобится всего двадцать рефренов. Запрос будет в десятки (сотни?) раз короче некоторых запросов в ЗиУП. 

Второе замечание, которое можно предупредить, это то, что, возможно, потребуется отдельный запрос для определения количества элементов в справочнике, чтобы оценить максимальную длину пути (уровень подчинения). Ответом здесь будет то, что на практике почти всегда можно будет взять некоторое достаточно большое число, например 256 или 1000, исходя из характера задачи.

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

Ну и, наконец, для тех, кто заметил сходство математики предлагаемого метода и "Порождающего запроса" [//infostart.ru/public/90367/], могу добавить, что порождающий запрос появился именно вследствие данного решения.

P.S.: Если провести небольшой рефакторинг и перевести функцию на английский, она будет выглядеть компактней (всего 9 строк!)


function closure(name, N, M = 1) export

q = new query(strreplace("select parent a, ref b into r1 from catalog._ where parent <> value(catalog._.emptyref) union select ref, ref from catalog._;", "_", name));

while
M < N do

   
q.text = q.text + strreplace(strreplace("select distinct p1.a, p2.b into r#2 from r#1 as p1 join r#1 as p2 on p1.b = p2.a; drop r#1;", "#1", format(M, "NG=0")), "#2", format(2 * M, "NG=0"));

   
M = 2 * M

enddo;

q.text = q.text + strreplace("select a Предок, b Потомок from r#2 where a <> b", "#2", format(M, "NG=0"));

return
q.execute().unload()

endfunction

Скачать файлы

Наименование Файл Версия Размер
Отчет "Транзитивное замыкание иерархии"

.erf 9,13Kb
197
.erf 9,13Kb 197 Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. AlX0id 30.10.12 09:18 Сейчас в теме
мм.. первыйнах..
А можно хоть для примера полный текст запроса глянуть? )
VasilyErmak; bow; tvilt; +3 Ответить
21. ildarovich 7416 30.10.12 14:15 Сейчас в теме
(1) Вот полный текст запроса на примере справочника "Военнослужащие" с иерархией элементов и ограничением длины замыканий равным 8:
ВЫБРАТЬ
	Военнослужащие.Родитель КАК НачалоДуги,
	Военнослужащие.Ссылка КАК КонецДуги
ПОМЕСТИТЬ ЗамыканияДлины1
ИЗ
	Справочник.Военнослужащие КАК Военнослужащие
ГДЕ
	Военнослужащие.Родитель <> ЗНАЧЕНИЕ(Справочник.Военнослужащие.ПустаяСсылка)

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	Военнослужащие.Ссылка,
	Военнослужащие.Ссылка
ИЗ
	Справочник.Военнослужащие КАК Военнослужащие
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
	ПерваяДуга.НачалоДуги,
	ВтораяДуга.КонецДуги
ПОМЕСТИТЬ ЗамыканияДлины2
ИЗ
	ЗамыканияДлины1 КАК ПерваяДуга
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины1 КАК ВтораяДуга
		ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги
;

////////////////////////////////////////////////////////////­////////////////////
УНИЧТОЖИТЬ ЗамыканияДлины1
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
	ПерваяДуга.НачалоДуги,
	ВтораяДуга.КонецДуги
ПОМЕСТИТЬ ЗамыканияДлины4
ИЗ
	ЗамыканияДлины2 КАК ПерваяДуга
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины2 КАК ВтораяДуга
		ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги
;

////////////////////////////////////////////////////////////­////////////////////
УНИЧТОЖИТЬ ЗамыканияДлины2
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
	ПерваяДуга.НачалоДуги,
	ВтораяДуга.КонецДуги
ПОМЕСТИТЬ ЗамыканияДлины8
ИЗ
	ЗамыканияДлины4 КАК ПерваяДуга
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины4 КАК ВтораяДуга
		ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги
;

////////////////////////////////////////////////////////////­////////////////////
УНИЧТОЖИТЬ ЗамыканияДлины4
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ЗамыканияДлины8.НачалоДуги КАК Предок,
	ЗамыканияДлины8.КонецДуги КАК Потомок
ИЗ
	ЗамыканияДлины8 КАК ЗамыканияДлины8
ГДЕ
	ЗамыканияДлины8.НачалоДуги <> ЗамыканияДлины8.КонецДуги
Показать
23. Altair777 643 30.10.12 14:38 Сейчас в теме
(21)
> и ограничением длины замыканий равным 8
А почему именно 8?

(0) > На самом деле, даже если справочник содержит миллион элементов в цепочке подчинения (мегаматрешка!), понадобится всего двадцать рефренов
А почему именно 20? Не увидел формулу для вычисления, возможно, я невнимательно прочитал?
24. ildarovich 7416 30.10.12 14:56 Сейчас в теме
(23) Восемь - потому, что военнослужащих шесть, а 8 - ближайшее к нему сверху число из ряда 1-2-4-8-16-32-64-128-256-512-1024 и так далее.
В справочнике из шести элементов не может существовать подчинения глубины больше 5-ти.
На каждом шаге находим подчинения уровня 1-2-4-8-16-32 и так далее, пока этот уровень не станет больше числа элементов справочника или заранее заданного числа (например, в конфигурации задана максимальная глубина иерархии справочника или есть соображения разумной достаточности).
Формулы в статье нет, в тексте программы формула применяется неявно, правильное объяснение в также в (15).
25. Altair777 643 30.10.12 15:19 Сейчас в теме
(24)
> например, в конфигурации задана максимальная глубина иерархии справочника
Этого мало :) Еще должна стоять галочка "Ограничение количества уровней иерархии".

Если все основано на иерархии, тогда минус.
(0) > Аналогично можно определять входимость деталей в узлы и готовые изделия по их спецификациям, определять подмножества аналогичных запчастей по цепочке аналогов, решать другие подобные задачи.

P.S. или я не прав?
P.P.S. вообще, неплохо бы не отчет поместить, а тестовую конфигурацию, в которой можно было бы "поиграться" с данными и проверить правильность выполнения отчета.
26. ildarovich 7416 30.10.12 15:56 Сейчас в теме
(25) Не совсем понял вопрос.
В самом сложном случае максимальная длина пути в графе транзитивного замыкания отношения (любого, не обязательно иерархического) совпадает с числом вершин - элементов. Число элементов легко посчитать предварительно, еще одним запросом. Так сделано в прилагаемой обработке. Она универсальна, работает во всех случаях, без всяких ограничений на глубину иерархии. Однако предварительный подсчет числа элементов справочника отдельным запросом даже не всегда нужен. Возьмите справочник Номенклатура. Может в нем быть больше 1000 уровней? По смыслу этого справочника? Или справочник контрагентов? Всегда можно определить какое-то число с большим запасом! Или возьмите отношение подчинения военнослужащих - знаете, сколько сейчас служащих в армии? - Тогда задайте это число как ограничение уровней иерархии!
Не все основано на иерархии - суть отношения может быть любой. В исходной задаче ("Реально написать хитрый запрос") речь шла просто о связанности элементов, когда один элемент имеет реквизит (или ТЧ), содержащий(содержащую) ссылку на другой элемент справочника.
В качестве тестовой можете использовать любую типовую демо-конфигурацию.
27. Altair777 643 30.10.12 16:01 Сейчас в теме
(26)
Речь об аналогах. Как можно решить эту задачу, используя данный метод?
Приведите пример запроса.

вот такой не работает
ВЫБРАТЬ
	Подразделения.Аналог КАК НачалоДуги,
	Подразделения.Ссылка КАК КонецДуги
ПОМЕСТИТЬ ЗамыканияДлины1
ИЗ
	Справочник.Подразделения КАК Подразделения
ГДЕ
	Подразделения.Аналог <> ЗНАЧЕНИЕ(Справочник.Подразделения.ПустаяСсылка)

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	Подразделения.Ссылка,
	Подразделения.Ссылка
ИЗ
	Справочник.Подразделения КАК Подразделения
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
	ПерваяДуга.НачалоДуги,
	ВтораяДуга.КонецДуги
ПОМЕСТИТЬ ЗамыканияДлины2
ИЗ
	ЗамыканияДлины1 КАК ПерваяДуга
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины1 КАК ВтораяДуга
		ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги
;

////////////////////////////////////////////////////////////­////////////////////
УНИЧТОЖИТЬ ЗамыканияДлины1
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
	ПерваяДуга.НачалоДуги,
	ВтораяДуга.КонецДуги
ПОМЕСТИТЬ ЗамыканияДлины4
ИЗ
	ЗамыканияДлины2 КАК ПерваяДуга
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины2 КАК ВтораяДуга
		ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги
;

////////////////////////////////////////////////////////////­////////////////////
УНИЧТОЖИТЬ ЗамыканияДлины2
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
	ПерваяДуга.НачалоДуги,
	ВтораяДуга.КонецДуги
ПОМЕСТИТЬ ЗамыканияДлины8
ИЗ
	ЗамыканияДлины4 КАК ПерваяДуга
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины4 КАК ВтораяДуга
		ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги
;

////////////////////////////////////////////////////////////­////////////////////
УНИЧТОЖИТЬ ЗамыканияДлины4
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ЗамыканияДлины8.КонецДуги КАК Ссылка,
	ЗамыканияДлины8.НачалоДуги КАК Аналог
ИЗ
	ЗамыканияДлины8 КАК ЗамыканияДлины8
ГДЕ
	ЗамыканияДлины8.НачалоДуги <> ЗамыканияДлины8.КонецДуги

УПОРЯДОЧИТЬ ПО
	Ссылка,
	Аналог
АВТОУПОРЯДОЧИВАНИЕ
Показать


> Возьмите справочник Номенклатура. Может в нем быть больше 1000 уровней?
А цепочка аналогов вполне ;)

т.е. подчиненность военнослужащих в (22) основана на иерархии справочника?! Стесняюсь спросить - Вы в армии служили?

P.S. Ну раз тут адвокаты прибежали и минус мне поставили, тогда и я поставлю :)
28. ildarovich 7416 30.10.12 16:18 Сейчас в теме
(27) Вот, пожалуйста, для УПП. Этот текст должен быть записан в переменную "Пролог":
ВЫБРАТЬ
                АналогиНоменклатуры.Номенклатура КАК НачалоДуги,
                АналогиНоменклатуры.Аналог КАК КонецДуги
ПОМЕСТИТЬ ЗамыканияДлины1
ИЗ
                РегистрСведений.АналогиНоменклатуры КАК АналогиНоменклатуры
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
                АналогиНоменклатуры.Аналог,
                АналогиНоменклатуры.Номенклатура
ИЗ
                РегистрСведений.АналогиНоменклатуры КАК АналогиНоменклатуры
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
                АналогиНоменклатуры.Номенклатура,
                АналогиНоменклатуры.Номенклатура
ИЗ
                РегистрСведений.АналогиНоменклатуры КАК АналогиНоменклатуры
Показать
29. Altair777 643 30.10.12 16:24 Сейчас в теме
(28)

НачалоДуги КонецДуги
Диван для отдыха Кухонный гарнитур "Тинга-У"
Диван для отдыха Компьютер
Кухонный гарнитур "Тинга-У" Диван для отдыха
Компьютер Диван для отдыха
Диван для отдыха Диван для отдыха
Диван для отдыха Диван для отдыха

хм....

Это не окончательный запрос?!
Прикрепленные файлы:
32. ildarovich 7416 30.10.12 16:46 Сейчас в теме
(29) Было сказано, что этот текст должен был записан в переменную "Пролог". То есть я посчитал, что Вы скачаете отчет, замените в модуле объекта текст в функции ТранзитивноеЗамыкание правее Знака равенства Пролог = на тот, который был прислан, ну и попытаетесь нажать кнопку "Выполнить" после всего. По хорошему, еще стоит посчитать записи в Регистре сведений "аналоги номенклатуры". Ну если Вам это трудно сделать, чуть подождите - сделаю готовый отчет.
34. Altair777 643 30.10.12 16:51 Сейчас в теме
(32)
скачал, заменил.

	//Запрос = Новый Запрос(СтрЗаменить(Пролог, "Номенклатура", ИмяСправочника));
	Запрос = Новый Запрос;
	Запрос.Текст = Пролог;


ВЫБРАТЬ
	АналогиНоменклатуры.Номенклатура КАК НачалоДуги,
	АналогиНоменклатуры.Аналог КАК КонецДуги
ПОМЕСТИТЬ ЗамыканияДлины1
ИЗ
	РегистрСведений.АналогиНоменклатуры КАК АналогиНоменклатуры

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	АналогиНоменклатуры.Аналог,
	АналогиНоменклатуры.Номенклатура
ИЗ
	РегистрСведений.АналогиНоменклатуры КАК АналогиНоменклатуры

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	АналогиНоменклатуры.Номенклатура,
	АналогиНоменклатуры.Номенклатура
ИЗ
	РегистрСведений.АналогиНоменклатуры КАК АналогиНоменклатурыВЫБРАТЬ РАЗЛИЧНЫЕ ПерваяДуга.НачалоДуги, ВтораяДуга.КонецДуги ПОМЕСТИТЬ ЗамыканияДлины2 ИЗ ЗамыканияДлины1 КАК ПерваяДуга 
 ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины1 КАК ВтораяДуга ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги; 
 УНИЧТОЖИТЬ ЗамыканияДлины1;ВЫБРАТЬ РАЗЛИЧНЫЕ ПерваяДуга.НачалоДуги, ВтораяДуга.КонецДуги ПОМЕСТИТЬ ЗамыканияДлины4 ИЗ ЗамыканияДлины2 КАК ПерваяДуга 
 ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины2 КАК ВтораяДуга ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги; 
 УНИЧТОЖИТЬ ЗамыканияДлины2;ВЫБРАТЬ РАЗЛИЧНЫЕ ПерваяДуга.НачалоДуги, ВтораяДуга.КонецДуги ПОМЕСТИТЬ ЗамыканияДлины8 ИЗ ЗамыканияДлины4 КАК ПерваяДуга 
 ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины4 КАК ВтораяДуга ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги; 
 УНИЧТОЖИТЬ ЗамыканияДлины4;ВЫБРАТЬ РАЗЛИЧНЫЕ ПерваяДуга.НачалоДуги, ВтораяДуга.КонецДуги ПОМЕСТИТЬ ЗамыканияДлины16 ИЗ ЗамыканияДлины8 КАК ПерваяДуга 
 ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины8 КАК ВтораяДуга ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги; 
 УНИЧТОЖИТЬ ЗамыканияДлины8;ВЫБРАТЬ НачалоДуги Предок, КонецДуги Потомок ИЗ ЗамыканияДлины16 ГДЕ НачалоДуги <> КонецДуги
Показать


{ВнешнийОтчет.ТранзитивноеЗамыканиеИерархии.МодульОбъекта(69)}: Ошибка при вызове метода контекста (Выполнить)
Возврат Запрос.Выполнить().Выгрузить()
по причине:
{(22, 69)}: Синтаксическая ошибка "РАЗЛИЧНЫЕ"
РегистрСведений.АналогиНоменклатуры КАК АналогиНоменклатурыВЫБРАТЬ <<?>>РАЗЛИЧНЫЕ ПерваяДуга.НачалоДуги, ВтораяДуга.КонецДуги ПОМЕСТИТЬ ЗамыканияДлины2 ИЗ ЗамыканияДлины1 КАК ПерваяДуга
37. ildarovich 7416 30.10.12 17:12 Сейчас в теме
(34) забыли в Прологе внутри "" поставить ";"
ZeroSumGame; +1 Ответить
38. Altair777 643 30.10.12 17:13 Сейчас в теме
40. ildarovich 7416 30.10.12 17:18 Сейчас в теме
(38) Мы с Вами забыли (((
ZeroSumGame; +1 Ответить
41. Altair777 643 30.10.12 17:21 Сейчас в теме
(40)
я не забыл, я копипастил :)
109. JorjKrut 6 27.11.17 12:04 Сейчас в теме
(41) вот так и кочуют ошибки по базам клиентов...на копипаст надейся да сам не плошай!))
30. ildarovich 7416 30.10.12 16:33 Сейчас в теме
(27) Чтобы в ЦЕПОЧКЕ аналогов было 1000 записей, у Вас должно быть 1000 РАЗЛИЧНЫХ И ВЗАИМОЗАМЕНЯЕМЫХ деталей. Неправдоподобный случай. Ну, если Вы настаиваете, возможно, подойдет число 65535?
ZeroSumGame; Casey1984; kostas; pwn; +4 1 Ответить
31. Altair777 643 30.10.12 16:35 Сейчас в теме
(30) вот не надо к мелочам цепляться.
Случай правдоподобный - Автозапчасти.
33. ildarovich 7416 30.10.12 16:48 Сейчас в теме
(31) Я не цепляюсь к мелочам. Просто ни знаю ни одной запчасти, у которой ОДНОЙ было бы 1000 аналогов, да еще заданных цепочкой.
35. Altair777 643 30.10.12 16:55 Сейчас в теме
(33) нужно различать понятия "неправдоподобное" и "маловероятное"
39. ildarovich 7416 30.10.12 17:15 Сейчас в теме
(27)(29)(32) Вот обещанный отчет для замыкания аналогии ...и результаты его работы после того как в Демо-Базе добавил четыре записи в Регистр АналогиНоменклатуры. Сделал аналогами все вентиляторы по цепочке
Прикрепленные файлы:
ТранзитивноеЗамыканиеАналогии.erf
kostas; KEV8383; eeeio; Altair777; +4 Ответить
42. Altair777 643 30.10.12 17:22 Сейчас в теме
(39) спасибо! вот теперь стало намного понятнее
43. AlexO 132 30.10.12 17:28 Сейчас в теме
(24)
в общем, не совсем понятно, как теория из статьи соотносится с практикой же из статьи :)
а именно - все эти x в n степени, где n-кратное 2, и сам запрос.
Имеем:
число элементов всего справочника (включая все каталоги) - 17
пусть вложенность = 5, берем до n=8 (ну, типа, теория у нас такая, будем пока её придерживаться :) )
1-ый запрос:
получили ВСЕ элементы справочника (и где ж тут ускорение, если у меня будет мильен элементов в справочнике должны ОДНОВРЕМЕННО лежать в памяти во временной таблице? ну ладно, это вопрос первый был) - их 17, плюс - еще 13 элементов, которые ТОЛЬКО ПОДЧИНЕННЫЕ (вложены).
Итого - на первом этапе имеем 30 записей в ВрТ "ЗамыканияДлины1".
2-ой запрос:
начинаем "замыкать" полученную таблицу на саму себя методом "конец хватай сам себя из начала любой записи".
Получаем "ЗамыканияДлины2", записей - уже 34.
3-ой запрос:
начинаем "замыкать" аналогично 2-му запросу, получаем ВрТ "ЗамыканияДлины4", получаем 39 записи (ну понятно, исходные плюс насоединевываем дополнительно пары Предок-Потомок из "соседних пар" реальных вложений согласно вложенности; это вроде как получили все пары первой вложенности с конца + исходные пары - хотя на самом деле ).
Ну, и крутим дальше наш запрос, пока не создадим все пары вложенностей потомков ко всем их родителям до n включительно, каковое n определяем эмпирически сами по глубине вложенности справочника.
3-ой запрос:
ВрТ "ЗамыканияДлины8" - 40 записей.
Чем больше вложенностей - тем больше записей добавляется.
В конце из полученной ВрТ "ЗамыканияДлины8" вырезаем замыкания записей на самих себя, оставляя только пары: 23 записи
Т.е. в результате получили длинющий список всех возможных вариантов отношений по реальной иерархии: т.е. если 1-2-3-4-5, то и 1 лежит в 5.
Но тут опять же перебор ВСЕХ потомков со ВСЕМИ предками.
Шило на мыло.
48. ildarovich 7416 30.10.12 17:43 Сейчас в теме
(43) Не понял, где шило, а где мыло. Пусть запрос, указанный в статье, "мыло". А где "шило"? Приведите свой, другой вариант запроса, который будет проще, быстрее. Тогда вопрос будет понятнее. Только не забудьте, что в итоговой таблице в данном запросе должны быть все пары элементов, из которых можно попасть друг в друга. Их всегда довольно много. Именно такая таблица называется транзитивным замыканием и дает возможность для любого элемента получить список его потомков (для подчиненности) и список его предков.
50. AlexO 132 30.10.12 17:50 Сейчас в теме
(48)
так вот же, дырка в реализации в (6)
52. AlexO 132 30.10.12 17:55 Сейчас в теме
(48)
Только не забудьте, что в итоговой таблице в данном запросе должны быть все пары элементов

что-то не знаю задачи, где нужны все потомки, какие есть в справочнике, со всеми свомими родителями вместе в одной таблице :)
56. ildarovich 7416 30.10.12 18:13 Сейчас в теме
(52) А для чего, по Вашему, используется запрос из (36)?
(49)(52) Ничего сложного в этой задаче нет. Почти все алгоритмы давно открыты и исследованы. Не хватает времени и грамотных автоматизаторов.
57. AlexO 132 30.10.12 18:20 Сейчас в теме
(56)
Почти все алгоритмы давно открыты и исследованы.

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

и опять ставите в тупик... :)
для чего-для чего - найти и построить недостающие связи на основе исходных данных.
Или Вы хотели сразу и всех родителей? :)
Нет, увы, там только пример подобной реализации для своих задач.
Так я уже поднимал этот вопрос в (9) - как раз именно это и легко реализовать на уровне платформы, причем 1с-справочники - это не инопланетные корабли, запущенные неизвестно кем :)
2. bogdan_sukonnov 57 30.10.12 09:31 Сейчас в теме
*bogdan_sukonnov отскребает мозг со стен
Сергей, я бы хотел понять эту статью, и вижу как Вы считаете, что объясняете свою мысль. Но Ваше представление об очевидном и понятном далеко от реальности (к сожалению, таких как я много).
Интересно наблюдать как от объяснений на русском - Хитровых,Дуровых вы перешли к "матрица смежности графа исходного отношения", "путей длины" и т.п.
Самое плохое, что когда Вы пытаетесь объяснить "словами, без формул" терминология от формул остается.
Может быть стоит добавить примеры? Исходный справочник, результаты первого соединения, результаты второго.
И может быть список литературы? Оно, конечно погуглить можно, но все-таки.
victorree; atomskxs; +2 Ответить
22. ildarovich 7416 30.10.12 14:37 Сейчас в теме
(2) Пример последовательности таблиц в задаче о подчинении военнослужащих
Дмитрий74Чел; okumsky; +2 Ответить
3. Gulf_Stream 30.10.12 09:49 Сейчас в теме
Сейчас увидим 1с-ников без программерско - математического образования =)
sashocq; VVladislav; jONES1979; SkyHunter; const000; +5 Ответить
88. for_sale 871 04.03.15 22:27 Сейчас в теме
(3) Gulf_Stream, я 1С-ник без математического образования - и чо? Я ни слова не понял из приведённого описания, но результирующий запрос настолько банален и бородат, что просто даже жалко потраченного автором времени на все эти страшные математические выкладки.

Можно получить родителей, последовательно соединив таблицу с самой собой, выравнивая по следующему родителю - целое открытие! Прочитав заголовок, я думал, что автор изобрёл способ, как можно ТОЛЬКО запросом выбрать всех родителей и приготовился уже встать и яростно аплодировать, но увидев то, что сам делал неоднократно и то, что видел неоднократно реализованным другими, только в более простом виде и без всей этой высшей математики, даже как-то грустно стало. У этой задачи, кстати, и вариации есть, из того, что помню - из отрезков А-Б нужно складывать маршруты, где последняя точка отрезка - это первая точка следующего. Ещё почти такая же задача - на диапазоны номеров документов, когда у вас есть номера от 1 до 10000 и вы можете внутри них продавать любое число меньших диапазонов (5-100, 4579-6793 и т.п.) - не совсем тоже самое, даже, наверное, посложнее будет, но принцип того, что есть связь А-Б-В-Г...-Н, тоже присутствует. В некоторых задачах даже к использованию кода не приходилось прибегать - когда заранее известна максимальная вложенность - сразу готовый текст запроса, без извращений. В общем, так и не понял, из чего такой сыр-бор и главное - зачем тут высшая математика, если родителя-то и получить никаким другим способом не получится, кроме как последовательно нанизывать запросы со следующим родителем.

П.С, прочёл комментарии - просто не могу поверить, что никто с таким не сталкивался.

П.П.С. уничтожать таблицы в запросе имеет смысл только если используется менеджер временных таблиц или если зачем-то вдруг понадобилось использовать тоже самое имя таблицы. Во всех других случаях они и так уничтожаются после выполнения запроса.
89. ildarovich 7416 04.03.15 22:50 Сейчас в теме
(88) for_sale, чтобы разобраться в сути метода, попробуйте ответить на вопрос: сколько "ваших" запросов потребуется, чтобы последовательным нанизыванием запросов установить наличие связи 1-100 при наличии парных связей 0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-...-90-91-92-93-94-95-96-97-98-99-100? Рискну предположить, что то, неоднократно виденное вами "грустное" решение потребует 100 запросов. То есть первым запросом определяем потомков первого уровня, вторым запросом соединением с потомками первого уровня получаем потомков второго уровня и так далее - всего 100 раз? - Вы этот метод имели ввиду?
Но мой метод требует для решения той-же задачи НЕ СТО, а ВСЕГО СЕМЬ запросов. А если цепочка будет иметь длину 1000 (глубина вложенности справочника 1000), потребуется ВСЕГО ДЕСЯТЬ ЗАПРОСОВ, миллион - ВСЕГО ДВАДЦАТЬ. Двадцати сделанных на всякий случай (с запасом) запросов будет хватать почти всегда. Даже запрос не нужно динамически строить. Его можно готовым записать. В этом и разница. За этим и нужна математика. Прием называется "матричное умножение" и довольно широко используется в других областях программирования.
Если посмотрите другие мои статьи - увидите другие решенные тем же методом практические задачи. В том числе определение кратчайших путей, критических путей и так далее.

- Ну что, теперь, наконец, развеселились?

Кстати, по-поводу задачки на номера документов. Если имеется ввиду объединение соседних отрезков в более крупные, то такая задачка для дат решена мной в статье "Минимализмы". Под номером 14. Даты легко изменить на номера. Там всего пара запросов - никакой "транзитивности" в той задаче я не усмотрел. Там находится инвариант точек одного непрерывного отрезка и по нему делается группировка. - Посмотрите!
И вообще, если знаете какие-нибудь трудные задачи по запросам, скажите, мне они интересны.

По-поводу уничтожения таблиц: да, их можно не уничтожать, но сколько времени мы таким образом сэкономим? - Ничтожно мало. Я считал, что показанный запрос будет использоваться как часть других запросов, которым может понадобится освобожденная память, занятое имя таблицы. Поэтому здесь и сделан дроп. Убрать удаление легче, чем добавить, кому не нужно - уберет.
90. for_sale 871 07.03.15 09:16 Сейчас в теме
(89) да, теперь я вижу, что вы не просто нанизываете одного родителя на другого, а в прогрессии сокращаете количество запросов с астрономического до приемлемого. С точки зрения математики это, наверное, занимательно. Но с практической точки зрения я могу ещё сильнее упростить ваш запрос!

"ВЫБРАТЬ Ссылка, Родитель ИЗ Справочник.Номенклатура"

Результат запроса будет почти такой же.

Вы просто выбираете все элементы и их родителей. Практическая ценность вашего решения существовала бы только если можно было бы получить всех родителей ОДНОГО ЗАДАННОГО элемента. Но этого как раз ваш запрос не даёт, к сожалению.

Нет, можно, конечно, в последнем запросе наложить условие, получить строки с родителями, в цикле обойти их, но, благодаря использованию конструкции РАЗЛИЧНЫЕ в запросе, он работает ооочень медленно (у меня на 130 тысячах элементов так и не получилось дождаться окончания запроса, пришлось брать справочник из примерно 100 элементов - это секунд за 10 отрабатывает). Поэтому, намного "дешевле" обойти рекурсивно всех родителей заданного элемента.

А по поводу вложенности - опять же, если спуститься на землю, то реальная вложенность какая бывает? Ну 3, ну 5, ну 10 уровней (никогда не видел). Получается, что и не нужны эти заоблачные соединения миллиона таблиц, в реальности, если брать запрос, то проще и правда нанизать одного родителя на другого и получить 3-5 запросов в пакете, но зато изначально отфильтрованных по нужному элементу.
91. ildarovich 7416 08.03.15 15:46 Сейчас в теме
(90) for_sale, вы верно подметили, что если стоит задача определения связей ОДНОГО элемента в ОЧЕНЬ БОЛЬШОМ и малоуровневом справочнике, то этот метод проиграет по быстродействию внезапросной технике или "бородатому" методу.

Это связано с особенностями предлагаемого метода, которые заключаются в том, что на промежуточном этапе метод вынужден оперировать со ВСЕМИ связями справочника. Если в справочнике 130 тысяч элементов и пять уровней, то связей там - больше полумиллиона. Естественно, три раза попарно соединить таблицы такого размера - не быстрое дело. Хотя и не бесконечно долгое. При этом дело не в "РАЗЛИЧНЫЕ" (это простая и линейная по отношению к размерам таблиц операция), а в соединениях (которые должны делаться через hash-match). Чуть позже я проведу эксперимент и покажу результаты на таком объеме данных и также покажу как без всякого обхода результатов вывести всех родителей одного элемента.

Не могу поверить, что справочник из 100 элементов обрабатывается 10 секунд. Тут у вас какая-то ошибка. Обработки на основе данного метода используются в самых разных задачах и в большинстве случаев показывают приемлемое быстродействие. Справочники до 5-10 тысяч элементов обрабатываются быстро.

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

Еще практические примеры применения данного метода можно найти в статьях Уровни, глубина, прародители, циклы и аналоги запросом и Определение кратчайших путей, критических путей одним запросом.
92. AlexO 132 10.03.15 09:38 Сейчас в теме
(89)
А если цепочка будет иметь длину 1000 (глубина вложенности справочника 1000), потребуется ВСЕГО ДЕСЯТЬ ЗАПРОСОВ, миллион - ВСЕГО ДВАДЦАТЬ.
Сергей, поддержу for_sale с одной стороны: вы когда-то начинали все эти матричные умножения с реальной задачи найти все спецификации и сделать полное разузлование. И в процессе ушли от этой задачи в область теории. Т.е. самая что ни на есть практическая задача с миллионами связей (может, единственная, может, нет, но точно - самая лежащая на поверхности) - так и осталась без должного внимания.
Я все ждал, когда вернетесь к практическим задачкам - но вы наоборот, все дальше уходите от практики :)
93. ildarovich 7416 11.03.15 20:00 Сейчас в теме
(92) AlexO, честно говоря, не помню, чтобы я собирался заниматься разузлованием, использую запросную технику. Наоборот, в споре с Ish_2 в обсуждении http://infostart.ru/public/78285/ я стоял на стороне решения этой задачи с использованием кода. Да и сейчас остаюсь на тех же позициях, если говорить о практике. Из соображений гибкости и кучи всевозможных параметров спецификации в УПП сделались слишком сложными, чтобы анализировать их чисто в запросе. У меня нет клиентов, которые имеют проблемы с временем разузлования. Так что кажется, что эта задача на данный момент свою актуальность потеряла. Во всяком случае, для меня.
Насчет ухода от практики - стараюсь как могу не уходить от нее.
4. sashocq 192 30.10.12 09:50 Сейчас в теме
Т. к. редко можно встретить программиста, не проходившего в ВУЗе математику, то, думаю, большинству объяснения понятны. Ценность данной статьи в том, что автор это реализовал и сделал замер производительности. Я не думал, что это будет эффективным решением с точки зрения производительности. Автор показал обратное. За это плюс.
5. AlexO 132 30.10.12 10:00 Сейчас в теме
(4) sashocq,
Т. к. редко можно встретить программиста, не проходившего в ВУЗе математику

сейчас и математику уже не проходят в россиянсих в вузах, а только учатся как бабло рубить, и 90% 1сников вообще учились на менеджеров..
6. mymyka 30.10.12 10:06 Сейчас в теме
С математической точки зрения интересно. С практической же ...
Запрос.Текст = "ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Ссылка = &Ссылка
|ИТОГИ ПО
| Ссылка ТОЛЬКО ИЕРАРХИЯ";
МассивРодителей = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
МассивРодителей.Удалить(МассивРодителей.Найти(Ссылка).Индекс);
Проще и нагляднее )
7. AlexO 132 30.10.12 10:14 Сейчас в теме
(6) mymyka,
С математической точки зрения интересно

совершенно верно... потому как с практической..
ildarovich, у вас идет накручивание запроса в цикле по частям - а как вы определяете связи дуг между собой? Что это - конец одной и начало другой?
Что "Иванов подчиняется лейтенанту Петрову, капитан Сидоров – майору Пронину" вы знаете, но где вы узнаете подчиненнность лейтенанта Петрова и капитана Сидорова между собой, пока не опросите весь гарнизон (миллионный справочник)?
Да еще и глубину надо задавать жестко..
8. ildarovich 7416 30.10.12 11:12 Сейчас в теме
(6) Действительно, найти ВСЕХ предков ОДНОГО элемента справочника можно с помощью предложенного Вами запроса, хотя его недостатком является использование выражения ИТОГИ, что не позволяет использовать его в пакете. Метод, описываемый в статье, находит сразу ВСЕХ предков (потомков) ВСЕХ элементов справочника, может быть использован в пакете и не использует объективно (в статье показано почему) медленную (причина тормозов многих запросов) конструкцию В ИЕРАРХИИ.
Кроме того, метод подходит и для других типов связей, например связей аналогов запасных частей, когда известно, что запасная часть Б является аналогом А, запасная часть В - аналогом Б, часть Г - аналогом В и нужно найти все аналоги А. Или, например, связи документов "на основании" и тому подобное.
rozhkovdmitriy; jONES1979; +2 Ответить
9. AlexO 132 30.10.12 11:18 Сейчас в теме
(8)
хотя его недостатком является использование выражения ИТОГИ

такой способ искать родителей - это просто сопутствующая дырка в разработке языка запросов 1С, появившаяся вследствии неграмотной методологии и разгильдяйской реализации.
И именно из-за этого это единственный верный и быстрый путь найти всех родителей, в том числе и из-за отсуствия грамотных профессиональных инструментов в 1С.
И никого в 1С не удивляет - что есть встроенные сущности (Справочники в том числе), на которых все выстроено, но нет серьезных и оптимизированных средств работы с этими придуманными ими же сущностями.
Типа, и так сойдет для сельской местности.
13. ildarovich 7416 30.10.12 12:38 Сейчас в теме
(9) Зря Вы так про 1С. Тем более она здесь ни при чем: в статье описан математический метод, алгоритм. Он будет хорошо работать на любой платформе: 1С, Java, T-SQL, C++ и так далее, давая в результате существенное ускорение построения транзитивного замыкания. Этому не помешает никакая "дырка в разработке языка 1С, Т-SQL, Java, C++, PHP (нужное подчеркнуть), появившаяся вследствии неграмотной методологии и разгильдяйской реализации"
It-developer; Drivingblind; const000; orfos; sacred; AlexSvt; ERP-master; pwn; fomaOp; +9 Ответить
14. AlexO 132 30.10.12 12:44 Сейчас в теме
(13)
да я не спорю, что ваш метод больше математический, чем 1совый :)
Я про то, что сам разработчик не может/не хочет (нужное подчеркнуть) разработать инструменты по работе с им же придуманными сущностям :)
sulfur17; +1 Ответить
20. Altair777 643 30.10.12 14:09 Сейчас в теме
(13)
Тем более она здесь ни при чем: в статье описан математический метод, алгоритм.

Это описание как-то далеко от математики. Про теорию множеств и кортежи вообще не упомянуто.
It-developer; i.kovtun; +2 Ответить
10. AlexO 132 30.10.12 11:22 Сейчас в теме
(8)
Метод, описываемый в статье, находит сразу ВСЕХ предков (потомков) ВСЕХ элементов

Вы не сможете найти ВСЕХ предков вашим методом, если цепочка генеалогической связи прерывается, и её надо восстанавливать на основе отсутствующих данных - проще говоря, если таковая связь нигде не обозначена (в именах потомков-предков, в отдельной таблице связей etc), единственный способо её найти - перебрать ВСЕ элементы иерархией и выяснить, у кого из них родственная связь с искомым.
11. sashocq 192 30.10.12 11:42 Сейчас в теме
(10) AlexO,
Вы не сможете найти ВСЕХ предков вашим методом, если цепочка генеалогической связи прерывается

Вообще непонятно к чему фраза. Что значит "цепочка прерывается"? Описанный в статье метод именно для этого и предназначен — для нахождение всех предков или всех потомков всех элементов. Даже если уровень вложенности сравним с общим количеством элементов таблицы.
12. AlexO 132 30.10.12 11:44 Сейчас в теме
(11) sashocq,
я вижу в методе только восстановление заранее известных цепочек "КонецДуги является началом НачалоДуги дуги-родственника", т.е. связь родственников между собой как-то и чем-то должна быть уже предопределена.
Как в примере "рядовой подчиняется лейтененату, лейтенант подчиняется капитану, значит рядовой подчиняется капитану" (хотя по субординации как раз не так :) )
А не перебор всех-ко-всем.
Как раз этого-то и избегает Сергей, и это же вынесено в качестве главного смысла метода.
Я не нахожу составления таблицы связей все-со-всеми и поиск по ней.
А перебор всех - это как раз и исключено.
15. sashocq 192 30.10.12 13:36 Сейчас в теме
(12) AlexO,
Я не нахожу составления таблицы связей все-со-всеми

А она есть. Выполняется несколько запросов в пакете.
1-й составляет связи длиной 1 (A - B)
2-й составляет связи длиной 2 (A - ? - B)
3-й — 4
4-й — 8
5-й — 16
i-й — 2^(i-1)
т.е. чтобы в таблице оказались связи длиной до 1048576 нужно выполнить 21 такой запрос.
Не в цикле! А в пакете.
И, похоже, при небольшой модификации запроса можно добавить поле длины пути между элементами.
VVladislav; VZhulanov; KlesAlex; ERP-master; ildarovich; +5 Ответить
16. ildarovich 7416 30.10.12 13:55 Сейчас в теме
(15) Все точно! Похожими запросами (добавив длину пути) можно определить максимальную глубину справочника, а также найти циклы. Вскоре я добавлю в статью эти запросы - пока просто не могу решить: делать одну функцию или две.
19. AlexO 132 30.10.12 14:05 Сейчас в теме
(15) sashocq,
3-й составляет связи длиной 4 (A - ? - ? - B)

ну, и где тогда искать 2 и 3-го родителя?
17. Altair777 643 30.10.12 14:01 Сейчас в теме
Последствия от использования такие же как на логотипе?
18. hame1e00n 523 30.10.12 14:04 Сейчас в теме
Умно!) Математика на службе у программистов 1с :-) Плюсую :-)
36. Altair777 643 30.10.12 17:10 Сейчас в теме
44. ildarovich 7416 30.10.12 17:32 Сейчас в теме
(36) Ссылку посмотрел, спасибо, однако по-прежнему думаю, что данный метод быстрее, поскольку в указанной RCTE используется рекурсия, которая не соединяет таблицу саму с собой, а добавляет к получаемой таблице "С" (в моей статье - это таблица "А") пути длины 1 на каждом шаге из указанной таблицы "rel". То есть рекурсия будет выполнятся столько раз, какова максимальная длина пути в графе, а у меня - гораздо меньше раз!
46. AlexO 132 30.10.12 17:37 Сейчас в теме
(44)
а разве соединение таблицы самой с собой и такие многократные прогоны, равные числу вложенностей, не являются рекурсией?
47. AlexO 132 30.10.12 17:39 Сейчас в теме
(44)
т.е. в любом случае любая реализация на уровне платформы, как в (36), будет быстрее костылей :)
59. ildarovich 7416 31.10.12 10:55 Сейчас в теме
(47) Совести у Вас нет - попрекать меня костылями(шутка). А вообще-то это не костыль, это (мой запрос) - трость! И даже весьма изящная.
45. AlexO 132 30.10.12 17:32 Сейчас в теме
(36) Altair777,
вот это реальное решение - когда средствами СУБД на "аппаратном" так сказать уровне, зная конец и начало Предков-Потомков, находим всю цепочку.
А в 1С - костыли, от которых 1С не перестает хромать на обе ноги :)
При всем уважении к Сергею и его масштабным усилиям закрасить ущербность нашей любимой платформы :)
53. ildarovich 7416 30.10.12 18:07 Сейчас в теме
(45) Позволю себе сказать, что кто-то хромает на обе ноги, когда научусь ходить сам, например, заставлю работать больше 9 миллионов строк кода больше чем у 1 миллиона пользователей.
"Уважение к потугам" почему-то привык всегда автоматом заменять в тексте на "уважение к усилиям".
(46) Рекурсия рекурсии рознь, ее можно построить по-разному. Еще раз повторяю, что в предлагаемом мной подходе соединений меньше!
(47) Если запрос, приведенный в статье, Вы называете костылем, то что для Вас, например, крылья?
Fressten; const000; Пан; ERP-master; +4 Ответить
54. AlexO 132 30.10.12 18:11 Сейчас в теме
(53)
заменять в тексте

заменил, без проблем :)
то что для Вас, например, крылья?

и опять же - пример крыльев в (36)
69. ildarovich 7416 01.11.12 15:45 Сейчас в теме
(54) Специально для Вас переписал функцию. Эта та же функция! На языке 1С! Может быть в этом виде она Вам понравится?
function closure(name, N) export
p = "select parent a, ref b into r1 from catalog._ where parent <> value(catalog._.emptyref) 
	| union select ref, ref from catalog._;";
r = "select distinct p1.a, p2.b into r#2 from r#1 as p1 join r#1 as p2 on p1.b = p2.a; 
	| drop r#1;";
e = "select a Предок, b Потомок from r#2 where a <> b";
q = new query(strreplace(p, "_", name));
M = 1;
while M < N do
	q.text = q.text + strreplace(strreplace(r, "#1", format(M, "ЧГ=0")), "#2", format(2 * M, "ЧГ=0"));
	M = 2 * M
enddo;
q.text = q.text + strreplace(e, "#2", format(M, "ЧГ=0")); 
return q.execute().unload()
endfunction
Показать
55. AlexO 132 30.10.12 18:13 Сейчас в теме
(53)
больше 9 миллионов строк кода больше чем у 1 миллиона пользователей.

ну это, наверное, не только меня поставило в тупик, что это, и откуда :)
49. Altair777 643 30.10.12 17:47 Сейчас в теме
осталось только решить одну классическую задачу для этого метода - прокладка оптимальных маршрутов между точками
51. AlexO 132 30.10.12 17:51 Сейчас в теме
(49) Altair777,
как раз этого-то никто никогда и не решит :)
Разве что позитронный мозг сделают для решения каждой конкретной задачи по нахождению оптимального маршрута в конкретном случае :)
84. ildarovich 7416 08.04.14 14:08 Сейчас в теме
58. ADirks 186 31.10.12 06:49 Сейчас в теме
Ну вот вам ещё на почитать: http://citforum.ru/database/articles/tree.shtml
Простым русским языком, что характерно.
60. ildarovich 7416 31.10.12 11:24 Сейчас в теме
(58) Спасибо за ссылку. Если внимательно просмотреть указанную статью, то в ней говорится:
1. Только об отношениях иерархии, тогда как в данной статье иерархия приведена как ОДИН из примеров прикладной задачи, решаемой предлагаемым методом;
2. Из-за особых свойств отношения иерархии для нее возможно использование вспомогательных структур "чтобы легко и быстро получать ответы на перечисленные вопросы". Запрос, приведенный в статье, не требует использования вспомогательных структур, "чтобы легко и быстро получать ответы на перечисленные вопросы".
3. Кстати, метод "вспомогательная таблица", без доказательств определяемый в статье как "более эффективный и удобный" использует в качестве ВСПОМОГАТЕЛЬНОЙ таблицы как раз таблицу ТРАНЗИТИВНОГО ЗАМЫКАНИЯ (!!!). Про ее получение в статье не сказано, говорится лишь (без доказательств! - а вдруг автор ошибся?), что
Модификация вспомогательной таблицы, при изменении основной, производится довольно просто. Заботу о ней можно предоставить либо триггерам, либо приложению
4. Примеров запросов в статье ни одного нет.
Поэтому лучше использовать первоисточники. Например, того же Joe Celco.
ERP-master; AlexSvt; +2 Ответить
61. ADirks 186 31.10.12 14:28 Сейчас в теме
(60) Вообще-то, в статейке описана точно та же структура данных, которую ты в итоге получаешь. Вот и всё, что я хотел сказать :)
Слово "иерархия" в статейке можно заменить любым другим отношением, суть не изменится.

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

Типа:

фильтр
SELECT
...
FROM
спрМатериалы Материалы
WHERE
Материалы.ID IN (SELECT ID FROM Дерево_Материалы WHERE ParentID = :ВыбМатериал)

уровень (на практике не используется, просто как пример)
SELECT Count(*) Уровень
FROM Дерево_Материалы
WHERE ID = :ВыбМатериал

вот кстати ещё, про практику http://www.1cpp.ru/forum/YaBB.pl?num=1153469047/0

Я не знаю, можно ли в восьмёрке поддерживать подобную структуру, но с точки зрения быстродействия это всё же выгоднее, чем генерить её каждый раз.
62. ildarovich 7416 31.10.12 15:47 Сейчас в теме
(61) Большое спасибо за ссылки!
Не знаю, нужно ли мне спорить? Не хочу спорить по пустякам, цепляясь к Вашим словам, хотя там есть неточности. Просто не понимаю, к чему Вы клоните.
Я с Вами согласен, что для эффективной работы с иерархическим справочником МОЖНО использовать дополнительные структуры данных. Я знаю, что отношение иерархии - особенное, вершины дерева нумеруются левосторонним обходом. На этом построен подход Joe Celco. Мог бы предложить свой вариант на принципах "арифметического кодирования". Можно использовать и таблицу транзитивного замыкания (довольно, кстати, большую (если матрешка состоит из 1000 матрешек, то там будет 500000 записей)), и малыми силами поддерживать ее в актуальном состоянии при вставке, обновлении и удалении элементов справочника. Кстати, очень заинтересовала работа Ваших триггеров. Как отрабатывается ситуация удаления из цепочки 1-2-3-4-5-6, элемента 3-4? Разрывается ли при этом связь 1-6? Или я чего-то просмотрел?
Однако в моей статье речь идет не совсем об этом. Предлагается НОВЫЙ (даже для T-SQL) метод БЫСТРОГО (за счет каскадного возведения в степень) построения транзитивного замыкания с "нуля" без использования вспомогательных таблиц. При этом метод работает с ЛЮБЫМИ транзитивными отношениями (в том числе с циклическими). Метод был предложен не из любви к искусству (хотя она присутствует), а потому что люди спрашивают: "как это сделать" (ссылки я привел). Можно, например, построить транзитивное замыкание перед выполнением сложного отчета, завязанного на иерархию. Думаю, найдутся и другие применения, кроме уже указанных в статье.
А вот для дерева прав метод не подойдет. Я этого и не утверждал. Поскольку выдаваемая таблица для проверки обладания правами ОДНИМ пользователем будет ИЗБЫТОЧНА.
66. ADirks 186 31.10.12 17:57 Сейчас в теме
(62) Я не имел целью спорить, и никуда особо не клоню. Просто потрындеть за практическую реализацию. Всё-таки меня практика гораздо больше занимает, чем теория :)

> Как отрабатывается ситуация удаления из цепочки 1-2-3-4-5-6, элемента 3-4? Разрывается ли при этом связь 1-6?
А никак не отрабатывается. Это всё рассчитано на очень конкретные условия применения, а именно на иерархию справочника. Из дерева тупо удаляются все пары, в которых участвует удаляемый элемент. При этом предполагается, что при удалении нетерминального узла, сначала будут удалены и все его подчинённые узлы. Иными словами, нетерминальные узлы вообще никогда не удаляются.
При удалении именно связи будет посложнее. Надо удалять пары 1-5, 1-6, 2-5, 2-6 и т.д.

Про права. Ну почему же не подойдёт? Вполне. Там смысл был найти первого родителя в дереве, у которого что-то явно прописано. Примерно так:
|SELECT Top 1
|
|FROM
| спрОбъектПриложенияПрав ОПП
| LEFT JOIN Дерево ON Дерево.ID = ОПП.ID
| LEFT JOIN спрОбъектПриложенияПрав ОПП_Действующий ON
| ОПП_Действующий.ParentID = Дерево.ParentID
| OR ОПП_Действующий.ID = :ОбъектПриложения
|
|WHERE
| ОПП = :ОбъектПриложения
| AND ОПП_Действующий.Право != $ПустойИД
|ORDER BY
| ОПП_Действующий.Уровень Desc
(я по привычке пишу ParentId и ID, в терминах статьи будет НачалоДуги, КонецДуги)

Иерархия объектов приложения при этом такая
Задача
Документ
Шапка
Реквизит
ТЧ
Справочник
...


Что же касается объёмов вспомогательной таблицы, то опять же, учитываем специфику SQL, т.е. начхать на объёмы, главное чтобы в индекс чотко попадать.
Избыточность же здесь вообще заранее задекларирована, и сомненью не подлежит.
68. ildarovich 7416 01.11.12 12:38 Сейчас в теме
(66) Все понятно, согласен.
(67) Да, именно так. Ну и так как Update можно сделать Как Delete+Insert, все случаи будут отработаны. Это замечательно свойство деревьев - транзитивное замыкание можно наращивать, добавляя по одной дуге основного отношения и симметрично сокращать, убирая по одной дуге. Такой симметрии нет, например, в сборочных спецификациях, когда одна деталь входит в разные узлы - это значит, что есть параллельные ветви и прием из (67) не работает. Получается, Ваш практический пример рассеял мои сомнения по поводу утверждения из статьи Виноградова
Модификация вспомогательной таблицы, при изменении основной, производится довольно просто. Заботу о ней можно предоставить либо триггерам, либо приложению
Спасибо!
63. bulpi 199 31.10.12 15:59 Сейчас в теме
Если я правильно понял, в тексте функции в статье есть ошибка :
ЗамыканияДлины1, а надо ЗамыканияДлины#1
(в прологе)
64. bulpi 199 31.10.12 16:05 Сейчас в теме
(63) bulpi,
Все, понял, был неправ
65. AlexO 132 31.10.12 16:07 Сейчас в теме
(63) bulpi,
все там правильно, это не часть Рефрен.
67. ADirks 186 31.10.12 18:05 Сейчас в теме
> При удалении именно связи будет посложнее. Надо удалять пары 1-5, 1-6, 2-5, 2-6 и т.д.

|DELETE FROM Дерево
|WHERE
| ParentID IN (Родители_для_3)
| AND ID IN (Потомки_для_4)

вроде так
70. ADirks 186 02.11.12 06:40 Сейчас в теме
Лучше уж на SQL. Всё-таки восьмёрошные средства написания запросов слегка удручают.

insert Дерево (ParentID, ID)
select ParentID, ID, 0
from спрМатериалы
where ParentID != ' 0 '

insert Дерево (ParentID, ID)
select ID, ID
from спрМатериалы

declare @level int
set @level = 0

while @@RowCount > 0
Begin
--print str(@level) + str(@@ROWCOUNT)
--set @level = @level + 1

insert Дерево (ParentID, ID)
select
Родители.ParentID, Потомки.ID
from
Дерево Родители
INNER JOIN Дерево Потомки ON Потомки.ParentID = Родители.ID
where
Not Exists (select * from Дерево Д where Д.ParentID = Родители.ParentID and Д.ID = Потомки.ID)
End


Кстати вопрос, а в чём практическая ценность записей (ref, ref)? Да и теоретическая тоже не очень понятна, ведь таких связей в графе нет.
71. ildarovich 7416 02.11.12 13:18 Сейчас в теме
(70) БЕЗ таких связей на первом шаге в таблице у нас будут ТОЛЬКО пути длины 1, на втором - ТОЛЬКО пути длины 2, на третьем - ТОЛЬКО пути длины 4, на пятом - ТОЛЬКО пути длины 8 и так далее. С такими связями на первом шаге в таблице у нас будут пути длины 0 и 1, на втором - пути длины 0, 1 и 2, на третьем - пути длины 0, 1, 2, 3 и 4, на четвертом - пути длины 0, 1, 2, 3, 4, 5, 6, 7 и 8 и так далее. Этот прием оставляет в накапливаемой таблице все ранее найденные связи. Теоретически это возведение в степень не самой матрицы A, а матрицы A + E, где E - единичная матрица.
adamx; kirinalex; +2 Ответить
78. Elisy 941 17.09.13 14:56 Сейчас в теме
(70) ADirks,
Вроде, MSSQL имеет более изящные средства.
Конструкция WITH ... AS позволяет реализовать рекурсию
72. plastilin 8 07.11.12 20:06 Сейчас в теме
спасибо отличная статья
73. Al-X 20.06.13 14:17 Сейчас в теме
Спасибо ! Для меня ОЧЕНЬ полезная статья. Как раз решаю нахождение всех комплектующих к определенному изделию да еще, если нет остатков, с аналогами комплектующих.... 8(
74. Fragster 1079 13.09.13 14:15 Сейчас в теме
мне кажется, механизм "соединений наборов данных СКД" может это заменить
75. ildarovich 7416 13.09.13 16:08 Сейчас в теме
(74) Совершенно не представляю, что здесь общего.
76. Sasha255n 13.09.13 20:57 Сейчас в теме
Не совсем все понял но спасибо статья хорошая.
77. sikuda 659 14.09.13 16:35 Сейчас в теме
Спасибо за статью. Частные решения задачи иерархии(и СКД тоже) важны в понимании не иерархической структуры реляционных баз данных.
79. Zmey_72 51 17.09.13 22:03 Сейчас в теме
Пытался решить эту задачу лет 10 назад, не хватило духу. Спасибо за статью, очень полезно.
80. GreenFox 18.09.13 10:52 Сейчас в теме
Спасибо, буду разбираться. Сейчас решаю задачи производства, и надеюсь это поможет ускорить разузлование спецификаций.
81. echo77 1471 20.09.13 16:11 Сейчас в теме
Ни хера не пойму как спецификацию развернуть :-/
82. invertercant 22 28.11.13 17:08 Сейчас в теме
Гениально. Пользуюсь уже с год. Мое почтение автору.
83. VZhulanov 4 21.01.14 13:25 Сейчас в теме
Отличная статья, есть хорошие комментарии, если исключить тупые придирки (точку с запятой сам поставить не додумался) некоторых авторов. У меня нервы сдали читать эти придирки, удивляюсь как у автора хватило терпения на них на все отвечать.

Много комментов типа "средствами СУБД" все проще - не пойму, будете в задаче анализировать какая СУБД используется и для каждой свои средства использовать что-ли ? Или просто выпендриться хотелось?
У меня, например, большинство клиентов на файловой базе работает, остальные на MSSQL и на Postgress. Ибо SQL-ный вариант 1С довольно таки дорого стоит и не все могут себе его позволить.

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

Автору жирный плюс за грамотный и красивый способ решения задачи, в некоторых местах своей разработки я 100% буду его применять для оптимизации работы. А в некоторых местах кода оставлю родные средства 1С, так как на 100% уверен в малом кол-ве вложенности и малом кол-ве записей данной предметной области.
chng; kirinalex; Артано; +3 Ответить
85. headMade 144 04.11.14 14:42 Сейчас в теме
Подскажите насчет второго замечания: "Второе замечание, которое можно предупредить, это то, что, возможно, потребуется отдельный запрос для определения количества элементов в справочнике, чтобы оценить максимальную длину пути (уровень подчинения)."

Если в справочнике стоит "Ограничения кол-ва уровней иерархии", то получить макс. длину путь можно будет так?
Если Метаданные.Справочники[ИмяСправочника].ОграничиватьКоличествоУровней Тогда
МаксимальнаяДлинаПути = Метаданные.Справочники[ИмяСправочника].КоличествоУровней;
КонецЕсли;


Спасибо.
86. ildarovich 7416 04.11.14 19:15 Сейчас в теме
(85) headMade, да, в точности так
87. ildarovich 7416 20.02.15 09:28 Сейчас в теме
В обсуждении http://forum.infostart.ru/forum86/topic125683/message1306905/#message1306905 приведена еще одна конкретная практическая задача про транзитивные скидки и ее решение с помощью метода, описанного в данной статье.
94. ildarovich 7416 15.08.15 22:43 Сейчас в теме
Присоединю ссылку на статью по данной теме: Хранение иерархических структур. Симбиоз «Closure Table» и «Adjacency List». Closure Table - это и есть таблица, получаемая методом транзитивного замыкания. В указанной статье ее предлагается хранить в БД, чтобы упростить выборку иерархических данных. Довольно очевидное решение.
95. hornet_X 1 18.11.15 16:15 Сейчас в теме
Сергей,
ссылка не рабочая...
96. ildarovich 7416 18.11.15 16:26 Сейчас в теме
97. ildarovich 7416 13.07.16 13:42 Сейчас в теме
Интересно, что этим способом можно считать нарастающий итог, если в качестве исходных данных взять линейный граф, на дугах которого будут слагаемые. Расстояние от первой вершины и будет нарастающим итогом.
Конечно, это очень не эффективный способ именно для нарастающего итога, но если требуется рассчитать нарастающий итог не для сумм, а для произведений, то такое решение уже может принести пользу.
Вот запрос, считающий таким образом ряд степеней двоек до 16-ой степени включительно:
ВЫБРАТЬ 1 НомерСтроки, 2 КАК Множитель
ПОМЕСТИТЬ Дано
ОБЪЕДИНИТЬ ВЫБРАТЬ  2, 2
ОБЪЕДИНИТЬ ВЫБРАТЬ  3, 2
ОБЪЕДИНИТЬ ВЫБРАТЬ  4, 2
ОБЪЕДИНИТЬ ВЫБРАТЬ  5, 2
ОБЪЕДИНИТЬ ВЫБРАТЬ  6, 2
ОБЪЕДИНИТЬ ВЫБРАТЬ  7, 2
ОБЪЕДИНИТЬ ВЫБРАТЬ  8, 2
ОБЪЕДИНИТЬ ВЫБРАТЬ  9, 2
ОБЪЕДИНИТЬ ВЫБРАТЬ 10, 2
ОБЪЕДИНИТЬ ВЫБРАТЬ 11, 2
ОБЪЕДИНИТЬ ВЫБРАТЬ 12, 2
ОБЪЕДИНИТЬ ВЫБРАТЬ 13, 2
ОБЪЕДИНИТЬ ВЫБРАТЬ 14, 2
ОБЪЕДИНИТЬ ВЫБРАТЬ 15, 2
;
ВЫБРАТЬ НомерСтроки КАК А, НомерСтроки + 1 КАК Б, Множитель
ПОМЕСТИТЬ ДугиДлины1
ИЗ Дано
ОБЪЕДИНИТЬ
ВЫБРАТЬ НомерСтроки, НомерСтроки, 1
ИЗ Дано
;
ВЫБРАТЬ РАЗЛИЧНЫЕ Дуга1.А, Дуга2.Б, Дуга1.Множитель * Дуга2.Множитель КАК Множитель
ПОМЕСТИТЬ ДугиДлины2
ИЗ ДугиДлины1 КАК Дуга1 СОЕДИНЕНИЕ ДугиДлины1 КАК Дуга2 ПО Дуга1.Б = Дуга2.А
;   
ВЫБРАТЬ РАЗЛИЧНЫЕ Дуга1.А, Дуга2.Б, Дуга1.Множитель * Дуга2.Множитель КАК Множитель
ПОМЕСТИТЬ ДугиДлины4
ИЗ ДугиДлины2 КАК Дуга1 СОЕДИНЕНИЕ ДугиДлины2 КАК Дуга2 ПО Дуга1.Б = Дуга2.А
;
ВЫБРАТЬ РАЗЛИЧНЫЕ Дуга1.А, Дуга2.Б, Дуга1.Множитель * Дуга2.Множитель КАК Множитель
ПОМЕСТИТЬ ДугиДлины8
ИЗ ДугиДлины4 КАК Дуга1 СОЕДИНЕНИЕ ДугиДлины4 КАК Дуга2 ПО Дуга1.Б = Дуга2.А
;
ВЫБРАТЬ РАЗЛИЧНЫЕ Дуга1.А, Дуга2.Б, Дуга1.Множитель * Дуга2.Множитель КАК Множитель
ПОМЕСТИТЬ ДугиДлины16
ИЗ ДугиДлины8 КАК Дуга1 СОЕДИНЕНИЕ ДугиДлины8 КАК Дуга2 ПО Дуга1.Б = Дуга2.А
;
ВЫБРАТЬ Дуга.Б КАК НомерСтроки, Дуга.Множитель
ИЗ ДугиДлины16 КАК Дуга
ГДЕ Дуга.А = 1
Показать

Если в таблицу дано записать рядом с номерами строк не двойки, а другие множители, то и получится нарастающий итог произведений без всяких логарифмов.
Если ряд большой (сотни элементов), то уже имеет смысл воспользоваться методом "Баттерфляй", который решит ту же задачу без избыточных операций.
Vlasenko.Oleg; +1 Ответить
98. Infector 180 09.11.16 17:54 Сейчас в теме
Коллеги, а что думаете о таком варианте решения:


ВЫБРАТЬ
Номенклатура1.Ссылка КАК Ссылка,
ВЫБОР
КОГДА Номенклатура.Ссылка = Номенклатура1.Ссылка
ТОГДА 0
КОГДА Номенклатура.Ссылка = Номенклатура1.Родитель
ТОГДА 1
КОГДА Номенклатура.Ссылка = Номенклатура1.Родитель.Родитель
ТОГДА 2
КОГДА Номенклатура.Ссылка = Номенклатура1.Родитель.Родитель.Родитель
ТОГДА 3
КОГДА Номенклатура.Ссылка = Номенклатура1.Родитель.Родитель.Родитель.Родитель
ТОГДА 4
КОНЕЦ КАК Вложенность
ИЗ
Справочник.Номенклатура КАК Номенклатура
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура1
ПО (ЛОЖЬ = Номенклатура1.ЭтоГруппа)
И (Номенклатура.Ссылка = Номенклатура1.Ссылка
ИЛИ Номенклатура.Ссылка = Номенклатура1.Родитель
ИЛИ Номенклатура.Ссылка = Номенклатура1.Родитель.Родитель
ИЛИ Номенклатура.Ссылка = Номенклатура1.Родитель.Родитель.Родитель
ИЛИ Номенклатура.Ссылка = Номенклатура1.Родитель.Родитель.Родитель.Родитель)
ГДЕ
Номенклатура.Ссылка = &КорневойЭлемент
Показать


Текст так же можно собирать циклом, а дописывание соединений в запросе к СУБД оставляем платформе и ее механизмам.
В отличии от метода автора, правда, за пределами языка запросов 1C неприменимо.


Оставьте свое сообщение

См. также

Безопасная работа с транзакциями во встроенном языке Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

Разбираемся с опасностями использования транзакций во встроенном языке 1С. Познаем ошибку "В данной транзакции уже происходили ошибки". Учимся защищаться от них.

1 стартмани

25.03.2019    47784    tormozit    59    

Практическое применение менеджера расчета для расчета зарплаты "на лету" через отчет за произвольное количество месяцев в конфигурации ЗУП 3.1 и ERP

Зарплата Практика программирования v8 v8::СПР ERP2 ЗУП3.x Россия БУ Абонемент ($m)

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

2 стартмани

11.01.2022    1186    maraty    6    

Доработка типового отчета на СКД с помощью расширения

Адаптация типовых решений Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

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

1 стартмани

09.01.2022    576    Spacer    7    

Пример создания документа с движениями в ERP 2.5.7

БСП (Библиотека стандартных подсистем) Практика программирования v8 ERP2 Россия УУ Абонемент ($m)

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

1 стартмани

10.08.2021    2974    maraty    10    

Как выполнить отчет на СКД через COM и получить данные отчета? Промо

Практика программирования v8 УПП1 Россия Абонемент ($m)

Для чего это нужно. Например, нужно в одной базе получить какой-либо показатель из другой базы. Этот показатель вычисляется в каком-либо сложном отчете, который написан на СКД. Можно, конечно, "скопипастить" текст запроса из другой базы, немного подправить его и выполнять в том же COM подключении. Но с этим теряется гибкость: если отчет изменился, то нужно помнить о том, что где-то есть его "немного модифицированная" копия. В статье будет рассмотрен пример получения данных из базы ЗУП.

2 стартмани

08.05.2018    35258    wowik    3    

Работа с абстрактным массивом

Математика и алгоритмы Практика программирования v8 Россия Абонемент ($m)

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

1 стартмани

07.07.2021    4096    kalyaka    56    

Семеро одного не ждут? Асинхронное исследование асинхронности

Работа с интерфейсом Практика программирования v8 1cv8.cf Абонемент ($m)

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

1 стартмани

08.06.2021    6075    Alxby    47    

Связи параметров выбора номенклатуры и характеристики в 1С 8.3

Практика программирования v8 v8::УФ 1cv8.cf УТ11 КА2 Россия Абонемент ($m)

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

1 стартмани

22.02.2021    1620    plotnikov1c    2    

Как нарисовать граф на 1С Промо

Практика программирования v8 Абонемент ($m)

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

1 стартмани

09.08.2013    73944    ildarovich    117    

Динамическая расшифровка СКД (на примере отчета)

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

Предлагаю Вашему неподкупному вниманию вариант более-менее унифицированной реализации динамически формирующейся расшифровки СКД на примере простейшего отчета для конфигурации УТ 11.

1 стартмани

08.12.2020    1761    mr_sav    2    

СКД: все, что вы хотели знать о подмене схемы компоновки данных в отчетах и обработках

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

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

1 стартмани

07.12.2020    5681    user1502278    18    

Cбор и анализ ошибок при помощи Sentry, или как упростить жизнь себе и пользователям

Интеграция с сервисами Практика программирования v8 Абонемент ($m)

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

1 стартмани

09.10.2020    8428    hexhoc    12    

Простой способ индексирования интервалов Промо

Практика программирования v8 Абонемент ($m)

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

1 стартмани

28.09.2016    42400    ildarovich    22    

Программная корректировка при выводе отчета СКД

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

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

1 стартмани

08.10.2020    12429    dabu-dabu    16    

Загрузка, скачивание, удаление файлов с помощью НачатьПомещениеФайлаНаСервер() и НачатьПолучениеФайлаССервера()

Практика программирования v8 1cv8.cf Абонемент ($m)

В платформе 8.3.15 появились новые методы НачатьПомещениеФайлаНаСервер() и НачатьПолучениеФайлаССервера(). В данной статье рассмотрено готовое решение проверенное и прекрасно работающее на тонком и веб-клиенте.

1 стартмани

25.07.2020    13489    Flashill    15    

Методика обновления формы объекта данных при изменении объекта

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

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

1 стартмани

09.03.2020    23388    tormozit    16    

Бесплатная проверка контрагентов в ФНС (общий модуль с алгоритмом). На примере выводим статус в список справочника контрагентов Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

Если вам интересно проверить контрагенте в ФНС, вам поможет данная публикация. Весь алгоритм работы строится на основе данных, полученных с сервиса http://npchk.nalog.ru совершенно бесплатно.

1 стартмани

01.02.2018    38966    rpgshnik    59    

Отправка уведомлений с помощью командной строки, Оповещения с сервера на клиент с помощью командной строки

Практика программирования v8 1cv8.cf Россия Абонемент ($m)

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

1 стартмани

05.03.2020    8502    user5300    3    

Вывод сообщений в HTML поле средствами 1С

Практика программирования v8 v8::УФ Абонемент ($m)

Пример использования вывода большого количества сообщений в поле HTML. С возможностью открывать ссылочные объекты и создавать новые объекты передавая параметры прямо из HTML поля. Протестировано на релизах 8.3.12 и 8.3.15+

2 стартмани

31.01.2020    13442    burni4    16    

Краткое руководство по внесению изменений в конфигурацию

Практика программирования v8 1cv8.cf Абонемент ($m)

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

1 стартмани

13.01.2020    23771    sapervodichka    41    

БСП: Дополнительная обработка (Регламенты), примеры от простого к сложному Промо

БСП (Библиотека стандартных подсистем) Практика программирования v8 1cv8.cf Абонемент ($m)

Очень много попадается странных решений, которые можно решить через БСП:Дополнительные отчеты и обработки. Я бы вообще БСП из-за этой подсистемы переименовал в «Большое Спасибо Программистам». Поработаем с подсистемой в части написания регламентных заданий.

1 стартмани

10.05.2018    56408    dsdred    46    

Универсальные функции: разложение произвольной строки адреса в структуру

Универсальные функции Практика программирования v8 1cv8.cf Абонемент ($m)

Процедуры и функции раскладывают произвольную строку адрес в структуру по ключевым словам.

1 стартмани

30.12.2019    6272    vik070777    12    

"Живые" картинки со Snap.SVG

WEB Работа с интерфейсом Практика программирования v8 Абонемент ($m)

В статье рассмотрен пример использования http-сервисов для визуализации данных

1 стартмани

24.10.2019    15397    blackhole321    7    

Полное копирование одной формы в другую

Универсальные обработки Работа с интерфейсом Практика программирования v8 1cv8.cf Абонемент ($m)

Однажды я столкнулся с необходимостью открыть форму ЛЮБОГО документа с определенными изменениями, не зависящими от структуры объекта (например, заблокировать все кнопки). В интернете решения я не нашел. Обычно на форумах на запросы подобного рода отвечают чем-то вроде "покажи первоначальную задачу, а не спрашивай как реализовать то, что ты придумал". Тем не менее, мне стало интересно, как это можно сделать.

1 стартмани

03.10.2019    8625    nekit_rdx    25    

Некоторая работа с данными через COM Промо

Практика программирования v8 Абонемент ($m)

В статье приведены примеры работы с Платформой 8.X через COM (точнее, через объект COMConnector). Примеры кода были использованы при реализации прикладных задач в процессе трудовой деятельности.

2 стартмани

05.12.2012    60452    wowik    32    

Многопоточная обработка данных на примере перепроведения документов

Обработка документов Практика программирования v8 ERP2 УТ11 КА2 Абонемент ($m)

Дальнейшее развитие темы фоновой обработки данных - проведение документов в потоках. Настройка параметров и запуск основного процесса (менеджера потоков). Разбивка документов для проведения на не связанные друг с другом наборы и запуск дополнительных фоновых заданий для отдельных потоков. Отслеживание выполнения каждого потока в родительском сеансе.

1 стартмани

17.09.2019    13513    ids79    46    

Отображение истории выполнения по всем задачам комплексного процесса в документообороте

Документооборот и делопроизводство Практика программирования v8 ДО УУ Абонемент ($m)

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

1 стартмани

15.09.2019    9081    pavelpribytkin96    8    

Описание формата внутреннего представления данных 1С в контексте обмена данными

Внешние источники данных Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

Фирма 1С не рекомендует использовать внутреннее представление данных для любых целей, которые отличны от обмена с 1С:Предприятием 7.7. Но сама возможность заглянуть на "внутреннюю кухню" платформы с помощью функций ЗначениеВСтрокуВнутр(), ЗначениеВФайл(), ЗначениеИзСтрокиВнутр() и ЗначениеИзФайла(), дала возможность сообществу программистов 1С разработать новые приемы разработки и анализа. Так, именно на использовании внутреннего представления был построен алгоритм "быстрого массива", который позволяет практически мгновенно создать массив в памяти на основании строки с разделителями. С помощью разбора внутреннего представления можно "на лету" программным кодом выполнить анализ обычной формы и даже сделать редактор графической схемы. Во внутреннем формате сохраняют свои данные между сеансами различные популярные внешние обработки. А еще это возможность сделать быстрый обмен с внешними системами.

1 стартмани

06.09.2019    22156    Dementor    31    

Многопоточность. Универсальный «Менеджер потоков» (фреймворк) с отслеживанием зависимости объектов Промо

Математика и алгоритмы Универсальные функции HighLoad оптимизация Практика программирования v8 1cv8.cf Россия Абонемент ($m)

Восстановление партий, расчет зарплаты, пакетное формирование документов или отчетов - теперь все это стало доступнее. * Есть желание повысить скорость работы медленных алгоритмов! Но... * Нет времени думать о реализации многопоточности? * о запуске и остановке потоков? * о поддержании потоков в рабочем состоянии? * о передаче данных в потоки и как получить ответ из потока? * об организации последовательности? Тогда ЭТО - то что надо!!!

26.05.2017    51843    DarkAn    87    

Удобный просмотр результата запроса с большим количеством временных таблиц

Практика программирования v8 Абонемент ($m)

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

1 стартмани

27.08.2019    13367    ids79    22    

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

Практика программирования v8 1cv8.cf Абонемент ($m)

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

2 стартмани

24.08.2019    18320    BenGunn    26    

Изменяющееся контекстное меню в 1С 8.3

Практика программирования v8 v8::УФ Абонемент ($m)

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

1 стартмани

06.08.2019    23733    signum2009    16    

Новый запрос и новая таблица значений как функции Промо

Практика программирования v8 Абонемент ($m)

Предлагается две простые функции, использование которых уменьшает объем кода в конфигурациях на платформе «1С:Предприятие 8». Эти функции можно добавлять к своему общему модулю, что сделает процесс программирования более эффективным.

1 стартмани

27.11.2012    46728    ildarovich    49    

Менеджер потоков: реализация "любой" задачи в потоках

Практика программирования v8 Абонемент ($m)

Менеджер потоков – один их новых инструментов, который упрощает работу разработчиков. Насколько легко с ним, на конференции Infostart Event 2018 Education показал начальник отдела автоматизации 1С Иван Филимонов компании «Трансстроймеханизация».

01.08.2019    11684    DarkAn    7    

Процедура ПриКомпоновкеРезультата

Практика программирования v8 1cv8.cf Абонемент ($m)

Коллекция кода

1 стартмани

26.07.2019    62557    vasilev2015    68    

10 способов получить модуль числа (а может, и больше)

Практика программирования v8 1cv8.cf Абонемент ($m)

Пишем функцию вычисления модуля числа. Сколько способов существует? Давайте посчитаем!

1 стартмани

11.07.2019    16097    sam441    35    

Уровни, глубина, прародители, циклы и аналоги запросом Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

В продолжение публикации «Транзитивное замыкание запросом» [http://infostart.ru/public/158512/] добавлены другие варианты использования того же приема. Приведены запросы для быстрого определения уровней всех элементов справочника, максимальной глубины справочника, прародителей произвольных элементов справочника, запрос для быстрого определения циклов (на примере справочника спецификаций «1С:Управление производственным предприятием») и определения множеств аналогов номенклатуры (также на примере конфигурации «1С:Управление производственным предприятием»).

1 стартмани

13.11.2012    121660    ildarovich    102    

Мониторинг производительности и искусственный интеллект

HighLoad оптимизация Практика программирования Идеи и тренды в разработке v8 Абонемент ($m)

Расскажем и покажем практически, как использовать искусственный интеллект на страже мониторинга производительности. У вас появится возможность создать собственного помощника Ларису, которая возьмет на себя вопросы по контролю и диагностике состояния обслуживаемой системы.

1 стартмани

01.07.2019    10600    ivanov660    28    

"Убер на складе": динамический расчет маршрутов с учетом реальных расстояний

Склад и ТМЦ Склад и ТМЦ Практика программирования v8 УУ Абонемент ($m)

Представляю методику и инструмент для динамического расчета маршрутов отбора на высоконагруженных складах для максимального повышения эффективности склада, ускорения проходимости и, как следствие, экономии денег. Это методика и обработка для интеграции в WMS решения. Тестировалось на 1С 8.3.14.1565.

3 стартмани

24.06.2019    20093    informa1555    17    

1С:Ассемблер. Немного летнего веселья!

Практика программирования v8 1cv8.cf Абонемент ($m)

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

1 стартмани

21.06.2019    34700    Evil Beaver    150    

Выразить строку как число и строку как дату в запросе Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

Приведены и прокомментированы запросы, помогающие решать указанные задачи в составе пакетных запросов. Отличием от других известных решений является простая структура, относительная компактность, высокие быстродействие и устойчивость к ошибкам исходных данных. Применяется техника искусственных таблиц, изначально упомянутая в статье "Порождающий запрос" [http://infostart.ru/public/90367/].

1 стартмани

24.01.2013    99500    ildarovich    58    

Еще раз о рабочих днях. Быстрый способ расчета в запросах

Практика программирования v8 Абонемент ($m)

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

1 стартмани

20.06.2019    15624    Alxby    15    

Простые примеры сложных отчетов на СКД

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

Подписи в отчете. Особенности соединения наборов: как соединить несоединяемое. Остатки на дату и обороты по месяцам в одном отчете. Курс валюты на каждую дату без группировок и соединений в запросе. Отчет с произвольными колонками и с произвольной последовательностью. "Неадекватный отчет".

1 стартмани

12.06.2019    38032    Hatson    32    

Графики работы из БСП

Практика программирования v8 1cv8.cf Россия Абонемент ($m)

Не очень давно на канале 1С:БСП была опубликована заметка по использованию Графиков работы и Календарных графиков.

1 стартмани

23.05.2019    4404    fenixnow    0    

Эффективная обработка данных в оперативной памяти за счет использования коллекции "соответствие" Промо

Практика программирования v8 1cv8.cf Россия Абонемент ($m)

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

1 стартмани

11.12.2010    57068    ildarovich    40    

Создание внешней печатной формы в формате документа Word

Практика программирования v8 1cv8.cf Абонемент ($m)

В статье написано, как создать внешнюю печатную форму (для конфигураций с БСП) в формате Word.

1 стартмани

17.05.2019    26292    ВикторП    23    

Поле адреса в своем справочнике на примере 1С:Бухгалтерия 3

Практика программирования v8 v8::БУ БП3.0 Россия Абонемент ($m)

В публикации описано, как добавить поле адреса в свой справочник, чтобы вводить адрес через адресный классификатор.

1 стартмани

17.05.2019    9030    vasilievil    5    

Пример настройки шаблонов и реализации печати отчетов в документ MS Word используя функциональную часть "Библиотеки Стандартных Подсистем 1С" (БСП)

Практика программирования v8 Россия Абонемент ($m)

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

1 стартмани

23.04.2019    9353    olegpkc    11    

XDTO - часть 3 Промо

Инструменты администратора БД Практика программирования v8 1cv8.cf Абонемент ($m)

Мы продолжаем цикл статей по изучению подсистемы XDTO в 1С:Предприятие. Это третья часть, в которой мы будем работать непосредственно с подсистемой, рассмотрим главные строительные блоки подсистемы и рассмотрим небольшой пример кода.

3 стартмани

28.01.2013    207489    Evil Beaver    177    

1C + Python + Django Rest Framework + Vue.js. Опыт несложной full-stack разработки

Практика программирования v8 1cv8.cf Абонемент ($m)

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

1 стартмани

22.04.2019    42787    riposte    69    

Вывод вариантов СКД в таблицы на управляемой форме

Работа с интерфейсом Практика программирования v8 v8::УФ v8::СКД 1cv8.cf Абонемент ($m)

Задача стояла такая: есть 2 различных запроса, результаты которых выгружаются на форму обработки в таблицы значений (далее ТЗ) и программно "соприкасаются" между собой определенным образом (как именно- в рамках данной статьи неважно). Нюанс в том, что запросы должны иметь свой компоновщик настроек и могут интерактивно на форме изменяться пользователем. На оригинальность публикации не претендую - изначально в рамках поставленной задачи пытался найти что-то подобное (уже готовый шаблон) на инфостарте, возможно "плохо искал" ;)

05.04.2019    13547    artkor    1    

Функциональное программирование в 1С

Практика программирования v8 1cv8.cf Абонемент ($m)

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

1 стартмани

28.03.2019    9848    alexey.kutya    26    

[EnterpriseData] Антисвертка характеристик номенклатуры при выгрузке в Бухгалтерию

Практика программирования v8 v8::ПВХ КД УНФ БП3.0 Россия БУ Абонемент ($m)

Рассмотрена выгрузка каждой пары значений Номенклатура - Характерстика из УНФ 1.6 в отдельную номенклатуру в Бухгалтерию 3.0 путём доработки правил обмена в формате EnterpriseData.

1 стартмани

27.03.2019    6096    nforce    6