Расширение позволяет пользователю, в случае наличия прав, самостоятельно добавить необходимые ему поля в динамических списках, на примере списка номенклатуры, изменять их "на лету", менять их порядок, пользоваться всеми "прелестями" динамических списков - отборами, сортировками, условным оформлением. Выбранные поля сохраняются в пользовательских настройках и доступны при следующем открытии формы. Использовались материалы: Статья уважаемой Евгении Карук
Установка Расширения:
Расширение устанавливается стандартно, через "НСИ и Администрирование" -> "Печатные формы, отчеты и обработки" -> "Расширения", далее -> "Добавить из файла..." -> выбираем файл расширения, перезапускаем по ссылке сеанс. Расширение работает в безопасном режиме, дополнительно не нужно никаких прав.
Как пользоваться расширением:
После установки расширения, в случае наличия у пользователя необходимых прав, в форме списка номенклатуры и в форме выбора номенклатуры, в кнопке группы кнопок командной панели "Еще" появится пункт "Настроить дополнительные поля списка"
По нажатию на который, пользователь увидит окно настроек дополнительных полей:
В котором он сможет добавить необходимые ему поля в нужном ему порядке. После принятия настроек, в настраиваемом списке вы увидите добавленные поля. Можете пользоваться ими, как обычными - отборы, сортировки, оформление. При следующем открытии формы настройки восстановятся.
Работает на (проверено, писалось на):
Платформа:
Как минимум не ниже 8.3.16 (установлен режим совместимости "минимум"), ниже не проверял
Конфигурации:
УТ 11.5.8.342
ЕРП 2.5.8.405
Инфа для разработчиков:
Перечень добавляемых полей и поддерживаемых форм может быть легко расширен. Все что потребуется - это описать добавляемые поля на примере перечисленных выше, добавить, в случае если ее не было, форму в расширение, и три процедуры в ее модуль и привязать обработчик при создании на сервере после. Минимум трудозатрат и классные плюшки.
Пример кода описания полей:
Процедура модификации списка:
Процедура МодифицироватьСписокИФорму(ЭтотОбъект)
ПараметрыСписка = ПолучитьПараметрыСписка(ЭтотОбъект.ИмяФормы);
ДСписок = ПараметрыСписка.ДСписок;
МассивТаблиц = ПараметрыСписка.МассивТаблиц;
ПолеСсылки = ПараметрыСписка.ПолеСсылки;
Префикс = "Расш_ДополнениеСписков"; //используем только для обозначения таблиц в запросе и полей формы,
//пользователь не видит, по нему, при обновлении все удаляем
СхемаЗапроса = Новый СхемаЗапроса;
СхемаЗапроса.УстановитьТекстЗапроса(ЭтотОбъект[ДСписок].ТекстЗапроса);
ПоследнийПакет = СхемаЗапроса.ПакетЗапросов.Количество() - 1;
Пакет = СхемаЗапроса.ПакетЗапросов[ПоследнийПакет];
Оператор = Пакет.Операторы[0]; //в результирующем пакете не должно быть (по идее...) объединений таблиц, поэтому беру 0
//восстановим запрос - удалим источники по префиксу
Для Сч = -(Оператор.Источники.Количество() - 1) По 0 Цикл
Если СтрНачинаетсяС(Оператор.Источники[-Сч].Источник.Псевдоним,Префикс) Тогда
Оператор.Источники.Удалить(-Сч);
КонецЕсли;
КонецЦикла;
ИндексСсылки = Пакет.Колонки.Индекс(Пакет.Колонки.Найти(ПолеСсылки)); //ищем "главное" поле в исходном запросе для последующих соединений
ГлавноеПоле = Оператор.ВыбираемыеПоля[ИндексСсылки]; //наименование поля ссылки на номенлатуру для соединения
ГлавнаяТаблица = СтрРазделить(ГлавноеПоле,".")[0]; //наименование таблицы со ссылкойна номенлатуру для поиска ее индекса и условий связей
Источники = Оператор.Источники;
ИндексГлавнойТаблицы = Источники.Индекс(Источники.НайтиПоПсевдониму(ГлавнаяТаблица)); //к ней по ее индексу и будем соединять
/////////////////////////////////////////////////////////////////////////////////////////////////////
//модификация запроса
/////////////////////////////////////////////////////////////////////////////////////////////////////
ДобавленныеПараметры = Новый Соответствие; //храним добавленные таблицы в разрезе значений параметра (Склад, Цена)
ДобавленныеПараметрыИмя = Новый Соответствие; //храним имя параметра в запросе: ПараметрРасширения1,2,3...
СчетчикИсточников = 1; //счетчик добавленных Источников для формирования Псевдонима в запросе
Попытка
Для каждого СтрокаПоле ИЗ ЭтотОбъект["НастройкиУниверсальные"] Цикл //в виде массива структур "Источник,ПсевдонимИсточника"
ЗначениеПараметра = СтрокаПоле.Значение; //текущее значение параметра (Склад, Цена)
Если ДобавленныеПараметры[ЗначениеПараметра] = Неопределено Тогда
ДобавленныеПараметры.Вставить(ЗначениеПараметра, Новый Массив);
ДобавленныеПараметрыИмя.Вставить(ЗначениеПараметра,"ПараметрРасширения" + ДобавленныеПараметры.Количество());
КонецЕсли;
ДобавленныйПараметр = ДобавленныеПараметры[ЗначениеПараметра]; //тут лежат уже добавленные по нему таблицы в виде массива структур
ДобавленныйПараметрИмя = ДобавленныеПараметрыИмя[ЗначениеПараметра]; //так он будет называться в запросе
ИндексНастройки = ЭтотОбъект["НастройкиУниверсальные"].Индекс(СтрокаПоле); //????? вроде без него обошелся
Настройка = ЭлементПоПредставлениюСервер(СтрокаПоле.ТипПредставление, ЭтотОбъект["СтруктураТипов"]); //текущая струтура в которой полное описание добавляемого поля
МассивЗанятыхИмен = ЭтотОбъект["НастройкиУниверсальные"].Выгрузить().ВыгрузитьКолонку("ЧеловеческоеИмя");
ЗначениеСтрока = ?(ЗначениеЗаполнено(ЗначениеПараметра), Строка(ЗначениеПараметра), Настройка.Ключ); //либо представление параметра, либо ключ структуры: Цена, ОстатокФактический и т.д.
Представление = ?(ПустаяСтрока(СтрокаПоле.Представление), ЗначениеСтрока, СтрокаПоле.Представление); //приоритет представлению, прописанному вручную
ЧеловеческоеИмя = ПолучитьЧеловеческоеИмя(Представление, МассивЗанятыхИмен); //приводим его к "допустимому имени реквизита", добавляем цыфры - если занят
СтрокаПоле.ЧеловеческоеИмя = ЧеловеческоеИмя; //в дальнейшем это будет поле в запросе и компоновке
//обходим добавляемые таблицы для поля, ищем их в ДобавленныйПараметр, если не находим - добавляем
ПсевдонимыИсточников = Новый Массив; //тут будем хранить псевдонимы добавленных/найденных источников, тобы их подставить в Поле по номеру
//в рамках строки настроек (по добавляемому полю)
Если НЕ Настройка.Значение.Свойство("Структура") Тогда
Сообщить("Свойства не заполнены: " + Настройка.Ключ);
Продолжить; //отладка, проверка заполнения свойств
КонецЕсли;
Для каждого Таблица Из Настройка.Значение.Структура.Источники Цикл
ТекущийИсточникТекст = Таблица.Источник;
ТекущийИсточникУсловие = Таблица.Условие;
ТекущийИсточникПараметры = Таблица.Параметры;
//поиск среди уже добавленных
ТекущийПсевдоним = "";
Для каждого ДобавленныйИсточник из ДобавленныйПараметр Цикл
Если ДобавленныйИсточник.Источник = ТекущийИсточникТекст Тогда
ТекущийПсевдоним = ДобавленныйИсточник.ПсевдонимИсточника;
Прервать;
КонецЕсли;
КонецЦикла;
//добавляем Источник, если не нашли в коллекцию добавленных и далее в запрос
Если ТекущийПсевдоним = "" Тогда
ТекущийПсевдоним = Префикс + СчетчикИсточников;
СчетчикИсточников = СчетчикИсточников + 1;
ДобавленныйПараметр.Добавить(Новый Структура("Источник,ПсевдонимИсточника", ТекущийИсточникТекст, ТекущийПсевдоним));
Иначе
ПсевдонимыИсточников.Добавить(ТекущийПсевдоним);
Прервать; //такой источник с установленным параметром Значение уже добавлен в запрос
КонецЕсли; //добавляем в массив ПсевдонимыИсточников для формирования выражения
//ВНИМАНИЕ возможно что при использовании виртуальных табл с разными параметрами они будут считаться ождинаковыми
ПсевдонимыИсточников.Добавить(ТекущийПсевдоним); //после добавления всех источников по Полю тут будут все псевдонимы
//добавленных источников, для формирования выражения поля, в нужном порядке
//добавляем в запрос
//проверим ЗначениеПараметра на заполнено, если не заполнено, тогда удалим
//из ТекущийИсточникТекст и ТекущийИсточникУсловие все строки из УдалитьПоНезаполнено
Если НЕ ЗначениеЗаполнено(ЗначениеПараметра) Тогда
Для Каждого УдаляемыйТекст из Таблица.УдалитьПоНезаполнено Цикл
ТекущийИсточникТекст = СтрЗаменить(ТекущийИсточникТекст, УдаляемыйТекст, "");
ТекущийИсточникУсловие = СтрЗаменить(ТекущийИсточникУсловие, УдаляемыйТекст, "");
КонецЦикла;
КонецЕсли;
//подставляем в ТекущийИсточникТекст и ТекущийИсточникУсловие параметр и псевдонимы источников
//в ТекущийИсточникТекст %1 это ДобавленныйПараметрИмя
//в ТекущийИсточникУсловие %0 это ДобавленныйПараметрИмя, %1 это ГлавнаяТаблица, %2 это ТекущийПсевдоним
ТекущийИсточникТекст = СтрЗаменить(ТекущийИсточникТекст, "%1", "&"+ДобавленныйПараметрИмя);
ТекущийИсточникУсловие = СтрЗаменить(ТекущийИсточникУсловие, "%0", "&"+ДобавленныйПараметрИмя);
ТекущийИсточникУсловие = СтрЗаменить(ТекущийИсточникУсловие, "%1", ГлавнаяТаблица);
ТекущийИсточникУсловие = СтрЗаменить(ТекущийИсточникУсловие, "%2", ТекущийПсевдоним);
Если СтрНачинаетсяС(ТекущийИсточникТекст, "ВЫБРАТЬ") Тогда
ДобавленныйИсточник = Источники.Добавить(Тип("ВложенныйЗапросСхемыЗапроса"), ТекущийПсевдоним);
ДобавленныйИсточник.Источник.Запрос.УстановитьТекстЗапроса(ТекущийИсточникТекст);
Иначе
ДобавленныйИсточник = Источники.Добавить(ТекущийИсточникТекст, ТекущийПсевдоним);
КонецЕсли;
//установим параметры виртуальных таблиц, в случае их наличия и заполненного параметра
Если ЗначениеЗаполнено(ЗначениеПараметра) И ТекущийИсточникПараметры.Количество() > 0 Тогда
Для Сч = 0 По ДобавленныйИсточник.Источник.Параметры.Количество()-1 Цикл
Если ТекущийИсточникПараметры.Количество() >= Сч+1 Тогда
ДобавленныйИсточник.Источник.Параметры[Сч].Выражение = Новый ВыражениеСхемыЗапроса(СтрЗаменить(ТекущийИсточникПараметры[Сч],"%1","&"+ДобавленныйПараметрИмя));
КонецЕсли;
КонецЦикла;
КонецЕсли;
ДобавленныйИсточник.Соединения.Очистить(); //система при добавлении сама генерит условие связи, чаще неверно
//добавляем сами
Оператор.Источники[ИндексГлавнойТаблицы].Соединения.Добавить(ДобавленныйИсточник, ТекущийИсточникУсловие);
КонецЦикла;
//добавляем Поле
Поле = Настройка.Значение.Структура.Поле;
//подставляем вместо %1 %2 Псевдонимы источников из ПсевдонимыИсточников
Для Сч = 0 По ПсевдонимыИсточников.ВГраница() Цикл
Поле = СтрЗаменить(Поле, "%" + (Сч + 1), ПсевдонимыИсточников[Сч]);
КонецЦикла;
//вместо 0% ДобавленныйПараметрИмя
Поле = СтрЗаменить(Поле, "%0", ДобавленныйПараметрИмя);
Колонка = Оператор.ВыбираемыеПоля.Добавить(Поле);
ИндексПоля = Оператор.ВыбираемыеПоля.Индекс(Колонка);
Пакет.Колонки[ИндексПоля].Псевдоним = Настройка.Ключ + "_" + ЧеловеческоеИмя; //если не заполнен параметр и псевдоним то Настройка.Ключ будет 2 раза...
КонецЦикла;
ЭтотОбъект[ДСписок].ТекстЗапроса = СхемаЗапроса.ПолучитьТекстЗапроса();
//Возврат;
//установим значения параметров запроса, обходя ДобавленныеПараметрыИмя
Для каждого Элемент Из ДобавленныеПараметрыИмя Цикл
Если ЗначениеЗаполнено(Элемент.Ключ) Тогда //не добавляем пустые ссылки, параметры таблиц с пустыми ссылками должны были быть удалены
ЭтотОбъект[ДСписок].Параметры.УстановитьЗначениеПараметра(Элемент.Значение, Элемент.Ключ);
КонецЕсли;
КонецЦикла;
/////////////////////////////////////////////////////////////////////////////////////////////////////
//модификация формы
/////////////////////////////////////////////////////////////////////////////////////////////////////
//удалим элементы по префиксу в таблицах из МассивТаблиц
/////////////////////////////////////////////////////////////////////////////////////////////////////
МассивУдаляемых = Новый Массив;
Для каждого ПроверяемаяТаблица из МассивТаблиц Цикл
Для каждого Элемент Из ЭтотОбъект.Элементы[ПроверяемаяТаблица].ПодчиненныеЭлементы Цикл
Если ТипЗнч(Элемент) = Тип("ПолеФормы") И СтрНачинаетсяС(Элемент.Имя, Префикс) тогда
МассивУдаляемых.Добавить(Элемент);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Для Каждого Элемент из МассивУдаляемых Цикл
ЭтотОбъект.Элементы.Удалить(Элемент);
КонецЦикла;
//добавим элементы в табличные части
/////////////////////////////////////////////////////////////////////////////////////////////////////
Для каждого СтрокаТЗ Из ЭтотОбъект["НастройкиУниверсальные"] Цикл
ИндексТекСтрока = ЭтотОбъект["НастройкиУниверсальные"].Индекс(СтрокаТЗ);
ЧеловеческоеИмя = СтрокаТЗ.ЧеловеческоеИмя;
Настройка = ЭлементПоПредставлениюСервер(СтрокаТЗ.ТипПредставление, ЭтотОбъект["СтруктураТипов"]);
Для каждого ТаблицаФормы Из МассивТаблиц Цикл
ИндексТаблицыФормы = МассивТаблиц.Найти(ТаблицаФормы);
Поле = ЭтотОбъект.Элементы.Добавить(Префикс + ИндексТаблицыФормы + ЧеловеческоеИмя, Тип("ПолеФормы"), ЭтотОбъект.Элементы[ТаблицаФормы]);
Поле.ТолькоПросмотр = Истина;
Если ЧеловеческоеИмя <> Настройка.Ключ Тогда
Ключ = Символы.ПС + "(" + Настройка.Ключ + ")";
Иначе
Ключ = "";
КонецЕсли;
Поле.Заголовок = СтрЗаменить(ЧеловеческоеИмя,"_"," ") + Ключ;//Символы.ПС + Настройка.Ключ;
Поле.ПутьКДанным = ДСписок + "." + Настройка.Ключ + "_" + ЧеловеческоеИмя;
КонецЦикла;
КонецЦикла;
Для каждого ТаблицаФормы Из МассивТаблиц Цикл
ЭтотОбъект.Элементы[ТаблицаФормы].ВысотаШапки = 2;
КонецЦикла;
КоллекцияДляПроверки = ЭтотОбъект[ДСписок].КомпоновщикНастроек.ПользовательскиеНастройки.Элементы;
УдалитьНедоступныеПоля(КоллекцияДляПроверки); ////infostart.ru/1c/articles/1812410/
Исключение
Сообщить("Ошибка модификации формы: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Проверено на следующих конфигурациях и релизах:
- Управление торговлей, редакция 11, релизы 11.5.16.115
- 1С:ERP Управление предприятием 2, релизы 2.5.16.115