Получение элементов справочника используя отбор вид сравнения и построитель запроса

1. SeverBaP 5 30.08.23 15:10 Сейчас в теме
Добрый день.
Понадобилась функция получения массива элементов справочника используя отбор. Отбор делается через обычный вид сравнения к реквизитам справочника. Входные параметры вид справочника, реквизит отбора, вид сравнения и два значения (основное и вспомогательное – для отбора по интервалу). С простыми реквизитам вроде все разобрался, а вот с отборами к табличной части что-то нет идей как реализовать.
Вот примерный листинг функции с отборами для простых реквизитов.
// Получает массив элементов справочника по установленному отбору
//
// Параметры:
//    СправочникИмя		- Строка - Имя справочника Например, БанковскиеСчетаОрганизаций.
//    РеквизитОтбора	- Строка - реквизит справочника Например, Наименование.
//    ВидОтбора			- ВидСравнения - значение вида сравнения Например, ВидСравнения.Интервал.
//    ОсновноеЗначение	- Произвольное - Основное значение для отбора, Например, строка "Сапог".
//    ДополнительноеЗначение - Произвольное - дополнительное значение для отбора, Например, дата.
// Возвращаемое значение:
//    Массив       - Массив элементов справочника после отбора.
//    Неопределено - если произошла ошибка в получении данных.
//
Функция СтрОтборДействие(СправочникИмя,РеквизитОтбора = "Ссылка",ВидОтбора,ОсновноеЗначение,ДополнительноеЗначение=Неопределено) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	МассивЭлементов = Новый Массив;
	
	МассивВидовИнтервал = Новый Массив;
	МассивВидовИнтервал.Добавить(ВидСравнения.Интервал);
	МассивВидовИнтервал.Добавить(ВидСравнения.ИнтервалВключаяГраницы);
	МассивВидовИнтервал.Добавить(ВидСравнения.ИнтервалВключаяНачало);
	МассивВидовИнтервал.Добавить(ВидСравнения.ИнтервалВключаяОкончание);
	
	ЭтоВидИнтервала = Ложь;
	Попытка
		ЭтоВидИнтервала = МассивВидовИнтервал.Найти(ВидОтбора)>0;
	Исключение
		ЭтоВидИнтервала = Ложь;
	КонецПопытки;	
	
	ПостроительЗапросаДанных = Новый ПостроительЗапроса("ВЫБРАТЬ
	                                                    |	тСправочника.Ссылка КАК Ссылка
	                                                    |ИЗ
	                                                    |	Справочник."+СправочникИмя+" КАК тСправочника
	                                                    |{ГДЕ
	                                                    |	тСправочника."+РеквизитОтбора+".*}");
	Попытка
		ОтборПоРеквизиту = ПостроительЗапросаДанных.Отбор.Добавить(РеквизитОтбора);
	Исключение
		Возврат Неопределено;
	КонецПопытки;
	
	ОтборПоРеквизиту.ВидСравнения  = ВидОтбора;
	Если ТипЗнч(ОтборПоРеквизиту.Значение)= Тип("СписокЗначений") Тогда
		ОтборПоРеквизиту.Значение.ЗагрузитьЗначения(ОсновноеЗначение); 
	ИначеЕсли ЭтоВидИнтервала Тогда 
		ОтборПоРеквизиту.ЗначениеС	= ОсновноеЗначение;
		ОтборПоРеквизиту.ЗначениеПо = ДополнительноеЗначение;
	Иначе
		ОтборПоРеквизиту.Значение = ОсновноеЗначение; 
	КонецЕсли;
	
	ОтборПоРеквизиту.Использование = Истина;
	
	Попытка
		ЗапросДанных = ПостроительЗапросаДанных.ПолучитьЗапрос();
	Исключение
		Возврат Неопределено;
	КонецПопытки;
	
	РезультатЗапроса = ЗапросДанных.Выполнить();
	Если НЕ РезультатЗапроса.Пустой() Тогда
		ВыборкаИзРезультата = РезультатЗапроса.Выбрать();
		Пока ВыборкаИзРезультата.Следующий() Цикл
			МассивЭлементов.Добавить(ВыборкаИзРезультата.Ссылка);
		КонецЦикла;	
	КонецЕсли;	
	
	Возврат МассивЭлементов;
	
КонецФункции
Показать

Посоветуйте как прикрутить так же отбор к табличной части
По теме из базы знаний
Найденные решения
11. SeverBaP 5 30.08.23 16:19 Сейчас в теме
Вроде разобрался, нужно было именование добавить и это станет работать не только с табличной частью, но и через точку.
Вот окончательный результат:
// Получает массив элементов справочника по установленному отбору
//
// Параметры:
//    СправочникИмя		- Строка - Имя справочника Например, БанковскиеСчетаОрганизаций.
//    РеквизитОтбора	- Строка - реквизит справочника Например, Наименование.
//    ВидОтбора			- ВидСравнения - значение вида сравнения Например, ВидСравнения.Интервал.
//    ОсновноеЗначение	- Произвольное - Основное значение для отбора, Например, строка "Сапог".
//    ДополнительноеЗначение - Произвольное - дополнительное значение для отбора, Например, дата.
// Возвращаемое значение:
//    Массив       - Массив элементов справочника после отбора.
//    Неопределено - если произошла ошибка в получении данных.
//
Функция СтрОтборДействие(СправочникИмя,РеквизитОтбора = "Ссылка",ВидОтбора,ОсновноеЗначение,ДополнительноеЗначение=Неопределено) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	МассивЭлементов = Новый Массив;
	
	МассивВидовИнтервал = Новый Массив;
	МассивВидовИнтервал.Добавить(ВидСравнения.Интервал);
	МассивВидовИнтервал.Добавить(ВидСравнения.ИнтервалВключаяГраницы);
	МассивВидовИнтервал.Добавить(ВидСравнения.ИнтервалВключаяНачало);
	МассивВидовИнтервал.Добавить(ВидСравнения.ИнтервалВключаяОкончание);

	ИмяОтбора = СтрЗаменить(РеквизитОтбора,".","_");
	
	ЭтоВидИнтервала = Ложь;
	Попытка
		ЭтоВидИнтервала = МассивВидовИнтервал.Найти(ВидОтбора)>0;
	Исключение
		ЭтоВидИнтервала = Ложь;
	КонецПопытки;	
	
	ПостроительЗапросаДанных = Новый ПостроительЗапроса("ВЫБРАТЬ
	                                                    |	тСправочника.Ссылка КАК Ссылка
	                                                    |ИЗ
	                                                    |	Справочник."+СправочникИмя+" КАК тСправочника
	                                                    |{ГДЕ
	                                                    |	тСправочника."+РеквизитОтбора+".* КАК "+ИмяОтбора+"}");
	Попытка
		ОтборПоРеквизиту = ПостроительЗапросаДанных.Отбор.Добавить(ИмяОтбора);
	Исключение
		Возврат Неопределено;
	КонецПопытки;
	
	ОтборПоРеквизиту.ВидСравнения  = ВидОтбора;
	Если ТипЗнч(ОтборПоРеквизиту.Значение)= Тип("СписокЗначений") Тогда
		ОтборПоРеквизиту.Значение.ЗагрузитьЗначения(ОсновноеЗначение); 
	ИначеЕсли ЭтоВидИнтервала Тогда 
		ОтборПоРеквизиту.ЗначениеС	= ОсновноеЗначение;
		ОтборПоРеквизиту.ЗначениеПо = ДополнительноеЗначение;
	Иначе
		ОтборПоРеквизиту.Значение = ОсновноеЗначение; 
	КонецЕсли;
	
	ОтборПоРеквизиту.Использование = Истина;
	
	Попытка
		ЗапросДанных = ПостроительЗапросаДанных.ПолучитьЗапрос();
	Исключение
		Возврат Неопределено;
	КонецПопытки;
	
	РезультатЗапроса = ЗапросДанных.Выполнить();
	Если НЕ РезультатЗапроса.Пустой() Тогда
		ВыборкаИзРезультата = РезультатЗапроса.Выбрать();
		Пока ВыборкаИзРезультата.Следующий() Цикл
			МассивЭлементов.Добавить(ВыборкаИзРезультата.Ссылка);
		КонецЦикла;	
	КонецЕсли;	
	
	Возврат МассивЭлементов;
	
КонецФункции
Показать
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. newlogin1 30.08.23 15:28 Сейчас в теме
(1)А почему не через СКД? там кажется удобней, на форму настройки просто вывести надо и пользак сам себе чего хочешь прикрутит, а скд это отберет
SlavaKron; +1 Ответить
12. SeverBaP 5 30.08.23 17:12 Сейчас в теме
(2) простой пример есть?
13. newlogin1 30.08.23 17:54 Сейчас в теме
(12)Вот эта статья должна подойти
https://infostart.ru/1c/articles/1577316/

ПС если конфа типовая, то отчет можно через БСП скомпоновать
3. SeverBaP 5 30.08.23 15:31 Сейчас в теме
Функция используется без формы.
Как-то так:
СтрОтборДействие("ДоговорыКонтрагентов","Наименование",ВидСравнения.Содержит,"Рога")
8. SlavaKron 30.08.23 16:01 Сейчас в теме
(3) Если функция использует только программный интерфейс, чем она лучше простого запроса с параметрами?
9. SeverBaP 5 30.08.23 16:03 Сейчас в теме
(8) Хороший вопрос, но так поставлен подход к получению данных.
4. пользователь 30.08.23 15:35
Сообщение было скрыто модератором.
...
5. SeverBaP 5 30.08.23 15:55 Сейчас в теме
(4) почему запретили? Можно конечно, вот только неясно как прикрутится к моей схеме оптимально.
Допустим, есть справочник ДоговорыКонтрагентов в нем есть табличные части как пример: ДоговорыСЗаказчиками. Если обращаться к функции:
СтрОтборДействие("ДоговорыКонтрагентов","ДоговорыКонтрагентов.ДоговорыСЗаказчиками.ДоговорСЗаказчиком",ВидСравнения.Равно,ДоговорОтбора);

вот тут сразу возникает вопрос в запросе как делать, если ставить как у меня выше то можно словить вот такой вроде правильный код запроса:
ВЫБРАТЬ
	ДоговорыКонтрагентов.Ссылка КАК Ссылка
ИЗ
	Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
{ГДЕ
	ДоговорыКонтрагентов.ДоговорыСЗаказчиками.ДоговорСЗаказчиком.*}

Возможно понадобится именование в отборе....
6. пользователь 30.08.23 15:58
Сообщение было скрыто модератором.
...
7. SeverBaP 5 30.08.23 16:01 Сейчас в теме
(6) Предложи в какаю сторону двигаться.
10. пользователь 30.08.23 16:08
Сообщение было скрыто модератором.
...
11. SeverBaP 5 30.08.23 16:19 Сейчас в теме
Вроде разобрался, нужно было именование добавить и это станет работать не только с табличной частью, но и через точку.
Вот окончательный результат:
// Получает массив элементов справочника по установленному отбору
//
// Параметры:
//    СправочникИмя		- Строка - Имя справочника Например, БанковскиеСчетаОрганизаций.
//    РеквизитОтбора	- Строка - реквизит справочника Например, Наименование.
//    ВидОтбора			- ВидСравнения - значение вида сравнения Например, ВидСравнения.Интервал.
//    ОсновноеЗначение	- Произвольное - Основное значение для отбора, Например, строка "Сапог".
//    ДополнительноеЗначение - Произвольное - дополнительное значение для отбора, Например, дата.
// Возвращаемое значение:
//    Массив       - Массив элементов справочника после отбора.
//    Неопределено - если произошла ошибка в получении данных.
//
Функция СтрОтборДействие(СправочникИмя,РеквизитОтбора = "Ссылка",ВидОтбора,ОсновноеЗначение,ДополнительноеЗначение=Неопределено) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	МассивЭлементов = Новый Массив;
	
	МассивВидовИнтервал = Новый Массив;
	МассивВидовИнтервал.Добавить(ВидСравнения.Интервал);
	МассивВидовИнтервал.Добавить(ВидСравнения.ИнтервалВключаяГраницы);
	МассивВидовИнтервал.Добавить(ВидСравнения.ИнтервалВключаяНачало);
	МассивВидовИнтервал.Добавить(ВидСравнения.ИнтервалВключаяОкончание);

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

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот