gifts2017

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

Опубликовал Максим Хмелев (hop) в раздел Программирование - Практика программирования

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

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

Функция ПолучитьРодительскиеДокументы(ДокументСсылка, СписокСвязанныхДокументов = Неопределено, мУжеВСписке = Неопределено) Экспорт 
	
	Если СписокСвязанныхДокументов = Неопределено Тогда 
		СписокСвязанныхДокументов = Новый СписокЗначений;
	КонецЕсли;
	Если мУжеВСписке = Неопределено Тогда 
		мУжеВСписке = Новый Соответствие;
	КонецЕсли;
	
	МетаданныеДокумента = ДокументСсылка.Метаданные();
	СписокРеквизитов = Новый СписокЗначений;
	
	Для Каждого Реквизит ИЗ МетаданныеДокумента.Реквизиты Цикл
		ТипыРеквизита = Реквизит.Тип.Типы();
		Для Каждого ТекущийТип ИЗ ТипыРеквизита Цикл
			МетаданныеРеквизита = Метаданные.НайтиПоТипу(ТекущийТип);
					
			Если МетаданныеРеквизита<>Неопределено И Метаданные.Документы.Содержит(МетаданныеРеквизита) 
				 И ПравоДоступа("Чтение", МетаданныеРеквизита) Тогда
				Попытка
					ЗначениеРеквизита = ДокументСсылка[Реквизит.Имя];
				Исключение
					Прервать;
				КонецПопытки;
				ЕСли ЗначениеРеквизита<>Неопределено И НЕ ЗначениеРеквизита.Пустая() И ТипЗнч(ЗначениеРеквизита) = ТекущийТип 
					 И мУжеВСписке[ЗначениеРеквизита] = Неопределено И СписокРеквизитов.НайтиПоЗначению(ДокументСсылка[Реквизит.Имя]) = Неопределено Тогда
					Попытка
						СписокРеквизитов.Добавить(ЗначениеРеквизита,Формат(ЗначениеРеквизита.Дата,"ДФ=yyyyMMddЧЧММсс"));
					Исключение
						 ОтладкаТекстОшибки = ОписаниеОшибки();
					КонецПопытки;	
				КонецЕсли;
			КонецЕсли;			
			
		КонецЦикла;
	КонецЦикла;
	
	Для Каждого ТЧ Из МетаданныеДокумента.ТабличныеЧасти Цикл
		СтрРеквизитов = "";
		
		Попытка
			СодержимоеТЧ = ДокументСсылка[ТЧ.Имя].Выгрузить();
		Исключение
			Прервать;
		КонецПопытки;
		
		Для Каждого Реквизит ИЗ ТЧ.Реквизиты Цикл
			ТипыРеквизита = Реквизит.Тип.Типы();
			Для Каждого ТекущийТип ИЗ ТипыРеквизита Цикл
				МетаданныеРеквизита = Метаданные.НайтиПоТипу(ТекущийТип);				
				Если МетаданныеРеквизита<>Неопределено И Метаданные.Документы.Содержит(МетаданныеРеквизита) 
					И ПравоДоступа("Чтение", МетаданныеРеквизита) Тогда
					СтрРеквизитов = СтрРеквизитов + ?(СтрРеквизитов = "", "", ", ") + Реквизит.Имя;
					Прервать;
				КонецЕсли;						
			КонецЦикла;
		КонецЦикла;
		
		СодержимоеТЧ.Свернуть(СтрРеквизитов);
		Для Каждого КолонкаТЧ ИЗ СодержимоеТЧ.Колонки Цикл
			Для Каждого СтрокаТЧ ИЗ СодержимоеТЧ Цикл
				Попытка
					ЗначениеРеквизита = СтрокаТЧ[КолонкаТЧ.Имя];
				Исключение
					Продолжить;
				КонецПопытки;
				МетаданныеЗначения = Метаданные.НайтиПоТипу(ТипЗнч(ЗначениеРеквизита));
				Если МетаданныеЗначения = Неопределено Тогда
					// базовый тип
					Продолжить;
				КонецЕсли;
				
				ЕСли ЗначениеРеквизита<>Неопределено И НЕ ЗначениеРеквизита.Пустая()
					 И Метаданные.Документы.Содержит(МетаданныеЗначения)
					 И мУжеВСписке[ЗначениеРеквизита] = Неопределено Тогда
					Если СписокРеквизитов.НайтиПоЗначению(ЗначениеРеквизита) = Неопределено Тогда
						Попытка
							СписокРеквизитов.Добавить(ЗначениеРеквизита,Формат(ЗначениеРеквизита.Дата,"ДФ=yyyyMMddЧЧММсс"));
						Исключение
							ОтладкаТекстОшибки = ОписаниеОшибки();
						КонецПопытки;
					КонецЕсли;
				КонецЕсли;
			КонецЦикла;
		КонецЦикла;		
	КонецЦикла;
	мУжеВСписке.Вставить(ДокументСсылка, Истина);
	
	Для Каждого СтрСЗ Из СписокРеквизитов Цикл 
		СписокСвязанныхДокументов = ПолучитьРодительскиеДокументы(СтрСЗ.Значение, СписокСвязанныхДокументов, мУжеВСписке);
	КонецЦикла;
		
	Запрос = Новый Запрос("ВЫБРАТЬ РАЗРЕШЕННЫЕ Ссылка
						   | ИЗ Документ."+МетаданныеДокумента.Имя + " ГДЕ Ссылка = &Ссылка");
						   
	Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);
	
	Выборка  = Запрос.Выполнить().Выбрать();
	ЕСли Выборка.Следующий() Тогда		
		СписокСвязанныхДокументов.Добавить(Выборка.Ссылка);
	Иначе
		СписокСвязанныхДокументов.Добавить(ДокументСсылка);
	КонецЕсли;
	
	Возврат СписокСвязанныхДокументов;
		
