В конфигурации "Управление торговлей" ред. 11 нет как таковых настроек пользователей для автозаполнения реквизитов создаваемых элементов справочников или документов как это было, например, в УТ версии 10.3 или УПП 1.3.
Теперь в конфигурации есть некоторые зачатки "разума", по которым программа самостоятельно определяет какое значение в реквизит документа нужно подставлять.
Далее рассмотрим принцип работы автозаполнения в конфигурации УТ 11.
Обратимся к документу "Заказ клиента". При его создании, вне зависимости от наличия документа-основания, выполняется процедура-обработчик модуля объекта:
"ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)"
Первым параметром передаются значения для заполнения нового документа в зависимости от основания и алгоритмов конфигурации. Второй параметр - это флаг стандартной обработки события.
Для документа "Заказ клиента" программный код обработчика заполнения следующий:
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка) ТипДанныхЗаполнения = ТипЗнч(ДанныеЗаполнения); ЗаполнитьПоЗначениямАвтозаполнения(ДанныеЗаполнения); Если ТипДанныхЗаполнения = Тип("Структура") Тогда ЗаполнитьДокументПоОтбору(ДанныеЗаполнения); ИначеЕсли ТипДанныхЗаполнения = Тип("СправочникСсылка.Партнеры") Тогда ЗаполнитьДокументНаОснованииПартнера(ДанныеЗаполнения); ИначеЕсли ТипДанныхЗаполнения = Тип("СправочникСсылка.СделкиСКлиентами") Тогда ЗаполнитьДокументНаОснованииСделкиПоПродаже(ДанныеЗаполнения); ИначеЕсли ТипДанныхЗаполнения = Тип("ДокументСсылка.КоммерческоеПредложениеКлиенту") Тогда ЗаполнитьДокументНаОснованииКоммерческогоПредложенияКлиенту(ДанныеЗаполнения); ИначеЕсли ТипДанныхЗаполнения = Тип("СправочникСсылка.СоглашенияСКлиентами") Тогда ЗаполнитьДокументНаОснованииИндивидуальногоСоглашенияСКлиентом(ДанныеЗаполнения); ИначеЕсли ТипДанныхЗаполнения = Тип("ДокументСсылка.ЗаданиеТорговомуПредставителю") Тогда ЗаполнитьДокументНаОснованииЗаданияТорговомуПредставителю(ДанныеЗаполнения); КонецЕсли; ИнициализироватьУсловияПродаж(); ИнициализироватьДокумент(ДанныеЗаполнения); КонецПроцедуры
Нас интересует случай, когда данные заполнения пустые. Тогда заполнение выполняется не из данных заполнения, а с помощью специального алгоритма. На листинге выше он реализован в процедуре "ЗаполнитьПоЗначениямАвтозаполнения". Вот так выглядит программный код этого обработчика:
Процедура ЗаполнитьПоЗначениямАвтозаполнения(ДанныеЗаполнения = Неопределено) ЕстьДанныеЗаполнения = (НЕ ДанныеЗаполнения = Неопределено); ДанныеЗаполненияСтруктура = (ТипЗнч(ДанныеЗаполнения) = Тип("Структура")); Если Не ЕстьДанныеЗаполнения Или ДанныеЗаполненияСтруктура И НЕ ДанныеЗаполнения.Свойство("ДокументОснование") Тогда // Заполним основные свойства СвойстваАвтозаполнения = Новый Структура("Организация, Склад, ХозяйственнаяОперация"); СтрокаКлючиСтруктуры = СокрЛП(ОбменДаннымиСобытия.КлючиСтруктурыВСтроку(СвойстваАвтозаполнения)); Если ДанныеЗаполненияСтруктура Тогда ЗаполнитьЗначенияСвойств(СвойстваАвтозаполнения, ДанныеЗаполнения); КонецЕсли; ОбщегоНазначенияУТ.ЗаполнитьЗначенияСвойствАвтозаполнения(Ссылка, СвойстваАвтозаполнения); ЗаполнитьЗначенияСвойств(ЭтотОбъект, СвойстваАвтозаполнения, СтрокаКлючиСтруктуры); // Заполним банковский счет и кассу в зависимости от организации СвойстваАвтозаполнения = Новый Структура("Организация, БанковскийСчет, Касса", Организация); СтрокаКлючиСтруктуры = СокрЛП(ОбменДаннымиСобытия.КлючиСтруктурыВСтроку(СвойстваАвтозаполнения)); Если ДанныеЗаполненияСтруктура Тогда ЗаполнитьЗначенияСвойств(СвойстваАвтозаполнения, ДанныеЗаполнения); КонецЕсли; ОбщегоНазначенияУТ.ЗаполнитьЗначенияСвойствАвтозаполнения(Ссылка, СвойстваАвтозаполнения); ЗаполнитьЗначенияСвойств(ЭтотОбъект, СвойстваАвтозаполнения, СтрокаКлючиСтруктуры); КонецЕсли;КонецПроцедуры
В случае, если данные заполнения не определены, то такие реквизиты как "Организация", "Склад" и "ХозяйственнаяОперация" заполняются автоматически с помощью процедуры "ЗаполнитьЗначенияСвойствАвтозаполнения" общего модуля "ОбщегоНазначенияУТ". При этом, если данные заполнения все же были переданы в виде структуры или документа, то при наличии значения заполнения в них, приоритет отдается данным заполнения.
Обратимся к процедуре "ЗаполнитьЗначенияСвойствАвтозаполнения":
// Получает значения автозаполнения по статистике и заполняет ими переданную структуру // Заполненные свойства не перезаполняются и выступают в роли отбора // Свойства, которые не найдены в метаданных объекта удаляются из структуры // // Параметры: // ОбъектСсылка - ДокументСсылка - ссылка на заполняемый документ // СвойстваАвтозаполнения - Структура - свойства, которые нужно заполнить // Процедура ЗаполнитьЗначенияСвойствАвтозаполнения(ОбъектСсылка, СвойстваАвтозаполнения) Экспорт // .... КонецПроцедуры
В соответствии с описанием процедуры, первым параметром передается ссылка на документ, вторым - структура полей для автозаполнения. По тем полям в структуре, для которых не установлено значение заполнения, система формируем запрос на получение последних пяти элементов (в нашем случае документов "Заказ клиента"), в которых получает часто использованные значения заполнения. Вот пример запроса для документа "Заказ клиента":
"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 5 | СтатистикаСДатами.ОбъектПоиска КАК ОбъектПоиска, | СУММА(СтатистикаСДатами.Использование) КАК ОбщийВес |ПОМЕСТИТЬ Статистика_Организация |ИЗ | (ВЫБРАТЬ ПЕРВЫЕ 5 | ВидДокумента.Организация КАК ОбъектПоиска, | 1 КАК Использование | ИЗ | Документ.ЗаказКлиента КАК ВидДокумента | ГДЕ | НЕ ВидДокумента.ПометкаУдаления | И ВидДокумента.Автор = &Автор | | УПОРЯДОЧИТЬ ПО | ВидДокумента.Дата УБЫВ) КАК СтатистикаСДатамиСГРУППИРОВАТЬ ПО | СтатистикаСДатами.ОбъектПоискаУПОРЯДОЧИТЬ ПО | ОбщийВес УБЫВ |;//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | СУММА(Статистика.ОбщийВес) КАК ОбщийВес |ПОМЕСТИТЬ ОбщееКоличество_Организация |ИЗ | Статистика_Организация КАК Статистика |;//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ВложенныйЗапрос.ОбъектПоиска |ИЗ | (ВЫБРАТЬ | Статистика.ОбъектПоиска КАК ОбъектПоиска, | 100 * Статистика.ОбщийВес / ОбщееКоличество.ОбщийВес КАК ВесПоСтатистике | ИЗ | Статистика_Организация КАК Статистика | ЛЕВОЕ СОЕДИНЕНИЕ ОбщееКоличество_Организация КАК ОбщееКоличество | ПО (ИСТИНА)) КАК ВложенныйЗапрос |ГДЕ | ВложенныйЗапрос.ВесПоСтатистике > 50 |;//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 5 | СтатистикаСДатами.ОбъектПоиска КАК ОбъектПоиска, | СУММА(СтатистикаСДатами.Использование) КАК ОбщийВес |ПОМЕСТИТЬ Статистика_Склад |ИЗ | (ВЫБРАТЬ ПЕРВЫЕ 5 | ВидДокумента.Склад КАК ОбъектПоиска, | 1 КАК Использование | ИЗ | Документ.ЗаказКлиента КАК ВидДокумента | ГДЕ | НЕ ВидДокумента.ПометкаУдаления | И ВидДокумента.Автор = &Автор | | УПОРЯДОЧИТЬ ПО | ВидДокумента.Дата УБЫВ) КАК СтатистикаСДатамиСГРУППИРОВАТЬ ПО | СтатистикаСДатами.ОбъектПоискаУПОРЯДОЧИТЬ ПО | ОбщийВес УБЫВ |;//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | СУММА(Статистика.ОбщийВес) КАК ОбщийВес |ПОМЕСТИТЬ ОбщееКоличество_Склад |ИЗ | Статистика_Склад КАК Статистика |;//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ВложенныйЗапрос.ОбъектПоиска |ИЗ | (ВЫБРАТЬ | Статистика.ОбъектПоиска КАК ОбъектПоиска, | 100 * Статистика.ОбщийВес / ОбщееКоличество.ОбщийВес КАК ВесПоСтатистике | ИЗ | Статистика_Склад КАК Статистика | ЛЕВОЕ СОЕДИНЕНИЕ ОбщееКоличество_Склад КАК ОбщееКоличество | ПО (ИСТИНА)) КАК ВложенныйЗапрос |ГДЕ | ВложенныйЗапрос.ВесПоСтатистике > 50 |;//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 5 | СтатистикаСДатами.ОбъектПоиска КАК ОбъектПоиска, | СУММА(СтатистикаСДатами.Использование) КАК ОбщийВес |ПОМЕСТИТЬ Статистика_ХозяйственнаяОперация |ИЗ | (ВЫБРАТЬ ПЕРВЫЕ 5 | ВидДокумента.ХозяйственнаяОперация КАК ОбъектПоиска, | 1 КАК Использование | ИЗ | Документ.ЗаказКлиента КАК ВидДокумента | ГДЕ | НЕ ВидДокумента.ПометкаУдаления | И ВидДокумента.Автор = &Автор | | УПОРЯДОЧИТЬ ПО | ВидДокумента.Дата УБЫВ) КАК СтатистикаСДатамиСГРУППИРОВАТЬ ПО | СтатистикаСДатами.ОбъектПоискаУПОРЯДОЧИТЬ ПО | ОбщийВес УБЫВ |;//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | СУММА(Статистика.ОбщийВес) КАК ОбщийВес |ПОМЕСТИТЬ ОбщееКоличество_ХозяйственнаяОперация |ИЗ | Статистика_ХозяйственнаяОперация КАК Статистика |;//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ВложенныйЗапрос.ОбъектПоиска |ИЗ | (ВЫБРАТЬ | Статистика.ОбъектПоиска КАК ОбъектПоиска, | 100 * Статистика.ОбщийВес / ОбщееКоличество.ОбщийВес КАК ВесПоСтатистике | ИЗ | Статистика_ХозяйственнаяОперация КАК Статистика | ЛЕВОЕ СОЕДИНЕНИЕ ОбщееКоличество_ХозяйственнаяОперация КАК ОбщееКоличество | ПО (ИСТИНА)) КАК ВложенныйЗапрос |ГДЕ | ВложенныйЗапрос.ВесПоСтатистике > 50"
Вот такой огромный, "страшный" запрос выполняется при каждом создании заказа клиента без документа-основания или других данных заполнения. Если кратко, то запрос получает 5 ближайших документов не помеченных на удаление, где автор документа - это текущий пользователь. Далее рассчитывается общий весь и вес каждого из значения реквизита. И в результате запрос возвращает значение, которое пользователь использовал наибольшее число раз.
В запросе выше описанная операция выполняется трижды, для каждого из реквизитов автозаполнения: для организации, для склада и для хоз. операции. На листинге процедуры "ЗаполнитьЗначенияСвойствАвтозаполнения" выше Вы также могли видеть, что автозаполнение для заказа покупателя выполняется для реквизитов "БанковскийСчет" и "Касса".
Такой способ автозаполнения документов возможно упрощает жизнь внедренцам или администраторам, заполняющим настройки пользователей, но ни в коем случае не делает работу пользователей более удобной. Если пользователь был только что создан, то автозаполнение не будет работать. Тем более в большинстве ситуаций пользователю необходимо заполнение документа одним единственным складов, вне зависимости от значений, которое он заполнял ранее.