Расскажу о небольшом опыте доработки функционала 1С:УНФ 3.0. Бизнес поставил задачу реализовать функционал подбора партий по остаткам номенклатуры.
Постановка задачи: при подборе партий номенклатуры в документ "Расходная накладная" должны отражаться только партии, имеющиеся в наличии на складе указанном в шапке документа, элемент формы Склад, реквизит объекта СтруктурнаяЕдиница, или в колонке Склад в табличной части документа (далее ТЧ), элемент формы ЗапасыСтруктурнаяЕдиницаРезерв, реквизит ТЧ Запасы.СтруктурнаяЕдиница. При этом, функционал должен быть задействован только при подборе (нажатие кнопки "Подобрать") или добавлении номенклатуры в строку ТЧ документа "Расходная накладная".

Реализация: естественно, все изменения выносим в расширение. На создании расширения останавливаться не буду, перейдем к описанию реализации. Первая мысль была создать свою форму, передать из документа параметры в виде структуры при открытии формы, переопределив форму выбора на свою. Но решение показалось громоздким и возникли опасения, что при обновлении / переходе на новый интерфейс придется все переделывать. Остановился на решении внесения минимальных изменений в типовой код.
Итак, сам процесс:
1. Смотрим в пользовательском режиме, какая форма открывается при подборе партий:

Далее, в модуле открывшейся формы (ФормаСписка, справочник ПартииНоменклатуры) ставим точку останова на первой строчке процедуры ПриСозданииНаСервере, еще раз открываем подбор партий в пользовательском режиме, переходим в конфигуратор и смотрим, какие параметры передаются в форму при ее создании. Параметры смотрим при нажатии ПКМ на слове Параметры.


Видим, что передается ВидОперации (Продажа покупателю) и номенклатура Владелец (товар), СтруктурнаяЕдиница (склад), к сожалению, не передается.
Наша задача передать в открываемую форму еще СтруктурнуюЕдиницу, назовем параметр Склад.
Продолжаем исполнение кода, переходим в пользовательский режим, нажатием на три точки в правом верхнем углу документа открываем форму документа в конфигураторе, добавляем форму в расширение.

Находим элемент формы ЗапасыПартия, переходим в СвязиПараметровВыбора, добавляем параметры Склад, (Объект.СтруктурнаяЕдиница), параметр нужен если склад указан в шапке документа и СкладТабличнаяЧасть, (Элементы.Запасы.ТекущиеДанные.СтруктурнаяЕдиница), параметр нужен если склад указан в строке ТЧ документа.

То же самое делаем при добавлении номенклатуры через подбор (нажатие кнопки "Подобрать"). В пользовательском режиме нажимаем кнопку и по алгоритму описанному выше переходим в конфигуратор, добавляем форму списка номенклатуры в расширение.

Находим элемент формы КорзинаРасшифровкаПартия, переходим в СвязиПараметровВыбора, добавляем параметр Склад, (Элементы.КорзинаРасшифровка.Текущие данные.СтруктурнаяЕдиница).

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

Добавляем процедуру ПриСозданииНаСервере() модуля ФормыСписка справочника ПартииНоменклатуры в расширение, тип вызова ставим После. В расширение также добавляется форма справочника.
Теперь переходим к запросу динамического списка ФормыСписка справочника ПартииНоменклатуры. Идея в следующем: мы не правим запрос динамического списка в расширении, а копируем исходный текст запроса и правим его в пользовательском режиме, через консоль запросов. Затем, переопределим текст запроса и будем вызывать его только при определенных условиях.
Итак, копируем текст запроса:

Обращаем внимание на основную таблицу динамического списка.

К исходному тексту запроса добавляем регистр сведений ОстаткиТоваров, выбираем ресурсы Количество, Резерв и измерение СтруктурнаяЕдиница.

Далее, на закладке Связи создаем связь (левое соединение между таблицами справочника ПартииНоменклатуры и рс ОстаткиТоваров), на закладке Условия добавляем параметры Номенклатура и Склад, на закладке Группировка задаем группировку, на закладке Псевднимы - псевдоним Склад для СтруктурнойЕдиницы.




