Найти основной договор

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

КонецФункции
3

Комментарии

tka4enk0.ilya
#1, ред. 30 августа 2020 07:43

Думаяю что выборку из первого запроса можно не обходить, если сперва проверить результат первого запроса на пустату, ну и ИМХО я бы выполнил запросы в пакете, вроде как чтоб два раза на СУБД не обращатся.


Farovsky
#2, ред. 30 августа 2020 11:03

(1) tka4enk0.ilya, а мне два запроса читабельнее


reborn85
#3, 30 августа 2020 11:27

В большинстве случаях основной договор установлен, а пакетный бы выполнял всегда запросы и первый и второй, а если учесть что второй использует агрегатные функции то это доп нагрузка, с точки зрения оптимальности и скорости на боевых решениях вполне адекватно смотрится.
Насчет обхода первого запроса получение пустого или получение первого значения особенной разницы по скорости не будет, запрос будет и так и так искать первую запись с точки зрения субд


См. также

Добавить договор

Удаление дублей договоров в 1С

ОсновнаяСтрана (БСП)

ЭтоОсновнаяСтрана (БСП)

Сформировать сумму строкой в договор

НайтиСертификат (БСП)

Найти значение в строке

ПолеОсновнойРаздел (БСП)

Модератору