Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Очень популярная тема (более 25 ответов) Отобрать подчиненные и док. основания (число прочтений - 8011 )
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Отобрать подчиненные и док. основания
29. Января 2008 :: 14:11
Печать  
Есть группа документов, вводимых на основании друг друга, структура подчиненности может быть нелинейной. Как имея один документ любого уровня подчиненности получить список всех взаимосвязанных документов?
Заранее спасибо
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Отобрать подчиненные и док. основания
Ответ #1 - 29. Января 2008 :: 14:33
Печать  
Если для отчёта, тут неплохой пример:
Граф подчиненности документов
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Отобрать подчиненные и док. основания
Ответ #2 - 29. Января 2008 :: 14:55
Печать  
Или вот ещё одна реализация графа подчиненности от noprogrammera
  
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Отобрать подчиненные и док. основания
Ответ #3 - 29. Января 2008 :: 15:16
Печать  
Не видел, как в приведенных выше ссылках сделано, но, чем черт не шутит - может, у меня по другому Улыбка

Код
Выбрать все
	ИдНачДока13	= РадугаСервис.ЗначениеВДлиннуюСтрокуБД(ДокДерева);
	ИдНачДока9	= Прав(ИдНачДока13,9);
	ТабДоковSQL	= глИмяВременнойТаблицы(); //"#ТабДоков"; //

	ОщийРеквизитДокументОснование	= //SP158
	ОщийРеквизитСуммаДокумента		= "SP"+РадугаМД.ИДОбъекта(Метаданные.ОбщийРеквизитДокумента("СуммаДокумента"));

	ТекстЗапроса = "
	| Set NoCount On
	| Declare @ИдТемпДок13 Char(13), @ИдКореньДок13 Char(13), @ИдПустойДок Char(13)
	|
	| Set @ИдПустойДок = '   0     0   '
	| Set @ИдТемпДок13 = '"+ИдНачДока13+"'
	|
	| While @ИдТемпДок13 <> @ИдПустойДок Begin
	| 	Set @ИдКореньДок13 = @ИдТемпДок13
	| 	Set @ИдТемпДок13   =
	| 		(
	| 			Select Top 1 "+ОщийРеквизитДокументОснование+" ДокОснование From _1SJOURN (NoLock)
	| 			Where IDDOC = Right(@ИдКореньДок13,9)
	| 		)
	| End
	|
	| Select Cast(Right(@ИдПустойДок,9) As Char(9)) ИдРодителя9, @ИдПустойДок ИдРодителя13, Cast(Right(@ИдКореньДок13,9) As Char(9)) ИдПодчДок9, @ИдКореньДок13 ИдПодчДок13 Into "+ТабДоковSQL+"
	|
	| While 1 = 1 Begin
	|	  Insert Into "+ТабДоковSQL+" (ИдРодителя9, ИдРодителя13, ИдПодчДок9, ИдПодчДок13)
	| 	Select
	| 		ИдРодителя9, ИдРодителя13, ИдПодчДок9, ИдПодчДок13
	| 	From
	| 	(
	| 	 	Select Right(ИдПодчДок13,9) ИдРодителя9, ИдПодчДок13 ИдРодителя13, Right(CHILD_DATE_TIME_IDDOC, 9) ИдПодчДок9, Журнал.SP810 ИдПодчДок13
	|		  From _1SCRDOC (NoLock)
	| 	 	Inner Join "+ТабДоковSQL+" (NoLock) On MDID = 0 And ParentVal = 'O1'+ИдПодчДок13
	| 		Left Join _1SJOURN Журнал (NoLock) On Журнал.IDDOC = CHILDID
	| 	 	Where
	| 		ИдПодчДок13 Not In (Select ИдРодителя13 From "+ТабДоковSQL+" (NoLock))
	| 	) Выборка
	| 	Where
	| 	ИдПодчДок9 Not In (Select ИдРодителя9 From "+ТабДоковSQL+" (NoLock))
	| 	And ИдПодчДок9 Not In (Select ИдПодчДок9 From "+ТабДоковSQL+" (NoLock))
	| 	And dbo.ВозможностьПодчинения(ИдРодителя9, ИдПодчДок9) = 1
	|
	| 	If @@RowCount = 0
	| 		Break
	| End
	|
	|
	| Select ИдРодителя9, ИдПодчДок9, IdDocDef ВидПодчДок
	| , dbo.ПредставлениеДокумента(ИдПодчДок9,1,1) ПредставлениеДока
	| , (Case When IsMark = 1 Then 3 Else Case When Closed&1 = 1 Then 2 Else 1 End End) Признак
	| , "+ОщийРеквизитСуммаДокумента+" СуммаДокумента
	| From "+ТабДоковSQL+" (NoLock)
	| Left Join _1SJOURN (NoLock) On ИдПодчДок9 = IDDOC
	| Order By Date_Time_IDDOC
	|
	| Drop Table "+ТабДоковSQL+"
	|
	| ";
 

  