В консоли запросов задаем параметры номенклатура и склад, проверяем запрос. Если все корректно, копируем текст запроса и переходим в конфигуратор в расширение, в модуль ФормыСписка справочника ПартииНоменклатуры. Здесь ниже нашей процедуры ПриСозданииНаСервере(), создаем функцию для переопределения запроса динамического списка, вставляем в нее скопированный запрос, функция возвращает текст запроса. В процедуре ПриСозданииНаСервере() переопределяем наш запрос, здесь пригодится основная таблица динамического списка, основываясь на передаваемых параметрах задаем условия, по которым будет исполняться наш код (при переключении между складами в шапке документа и ТЧ документа реквизиты не очищаются, поэтому есть вероятность, что будут передаваться разные значения из шапки и из ТЧ документа), затем программно создаем необходимые колонки (не будем ломать форму). Код приведен ниже.
&НаСервере
Процедура ОС_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("Отбор") И Параметры.Отбор.Свойство("Владелец") И Параметры.Свойство("ВидОперации") Тогда
ТекстЗапроса = ОС_ТекстЗапросаПартииНоменклатуры();
СвойстваСписка = ОбщегоНазначения.СтруктураСвойствДинамическогоСписка();
СвойстваСписка.ТекстЗапроса = ТекстЗапроса;
СвойстваСписка.ОсновнаяТаблица = "Справочник.ПартииНоменклатуры";
СвойстваСписка.ДинамическоеСчитываниеДанных = Истина;
ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(Элементы.Список, СвойстваСписка);
Если ЗначениеЗаполнено(Параметры.Склад) И НЕ ЗначениеЗаполнено(Параметры.СкладТабличнаяЧасть) Тогда
Список.Параметры.УстановитьЗначениеПараметра("Склад", Параметры.Склад);
Список.Параметры.УстановитьЗначениеПараметра("Номенклатура", Параметры.Отбор.Владелец);
ИначеЕсли ЗначениеЗаполнено(Параметры.СкладТабличнаяЧасть) И НЕ ЗначениеЗаполнено(Параметры.Склад) Тогда
Список.Параметры.УстановитьЗначениеПараметра("Склад", Параметры.СкладТабличнаяЧасть);
Список.Параметры.УстановитьЗначениеПараметра("Номенклатура", Параметры.Отбор.Владелец);
ИначеЕсли ЗначениеЗаполнено(Параметры.Склад) И ЗначениеЗаполнено(Параметры.СкладТабличнаяЧасть)
И Параметры.Склад = Параметры.СкладТабличнаяЧасть Тогда
Список.Параметры.УстановитьЗначениеПараметра("Склад", Параметры.Склад);
Список.Параметры.УстановитьЗначениеПараметра("Номенклатура", Параметры.Отбор.Владелец);
ИначеЕсли ЗначениеЗаполнено(Параметры.Склад) И ЗначениеЗаполнено(Параметры.СкладТабличнаяЧасть)
И Параметры.Склад <> Параметры.СкладТабличнаяЧасть Тогда
Параметры.Склад = "";
Параметры.СкладТабличнаяЧасть = "";
Параметры.Отбор.Владелец = "";
Список.Параметры.УстановитьЗначениеПараметра("Склад", Параметры.Склад);
Список.Параметры.УстановитьЗначениеПараметра("Номенклатура", Параметры.Отбор.Владелец);
Сообщить("ВНИМАНИЕ! Невозможно подобрать партии! Склады в шапке документа и в табличной части заполнены разными значениями! Проверьте заполнение реквизитов!");
КонецЕсли;
Если Параметры.Свойство("Отбор") И Параметры.Отбор.Свойство("Владелец") И НЕ Параметры.Свойство("ВидОперации") Тогда
Список.Параметры.УстановитьЗначениеПараметра("Склад", Параметры.Склад);
Список.Параметры.УстановитьЗначениеПараметра("Номенклатура", Параметры.Отбор.Владелец);
КонецЕсли;
//Создаем колонки "Количество", "Резерв", "Склад"
НовыйЭлемент = Элементы.Вставить("Резерв", Тип("ПолеФормы"), Элементы.Список, Элементы.ВладелецПартии);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ГоризонтальноеПоложение = ГоризонтальноеПоложениеЭлемента.Лево;
НовыйЭлемент.ПутьКДанным = "Список.Резерв";
НовыйЭлемент.Заголовок = "Резерв";
НовыйЭлемент = Элементы.Вставить("Количество", Тип("ПолеФормы"), Элементы.Список, Элементы.Резерв);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ГоризонтальноеПоложение = ГоризонтальноеПоложениеЭлемента.Лево;
НовыйЭлемент.ПутьКДанным = "Список.Количество";
НовыйЭлемент.Заголовок = "Количество";
НовыйЭлемент = Элементы.Вставить("Склад", Тип("ПолеФормы"), Элементы.Список, Элементы.Ссылка);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "Список.Склад";
НовыйЭлемент.Заголовок = "Склад";
КонецЕсли;
КонецПроцедуры
// <Описание функции>
// Измененный запрос динамического списка, добавлен регистр сведений "ОстаткиТоваров"
//
// Параметров нет
//
// Возвращаемое значение:
// Текст измененного запроса динамического списка.
//
&НаСервере
Функция ОС_ТекстЗапросаПартииНоменклатуры()
ТекстЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
| ВЫБОР
| КОГДА ПартииКонтрагентов.Номенклатура ЕСТЬ NULL
| ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ КАК Основная,
| СправочникПартииНоменклатуры.Ссылка КАК Ссылка,
| СправочникПартииНоменклатуры.ПометкаУдаления КАК ПометкаУдаления,
| СправочникПартииНоменклатуры.Владелец КАК Владелец,
| СправочникПартииНоменклатуры.Код КАК Код,
| СправочникПартииНоменклатуры.Наименование КАК Наименование,
| СправочникПартииНоменклатуры.Статус КАК Статус,
| ВЫБОР
| КОГДА СправочникПартииНоменклатуры.ВладелецПартии = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
| ТОГДА ""<Без владельца>""
| ИНАЧЕ СправочникПартииНоменклатуры.ВладелецПартии
| КОНЕЦ КАК ВладелецПартии,
| СправочникПартииНоменклатуры.Предопределенный КАК Предопределенный,
| СправочникПартииНоменклатуры.ИмяПредопределенныхДанных КАК ИмяПредопределенныхДанных,
| СправочникПартииНоменклатуры.Недействителен КАК Недействителен,
| ВЫБОР
| КОГДА СправочникПартииНоменклатуры.ПометкаУдаления ЕСТЬ NULL
| ТОГДА 1
| ИНАЧЕ ВЫБОР
| КОГДА СправочникПартииНоменклатуры.ПометкаУдаления
| ТОГДА 5
| ИНАЧЕ 4
| КОНЕЦ
| КОНЕЦ КАК ИндексКартинки,
| ВЫБОР
| КОГДА НаличиеФайлов.ЕстьФайлы ЕСТЬ NULL
| ТОГДА 0
| КОГДА НаличиеФайлов.ЕстьФайлы
| ТОГДА 1
| ИНАЧЕ 0
| КОНЕЦ КАК ЕстьФайлы,
| ВЫБОР
| КОГДА &ЗапретКомиссионныхПартийБезВладельца
| И СправочникПартииНоменклатуры.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыПартий.ТоварыНаКомиссии)
| И СправочникПартииНоменклатуры.ВладелецПартии = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ КАК ЗапретВыбораПартии,
| СУММА(ОстаткиТоваров.Количество) КАК Количество,
| СУММА(ОстаткиТоваров.Резерв) КАК Резерв,
| ОстаткиТоваров.СтруктурнаяЕдиница КАК Склад
|ИЗ
| Справочник.ПартииНоменклатуры КАК СправочникПартииНоменклатуры
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПартииКонтрагентов КАК ПартииКонтрагентов
| ПО СправочникПартииНоменклатуры.Ссылка = ПартииКонтрагентов.Партия
| {ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НаличиеФайлов КАК НаличиеФайлов
| ПО СправочникПартииНоменклатуры.Ссылка = НаличиеФайлов.ОбъектСФайлами}
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ОстаткиТоваров КАК ОстаткиТоваров
| ПО СправочникПартииНоменклатуры.Ссылка = ОстаткиТоваров.Партия
|ГДЕ
| НЕ СправочникПартииНоменклатуры.Статус В (&ФОДляИсключения)
| И ОстаткиТоваров.СтруктурнаяЕдиница = &Склад
| И ОстаткиТоваров.Номенклатура = &Номенклатура
|
|СГРУППИРОВАТЬ ПО
| ВЫБОР
| КОГДА ПартииКонтрагентов.Номенклатура ЕСТЬ NULL
| ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ,
| СправочникПартииНоменклатуры.Ссылка,
| СправочникПартииНоменклатуры.ПометкаУдаления,
| СправочникПартииНоменклатуры.Владелец,
| СправочникПартииНоменклатуры.Код,
| СправочникПартииНоменклатуры.Наименование,
| СправочникПартииНоменклатуры.Статус,
| ВЫБОР
| КОГДА СправочникПартииНоменклатуры.ВладелецПартии = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
| ТОГДА ""<Без владельца>""
| ИНАЧЕ СправочникПартииНоменклатуры.ВладелецПартии
| КОНЕЦ,
| СправочникПартииНоменклатуры.Предопределенный,
| СправочникПартииНоменклатуры.ИмяПредопределенныхДанных,
| СправочникПартииНоменклатуры.Недействителен,
| ВЫБОР
| КОГДА СправочникПартииНоменклатуры.ПометкаУдаления ЕСТЬ NULL
| ТОГДА 1
| ИНАЧЕ ВЫБОР
| КОГДА СправочникПартииНоменклатуры.ПометкаУдаления
| ТОГДА 5
| ИНАЧЕ 4
| КОНЕЦ
| КОНЕЦ,
| ВЫБОР
| КОГДА НаличиеФайлов.ЕстьФайлы ЕСТЬ NULL
| ТОГДА 0
| КОГДА НаличиеФайлов.ЕстьФайлы
| ТОГДА 1
| ИНАЧЕ 0
| КОНЕЦ,
| ВЫБОР
| КОГДА &ЗапретКомиссионныхПартийБезВладельца
| И СправочникПартииНоменклатуры.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыПартий.ТоварыНаКомиссии)
| И СправочникПартииНоменклатуры.ВладелецПартии = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ,
| ОстаткиТоваров.СтруктурнаяЕдиница";
Возврат ТекстЗапроса;
КонецФункции // ОС_ТекстЗапросаПартииНоменклатуры()
Проверяем, получаем нужный результат.
P. S. Прошу не судить строго, в разработке не так давно) Статья, как мне кажется, будет полезна тем, кто только начинает свой путь в разработке.
Вступайте в нашу телеграмм-группу Инфостарт