КонецФункции

Функция ПолучитьПодчиненныеДокументы(ДокументСсылка, СписокСвязанныхДокументов = Неопределено, мУжеВСписке = Неопределено) Экспорт
	
	Если СписокСвязанныхДокументов = Неопределено Тогда 
		СписокСвязанныхДокументов = Новый СписокЗначений;
	КонецЕсли;
	Если мУжеВСписке = Неопределено Тогда 
		мУжеВСписке = Новый Соответствие;
	КонецЕсли;
	
	Таблица = ПолныеПрава.ПолучитьВыборкуПоКритериюОтбора("СвязанныеДокументы", ДокументСсылка);	
	КэшПоТипамДокументов = Новый Соответствие;
	
	Для Каждого СтрокаТаблицы ИЗ Таблица Цикл
		МетаданныеДокумента = СтрокаТаблицы.Ссылка.Метаданные();
		Если Не ПравоДоступа("Чтение", МетаданныеДокумента) Тогда
			Продолжить;
		КонецЕсли;			
		ИмяДокумента = МетаданныеДокумента.Имя;
		СинонимДокумента = МетаданныеДокумента.Синоним;
		
		СтруктураТипа = КэшПоТипамДокументов[ИмяДокумента];
		Если СтруктураТипа = Неопределено Тогда
			СтруктураТипа = Новый Структура("Синоним, МассивСсылок", СинонимДокумента, Новый Массив);
			КэшПоТипамДокументов.Вставить(ИмяДокумента, СтруктураТипа);
		КонецЕсли;
		СтруктураТипа.МассивСсылок.Добавить(СтрокаТаблицы.Ссылка);		
	КонецЦикла;
	
	ЕСли КэшПоТипамДокументов.Количество() = 0 Тогда 
		Возврат СписокСвязанныхДокументов;
	КонецЕсли;
	
	ТекстЗапросаНачало = "ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ (";
	ТекстЗапросаКонец = ") КАК ПодчиненныеДокументы ";
	Запрос = Новый Запрос;
	Для Каждого КлючИЗначение ИЗ КэшПоТипамДокументов Цикл
		Запрос.Текст = Запрос.Текст + ?(Запрос.Текст = "", "
					|ВЫБРАТЬ ", "
					|ОБЪЕДИНИТЬ ВСЕ
					|ВЫБРАТЬ") + "
					|Ссылка
					|ИЗ Документ." + КлючИЗначение.Ключ + "
					|ГДЕ Ссылка В (&" + КлючИЗначение.Ключ + ")";
					
		Запрос.УстановитьПараметр(КлючИЗначение.Ключ, КлючИЗначение.Значение.МассивСсылок);		
	КонецЦикла;
	
	Запрос.Текст = ТекстЗапросаНачало + Запрос.Текст + ТекстЗапросаКонец;
	
	Выборка = Запрос.Выполнить().Выбрать();	
	Пока Выборка.Следующий() Цикл
		Если мУжеВСписке[Выборка.Ссылка] = Неопределено Тогда
			СписокСвязанныхДокументов.Добавить(Выборка.Ссылка);
			мУжеВСписке.Вставить(Выборка.Ссылка, Истина);
			СписокСвязанныхДокументов = ПолучитьПодчиненныеДокументы(Выборка.Ссылка, СписокСвязанныхДокументов, мУжеВСписке);
		КонецЕсли;
	КонецЦикла;
	
	Возврат СписокСвязанныхДокументов;
	
КонецФункции

Основной параметр функций "ДокументСсылка" - обязательный. Это ссылка на документ, для которого будем получать родительские (подчиненные) документы.

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

 

Примеры:

1. Получение общего списка родительских документов двух и более документов.

СписокСвязанныхДокументов = ПолучитьРодительскиеДокументы(ДокументСсылка1);
СписокСвязанныхДокументов = ПолучитьРодительскиеДокументы(ДокументСсылка2, СписокСвязанныхДокументов);

2. Получение общего списка и родительских, и подчиненных документов.

СписокСвязанныхДокументов = ПолучитьРодительскиеДокументы(ДокументСсылка);
СписокСвязанныхДокументов = ПолучитьПодчиненныеДокументы(ДокументСсылка, СписокСвязанныхДокументов);

 

Дополнение:

Функция ПолучитьВыборкуПоКритериюОтбора(ИмяКритерияОтбора, ЗначениеКритерия) Экспорт
       
    Запрос = Новый Запрос;
    ТекстЗапроса = "";
   
    Для Каждого ЭлементСостава ИЗ Метаданные.КритерииОтбора[ИмяКритерияОтбора].Состав Цикл
       
        Если Не ЭлементСостава.Тип.СодержитТип(ТипЗнч(ЗначениеКритерия)) Тогда
            Продолжить;
        КонецЕсли;
       
        ПутьКДанным = ЭлементСостава.ПолноеИмя();
        СтруктураПутьКДанным = ОбщегоНазначения.РазобратьПутьКОбъектуМетаданных(ПутьКДанным, ЭлементСостава.Родитель());
       
        ЕСли НЕ ПравоДоступа("Чтение", СтруктураПутьКДанным.Метаданные) Тогда
            Продолжить;
        КонецЕсли;
       
        ИмяОбъекта = СтруктураПутьКДанным.ТипОбъекта + "." + СтруктураПутьКДанным.ВидОбъекта;
        ПсевдонимТаблицы = СтруктураПутьКДанным.ТипОбъекта + "_" + СтруктураПутьКДанным.ВидОбъекта + "_" + СтруктураПутьКДанным.ИмяТаблЧасти;
       
        ТекущаяСтрокаГДЕ = "ГДЕ " + ПсевдонимТаблицы + "." +СтруктураПутьКДанным.ИмяРеквизита + " = &ЗначениеКритерияОтбора";
           
        ИмяТЧ = Лев(СтруктураПутьКДанным.ИмяРеквизита, Найти(СтруктураПутьКДанным.ИмяРеквизита, ".")-1);
        ИмяРеквизита = Лев(СтруктураПутьКДанным.ИмяРеквизита, Найти(СтруктураПутьКДанным.ИмяРеквизита, ".")-1);
        ТекстЗапроса = ТекстЗапроса + (?(ТекстЗапроса = "", "ВЫБРАТЬ", "ОБЪЕДИНИТЬ ВСЕ
        |ВЫБРАТЬ") + "
        |" + ПсевдонимТаблицы + ".Ссылка ИЗ " + ИмяОбъекта + "." + СтруктураПутьКДанным.ИмяТаблЧасти + " КАК " + ПсевдонимТаблицы + "
        |" + СтрЗаменить(ТекущаяСтрокаГДЕ, "..", ".") + "
        |");
       
    КонецЦикла;
   
    Если ТекстЗапроса = "" Тогда
        Возврат Новый ТаблицаЗначений;
    КонецЕсли;
   
    Запрос.Текст = ТекстЗапроса;
    Запрос.УстановитьПараметр("ЗначениеКритерияОтбора", ЗначениеКритерия);
    Возврат Запрос.Выполнить().Выгрузить();
   
КонецФункции

Функция РазобратьПутьКОбъектуМетаданных(ПутьКДанным, МетаданныеОбъекта = Неопределено) Экспорт
   
    Структура = Новый Структура;
   
    СоответствиеИмен = Новый Массив();
    СоответствиеИмен.Добавить("ТипОбъекта");
    СоответствиеИмен.Добавить("ВидОбъекта");
    СоответствиеИмен.Добавить("ПутьКДанным");
    СоответствиеИмен.Добавить("ИмяТаблЧасти");
    СоответствиеИмен.Добавить("ИмяРеквизита");
   
    Для индекс = 1 по 3 Цикл
       
        Точка = Найти(ПутьКДанным, ".");
        ТекущееЗначение = Лев(ПутьКДанным, Точка-1);
        Структура.Вставить(СоответствиеИмен[индекс-1], ТекущееЗначение);
        ПутьКДанным = Сред(ПутьКДанным, Точка+1);
       
    КонецЦикла;
   
    ПутьКДанным = СтрЗаменить(ПутьКДанным, "Реквизит.", "");
   
    Если Структура.ПутьКДанным = "ТабличнаяЧасть" Тогда
       
        Для индекс = 4 по 5  Цикл
           
            Точка = Найти(ПутьКДанным, ".");
            Если Точка = 0 Тогда
                ТекущееЗначение = ПутьКДанным;
            Иначе
                ТекущееЗначение = Лев(ПутьКДанным, Точка-1);
            КонецЕсли;
           
            Структура.Вставить(СоответствиеИмен[индекс-1], ТекущееЗначение);
            ПутьКДанным = Сред(ПутьКДанным,  Точка+1);
           
        КонецЦикла;
       
    Иначе
       
        Структура.Вставить(СоответствиеИмен[3], "");
        Структура.Вставить(СоответствиеИмен[4], ПутьКДанным);
       
    КонецЕсли;
   
    Если МетаданныеОбъекта <> Неопределено Тогда
        Структура.Вставить("Метаданные", МетаданныеОбъекта);
    Иначе
        Если Структура.ТипОбъекта = "Документ" Тогда
            Структура.Вставить("Метаданные", Метаданные.Документы[Структура.ВидОбъекта]);
        Иначе
            Структура.Вставить("Метаданные", Метаданные.Справочники[Структура.ВидОбъекта]);
        КонецЕсли;
    КонецЕсли;
   
    Возврат Структура;
   
КонецФункции

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Мари Бочарова (AJlEKCA) 12.11.13 00:05
не во всех конфигурациях есть модуль "ПолныеПрава"
2. Александр Киричков (Bezeus) 15.01.14 12:48
Кстати, верное замечание. Или перетащи функцию ПолучитьВыборкуПоКритериюОтбор() к себе, или сам напиши.
3. bursanb Sanh (bursanb) 24.02.14 12:44
Самое оно! В Комплексной модуль "ПолныеПрава" есть, т.ч. мне подходит.
4. Николай Романов (LexBG) 01.08.14 13:08
В БП 3.0 модуля ПолныеПрава нет, а жаль очень полезная функция была бы
5. Павел Жданов (heavymetal) 28.10.14 06:09
(4) LexBG, а что мешает взять эту функцию из другой конфы, в которой есть?
// ПРОЦЕДУРЫ И ФУНКЦИИ РАБОТЫ С КРИТЕРИЯМИ ОТБОРА

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

Функция ПолучитьВыборкуПоКритериюОтбора(ИмяКритерияОтбора, ЗначениеКритерия) Экспорт
		
	Запрос = Новый Запрос;
	ТекстЗапроса = "";
	
	Для Каждого ЭлементСостава ИЗ Метаданные.КритерииОтбора[ИмяКритерияОтбора].Состав Цикл
		
		Если Не ЭлементСостава.Тип.СодержитТип(ТипЗнч(ЗначениеКритерия)) Тогда
			Продолжить;
		КонецЕсли;
		
		ПутьКДанным = ЭлементСостава.ПолноеИмя();
		СтруктураПутьКДанным = РазобратьПутьКОбъектуМетаданных(ПутьКДанным, ЭлементСостава.Родитель());
		
		ЕСли НЕ ПравоДоступа("Чтение", СтруктураПутьКДанным.Метаданные) Тогда
			Продолжить;
		КонецЕсли;
		
		ИмяОбъекта = СтруктураПутьКДанным.ТипОбъекта + "." + СтруктураПутьКДанным.ВидОбъекта;
		ПсевдонимТаблицы = СтруктураПутьКДанным.ТипОбъекта + "_" + СтруктураПутьКДанным.ВидОбъекта + "_" + СтруктураПутьКДанным.ИмяТаблЧасти;
		
		ТекущаяСтрокаГДЕ = "ГДЕ " + ПсевдонимТаблицы + "." +СтруктураПутьКДанным.ИмяРеквизита + " = &ЗначениеКритерияОтбора";
			
		ИмяТЧ = Лев(СтруктураПутьКДанным.ИмяРеквизита, Найти(СтруктураПутьКДанным.ИмяРеквизита, ".")-1);
		ИмяРеквизита = Лев(СтруктураПутьКДанным.ИмяРеквизита, Найти(СтруктураПутьКДанным.ИмяРеквизита, ".")-1);
		ТекстЗапроса = ТекстЗапроса + (?(ТекстЗапроса = "", "ВЫБРАТЬ", "ОБЪЕДИНИТЬ ВСЕ
		|ВЫБРАТЬ") + "
		|" + ПсевдонимТаблицы + ".Ссылка ИЗ " + ИмяОбъекта + "." + СтруктураПутьКДанным.ИмяТаблЧасти + " КАК " + ПсевдонимТаблицы + "
		|" + СтрЗаменить(ТекущаяСтрокаГДЕ, "..", ".") + "
		|");
		
	КонецЦикла;
	
	Если ТекстЗапроса = "" Тогда
		Возврат Новый ТаблицаЗначений;
	КонецЕсли;
	
	Запрос.Текст = ТекстЗапроса;
	Запрос.УстановитьПараметр("ЗначениеКритерияОтбора", ЗначениеКритерия);
	Возврат Запрос.Выполнить().Выгрузить();
	
КонецФункции
...Показать Скрыть


Надеюсь никаких больше общих модулей не пропустил. Честно скажу, что весь код и не пробовал. Просто случайно увидел комментарии, решил помочь.
6. Немцев Максим (sahn) 28.10.14 06:34
В БП 3.0 модуля ПолныеПрава нет, а жаль очень полезная функция была бы. Нет модуля. Используй УстановитьПривилегированныйРежим(Истина)
heavymetal; +1 Ответить 1
7. Павел Жданов (heavymetal) 28.10.14 06:47
(6) sahn, кстати да. В управляемом приложение необходимо использовать данную функцию "УстановитьПривилегированныйРежим(Истина)". В обычном же приложение положить эти функции в общий модуль с привилегированным режимом выполнения на сервере.
8. Богдан Носалик (1CSoft) 03.11.14 02:47
Использовал функции без доработок в обработке групповой печати документов реализации для получения связанных с документами "Реализация товаров и услуг" счетов, заказов и налоговых накладных.
Все работало без замечаний благодарность автору!
9. Виктор Курченко (v777k) 30.12.14 15:36
Спасибо за статью, очень выручила!
10. Максим Максим (zmaxp) 19.05.15 11:45
Очень полезная статья. Большое спасибо
11. Владимир Степанов (vgstepanov) 15.01.16 00:14
Функции для получения списка подчиненных документов можно реализовать так:

//С запросом
Функция ПолучитьСписокПодчиненныхДокументов()
	
	ТаблицаСвязанныхДокументов = Новый ТаблицаЗначений;
	ТаблицаСвязанныхДокументов.Колонки.Добавить("Ссылка");
	НоваяСтрока = ТаблицаСвязанныхДокументов.Добавить();
	НоваяСтрока.Ссылка = СсылкаНаДокумент;
	
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ РАЗРЕШЕННЫЕ
	|	СвязанныеДокументы.Ссылка
	|ИЗ
	|	КритерийОтбора.СвязанныеДокументы(&ЗначениеКритерияОтбора) КАК СвязанныеДокументы";
	
	Для Каждого СтрокаТаблицы Из ТаблицаСвязанныхДокументов Цикл
		
		Если Метаданные.КритерииОтбора.СвязанныеДокументы.Тип.СодержитТип(ТипЗнч(СтрокаТаблицы.Ссылка))  Тогда
			
			Запрос.УстановитьПараметр("ЗначениеКритерияОтбора", СтрокаТаблицы.Ссылка);
			ТаблицаСвязанныхДокументовВременная = Запрос.Выполнить().Выгрузить();
			
			Для Каждого ЭлементКоллекции Из ТаблицаСвязанныхДокументовВременная Цикл
				РезультатПоиска = ТаблицаСвязанныхДокументов.Найти(ЭлементКоллекции.Ссылка);
				Если РезультатПоиска = НеОпределено Тогда
					НоваяСтрока = ТаблицаСвязанныхДокументов.Добавить();
					НоваяСтрока.Ссылка = ЭлементКоллекции.Ссылка;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
	КонецЦикла;
		
	Возврат ТаблицаСвязанныхДокументов ;
		
КонецФункции

//Без запроса
Функция ПолучитьСписокПодчиненныхДокументов()
	
	ТаблицаСвязанныхДокументов = Новый ТаблицаЗначений;
	ТаблицаСвязанныхДокументов.Колонки.Добавить("Ссылка");
	НоваяСтрока = ТаблицаСвязанныхДокументов.Добавить();
	НоваяСтрока.Ссылка = СсылкаНаДокумент;
	
	Для Каждого СтрокаТаблицы Из ТаблицаСвязанныхДокументов Цикл
		МассивСвязанныхДокументов = КритерииОтбора.СвязанныеДокументы.Найти(СтрокаТаблицы.Ссылка);
		
		Для Каждого ЭлементКоллекции Из МассивСвязанныхДокументов Цикл
			РезультатПоиска = ТаблицаСвязанныхДокументов.Найти(ЭлементКоллекции);
			Если РезультатПоиска = НеОпределено Тогда
				НоваяСтрока = ТаблицаСвязанныхДокументов.Добавить();
				НоваяСтрока.Ссылка = ЭлементКоллекции.Ссылка;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
		
	Возврат ТаблицаСвязанныхДокументов ;
		
КонецФункции
...Показать Скрыть
plusaliance; +1 Ответить
12. Людмила Чумак (vesta60) 04.02.16 17:30
Спасибо большое, Сэкономила кучу времени. Пришлось в акт инвентаризации добавлять суммы из документа списание.
13. Kirill Shlykov (smellofsky) 21.04.16 07:38
Большое спасибо за подаренное время! Автору респект :)
14. Прокопов Алексей (alexisalserv) 27.10.16 13:18
15. Константин Куликов (Светлый ум) 06.11.16 08:50
Пример теста функции на внешней обработке - упр. формы (заменяйте СсылкаНаОбъект на свои документы)
Прикрепленные файлы:
МояСтруктураПодчинен.epf
Team leader; +1 Ответить
16. Александр Крынецкий (echo77) 06.11.16 10:43
За публикацию плюс. Но сколько времени будут работать данные функции, если структура подчиненности очень ветвистая, как здесь:
https://yadi.sk/i/e9IAtTyEy9Xng
17. Юра Мерж (morgershtern) 28.11.16 19:22
Спасибо! очень полезно. Использовал при групповом создании документов наряда на основании заказов.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа