Создаем универсальный механизм отбора и сортировки для управляемых форм

02.05.12

Разработка - Инструментарий разработчика

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Универсальный отбор
.epf 19,53Kb
271
271 Скачать (1 SM) Купить за 1 850 руб.

Осноные возможноси:

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].ПравоеЗначение;
        КонецЕсли;
    КонецЦикла;

   
//Выполняем запрос
   
ТСтрока = Элементы.ИерархияНоменклатуры.ТекущаяСтрока;
    Если НЕ
ТСтрока.Пустая() Тогда
       
СформироватьКлиент(ТСтрока);
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура СортироватьПоВозрастанию(Команда)
   
ТСтрока  = Элементы.ИерархияНоменклатуры.ТекущаяСтрока;
   
ТДанные  = Элементы.ТаблицаНоменклатуры.ТекущиеДанные;
   
ТЭлемент = Элементы.ТаблицаНоменклатуры.ТекущийЭлемент;
    Если НЕ
ТСтрока.Пустая() И НЕ Элементы.ТаблицаНоменклатуры.ТекущиеДанные = Неопределено Тогда
       
ИмяЭлемента = ТЭлемент.Имя;
       
СформироватьКлиент(ТСтрока, , НаправлениеСортировкиКомпоновкиДанных.Возр, ТДанные.ПолучитьИдентификатор(), ИмяЭлемента);
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура СортироватьПоУбыванию(Команда)
   
ТСтрока  = Элементы.ИерархияНоменклатуры.ТекущаяСтрока;
   
ТДанные  = Элементы.ТаблицаНоменклатуры.ТекущиеДанные;
   
ТЭлемент = Элементы.ТаблицаНоменклатуры.ТекущийЭлемент;
    Если НЕ
ТСтрока.Пустая() И НЕ Элементы.ТаблицаНоменклатуры.ТекущиеДанные = Неопределено Тогда
       
ИмяЭлемента = ТЭлемент.Имя;
       
СформироватьКлиент(ТСтрока, , НаправлениеСортировкиКомпоновкиДанных.Убыв, ТДанные.ПолучитьИдентификатор(), ИмяЭлемента);
    КонецЕсли;
КонецПроцедуры

См. также

SALE! 15%

Инструментарий разработчика Роли и права Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    159472    874    399    

862

SALE! 15%

Инструментарий разработчика Чистка данных Свертка базы Инструменты администратора БД Системный администратор Программист Руководитель проекта Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 10 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 Россия Платные (руб)

Инструмент представляет собой обработку для проведения свёртки или обрезки баз данных. Работает на ЛЮБЫХ конфигурациях (УТ, БП, ERP и т.д.). Поддерживаются управляемые и обычные формы. Может выполнять свертку сразу нескольких баз данных и выполнять их автоматически без непосредственного участия пользователя.

8400 7140 руб.

20.08.2024    7785    57    22    

66

Инструментарий разработчика Программист Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

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

9360 руб.

17.05.2024    23444    68    45    

117

SALE! 15%

Инструменты администратора БД Инструментарий разработчика Роли и права Программист Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.

10000 8500 руб.

10.11.2023    10434    36    25    

61

SALE! 15%

Пакетная печать Печатные формы Инструментарий разработчика Программист Платформа 1С v8.3 Запросы 1С:Зарплата и кадры бюджетного учреждения 1С:Конвертация данных 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 Платные (руб)

Инструмент, позволяющий абсолютно по-новому взглянуть на процесс разработки печатных форм. Благодаря конструктору можно значительно снизить затраты времени на разработку печатных форм, повысить качество и "прозрачность" разработки, а также навести порядок в многообразии корпоративных печатных форм.

22200 19980 руб.

06.10.2023    15405    35    7    

70

SALE! 35%

Инструментарий разработчика Инструменты администратора БД Системный администратор Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Россия Платные (руб)

Универсальный инструмент программиста для администрирования конфигураций. Сборник наиболее часто используемых обработок под единым интерфейсом.

4800 3120 руб.

14.01.2013    187996    1140    0    

912

SALE! 15%

Инструментарий разработчика Программист 8.3.14 1С:Конвертация данных Россия Платные (руб)

Расширение для конфигурации “Конвертация данных 3”. Добавляет подсветку синтаксиса, детальную контекстную подсказку, глобальный поиск по коду.

15000 12750 руб.

07.10.2021    17304    6    32    

42

Инструментарий разработчика Программист Платные (руб)

Менеджер конфигураций 1С — альтернативный стартер информационных баз 1С:Предприятие.

1800 руб.

21.02.2023    7697    8    35    

23
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
0. pbazeliuk 1969 02.05.12 10:01 Сейчас в теме
Причиной этого труда стало: отсутствие привычной кнопки "Отбор по значению в текущей колонке", некоторые проблемы с динамическими списками, отсутствие истории отборов, авто восстановления настроек отборов при перезапуске формы (динамических списков), а так же стремление увеличить функциональность отборов и сортировок с учетом возможностей управляемых форм.

Перейти к публикации

1. zavedeev 03.05.12 13:25 Сейчас в теме
Отлично. Спасибо!!!
pbazeliuk; +1 Ответить
2. afanasko 35 03.05.12 16:11 Сейчас в теме
Отличная вещь! Побежал прикручивать к своим конфам.
pbazeliuk; +1 Ответить
3. dandrontiy 04.05.12 08:18 Сейчас в теме
Очень интересно. Получается не только чисто отбор можно использовать, но еще и дополнительные запросы.
Функционал явно превосходит механизм отборов в 1с 8.1
Так можно подумать и добавить спец запросы (сделанные не пользователем, а разрабочиком и прикрученные к механизму отбора) а пользователь будет задавать только конечные параметры. Например отбор по реквизитам подчиненного документа.

Плюс однозначно!
Но с кодом еще придется поразбираться ;-) не тривиально всё.
4. Saipl 7 04.05.12 08:28 Сейчас в теме
Работа проделана конечно большая и это +, надеюсь что данный сервис появится на уровне платформы (то что до сих пор не появился это -)
5. khaoos 239 05.05.12 06:35 Сейчас в теме
Хорошая серьезная разработка. Автор молодец. Однозначно плюс, к тому же еще и код выложил!
6. gavrikprog 118 05.05.12 16:43 Сейчас в теме
7. xzorkiix 35 05.05.12 17:25 Сейчас в теме
2. Отсутсвует ошибка при использовании истории отборов (в 1С Предприятии 8.1 если установлен отбор и воспользоватся отбором из истории текущий отбор не отменяется);


Не знал даже этого.
8. aviaye 10.05.12 05:58 Сейчас в теме
Очень этого не хватало, спасибо автору) И пошла пробовать-экспериментировать
9. Den_D 54 10.05.12 11:49 Сейчас в теме
Вот это штукенция очень надо. Спасибо огромное!
10. An-Aleksey 64 10.05.12 13:35 Сейчас в теме
То что доктор прописал :) Однозначно +
11. nizar 11.05.12 15:26 Сейчас в теме
12. Bober777 26 02.08.12 00:11 Сейчас в теме
13. Yashazz 4791 15.11.12 18:02 Сейчас в теме
Красиво, но для добавляемых колонок нежизнеспособно, ибо сделать такой универсал очень трудно.

Вот есть у меня динам.список по выборке, а выборка строится с использованием механизма характеристик. И вот хочу я отобрать по колонке, принудительно выведенной на интерфейс. И тут, подозреваю, нифига не выйдет.
Да, и если в именах полей, сами по себе, есть знаки подчёркивания - тоже сомневаюсь в безошибочности.
pbazeliuk; +1 Ответить
14. pbazeliuk 1969 13.12.12 23:41 Сейчас в теме
(13) Yashazz, Подчеркивания обрабатываются вот этим куском, если это добавленая колонка, тогда поиск идет по метаданным на совпадение (В случае, когда в метаданных есть "Полное_Наименование" оно обработается правильно). Проблема присутствует, если в выборке множество реквизитов ссылочного типа, а не один.

Пока i <= Колич_Имен Цикл
ВремЗначение = МетаВремЗначение.Реквизиты.Найти(МассивИмен[i]);
Если НЕ ВремЗначение = Неопределено Тогда
АдресРеквизита = АдресРеквизита + МассивИмен[i];
формироватьАдресРеквизита(i, Колич_Имен, МетаВремЗначение, ВремЗначение, АдресРеквизита);
Иначе
Попытка
ВремЗначение = МетаВремЗначение.СтандартныеРеквизиты[МассивИмен[i]];
АдресРеквизита = АдресРеквизита + МассивИмен[i];
формироватьАдресРеквизита(i, Колич_Имен, МетаВремЗначение, ВремЗначение, АдресРеквизита);
Исключение
МассивИмен[i+1] = МассивИмен[i] + "_" + МассивИмен[i+1];
КонецПопытки;
КонецЕсли;
i=i+1;
КонецЦикла;


Почти все нюансы эти уже исправлены, но руки не доходят обновить публикацию.
15. m1kll 7 14.12.12 05:59 Сейчас в теме
спасибо, автор молодец
16. tommyknocker 25.12.12 19:47 Сейчас в теме
Отличная идея. Пользователям жутко не хватает этих кнопок. Вроде как в УФ это и есть, но где раньше было одно нажатие, теперь нужно 2-3 в лучшем случае, а при составных отборах и того больше.
Еще бы как-то это в общую команду оформить...
17. prodines 107 26.04.13 14:53 Сейчас в теме
Да как этим пользоваться, объясните... (для тех, кто управляемые формы видит в первый раз)

У меня управляемая форма списка реализаций товаров и услуг. Основной реквизит - Список с типом ДинамическийСписок. Чекбокс Произвольный запрос установлен.

В скаченной обработке среди реквизитов есть таблица значений. Значит, работаем вместо динамического списка с таблицей значений, что ли?

И окна "Иерархия номенклатуры" у меня нет = значит, из программного кода придётся вырезать куски кода под него?
18. pbazeliuk 1969 27.04.13 18:20 Сейчас в теме
(17) prodines, это как пример. Для динамического списка эта публикация не подойдет. Для динамического списка все совсем иначе и в описании еще написано:
отсутствие привычной кнопки "Отбор по значению в текущей колонке", некоторые проблемы с динамическими списками, отсутствие истории отборов, авто восстановления настроек отборов при перезапуске формы (динамических списков)
.
19. validat 1 09.06.13 14:05 Сейчас в теме
Скачал. Опыта маловато. Буду пробовать. Сортировка нужна в платформе, однозначно.
20. lesenoklenok 35 20.01.15 21:50 Сейчас в теме
Отличная статья! Очень помогла! Спасибо автору!
21. IDija 154 24.11.15 11:21 Сейчас в теме
Подскажите а как бы этот функционал использовать в форме выбора? Чтобы возвращало значение?
22. pbazeliuk 1969 24.11.15 13:27 Сейчас в теме
(21) IDija, можете детально описать проблему, не понятно зачем это использовать в форме выбора?
23. IDija 154 24.11.15 14:18 Сейчас в теме
(22) pbazeliuk, В документе при выборе в ТЧ Номенклатуры нет истории предыдущего выбора. Что бы при написании наименования предлагалась предыдущие варианты поиска.
Может есть и вариант попроще, но не шел?
24. pbazeliuk 1969 24.11.15 18:50 Сейчас в теме
(23) IDija, историю выбора номенклатуры нужно реализовывать самому. Задача по своей сути очень простая, если не нужно использовать переопределение вызовов и динамическое подключение функциональности.
25. Manticor 66 04.07.16 17:48 Сейчас в теме
Подскажите пожалуйста, возможно ли данный механизм реализовать под обычные формы для табличного поля с типом таблица значений??
26. pbazeliuk 1969 05.07.16 08:27 Сейчас в теме
(25) Manticor, для обычных форм можно использовать только идею, но не сам код что тут представлен, нужны множественные доработки.
Оставьте свое сообщение