&НаСервере
Функция ПолучитьОсновнойДоговор(Организация, Контрагент, ВидДоговора)
Рез = Справочники.ДоговорыКонтрагентов.ПустаяСсылка();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ОсновныеДоговорыКонтрагента.Договор КАК Договор
|ИЗ
| РегистрСведений.ОсновныеДоговорыКонтрагента КАК ОсновныеДоговорыКонтрагента
|ГДЕ
| ОсновныеДоговорыКонтрагента.Организация = &Организация
| И ОсновныеДоговорыКонтрагента.Контрагент = &Контрагент
| И ОсновныеДоговорыКонтрагента.ВидДоговора = &ВидДоговора";
Запрос.УстановитьПараметр("ВидДоговора", ВидДоговора);
Запрос.УстановитьПараметр("Контрагент", Контрагент);
Запрос.УстановитьПараметр("Организация", Организация);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Если ВыборкаДетальныеЗаписи.Следующий() Тогда
Рез = ВыборкаДетальныеЗаписи.Договор;
КонецЕсли;
//если основной договор не отмечен, то поищем среди всех договоров и если по данному виду он один и непомеченный на удаление, то возьмем его
Если Рез.Пустая() Тогда
Запрос.Текст =
"ВЫБРАТЬ
| МАКСИМУМ(ДоговорыКонтрагентов.Ссылка) КАК Договор,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ДоговорыКонтрагентов.Ссылка) КАК КоличествоДоговоров
|ИЗ
| Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
|ГДЕ
| ДоговорыКонтрагентов.Владелец = &Контрагент
| И ДоговорыКонтрагентов.ВидДоговора = &ВидДоговора
| И ДоговорыКонтрагентов.Организация = &Организация
| И НЕ ДоговорыКонтрагентов.ПометкаУдаления";
Запрос.УстановитьПараметр("ВидДоговора", ВидДоговора);
Запрос.УстановитьПараметр("Контрагент", Контрагент);
Запрос.УстановитьПараметр("Организация", Организация);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Если ВыборкаДетальныеЗаписи.Следующий() Тогда
Если ВыборкаДетальныеЗаписи.КоличествоДоговоров=1 Тогда
Рез = ВыборкаДетальныеЗаписи.Договор;
ИначеЕсли ВыборкаДетальныеЗаписи.КоличествоДоговоров=0 Тогда
Рез = СоздатьОсновнойДоговор(Организация, Контрагент, ВидДоговора);
ИначеЕсли ВыборкаДетальныеЗаписи.КоличествоДоговоров>1 Тогда
Рез = ВыборкаДетальныеЗаписи.Договор;
ТекстОшибки = СтрШаблон("Для контрагента %1 подставлен первый договор из нескольких по виду %2 для организации %3", Контрагент, ВидДоговора, Организация);
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстОшибки);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Рез;
КонецФункции
&НаСервере
Функция ПолучитьОсновнойДоговор(Организация, Контрагент, ВидДоговора)
Рез = Справочники.ДоговорыКонтрагентов.ПустаяСсылка();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ОсновныеДоговорыКонтрагента.Договор КАК Договор
|ИЗ
| РегистрСведений.ОсновныеДоговорыКонтрагента КАК ОсновныеДоговорыКонтрагента
|ГДЕ
| ОсновныеДоговорыКонтрагента.Организация = &Организация
| И ОсновныеДоговорыКонтрагента.Контрагент = &Контрагент
| И ОсновныеДоговорыКонтрагента.ВидДоговора = &ВидДоговора";
Запрос.УстановитьПараметр("ВидДоговора", ВидДоговора);
Запрос.УстановитьПараметр("Контрагент", Контрагент);
Запрос.УстановитьПараметр("Организация", Организация);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Если ВыборкаДетальныеЗаписи.Следующий() Тогда
Рез = ВыборкаДетальныеЗаписи.Договор;
КонецЕсли;
//если основной договор не отмечен, то поищем среди всех договоров и если по данному виду он один и непомеченный на удаление, то возьмем его
Если Рез.Пустая() Тогда
Запрос.Текст =
"ВЫБРАТЬ
| МАКСИМУМ(ДоговорыКонтрагентов.Ссылка) КАК Договор,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ДоговорыКонтрагентов.Ссылка) КАК КоличествоДоговоров
|ИЗ
| Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
|ГДЕ
| ДоговорыКонтрагентов.Владелец = &Контрагент
| И ДоговорыКонтрагентов.ВидДоговора = &ВидДоговора
| И ДоговорыКонтрагентов.Организация = &Организация
| И НЕ ДоговорыКонтрагентов.ПометкаУдаления";
Запрос.УстановитьПараметр("ВидДоговора", ВидДоговора);
Запрос.УстановитьПараметр("Контрагент", Контрагент);
Запрос.УстановитьПараметр("Организация", Организация);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Если ВыборкаДетальныеЗаписи.Следующий() Тогда
Если ВыборкаДетальныеЗаписи.КоличествоДоговоров=1 Тогда
Рез = ВыборкаДетальныеЗаписи.Договор;
ИначеЕсли ВыборкаДетальныеЗаписи.КоличествоДоговоров=0 Тогда
Рез = СоздатьОсновнойДоговор(Организация, Контрагент, ВидДоговора);
ИначеЕсли ВыборкаДетальныеЗаписи.КоличествоДоговоров>1 Тогда
Рез = ВыборкаДетальныеЗаписи.Договор;
ТекстОшибки = СтрШаблон("Для контрагента %1 подставлен первый договор из нескольких по виду %2 для организации %3", Контрагент, ВидДоговора, Организация);
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстОшибки);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Рез;
КонецФункции
#1, ред. 30 августа 2020 07:43
Думаяю что выборку из первого запроса можно не обходить, если сперва проверить результат первого запроса на пустату, ну и ИМХО я бы выполнил запросы в пакете, вроде как чтоб два раза на СУБД не обращатся.
#2, ред. 30 августа 2020 11:03
(1) tka4enk0.ilya, а мне два запроса читабельнее
#3, 30 августа 2020 11:27
В большинстве случаях основной договор установлен, а пакетный бы выполнял всегда запросы и первый и второй, а если учесть что второй использует агрегатные функции то это доп нагрузка, с точки зрения оптимальности и скорости на боевых решениях вполне адекватно смотрится.
Насчет обхода первого запроса получение пустого или получение первого значения особенной разницы по скорости не будет, запрос будет и так и так искать первую запись с точки зрения субд