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