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

Организация сложных фильтров объединенных условием и/или (Работа со списками значений)

Организация сложных фильтров объединенных условием и/или (Работа со списками значений)

В наличии

1С:Предприятие 7.7
Предположим у нас есть справочник, с кучей подчиненных справочников. И нам хотелось бы организовать в форме списка отбор элементов справочника по полям подчиненных справочников, причем, для простоты, используя два (хотя можно и более) условия отбора, объединенных условиями и/или. Или просто нам не помешают приведенные функции работы со списками значений:-)
Основное — возможность получить объединение и пересечение двух или более множеств, используя приведенные функции работы со СпискамиЗначений.

Категория:

Описание

Один из возможных простых способов:

Пишем простенькие функции отбора (столько, сколько вариантов отбора мы хотим):

// На подобии этой, отбор списка владельцев подчиненного справочника, по полю
// подчиненного справочника. Возвращает список значений владельцев подчиненного 
// справочника.
// ----------------------------------------------------------------------
Функция гл7ПолучитьСписокСертификатовПоНомеруРамы(Знач НомерРамы) Экспорт
	Перем СпрРамыДвигатели, СпСертификатов;
	
	НомерРамы=СокрЛП(НомерРамы);
	
	СпСертификатов=СоздатьОбъект("СписокЗначений");
	СпрРамыДвигатели=СоздатьОбъект("Справочник.СертификатыРамыДвигатели");

	СпрРамыДвигатели.ВыбратьЭлементыПоРеквизиту("НомерРамы",НомерРамы,0,0);
	Пока СпрРамыДвигатели.ПолучитьЭлемент()=1 Цикл
		Если СпрРамыДвигатели.ПометкаУдаления()=1 Тогда
			Продолжить;
		КонецЕсли;
		
		ТекВлад=СпрРамыДвигатели.ТекущийЭлемент().Владелец;
		Если СпСертификатов.НайтиЗначение(ТекВлад)<1 Тогда
			СпСертификатов.ДобавитьЗначение(ТекВлад);
		КонецЕсли;
	КонецЦикла;
	
	Возврат СпСертификатов;
КонецФункции	// гл7ПолучитьСписокСертификатовПоНомеруРамы
// ----------------------------------------------------------------------

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

// ----------------------------------------------------------------------
Функция гл8УдалитьДвойниковИзСписка(Знач Сп1) Экспорт
	Перем Сп, СпУдалПоз, СпУдалЗнач;
	
	Сп=СоздатьОбъект("СписокЗначений"); 
	СпУдалПоз=СоздатьОбъект("СписокЗначений"); 
	СпУдалЗнач=СоздатьОбъект("СписокЗначений"); 
	
	Если ВРег(СокрЛП(ТипЗначенияСтр(Сп1))) <> ВРег("СписокЗначений") Тогда
		Возврат Сп;
	КонецЕсли;
	
	Если Сп1.РазмерСписка()<1 Тогда
		Возврат Сп;
	КонецЕсли;
	
	N=Сп1.РазмерСписка();
	
	i=0;
	Пока i<N Цикл
		i=i+1;
		Sx="";
		V=Сп1.ПолучитьЗначение(i,Sx);

		Если (СпУдалЗнач.НайтиЗначение(V)<1) Тогда
			j=0;
			Пока j<N Цикл
				j=j+1;
				Sx2="";
				V2=Сп1.ПолучитьЗначение(j,Sx2);
				Попытка
					Если (V=V2) И (i<>j) И (СпУдалЗнач.НайтиЗначение(V2)>0) Тогда
						СпУдалПоз.ДобавитьЗначение(j);
					КонецЕсли;	
					Если (V=V2) Тогда
						СпУдалЗнач.ДобавитьЗначение(V2,Sx2);
					КонецЕсли;
				Исключение
				КонецПопытки;
			КонецЦикла;
		КонецЕсли;
	КонецЦикла;

	i=0;
	Пока i<N Цикл
		i=i+1;
		Sx="";
		V=Сп1.ПолучитьЗначение(i,Sx); 
		Если СпУдалПоз.НайтиЗначение(i)<1 Тогда
			Сп.ДобавитьЗначение(V,Sx);	
		КонецЕсли;
	КонецЦикла;

	Возврат Сп;
КонецФункции	// гл8УдалитьДвойниковИзСписка
// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
Функция гл8ПолучитьПересечениеСписков(Знач Сп1, Знач Сп2) Экспорт
	Перем Сп;

	Сп=СоздатьОбъект("СписокЗначений");
	
	Если ВРег(СокрЛП(ТипЗначенияСтр(Сп1))) <> ВРег("СписокЗначений") Тогда
		Возврат Сп;
	КонецЕсли;

	Если ВРег(СокрЛП(ТипЗначенияСтр(Сп2))) <> ВРег("СписокЗначений") Тогда
		Возврат Сп;
	КонецЕсли;
	
	Если Сп1.РазмерСписка()<1 Тогда
		Возврат Сп;
	КонецЕсли;

	Если Сп2.РазмерСписка()<1 Тогда
		Возврат Сп;
	КонецЕсли;

	Сп1=гл8УдалитьДвойниковИзСписка(Сп1);
	Сп2=гл8УдалитьДвойниковИзСписка(Сп2);
	
	N=Сп1.РазмерСписка();

	i=0;
	Пока i<N Цикл
		i=i+1;
		Sx="";
		V=Сп1.ПолучитьЗначение(i,Sx);
		Если Сп2.НайтиЗначение(V)>0 Тогда
			Сп.ДобавитьЗначение(V,Sx);
		КонецЕсли;
	КонецЦикла;

	Возврат Сп;
КонецФункции	// гл8ПолучитьПересечениеСписков
// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
Функция гл8ПолучитьОбъединениеСписков(Знач Сп1, Знач Сп2) Экспорт
	Перем Сп;

	Сп=СоздатьОбъект("СписокЗначений");

	Если ВРег(СокрЛП(ТипЗначенияСтр(Сп1))) <> ВРег("СписокЗначений") Тогда
		Сп1=СоздатьОбъект("СписокЗначений");
	КонецЕсли;

	Если ВРег(СокрЛП(ТипЗначенияСтр(Сп2))) <> ВРег("СписокЗначений") Тогда
		Сп2=СоздатьОбъект("СписокЗначений");
	КонецЕсли;
	
	Если Сп1.РазмерСписка()<1 Тогда
		Если Сп2.РазмерСписка()<1 Тогда
			Возврат Сп;
		Иначе
			Сп2.Выгрузить(Сп);
			Возврат Сп;
		КонецЕсли;
	КонецЕсли;

	Если Сп2.РазмерСписка()<1 Тогда
		Если Сп1.РазмерСписка()<1 Тогда
			Возврат Сп;
		Иначе
			Сп1.Выгрузить(Сп);
			Возврат Сп;
		КонецЕсли;	
	КонецЕсли;
	
	Сп1=гл8УдалитьДвойниковИзСписка(Сп1);
	Сп2=гл8УдалитьДвойниковИзСписка(Сп2);
	
	N=Сп1.РазмерСписка();

	i=0;
	Пока i<N Цикл
		i=i+1;
		Sx="";
		V=Сп1.ПолучитьЗначение(i,Sx);
		Поз=Сп2.НайтиЗначение(V);
		Если Поз>0 Тогда
			Сп2.УдалитьЗначение(Поз);
		КонецЕсли;
	КонецЦикла;
	
	Сп=гл9ОбъединитьСпискиЗначений(Сп1,Сп2);
	
	Возврат Сп;
КонецФункции	// гл8ПолучитьОбъединениеСписков
// ----------------------------------------------------------------------

Использовать можно следующим образом (упрощенно):

Перем СпСертификатов, СпСертификатов1, СпИтоговый;

СпСертификатов=гл7ПолучитьСписокСертификатовПоНомеруРамы(ЗначениеВВидеСтроки);
СпСертификатов1=гл7ПолучитьСписокСертификатовПоНомеруДвигателя(ЗначениеВВидеСтроки1);

// И
СпИтоговый=гл8ПолучитьПересечениеСписков(СпСертификатов,СпСертификатов1);
ИспользоватьСписокЭлементов(СпИтоговый);

// ИЛИ
СпИтоговый=гл8ПолучитьОбъединениеСписков(СпСертификатов,СпСертификатов1);
ИспользоватьСписокЭлементов(СпИтоговый);

has been added to your cart:
Оформление заказа