У реквизитов документов есть замечательное свойство «История выбора при вводе». Все бы хорошо, но как обычно дьявол кроется в деталях. Для примера возьмем реквизит «Контрагент» документа «ГТДПоИмпорт» (ГТД по импорту), в который обычно заносится не просто элемент из справочника «Контрагенты», а нужна именно таможня. Таким образом, вся наша предыдущая история выбора никуда не годится, так как она не учитывает специфику данного контекста.
Чтобы реализовать свою логику придется немного попрограммировать. Для начала создадим функцию, которая вернет нам список нужных контрагентов:
&НаСервереБезКонтекста
Функция КонтрагентНачалоВыбораИзСпискаНаСервере()
Запрос = Новый Запрос("ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 7
| ГТДПоИмпорту.Контрагент КАК Контрагент
|ИЗ
| Документ.ГТДПоИмпорту КАК ГТДПоИмпорту
|ГДЕ
| ГТДПоИмпорту.Проведен = ИСТИНА
|
|УПОРЯДОЧИТЬ ПО
| Контрагент
|АВТОУПОРЯДОЧИВАНИЕ");
Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(0);
КонецФункции
Данный вариант запроса можно рассматривать только как базовый потому, что чаще всего на практике есть много нюансов, которые можно и даже нужно использовать. Например, ни к чему сканировать все документы в базе, достаточно запросить документы за последний квартал. Тогда наша функция примет следующий вид:
Функция КонтрагентНачалоВыбораИзСпискаНаСервере()
Запрос = Новый Запрос("ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 7
| ГТДПоИмпорту.Контрагент КАК Контрагент
|ИЗ
| Документ.ГТДПоИмпорту КАК ГТДПоИмпорту
|ГДЕ
| ГТДПоИмпорту.Дата > &Дата
| И ГТДПоИмпорту.Проведен = ИСТИНА
|
|УПОРЯДОЧИТЬ ПО
| Контрагент
|АВТОУПОРЯДОЧИВАНИЕ");
Запрос.УстановитьПараметр("Дата", НачалоМесяца(ДобавитьМесяц(ТекущаяДата(), -4)));
Выборка = Запрос.Выполнить();
Если Выборка.Пустой() Тогда
Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 7
| ГТДПоИмпорту.Контрагент КАК Контрагент
|ИЗ
| Документ.ГТДПоИмпорту КАК ГТДПоИмпорту
|ГДЕ
| ГТДПоИмпорту.Проведен = ИСТИНА
|
|УПОРЯДОЧИТЬ ПО
| Контрагент
|АВТОУПОРЯДОЧИВАНИЕ";
Выборка = Запрос.Выполнить();
КонецЕсли;
Возврат Выборка.Выгрузить().ВыгрузитьКолонку(0);
КонецФункции
или такой вариант
Функция КонтрагентНачалоВыбораИзСпискаНаСервере()
Запрос = Новый Запрос("ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 7
| ГТДПоИмпорту.Контрагент КАК Контрагент,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ГТДПоИмпорту.Ссылка) КАК Количество
|ПОМЕСТИТЬ ТопЧарт
|ИЗ
| Документ.ГТДПоИмпорту КАК ГТДПоИмпорту
|ГДЕ
| ГТДПоИмпорту.Дата > &Дата
| И ГТДПоИмпорту.Проведен = ИСТИНА
|
|СГРУППИРОВАТЬ ПО
| ГТДПоИмпорту.Контрагент
|
|УПОРЯДОЧИТЬ ПО
| Количество УБЫВ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТопЧарт.Контрагент КАК Контрагент
|ИЗ
| ТопЧарт КАК ТопЧарт
|
|УПОРЯДОЧИТЬ ПО
| Контрагент
|АВТОУПОРЯДОЧИВАНИЕ");
Запрос.УстановитьПараметр("Дата", НачалоМесяца(ДобавитьМесяц(ТекущаяДата(), -4)));
Выборка = Запрос.Выполнить();
Если Выборка.Пустой() Тогда
Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 7
| ГТДПоИмпорту.Контрагент КАК Контрагент
|ИЗ
| Документ.ГТДПоИмпорту КАК ГТДПоИмпорту
|ГДЕ
| ГТДПоИмпорту.Проведен = ИСТИНА
|
|УПОРЯДОЧИТЬ ПО
| Контрагент
|АВТОУПОРЯДОЧИВАНИЕ";
Выборка = Запрос.Выполнить();
КонецЕсли;
Возврат Выборка.Выгрузить().ВыгрузитьКолонку(0);
КонецФункции
Нюансов может быть сколько угодно. Например, если в базе используется несколько организаций, то возможно следует добавить отбор по организациям. Или к примеру, если каждый оператор работает со своим отделением таможни, то в запросах следует учитывать текущего оператора.
После того как разобрались с функцией формирования списка, ее следует вызвать. Добавим процедуру вызова в реквизит формы «Контрагент»:
&НаКлиенте
Процедура КонтрагентНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
Элемент.СписокВыбора.ЗагрузитьЗначения(КонтрагентНачалоВыбораИзСпискаНаСервере());
КонецПроцедуры
Трудно представить, что документы формируются каждую секунду, хотя такой сценарий и не исключен. Так вот если документов не так много, то упростим жизнь серверу:
Процедура КонтрагентНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
Если Элемент.СписокВыбора.Количество() = 0 Тогда
Элемент.СписокВыбора.ЗагрузитьЗначения(КонтрагентНачалоВыбораИзСпискаНаСервере());
КонецЕсли;
КонецПроцедуры
Или если хочется совсем уж все и вся автоматизировать, тогда такой вариант:
Процедура КонтрагентНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
Если Элемент.СписокВыбора.Количество() = 0 Тогда
Элемент.СписокВыбора.ЗагрузитьЗначения(КонтрагентНачалоВыбораИзСпискаНаСервере());
КонецЕсли;
Если ПустаяСтрока(Объект.Контрагент) И Элемент.СписокВыбора.Количество() = 1 Тогда
СтандартнаяОбработка = Ложь;
Объект.Контрагент = Элемент.СписокВыбора[0].Значение;
КонецЕсли;
КонецПроцедуры
После всех манипуляций получаем:
Документ «ГТД по импорту» рассмотрен только для демонстрации методики, данное решение может применяться в любом другом документе.
В качестве эпилога
У реквизитов есть еще одно интересное свойство «Создание при вводе». Все бы ничего, но для чего разработчики добавили его к реквизитам отчетов? Не смог придумать сценарий его использования, ведь если создать новый элемент, то какой должен получиться отчет? Если есть у кого какие мысли по этому поводу, бенвенуто в обсуждения…