Осноные возможноси:
1. Отбор имеет полный функционал как и в 1С Предприятие 8.1;
2. Отсутсвует ошибка при использовании истории отборов (в 1С Предприятии 8.1 если установлен отбор и воспользоватся отбором из истории текущий отбор не отменяется);
3. Возможность использования отборов и сортировки для всех возможных реквизитов, которые присутствуют в таблице и тех которые добавлены через команду формы «Изменить форму» (Например, Номенклатура.Ссылка.Ссылка.ВидНоменклатуры.Код);
4. Сортировка по любому реквизиту в таблице;
5. История отборов размером в 20 элементов;
6. Все построенно на СКД с выводом в таблицу значений, что дает возможность использовать дополнительные поля которые есть в запросе;
7. Минимум серверных вызовов;
8. Для использования в своих разработках достаточно изменить запрос в наборе данных, структуру полей компоновщика (ПриСозданииНаСервере) и подкоректировать таблицу значений для вывода.
Код обработки, работоспособен в конфигурации УТ 11:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
//1. Создаем схему компоновки данных
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
//1.1 определяем источник данных для схемы
ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить();
ИсточникДанных.Имя = «ИсточникДанных»;
ИсточникДанных.СтрокаСоединения = «»;
ИсточникДанных.ТипИсточникаДанных = «Local»;
//1.2 определяем набор данных
НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип(«НаборДанныхЗапросСхемыКомпоновкиДанных»));
НаборДанных.Имя = «НаборДанных»;
НаборДанных.ИсточникДанных = «ИсточникДанных»;
НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
НаборДанных.Запрос = «
|ВЫБРАТЬ
| СпрНоменклатура.Ссылка КАК Номенклатура,
| СвободныеОстатки.ВНаличииОстаток КАК ВНаличии,
| СвободныеОстатки.ВРезервеОстаток КАК ВРезерве
|
|ИЗ
| Справочник.Номенклатура КАК СпрНоменклатура
|
|ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.СвободныеОстатки.Остатки КАК СвободныеОстатки
|ПО СпрНоменклатура.Ссылка = СвободныеОстатки.Номенклатура
|
|ГДЕ
|НЕ СпрНоменклатура.ЭтоГруппа
|И СпрНоменклатура.Родитель = &ГруппаНоменклатуры»;
//1.2.1 добавляем поля
ПолеНоменклатуры = НаборДанных.Поля.Добавить(Тип(«ПолеНабораДанныхСхемыКомпоновкиДанных»));
ПолеНоменклатуры.ПутьКДанным = «Номенклатура»;
ПолеНоменклатуры.Заголовок = «Номенклатура»;
ПолеНоменклатуры.Поле = «Номенклатура»;
//1.3 определяем ресурсы
//ПолеРесурса = СхемаКомпоновкиДанных.ПоляИтога.Добавить();
//ПолеРесурса.Выражение = «»;
//ПолеРесурса.ПутьКДанным = «»;
//2. создаем настройки для схемы
//НастройкиКомпоновкиДанных = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
АдресСхемыКомпоновкиДанных = ПоместитьВоВременноеХранилище(СхемаКомпоновкиДанных, УникальныйИдентификатор);
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемыКомпоновкиДанных));
//2.1 определяем структуру
//2.1.1 добавляем группировку «Номенклатура»
ГруппировкаНоменклатуры = КомпоновщикНастроек.Настройки.Структура.Добавить(Тип(«ГруппировкаКомпоновкиДанных»));
ГруппировкаНоменклатуры.Использование = Истина;
//2.2 определим выбранные поля
ВыбранноеПоле = ГруппировкаНоменклатуры.Выбор.Элементы.Добавить(Тип(«ВыбранноеПолеКомпоновкиДанных»));
ВыбранноеПоле.Заголовок = «Номенклатура»;
ВыбранноеПоле.Использование = Истина;
ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных(«Номенклатура»);
ВыбранноеПоле = ГруппировкаНоменклатуры.Выбор.Элементы.Добавить(Тип(«ВыбранноеПолеКомпоновкиДанных»));
ВыбранноеПоле.Заголовок = «ВНаличии»;
ВыбранноеПоле.Использование = Истина;
ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных(«ВНаличии»);
ВыбранноеПоле = ГруппировкаНоменклатуры.Выбор.Элементы.Добавить(Тип(«ВыбранноеПолеКомпоновкиДанных»));
ВыбранноеПоле.Заголовок = «ВРезерве»;
ВыбранноеПоле.Использование = Истина;
ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных(«ВРезерве»);
ГруппировкаНоменклатуры.Порядок.Элементы.Добавить(Тип(«АвтоЭлементПорядкаКомпоновкиДанных»));
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
//Проводим инициализацию отборов из загруженных данных при последнем сохранении
ИнициализироватьОтборы();
//Обновляем пометки кнопок для визуального восприятия отборов
ОбновитьДанныеОтбора();
КонецПроцедуры
&НаСервере
Процедура ИнициализироватьОтборы()
//Список значений «ИсторияОтборов» хранит историю отборов, максимум 20 элементов
Для і=0 По ИсторияОтборов.Количество()-1 Цикл
//Получаем имя команды которая соответствует отбору
ИмяКоманды = ИсторияОтборов[і].Значение.ИмяКоманды;
//Получаем представление отбора, которое является аналогичным 1С 8.1
Представление = ПолучитьПредставлениеОтбора(ИсторияОтборов[і].Значение.МассивОтборов);
//Динамически добавляем команду формы и добавляем элемент формы, который привязываем к команде формы
ДобавитьКомандуКФорме(ИмяКоманды, Представление);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ИерархияНоменклатурыПередНачаломИзменения(Элемент, Отказ)
//Запрет изменения элементов пользователю
Отказ = Истина;
КонецПроцедуры
&НаКлиенте
Процедура ИерархияНоменклатурыПередУдалением(Элемент, Отказ)
//Запрет удаления элементов пользователю
Отказ = Истина;
КонецПроцедуры
&НаКлиенте
Процедура ИерархияНоменклатурыПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа)
//Запрет добавления элементов пользователю
Отказ = Истина;
КонецПроцедуры
&НаКлиенте
Процедура ИерархияНоменклатурыПриАктивизацииСтроки(Элемент)
//Так как это пример, решил упростить задачу — не обрабатывать пустую ссылку
Если Элемент.ТекущаяСтрока.Пустая() Тогда
ТаблицаНоменклатуры.Очистить();
Иначе
СформироватьКлиент(Элемент.ТекущаяСтрока);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура СформироватьКлиент(ГруппаНоменклатуры, Отбор = Ложь, Сортировка = Ложь, Идентификатор = Неопределено, ИмяЭлемента = Неопределено)
Перем ПараметрыОтбора;
//Запомним данные, возможно нам понадобится востановить курсор пользователя
ТекущиеДанные = Элементы.ТаблицаНоменклатуры.ТекущиеДанные;
Если НЕ ТекущиеДанные = Неопределено Тогда
ПараметрыОтбора = Новый Структура(«Номенклатура», ТекущиеДанные.Номенклатура);
КонецЕсли;
СформироватьСервер(ГруппаНоменклатуры, Отбор, Сортировка, Идентификатор, ИмяЭлемента);
//Обновляем пометки кнопок для визуального восприятия отборов
ОбновитьДанныеОтбора();
//Востанавливаем курсор на позицию, если она не пропала из выгрузки
Если НЕ ПараметрыОтбора = Неопределено Тогда
Массив = ТаблицаНоменклатуры.НайтиСтроки(ПараметрыОтбора);
Если Массив.Количество() Тогда Элементы.ТаблицаНоменклатуры.ТекущаяСтрока = Массив[0].ПолучитьИдентификатор(); КонецЕсли;
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура СформироватьСервер(ГруппаНоменклатуры, Отбор = Ложь, Сортировка = Ложь, Идентификатор = Неопределено, ИмяЭлемента = Неопределено)
Перем Значение, ВремОбъект;
//Получаем СКД из временного хранилища
СхемаКомпоновкиДанных = ПолучитьИзВременногоХранилища(АдресСхемыКомпоновкиДанных);
КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра(«ГруппаНоменклатуры», ГруппаНоменклатуры);
//У пользователя есть возможность изменять форму, нужно проверить имя реквизита — возможно реквизит был добавлен через «Изменить форму…»
Если Отбор ИЛИ НЕ Сортировка = Ложь Тогда
ТекущиеДанные = ТаблицаНоменклатуры.НайтиПоИдентификатору(Идентификатор);
//Проверяем есть ли реквизит
РеквизитИзТаб = ТекущиеДанные.Свойство(ИмяЭлемента, Значение);
Если РеквизитИзТаб Тогда
Если Отбор Тогда
ДобавитьОтборПоЗначению(КомпоновщикНастроек, ИмяЭлемента, Значение);
ОбновитьИсториюОтборов(КомпоновщикНастроек, ИсторияОтборов);
Иначе
ДобавитьСортировку(КомпоновщикНастроек, ИмяЭлемента, Сортировка);
КонецЕсли;
Иначе
//Реквизита нет в таблице, разбиваем ИмяЭлемента на слова
МассивИмен = ПолучитьМассивИмен(ИмяЭлемента);
Колич_Имен = МассивИмен.Количество() — 1;
//Данный цикл предназначен для поиска реквизита ссылочного типа, который является родителем реквизита по которому
//выполняется отбор или сортировка
Для i = 0 По Колич_Имен Цикл
Если ТекущиеДанные.Свойство(МассивИмен[i], ВремОбъект) Тогда
Если Найти(XMLТипЗнч(ВремОбъект).ИмяТипа, «Ref») = 0 Тогда
//Добавлять дополнительные поля возможно только из реквизитов ссылочного типа
ВызватьИсключение «Возникла неизвестная ошибка. Реквизит имеет не ссылочный тип: » + ИмяЭлемента;
КонецЕсли;
ИмяЭлемента = МассивИмен[i];
i=i+1;
Прервать;
ИначеЕсли i+1 <= Колич_Имен Тогда
МассивИмен[i+1] = МассивИмен[i] + «_» + МассивИмен[i+1];
Иначе
ВызватьИсключение «Возникла неизвестная ошибка. В таблице нет данных о имени: » + ИмяЭлемента;
КонецЕсли;
КонецЦикла;
//Выполняем построение адреса реквизита по которому нужно выполнить отбор или сортировку
АдресРеквизита = «»;
МетаВремЗначение = ВремОбъект.Метаданные();
Пока i <= Колич_Имен Цикл
ВремЗначение = МетаВремЗначение.Реквизиты.Найти(МассивИмен[i]);
Если НЕ ВремЗначение = Неопределено Тогда
АдресРеквизита = АдресРеквизита + МассивИмен[i];
формироватьАдресРеквизита(i, Колич_Имен, МетаВремЗначение, ВремЗначение, АдресРеквизита);
Иначе
Попытка
ВремЗначение = МетаВремЗначение.СтандартныеРеквизиты[МассивИмен[i]];
АдресРеквизита = АдресРеквизита + МассивИмен[i];
формироватьАдресРеквизита(i, Колич_Имен, МетаВремЗначение, ВремЗначение, АдресРеквизита);
Исключение
МассивИмен[i+1] = МассивИмен[i] + «_» + МассивИмен[i+1];
КонецПопытки;
КонецЕсли;
i=i+1;
КонецЦикла;
Если Отбор Тогда
ДобавитьОтборПоЗначению(КомпоновщикНастроек, ИмяЭлемента + ?(ПустаяСтрока(АдресРеквизита), «», «.» + АдресРеквизита), ПолучитьЗначениеРеквизита(АдресРеквизита, ВремОбъект));
ОбновитьИсториюОтборов(КомпоновщикНастроек, ИсторияОтборов);
Иначе
ДобавитьСортировку(КомпоновщикНастроек, ИмяЭлемента + ?(ПустаяСтрока(АдресРеквизита), «», «.» + АдресРеквизита), Сортировка);
КонецЕсли;
КонецЕсли;
КонецЕсли;
//3. готовим макет
КомпоновщикМакетаДанных = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакетаДанных.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, , , Тип(«ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений»));
//4. исполняем макет
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных);
//5. выводим результат
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ТаблицаНоменклатуры.Загрузить(ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных));
КонецПроцедуры
&НаСервере
Процедура ДобавитьСортировку(КомпоновщикНастроек, ИмяЭлемента, Направление)
ЭлементыПорядка = КомпоновщикНастроек.Настройки.Порядок.Элементы;
ЭлементыПорядка.Очистить();
ЭлементПорядка = ЭлементыПорядка.Добавить(Тип(«ЭлементПорядкаКомпоновкиДанных»));
ЭлементПорядка.Использование = Истина;
ЭлементПорядка.ТипУпорядочивания = Направление;
ЭлементПорядка.Поле = Новый ПолеКомпоновкиДанных(ИмяЭлемента);
КонецПроцедуры
&НаСервере
Процедура ДобавитьОтборПоЗначению(КомпоновщикНастроек, ИмяЭлемента, Значение)
Перем ЭлементОтбораНайден;
ЭлементыОтбора = КомпоновщикНастроек.Настройки.Отбор.Элементы;
Для Каждого ЭлементОтбора Из ЭлементыОтбора Цикл
ЭлементОтбора.Представление = ЭлементОтбора.ЛевоеЗначение;
Если ЭлементОтбора.Представление = ИмяЭлемента И ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно Тогда
ЭлементОтбора.Использование = НЕ ЭлементОтбора.Использование;
ЭлементОтбора.ПравоеЗначение = Значение;
ЭлементОтбораНайден = ЭлементОтбора;
КонецЕсли;
КонецЦикла;
Если ЭлементОтбораНайден = Неопределено Тогда
ЭлементОтбора = ЭлементыОтбора.Добавить(Тип(«ЭлементОтбораКомпоновкиДанных»));
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяЭлемента);
ЭлементОтбора.Представление = ЭлементОтбора.ЛевоеЗначение;
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Значение;
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ОбновитьИсториюОтборов(КомпоновщикНастроек, ИсторияОтборов)
//Создаем уникальное имя команды, УникальныйИдентификатор не всегда начинается с буквы, добавляем вначале «n»
ИмяКоманды = «n» + СтрЗаменить(Новый УникальныйИдентификатор, «-«, «»);
МассивОтборов = Новый Массив;
ЭлементыОтбора = КомпоновщикНастроек.Настройки.Отбор.Элементы;
Для Каждого ЭлементОтбора Из ЭлементыОтбора Цикл
Если ЭлементОтбора.Использование Тогда
МассивОтборов.Добавить(Новый Структура(«ЛевоеЗначение, ВидСравнения, ПравоеЗначение», ЭлементОтбора.ЛевоеЗначение, ЭлементОтбора.ВидСравнения, ЭлементОтбора.ПравоеЗначение));
КонецЕсли;
КонецЦикла;
Если МассивОтборов.Количество() Тогда
ПредставлениеОтбора = ПолучитьПредставлениеОтбора(МассивОтборов);
КоличествоЭлементов = ИсторияОтборов.Количество()-1;
Для i=0 По КоличествоЭлементов Цикл
//Если отбор найден перемещаем команду в начало списка, так же в списке значений изменяем положение отбора
Если ПредставлениеОтбора = ИсторияОтборов[i].Представление Тогда
ПереместитьКомандуФормы(ИсторияОтборов[i].Значение.ИмяКоманды, ИсторияОтборов[0].Значение.ИмяКоманды);
ИсторияОтборов.Сдвинуть(i, —i);
Прервать;
//Это новый элемент создаем вначале списка значений, так же команду устанавливаем вначало списка
ИначеЕсли i = КоличествоЭлементов Тогда
ДобавитьКомандуКФорме(ИмяКоманды, ПредставлениеОтбора, ИсторияОтборов[0].Значение.ИмяКоманды);
ИсторияОтборов.Вставить(0, Новый Структура(«ИмяКоманды, МассивОтборов», ИмяКоманды, МассивОтборов), ПредставлениеОтбора);
КонецЕсли;
КонецЦикла;
//Элементов еще нет, создаем первые элементы
Если КоличествоЭлементов < 0 Тогда
ДобавитьКомандуКФорме(ИмяКоманды, ПредставлениеОтбора);
ИсторияОтборов.Вставить(0, Новый Структура(«ИмяКоманды, МассивОтборов», ИмяКоманды, МассивОтборов), ПредставлениеОтбора);
КонецЕсли;
КонецЕсли;
//Элементов больше 20, удаляем лишнее
Если ИсторияОтборов.Количество() = 21 Тогда
УдалитьКомандуФормы(ИсторияОтборов[20].Значение.ИмяКоманды);
ИсторияОтборов.Удалить(20);
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ПолучитьПредставлениеОтбора(МассивОтборов)
ПредставлениеОтбора = «»;
КоличествоЭлементов = МассивОтборов.Количество()-1;
Для i=0 По КоличествоЭлементов Цикл
ПредставлениеОтбора = ПредставлениеОтбора + МассивОтборов[i].ЛевоеЗначение + » «
+ МассивОтборов[i].ВидСравнения + » «
+ МассивОтборов[i].ПравоеЗначение + ?(i<КоличествоЭлементов, «, «, «»);
КонецЦикла;
Возврат ПредставлениеОтбора;
КонецФункции
&НаСервере
Процедура ДобавитьКомандуКФорме(ИмяКоманды, Представление, ИмяПозицииВставки = Неопределено)
Команда = Команды.Добавить(ИмяКоманды);
Команда.Действие = «ОтборИстория»;
Команда.Заголовок = Представление;
КомандаФормы = Элементы.Вставить(Команда.Имя, Тип(«КнопкаФормы»), Элементы.ИсторияОтборов, Элементы.Найти(ИмяПозицииВставки));
КомандаФормы.ИмяКоманды = Команда.Имя;
КомандаФормы.Заголовок = Представление;
КомандаФормы.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
КонецПроцедуры
&НаСервере
Процедура ПереместитьКомандуФормы(ИмяКоманды, ИмяПозицииПеремещения)
Элементы.Переместить(Элементы.Найти(ИмяКоманды), Элементы.ИсторияОтборов, Элементы.Найти(ИмяПозицииПеремещения));
КонецПроцедуры
&НаСервере
Процедура УдалитьКомандуФормы(ИмяКоманды)
Элементы.Удалить(Элементы.Найти(ИмяКоманды));
Команды.Удалить(Команды.Найти(ИмяКоманды));
КонецПроцедуры
&НаСервере
Функция ПолучитьЗначениеРеквизита(АдресРеквизита, Объект)
Перем ЗначениеРеквизита;
Выполнить(«ЗначениеРеквизита = Объект.» + АдресРеквизита + «;»);
Возврат ЗначениеРеквизита;
КонецФункции
&НаСервере
Функция ПолучитьМассивИмен(ИмяЭлемента)
МассивСлов = Новый Массив;
ЧислоВхождений = СтрЧислоВхождений(ИмяЭлемента, «_»);
Если ЧислоВхождений = 0 Тогда
МассивСлов.Добавить(ИмяЭлемента);
Иначе
Для Итератор = 0 По ЧислоВхождений — 1 Цикл
Разделитель = Найти(ИмяЭлемента, «_»);
МассивСлов.Добавить(Лев(ИмяЭлемента, Разделитель — 1));
ИмяЭлемента = Прав(ИмяЭлемента, СтрДлина(ИмяЭлемента) — Разделитель);
КонецЦикла;
МассивСлов.Добавить(ИмяЭлемента);
КонецЕсли;
Возврат МассивСлов;
КонецФункции
&НаСервере
Процедура формироватьАдресРеквизита(i, Колич_Имен, МетаВремЗначение, ВремЗначение, АдресРеквизита)
Если i + 1 <= Колич_Имен Тогда
//Из описания типа получаем метаданные
МетаВремЗначение = ВремЗначение.Тип.ПривестиЗначение(Неопределено).Метаданные();
АдресРеквизита = АдресРеквизита + «.»;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ОбновитьДанныеОтбора(ОтключитьОтбор = Ложь)
Элементы.ОтборПоЗначению.Пометка = Ложь;
Элементы.ОтборИСортировка.Пометка = Ложь;
Для Каждого Элемент Из КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
Если ОтключитьОтбор Тогда Элемент.Использование = Ложь; КонецЕсли;
Если Элемент.Использование И Элемент.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно Тогда
Элементы.ОтборПоЗначению.Пометка = Истина;
ИначеЕсли Элемент.Использование Тогда
Элементы.ОтборИСортировка.Пометка = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ОтборИСортировка(Команда)
Результат = ОткрытьФормуМодально(«ВнешняяОбработка.УниверсальныйОтбор.Форма.ФормаНастройки», Новый Структура(«КомпоновщикНастроек», КомпоновщикНастроек), ЭтаФорма);
Если ТипЗнч(Результат) = Тип(«КомпоновщикНастроекКомпоновкиДанных») Тогда
КомпоновщикНастроек = Результат;
ОбновитьДанныеОтбора();
ОбновитьИсториюОтборов(КомпоновщикНастроек, ИсторияОтборов);
ТСтрока = Элементы.ИерархияНоменклатуры.ТекущаяСтрока;
Если НЕ ТСтрока.Пустая() Тогда СформироватьКлиент(ТСтрока); КонецЕсли;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ОтборПоЗначению(Команда)
ТСтрока = Элементы.ИерархияНоменклатуры.ТекущаяСтрока;
ТДанные = Элементы.ТаблицаНоменклатуры.ТекущиеДанные;
ТЭлемент = Элементы.ТаблицаНоменклатуры.ТекущийЭлемент;
Если НЕ ТСтрока.Пустая() И НЕ Элементы.ТаблицаНоменклатуры.ТекущиеДанные = Неопределено Тогда
ИмяЭлемента = ТЭлемент.Имя;
СформироватьКлиент(ТСтрока, Истина, , ТДанные.ПолучитьИдентификатор(), ИмяЭлемента);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ОтключитьОтбор(Команда)
ОбновитьДанныеОтбора(Истина);
ТСтрока = Элементы.ИерархияНоменклатуры.ТекущаяСтрока;
Если НЕ ТСтрока.Пустая() Тогда СформироватьКлиент(ТСтрока); КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ОтборИстория(Команда)
//Ищем в истории отборов отбор соответствующий имени команды
Перем МассивОтборов;
Для i=0 По ИсторияОтборов.Количество()-1 Цикл
Если ИсторияОтборов[i].Значение.ИмяКоманды = Команда.Имя Тогда
МассивОтборов = ИсторияОтборов[i].Значение.МассивОтборов;
ПереместитьКомандуФормы(Команда.Имя, ИсторияОтборов[0].Значение.ИмяКоманды);
Если ИсторияОтборов.Количество() > 1 Тогда ИсторияОтборов.Сдвинуть(i, —i); КонецЕсли;
Прервать;
КонецЕсли;
КонецЦикла;
//Обнуляем все отборы, перед установкой отбора из истории отборов
ЭлементыОтбора = КомпоновщикНастроек.Настройки.Отбор.Элементы;
Для Каждого Элемент Из ЭлементыОтбора Цикл Элемент.Использование = Ложь; КонецЦикла;
//Устанавливаем отборы
Для i=0 По МассивОтборов.Количество()-1 Цикл
ОтборИзМассиваОпределен = Неопределено;
Для Каждого Элемент Из ЭлементыОтбора Цикл
Если Элемент.ЛевоеЗначение = МассивОтборов[i].ЛевоеЗначение
И Элемент.ВидСравнения = МассивОтборов[i].ВидСравнения Тогда
Элемент.ПравоеЗначение = МассивОтборов[i].ПравоеЗначение;
Элемент.Использование = Истина;
ОтборИзМассиваОпределен = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
//Возможно была очистка отборов вручную, значит создаем нужный отбор
Если ОтборИзМассиваОпределен = Неопределено Тогда
ЭлементОтбора = ЭлементыОтбора.Добавить(Тип(«ЭлементОтбораКомпоновкиДанных»));
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(МассивОтборов[i].ЛевоеЗначение);
ЭлементОтбора.Представление = МассивОтборов[i].ЛевоеЗначение;
ЭлементОтбора.ВидСравнения = МассивОтборов[i].ВидСравнения;
ЭлементОтбора.ПравоеЗначение = МассивОтборов[i].ПравоеЗначение;
КонецЕсли;
КонецЦикла;
//Выполняем запрос
ТСтрока = Элементы.ИерархияНоменклатуры.ТекущаяСтрока;
Если НЕ ТСтрока.Пустая() Тогда
СформироватьКлиент(ТСтрока);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура СортироватьПоВозрастанию(Команда)
ТСтрока = Элементы.ИерархияНоменклатуры.ТекущаяСтрока;
ТДанные = Элементы.ТаблицаНоменклатуры.ТекущиеДанные;
ТЭлемент = Элементы.ТаблицаНоменклатуры.ТекущийЭлемент;
Если НЕ ТСтрока.Пустая() И НЕ Элементы.ТаблицаНоменклатуры.ТекущиеДанные = Неопределено Тогда
ИмяЭлемента = ТЭлемент.Имя;
СформироватьКлиент(ТСтрока, , НаправлениеСортировкиКомпоновкиДанных.Возр, ТДанные.ПолучитьИдентификатор(), ИмяЭлемента);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура СортироватьПоУбыванию(Команда)
ТСтрока = Элементы.ИерархияНоменклатуры.ТекущаяСтрока;
ТДанные = Элементы.ТаблицаНоменклатуры.ТекущиеДанные;
ТЭлемент = Элементы.ТаблицаНоменклатуры.ТекущийЭлемент;
Если НЕ ТСтрока.Пустая() И НЕ Элементы.ТаблицаНоменклатуры.ТекущиеДанные = Неопределено Тогда
ИмяЭлемента = ТЭлемент.Имя;
СформироватьКлиент(ТСтрока, , НаправлениеСортировкиКомпоновкиДанных.Убыв, ТДанные.ПолучитьИдентификатор(), ИмяЭлемента);
КонецЕсли;
КонецПроцедуры
Причиной этого труда стало: отсутствие привычной кнопки «Отбор по значению в текущей колонке», некоторые проблемы с динамическими списками, отсутствие истории отборов, авто восстановления настроек отборов при перезапуске формы (динамических списков), а так же стремление увеличить функциональность отборов и сортировок с учетом возможностей управляемых форм.
Перейти к публикации
Отлично. Спасибо!!!
Отличная вещь! Побежал прикручивать к своим конфам.
Очень интересно. Получается не только чисто отбор можно использовать, но еще и дополнительные запросы.
Функционал явно превосходит механизм отборов в 1с 8.1
Так можно подумать и добавить спец запросы (сделанные не пользователем, а разрабочиком и прикрученные к механизму отбора) а пользователь будет задавать только конечные параметры. Например отбор по реквизитам подчиненного документа.
Плюс однозначно!
Но с кодом еще придется поразбираться 😉 не тривиально всё.
Работа проделана конечно большая и это +, надеюсь что данный сервис появится на уровне платформы (то что до сих пор не появился это -)
Хорошая серьезная разработка. Автор молодец. Однозначно плюс, к тому же еще и код выложил!
делете
Не знал даже этого.
Очень этого не хватало, спасибо автору) И пошла пробовать-экспериментировать
Вот это штукенция очень надо. Спасибо огромное!
То что доктор прописал 🙂 Однозначно +
Офигенно
МОЛОДЦА
Красиво, но для добавляемых колонок нежизнеспособно, ибо сделать такой универсал очень трудно.
Вот есть у меня динам.список по выборке, а выборка строится с использованием механизма характеристик. И вот хочу я отобрать по колонке, принудительно выведенной на интерфейс. И тут, подозреваю, нифига не выйдет.
Да, и если в именах полей, сами по себе, есть знаки подчёркивания — тоже сомневаюсь в безошибочности.
(13) Yashazz, Подчеркивания обрабатываются вот этим куском, если это добавленая колонка, тогда поиск идет по метаданным на совпадение (В случае, когда в метаданных есть «Полное_Наименование» оно обработается правильно). Проблема присутствует, если в выборке множество реквизитов ссылочного типа, а не один.
Пока i <= Колич_Имен Цикл
ВремЗначение = МетаВремЗначение.Реквизиты.Найти(МассивИмен[i]);
Если НЕ ВремЗначение = Неопределено Тогда
АдресРеквизита = АдресРеквизита + МассивИмен[i];
формироватьАдресРеквизита(i, Колич_Имен, МетаВремЗначение, ВремЗначение, АдресРеквизита);
Иначе
Попытка
ВремЗначение = МетаВремЗначение.СтандартныеРеквизиты[МассивИмен[i]];
АдресРеквизита = АдресРеквизита + МассивИмен[i];
формироватьАдресРеквизита(i, Колич_Имен, МетаВремЗначение, ВремЗначение, АдресРеквизита);
Исключение
МассивИмен[i+1] = МассивИмен[i] + «_» + МассивИмен[i+1];
КонецПопытки;
КонецЕсли;
i=i+1;
КонецЦикла;
Почти все нюансы эти уже исправлены, но руки не доходят обновить публикацию.
спасибо, автор молодец
Отличная идея. Пользователям жутко не хватает этих кнопок. Вроде как в УФ это и есть, но где раньше было одно нажатие, теперь нужно 2-3 в лучшем случае, а при составных отборах и того больше.
Еще бы как-то это в общую команду оформить…
Да как этим пользоваться, объясните… (для тех, кто управляемые формы видит в первый раз)
У меня управляемая форма списка реализаций товаров и услуг. Основной реквизит — Список с типом ДинамическийСписок. Чекбокс Произвольный запрос установлен.
В скаченной обработке среди реквизитов есть таблица значений. Значит, работаем вместо динамического списка с таблицей значений, что ли?
И окна «Иерархия номенклатуры» у меня нет = значит, из программного кода придётся вырезать куски кода под него?
(17) prodines, это как пример. Для динамического списка эта публикация не подойдет. Для динамического списка все совсем иначе и в описании еще написано:
.
Скачал. Опыта маловато. Буду пробовать. Сортировка нужна в платформе, однозначно.
Отличная статья! Очень помогла! Спасибо автору!
Подскажите а как бы этот функционал использовать в форме выбора? Чтобы возвращало значение?
(21) IDija, можете детально описать проблему, не понятно зачем это использовать в форме выбора?
(22) pbazeliuk, В документе при выборе в ТЧ Номенклатуры нет истории предыдущего выбора. Что бы при написании наименования предлагалась предыдущие варианты поиска.
Может есть и вариант попроще, но не шел?
(23) IDija, историю выбора номенклатуры нужно реализовывать самому. Задача по своей сути очень простая, если не нужно использовать переопределение вызовов и динамическое подключение функциональности.
Подскажите пожалуйста, возможно ли данный механизм реализовать под обычные формы для табличного поля с типом таблица значений??
(25) Manticor, для обычных форм можно использовать только идею, но не сам код что тут представлен, нужны множественные доработки.