!!! ВНИМАНИЕ !!! Ещё не тестировал, написал в промежутке, между основными задачами, оттестирую и доработаю как появится время. Если кто оттестит, буду очень рад конструктивным отзывам.
Часто какие-то процедуры требуют какие-то значения полей справочника, при этом используется только для чтения. Однако, в коде часто попадается ПолучитьОбъект, или обращение к полям через точку от ссылки. Это приводит к множественным запросам к СУБД, особенно если в теле процедуры много таких обращений.
Например, может даже в модуле объекта (документа), или какой обработки, фонового... использоваться
Если ЗначениеЗаполнено(Контрагент.ДокументУдостоверяющийЛичность) Тогда
То происходит запрос "ВЫБРАТЬ ПЕРВЫЕ 1 Т.ДокументУдостоверяющийЛичность ИЗ Справочник.Контрагенты КАК Т ГДЕ Т.Ссылка=&Ссылка"
И так на каждое обращение к реквизиту.
В таком случае лучше в модуле менеджера разместить такую функцию и получить все нужные поля заранее
РеквКонтрагента = Справочники.Контрагенты.ПолучитьНужныеПоляЭлемента(Ссылка, "ДокументУдостоверяющийЛичность,ИНН,КПП");
А потом писать
Если ЗначениеЗаполнено(РеквКонтрагента.ДокументУдостоверяющийЛичность) Тогда
В таком случае система отправит один запрос
// Функция - Получить нужные поля элемента (без табличных частей)
//
// Параметры:
// пСсылка - Ссылка - Ссылка на элемент справочника
// СписокПолей - Строка - Список полей разделенных запятой
//
// Возврат:
// Структура - Структура с заполненными значениями запрошенных полей
//
Функция ПолучитьНужныеПоляЭлемента(пСсылка, СписокПолей = "") Экспорт
ТЗ = "ВЫБРАТЬ ПЕРВЫЕ 1
| ТекСправочник.Ссылка КАК Ссылка{ТекстПоляЗапроса}
|ИЗ
| Справочник.ТекСправочник AS ТекСправочник
|ГДЕ
| ТекСправочник.Ссылка = &Ссылка";
ТекстШаблона = ",
| ТекСправочник.%1 КАК %1";
МассивСписокПолей = СтрРазделить(СписокПолей, ",");
ДобавленныеПоля = Новый Массив;
ТекстПоляЗапроса = "";
Для Каждого ТекПоле Из МассивСписокПолей Цикл
ТекПоле = СокрЛП(ТекПоле);
Если ТекПоле = "Ссылка" Тогда Продолжить КонецЕсли; // Поле уже есть в запросе
Если ДобавленныеПоля.Найти(ТекПоле) Тогда Продолжить КонецЕсли;
ДобавленныеПоля.Добавить(ТекПоле);
ТекСтр = СтрШаблон(ТекстШаблона, ТекПоле);
ТекстПоляЗапроса = ТекстПоляЗапроса + ТекСтр
КонецЦикла;
ТЗ = СтрЗаменить(ТЗ, "{ТекстПоляЗапроса}", ТекстПоляЗапроса);
Запрос = Новый Запрос(ТЗ);
Запрос.УстановитьПараметр("Ссылка", пСсылка);
Выборка = Запрос.Выполнить().Выгрузить();
Результат = Новый Структура;
Для Каждого ТекКолонка Из Выборка.Колонки Цикл
Результат.Вставить(ТекКолонка.Имя, Выборка[0][ТекКолонка.Имя])
КонецЦикла;
Возврат Результат
КонецФункции
СтруктураВидаКонтактнойИнформации (БСП)
Как получить дату и время создания элемента справочника, документа по ссылке
СнятьПризнакПредопределенныйДляВидовКонтактнойИнформации (БСП)
#1, 20 сентября 2022 18:18
Необязательно выгружать в таблицу значений, чтобы обратиться к колонкам. В РезультатеЗапроса тоже можно обойти коллекцию по колонкам
#2, ред. 23 сентября 2022 12:22
Идея очень понравилась, спасибо. Может имеет смысл использовать ЗаполнитьЗначенияСвойств.
Набросал свой вариант для пояснения. Интересно ваше мнение.
#3, 10 ноября 2022 16:43
А почему нельзя использовать функции БСП:
ОбщегоНазначения.ЗначениеРеквизитаОбъекта
ОбщегоНазначения.ЗначенияРеквизитовОбъекта
ОбщегоНазначения.ЗначениеРеквизитаОбъектов
ОбщегоНазначения.ЗначенияРеквизитовОбъектов
#4, 19 ноября 2022 10:07
(3) vlhown, Можно, можно ))
Но я писал в конфу без БСП и сложности все запихивать не хотел. Вот и родилась простенькая простенькая функция. А то в ней понаписана куча всяких получений объектов или обращений к реквизитам через точку, решил переделать всё по нормальному.