Наверх
 
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #4 - 29. Января 2008 :: 17:02
Печать  
Спасибо всем, беру таймаут чтобы попробывать
  
Наверх
 
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #5 - 30. Января 2008 :: 07:29
Печать  
Спасибо всем за инфу
Все описанные методы используют следующее: поиск документа верхнего уровня, сефинг вниз по подчиненным документам, при этом число запросов в общем случае 2*ЧислоУровнейИерархии. Я делал также, алгоритм адаптирован к построению дерева, из предложенного взял поиск Документа основания через1С++. А если дерево подчиненности не нужно, нужен только список связанных документов, можно ли уменьшить общее число запросов (применяю это в модуле проведения, хочется ускорить)?

  
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Отобрать подчиненные и док. основания
Ответ #6 - 30. Января 2008 :: 08:03
Печать  
Что есть "список связанных документов"?
  
Наверх
 
IP записан
 
Вадимко
God Member
*****
Отсутствует


Нам бы чего про ОдноЦэ...

Сообщений: 1048
Местоположение: Минск
Зарегистрирован: 24. Мая 2006
Пол: Мужской
Re: Отобрать подчиненные и док. основания
Ответ #7 - 30. Января 2008 :: 08:24
Печать  
Если хочется ускорить, то может хранить данные в регистре а не выуживать их бегая по десяткам доков? Как считаешь?
  

Кампутер, кофе и сигареты - это очень плохо для моего здоровья...
Наверх
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Отобрать подчиненные и док. основания
Ответ #8 - 30. Января 2008 :: 08:31
Печать  
Цитата:
Если хочется ускорить, то может хранить данные в регистре а не выуживать их бегая по десяткам доков? Как считаешь?

+1

Сам исправлял подобное - достаточно много геморроя при исправлении - но потом лафа.
Особенно лафа прочувствовалась когда потребовалось дополнительно вводить сторнирущие
и корректирующие документы - тут по подчиненным не убегаешься.
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Отобрать подчиненные и док. основания
Ответ #9 - 30. Января 2008 :: 10:43
Печать  
mov68 писал(а) 30. Января 2008 :: 07:29:
Все описанные методы используют следующее: поиск документа верхнего уровня, сефинг вниз по подчиненным документам, при этом число запросов в общем случае 2*ЧислоУровнейИерархии. А если дерево подчиненности не нужно, нужен только список связанных документов, можно ли уменьшить общее число запросов (применяю это в модуле проведения, хочется ускорить)?

Можно сложить все инструкции в один запрос. Скажем, так:
Код
Выбрать все
	рс = СоздатьОбъект("ODBCRecordSet");
	рс.УложитьСписокОбъектов(спВыбДоки, "#docs");
	рс.ВыполнитьИнструкцию("
		|set nocount on
		|while 1=1 begin
		|	insert #docs (val)
		|	select substring(parentval, 7, 9)
		|	from _1scrdoc (nolock)
		|		inner join #docs on childid = val
		|	where mdid = 0
		|		and substring(parentval, 7, 9) not in (select val from #docs)
		|	if @@rowcount = 0 break
		|end
		|while 1=1 begin
		|	insert #docs (val)
		|	select right(child_date_time_iddoc, 9)
		|	from _1scrdoc (nolock)
		|		inner join #docs on parentval like 'O1____' + val
		|	where mdid = 0
		|		and right(child_date_time_iddoc, 9) not in (select val from #docs)
		|	if @@rowcount = 0 break
		|end
		|set nocount off
		|");
	спДоки = рс.ВыполнитьИнструкцию("
		|select val [Док $Документ]
		|	, iddocdef Док_вид
		|from #docs
		|	inner join _1sjourn (nolock) on val = iddoc
		|", СоздатьОбъект("СписокЗначений")); 


Или так:
Код
Выбрать все
	рс.ВыполнитьИнструкцию("
		|set nocount on
		|declare @doccount integer
		|set @doccount = 1
		|while @doccount > 0 begin
		|	insert #docs (val)
		|	select right(child_date_time_iddoc, 9)
		|	from _1scrdoc (nolock)
		|		inner join #docs on parentval like 'O1____' + val
		|	where mdid = 0
		|		and right(child_date_time_iddoc, 9) not in (select val from #docs)
		|	set @doccount = @@rowcount
		|	insert #docs (val)
		|	select substring(parentval, 7, 9)
		|	from _1scrdoc (nolock)
		|		inner join #docs on childid = val
		|	where mdid = 0
		|		and substring(parentval, 7, 9) not in (select val from #docs)
		|	set @doccount = @doccount + @@rowcount
		|end
		|set nocount off
		|"); 


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

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #10 - 30. Января 2008 :: 14:57
Печать  
sadovnikov писал(а) 30. Января 2008 :: 08:03:
Что есть "список связанных документов"?


Документы, вводимые на основании друг друга
  
Наверх
 
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #11 - 30. Января 2008 :: 14:58
Печать  
kiruha писал(а) 30. Января 2008 :: 08:31:
Цитата:
Если хочется ускорить, то может хранить данные в регистре а не выуживать их бегая по десяткам доков? Как считаешь?

+1

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


Поделитесь реализацией, плиз...
  
Наверх
 
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #12 - 30. Января 2008 :: 15:03
Печать  
berezdetsky писал(а) 30. Января 2008 :: 10:43:
mov68 писал(а) 30. Января 2008 :: 07:29:
Все описанные методы используют следующее: поиск документа верхнего уровня, сефинг вниз по подчиненным документам, при этом число запросов в общем случае 2*ЧислоУровнейИерархии. А если дерево подчиненности не нужно, нужен только список связанных документов, можно ли уменьшить общее число запросов (применяю это в модуле проведения, хочется ускорить)?


Можно сложить все инструкции в один запрос. Скажем, так: [code]      Во втором варианте, в общем случае, количество найденных документов будет больше, чем в первом.


Кажется то что нужно, попробую
  
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Отобрать подчиненные и док. основания
Ответ #13 - 31. Января 2008 :: 04:40
Печать  
Создать таблицу структуры:
- первый док сделки.
- текущий док сделки.

При записи документа писать в нее. А потом элементарным селектом доставать все документы.
Быстро и дешево.
  
Наверх
 
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #14 - 31. Января 2008 :: 11:38
Печать  
sadovnikov писал(а) 31. Января 2008 :: 04:40:
Создать таблицу структуры:
- первый док сделки.
- текущий док сделки.

При записи документа писать в нее. А потом элементарным селектом доставать все документы.
Быстро и дешево.


При этом, как я понимаю, при записи каждого документа необходимо найти коренной документ (первый документ сделки), тогда для произвольного документа извлекаем корневой документ и уже по нему быстро и дешево получаем все связанные. Если при записи поиск не делать, а в таблицу писать Документ основание - текущий документ, то возвращаемся к первоначальной задаче но по другой таблице. Или я что-то упустил?
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать