gifts2017

Быстрый отбор в форме списка (выбора) справочника

Опубликовал Саўка Збянтэжаны (Збянтэжаны Саўка) в раздел Программирование - Практика программирования

Установка быстрых отборов в форме списка (выбора) справочника для новичков в 1С.
В архиве эта же статейка в PDF.

Установка быстрых отборов в форме списка (выбора) справочника (для новичков)

 

Я сам новичок в 1С и знаю, как трудно поначалу разобраться в море незнакомой информации и быстро найти нужную для решения какой-либо срочной задачи. Поэтому эту статейку пишу и для себя тоже.

 

Иногда пользователю нужно быстро отобрать нужные строки в списке по нескольким не точным критериям.

 

В списках отбор может быть установлен вручную пользователем стандартным способом через контекстное меню списка «Установить отбор и сортировку списка»


 

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

 

1) Рассмотрим установку такого отбора на примере списка справочника Номенклатура.

 

Открываем в конфигураторе форму списка справочника Номенклатура.

Уменьшим высоту табличного поля «Список».

На освободившееся место над табличным полем разместим 5 элементов:

  - метку,  

  - два флажка

  - два поля ввода.

 

со следующими именами:

 

1) Отборы

2) фНомер                 – Булево

3) отбНомер              – Строка(20)

4) фНаименование    – Булево

5) отбНаименование – Строка(150)

 

Результат будет выглядеть примерно так:

 

Сверим список реквизитов формы на закладке «Реквизиты», наши новые обведены красным:


 

Теперь пишем в модуле формы обработчики событий «При изменении» для флажков и полей ввода.

 

Для назначения обработчика события элементу формы выбираем мышкой нужный элемент, идем в панель «Свойства» , ищем в разделе «События» событие «ПриИзменении»  и щелкаем мышкой по лупе:


 

И в созданную заготовку процедуры вписываем нужный код:


 

Вот код этих четырех обработчиков:

// при изменении флажка фНомер
Процедура фНомерПриИзменении(Элемент)
  // если не заполнен Номер для отбора не будем понапрасну дергать Отбор
 
Если ЗначениеЗаполнено(отбНомер) Тогда
   
УстановитьОтборыФормы();
  КонецЕсли;
КонецПроцедуры

// при изменении поля ввода отбНомер
Процедура отбНомерПриИзменении(Элемент)
  // если не установлен флажок не будем понапрасну дергать Отбор
 
Если фНомер Тогда
   
УстановитьОтборыФормы();
  КонецЕсли;
КонецПроцедуры


Процедура
фНаименованиеПриИзменении(Элемент)
  // если не заполнено Наименование для отбора не будем понапрасну дергать Отбор
 
Если ЗначениеЗаполнено(отбНаименование) Тогда
   
УстановитьОтборыФормы();
  КонецЕсли;
КонецПроцедуры

Процедура
отбНаименованиеПриИзменении(Элемент)
  // если не установлен флажок не будем понапрасну дергать Отбор
 
Если фНаименование Тогда
   
УстановитьОтборыФормы();
  КонецЕсли;
КонецПроцедуры


На двух наших полях ввода включим свойство «КнопкаОчистки».
При очистке поля ввода мы будем сбрасывать соответсвующий флажок и перечитывать отбор:

// при очистке поля ввода отбНомер
Процедура отбНомерОчистка(Элемент, СтандартнаяОбработка)
  фНомер = Ложь;
 
УстановитьОтборыФормы();
КонецПроцедуры

// при очистке поля ввода отбНаименование
Процедура отбНаименованиеОчистка(Элемент, СтандартнаяОбработка)
  фНаименование = Ложь;
 
УстановитьОтборыФормы();
КонецПроцедуры


Теперь пишем процедуру установки отбора:

Процедура УстановитьОтборыФормы()
 

  // запомним состояние иерархии
  мИерархическийПросмотр = ЭлементыФормы.Список.ИерархическийПросмотр;

 
Если (фНомер И НЕ ПустаяСтрока(отбНомер))
    или (
фНаименование И ЗначениеЗаполнено(отбНаименование))
  Тогда

   
// сбросим иерархию
    Если ЭлементыФормы.Список.ИерархическийПросмотр Тогда
     
ЭлементыФормы.Список.ИерархическийПросмотр = Ложь;
    КонецЕсли;

   
// получаем запросом список с установленными критериями отбора
   
сз = ВернутьСписок();

   
// устанавливаем отбор на ссылки, входящие в возвращенный список ссылок
   
ЭтаФорма.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке;
   
ЭтаФорма.Отбор.Ссылка.Значение = сз;
   
ЭтаФорма.Отбор.Ссылка.Использование = Истина;

  Иначе

   
// сбросим отбор
   
ЭтаФорма.Отбор.Ссылка.Использование = Ложь;
    // вернем иерархию взад
    Если НЕ мИерархическийПросмотр Тогда
      ЭлементыФормы.Список.ИерархическийПросмотр = Истина;
    КонецЕсли;

 
КонецЕсли;
КонецПроцедуры


А теперь пишем функцию, выбирающую запросом ссылки по введенным пользователем критериям  и возвращающую как результат список отобранных ссылок:

Функция ВернутьСписок()

   
Запрос = Новый Запрос;

   
// устанавливаем параметры запроса введенными критериями
   
Запрос.УстановитьПараметр("фНомер"       , фНомер);
   
Запрос.УстановитьПараметр("фНаименование", фНаименование);
   
Запрос.УстановитьПараметр("пНомер"       , "%" + СокрЛП(отбНомер) + "%");
   
Запрос.УстановитьПараметр("пНаименование", "%" + СокрЛП(отбНаименование) + "%");

   
// нам нужна только ссылка для построения списка значений
   
Запрос.Текст = "ВЫБРАТЬ
        |   Ссылка
        |ИЗ
        |   Справочник.Номенклатура
        |
        |ГДЕ
        | // 1-ое условие
        |   (&фНомер = Ложь
        |       или (&фНомер и НоменклатурныйНомер ПОДОБНО &пНомер)
        |   )
        | // соединим условия союзом И
        |   И
        |
        | // 2-ое условие
        |   (&фНаименование = Ложь
        |       или (&фНаименование и Наименование ПОДОБНО &пНаименование)
        |   )
        |"
;

   
Результат = Запрос.Выполнить();

   
// создаем новый список значений и выгружаем в него колонку «Ссылка» из  результата запроса
   
сз = Новый СписокЗначений;
   
сз.ЗагрузитьЗначения(Результат.Выгрузить().ВыгрузитьКолонку("Ссылка"));

   
// возвращаем результат - полученный список зачений
   
Возврат сз;

КонецФункции

 

Вот результат отбора по двум критериям:


Взглянем на форму отборов опять для сравнения и видим на ней установленный наш отбор по ссылке:

 

2) Рассмотрим более сложный пример со справочником «Основные средства».

 

Размещаем над списком 7 элементов:

Где 1 – это просто метка, а остальные реквизиты имеют следующие типы:


 

Добавим в модуль списка новую процедуру ЭлементОтбораПриИзменении и впишем в нее следующий код:

Процедура ЭлементОтбораПриИзменении(Элемент)
   
УстановитьОтборыФормы();
КонецПроцедуры

Всем новым элементам (кроме метки, хе-хе) назначаем этот обработчик, чтобы не плодить их тучу однотипных:


 

Пишем процедуру установки снятия отбора:

 

Процедура УстановитьОтборыФормы()

   
мИерархияВкл = ЭлементыФормы.СправочникСписок.ИерархическийПросмотр;

    Если  (
флПоИнвНомеру и НЕ ПустаяСтрока(отбИнвНомер))
        или (
флПоПодразделению и ЗначениеЗаполнено(отбПодразделение))
        или (
флПоМОЛ и ЗначениеЗаполнено(отбМОЛ))Тогда

        Если
мИерархияВкл Тогда
           
ЭлементыФормы.СправочникСписок.ИерархическийПросмотр = Ложь;
        КонецЕсли;

       
СписокОС = ВернутьСписокОС();

       
ЭтаФорма.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке;
       
ЭтаФорма.Отбор.Ссылка.Значение = СписокОС;
       
ЭтаФорма.Отбор.Ссылка.Использование = Истина;
    Иначе
        Если
ЭтаФорма.Отбор.Ссылка.Использование Тогда
           
ЭтаФорма.Отбор.Ссылка.Использование = Ложь;
           
ЭлементыФормы.СправочникСписок.ИерархическийПросмотр = мИерархияВкл;
        КонецЕсли;
    КонецЕсли;

КонецПроцедуры

И пишем еще одну процедурку получения списка ссылок запросом.

Здесь мы будем получать последние сведения по ОС из регистров сведений:

  - Инвентарный Номер из РС ПервоначальныеСведения

  - Подразделение и МОЛ из РС МестонахождениеОС.

 

Функция ВернутьСписокОС()

   
Запрос = Новый Запрос;

    Если
флПоИнвНомеру и НЕ (флПоПодразделению или флПоМОЛ) Тогда

       
// отбор только по инв. номерам только
       
Запрос.Текст = "ВЫБРАТЬ
            |   ПервоначальныеСведенияОССрезПоследних.ОсновноеСредство
            |ИЗ
            |   РегистрСведений.ПервоначальныеСведенияОСБухгалтерскийУчет.СрезПоследних(
            |           &пДата,
            |           ИнвентарныйНомер ПОДОБНО &пИнвНомер)
            |КАК ПервоначальныеСведенияОССрезПоследних"
;

    Иначе

       
аргУсловие = "";

        Если
флПоПодразделению И ЗначениеЗаполнено(отбПодразделение) Тогда
           
аргУсловие = "МестонахождениеОССрезПоследних.Местонахождение = &пПодразделение"
       
КонецЕсли;

        Если
флПоМОЛ И ЗначениеЗаполнено(отбМОЛ) Тогда
           
стрМОЛ = "МестонахождениеОССрезПоследних.МОЛ = &пМОЛ";
           
аргУсловие = ?(ПустаяСтрока(аргУсловие), стрМОЛ, аргУсловие + " И " + стрМОЛ);
        КонецЕсли;

        Если НЕ
флПоИнвНомеру Тогда

           
Запрос.Текст = "ВЫБРАТЬ
                |   МестонахождениеОССрезПоследних.ОсновноеСредство
                |ИЗ
                |   РегистрСведений.МестонахождениеОСБухгалтерскийУчет.СрезПоследних(&пДата, )
                |КАК МестонахождениеОССрезПоследних
                |ГДЕ "
+ аргУсловие;

        Иначе

           
Запрос.Текст = "ВЫБРАТЬ
                |   ПервоначальныеСведенияОССрезПоследних.ОсновноеСредство
                |ИЗ
                |   РегистрСведений.ПервоначальныеСведенияОСБухгалтерскийУчет.СрезПоследних(
                |           &пДата,
                |           ИнвентарныйНомер ПОДОБНО &пИнвНомер)
                |   КАК ПервоначальныеСведенияОССрезПоследних
                |       ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.МестонахождениеОСБухгалтерскийУчет.СрезПоследних(&пДата, )
                |       КАК МестонахождениеОССрезПоследних
                |       ПО ПервоначальныеСведенияОССрезПоследних.ОсновноеСредство = МестонахождениеОССрезПоследних.ОсновноеСредство
                |ГДЕ "
+ аргУсловие;
        КонецЕсли;

    КонецЕсли;

   
Запрос.УстановитьПараметр("пИнвНомер"     , "%" + СокрЛП(отбИнвНомер) + "%");
   
Запрос.УстановитьПараметр("пДата"         , ТекущаяДата());
   
Запрос.УстановитьПараметр("пПодразделение", отбПодразделение);
   
Запрос.УстановитьПараметр("пМОЛ"          , отбМОЛ);

   
Результат = Запрос.Выполнить();

   
сз = Новый СписокЗначений;
   
сз.ЗагрузитьЗначения(Результат.Выгрузить().ВыгрузитьКолонку("ОсновноеСредство"));

    Возврат
сз;


КонецФункции

Теперь добавляем в список две новых колонки МОЛ и Местонахождение без привязки к данным

Установим их свойства «Видимость» в Ложь, чтобы они не светились в списке сразу. Их заполение мы будем обрабатывать в событии ПриПолученииДанных (см. ниже)

В свойстве ЭлементУправления обоим назначаем «Поле ввода»

В обработчик ПриПолученииДанных добавляем код для отображения значений наших добавленных колонок:

Процедура СправочникСписокПриПолученииДанных(Элемент, ОформленияСтрок)

  // создаем структуру для получения сведений из регистра
  СтруктураОтбора = Новый Структура;
 
СтруктураОтбора.Вставить("Организация"     , Организация);
 
СтруктураОтбора.Вставить("ОсновноеСредство", ДанныеСтроки.Ссылка);

  // будем запрашивать и выводить данные только при видимости наших колонок
  Если ОформлениеСтроки.Ячейки.МОЛ.Видимость
  
или ОформлениеСтроки.Ячейки.Местонахождение.Видимость Тогда


   МестонахождениеОС
=

           РегистрыСведений.МестонахождениеОСБухгалтерскийУчет.ПолучитьПоследнее(

                                                    ДатаСведений, СтруктураОтбора);

   ОформлениеСтроки.Ячейки.МОЛ.Значение = МестонахождениеОС.МОЛ;
   ОформлениеСтроки.Ячейки.Местонахождение.Значение =

                                          МестонахождениеОС.Подразделение;
  КонецЕсли;

КонецПроцедуры

 

Сохраняемся, запускаемся.

Открываем список ОС, устанавливаем видимость наших новых колонок МОЛ и Местонахождение, вводим критерии отбора и вуаля:


P.S.

Недостаток рассмотренного подхода в том, что если ранее был каким-либо образом установлен отбор по ссылке, то он будет затерт нашим.

А как скомбинировать старый отбор с новым я не знаю, пока.

 

Спасибо за внимание.

Успехов!

До встречи.


Скачать файлы

Наименование Файл Версия Размер
Статья в PDF 48
.zip 657,93Kb
18.07.11
48
.zip 657,93Kb Скачать

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Артур Аюханов (artbear) 16.07.11 12:38
Для начинающих все равно не очень подойдет :(
Зачем начинающим нужен голый код без комментариев по нему? они же ничего не поймут :(
Есть лишний/дублирующий код :( - ЗначениеЗаполнена(Строка) и тут НЕ ПустаяСтрока(Строка) и т.п.
Юзай разукрашку, тебе уже говорили :(
2. Артур Аюханов (artbear) 16.07.11 12:40
(0) Цитата: "Размещаем на форме списка четыре элемента: два флажка и два поля ввода"
пять все-таки :) надпись "Отборы" не забываем.
3. Роман Осадченко (cleaner_it) 17.07.11 07:46
Претензии в (1) по существу, несмотря на очевидную полезность публикации. ИМХО, нужно доработать для положительной оценки
4. Саўка Збянтэжаны (Збянтэжаны Саўка) 18.07.11 08:58
(1), (3) Спасибо за критику. Исправлю на днях.
5. Саўка Збянтэжаны (Збянтэжаны Саўка) 18.07.11 12:34
(1), (3) Подправил маленько :)
Какие еще советы дадите новичку?
6. Роман Романов (romansun) 18.07.11 14:16
(5)
я для таких вещей стараюсь использовать обычно более короткие конструкции:

приведу пример не для галок, а для нескольких кнопок в командной панели на форме списка журнала документов

единый обработчик события нажатия на кнопку

Процедура ОтобратьПоВидамУчета(Кнопка)
		
	Кнопка.Пометка = Не Кнопка.Пометка;
		
	Отбор[Кнопка.Имя].Значение = Кнопка.Пометка;
	Отбор[Кнопка.Имя].Использование = Кнопка.Пометка;
	
КонецПроцедуры
...Показать Скрыть


где имена кнопок = именам граф журнала

думаю, и в вашем примере как минимум обработчики однотипных элементов формы лучше свести вместе для упрощения обслуживания кода
Збянтэжаны Саўка; +1 Ответить 1
7. Артур Аюханов (artbear) 18.07.11 17:17
(0) Вот сейчас уже намного лучше!
8. Саўка Збянтэжаны (Збянтэжаны Саўка) 18.07.11 17:24
9. Ranika (Ranika) 05.02.12 15:37
Вот теперь мне тоже нравится ))) +1 автору
10. Владимир Б (antares_of) 20.06.12 15:52
А у меня не работает "Процедура СправочникСписокПриПолученииДанных(Элемент, ОформленияСтрок)"
пишет: {Справочник.ОсновныеСредства.Форма.ФормаВыбора.Форма(156,48)}: Переменная не определена (Организация)
СтруктураОтбора.Вставить("Организация" , <<?>>Организация); (Проверка: Толстый клиент (обычное приложение))
Переменная не определена (ДанныеСтроки)
Переменная не определена (ОформлениеСтроки)
Переменная не определена (ДатаСведений)
И как сделать чтобы инвентарные номера тоже можно было видеть отдельной колонкой?
11. Саўка Збянтэжаны (Збянтэжаны Саўка) 27.06.12 17:46
(9) Ranika, Спасибо.
(10) antares_of,
Прошу прощения за задержку с ответом
В статье только вырезанный кусок кода из процедуры
Вот полный ее код (это для БП):

Процедура СправочникСписокПриПолученииДанных(Элемент, ОформленияСтрок)
	
	Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
		
		ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
		
		Если НЕ ДанныеСтроки.ЭтоГруппа Тогда
			ОсновноеСредство  = ДанныеСтроки.Ссылка;
			Период            = ТекущаяДата();
			Организация       = глЗначениеПеременной("ОсновнаяОрганизация");
			
			//бз помечает списанные розовым цветом >>>
			Если Не ОсновноеСредство.ЭтоГруппа Тогда  	
				ПоследнееСостояниеСостояниеОС = УправлениеВнеоборотнымиАктивами.ПолучитьПоследнееСостояниеОС(Период, ОсновноеСредство, Организация);
				Если ПоследнееСостояниеСостояниеОС.СостояниеОС = Перечисления.СостоянияОС.СнятоСУчета Тогда
					ОформлениеСтроки.ЦветФона = WebЦвета.Розовый;
				КонецЕсли;	
			КонецЕсли;	
			// <<<
			
			//ага+ 09/12/2010 >>>
			Если ТипЗнч(СтруктураВидимыхКолонок) <> Тип("Структура") Тогда
				Продолжить;
			КонецЕсли;
			
			Если СтруктураВидимыхКолонок.Количество() > 0 Тогда
				ПервоначальныеСведенияОС = РегистрыСведений.ПервоначальныеСведенияОСБухгалтерскийУчет.ПолучитьПоследнее(ДатаСведений, Новый Структура("ОсновноеСредство", ДанныеСтроки.Ссылка));
				Для Каждого ЭлементСтруктуры Из ПервоначальныеСведенияОС Цикл
					Если СтруктураВидимыхКолонок.Свойство(ЭлементСтруктуры.Ключ)Тогда
						Если Лев(ЭлементСтруктуры.Ключ, 4) = "Флаг" Тогда
							ОформлениеСтроки.Ячейки[ЭлементСтруктуры.Ключ].УстановитьФлажок(ЭлементСтруктуры.Значение);
						Иначе
							ОформлениеСтроки.Ячейки[ЭлементСтруктуры.Ключ].Значение = ЭлементСтруктуры.Значение;
						КонецЕсли;
					КонецЕсли;
				КонецЦикла;
			Иначе
				Продолжить;
			КонецЕсли;
			
			ТекОрганизация = ПервоначальныеСведенияОС.Организация;
			
			Если НЕ ЗначениеЗаполнено(ТекОрганизация) Тогда
				Продолжить;
			КонецЕсли;
			
			СтруктураОтбора = Новый Структура;
			СтруктураОтбора.Вставить("Организация"   , ТекОрганизация);
			//СтруктураОтбора.Вставить("Организация"     , Организация);
			СтруктураОтбора.Вставить("ОсновноеСредство", ДанныеСтроки.Ссылка);
			
			Если СтруктураВидимыхКолонок.Свойство("МОЛ") ИЛИ СтруктураВидимыхКолонок.Свойство("Подразделение")
				ИЛИ СтруктураВидимыхКолонок.Свойство("Местонахождение") Тогда
				МестонахождениеОС = РегистрыСведений.МестонахождениеОСБухгалтерскийУчет.ПолучитьПоследнее(ДатаСведений, СтруктураОтбора);
				Для Каждого ЭлементСтруктуры Из МестонахождениеОС Цикл
					Если СтруктураВидимыхКолонок.Свойство(ЭлементСтруктуры.Ключ)Тогда
						ОформлениеСтроки.Ячейки[ЭлементСтруктуры.Ключ].Значение = ЭлементСтруктуры.Значение;
					КонецЕсли;
				КонецЦикла;
			КонецЕсли;
			
			Если СтруктураВидимыхКолонок.Свойство("СостояниеОС") Тогда
				
				ПоследнееСостояниеСостояниеОС = УправлениеВнеоборотнымиАктивами.ПолучитьПоследнееСостояниеОС(Период, ОсновноеСредство, Организация);
				ОформлениеСтроки.Ячейки.СостояниеОС.Значение = ПоследнееСостояниеСостояниеОС.СостояниеОС;
				
				//ВыборкаСостоянияОС = ПолучитьДокументыБухСостоянийОС(ДанныеСтроки.Ссылка, ТекОрганизация);
				
				ВыборкаСостояний = Новый Структура;
				
				СтруктураОтбора.Вставить("Состояние", Перечисления.СостоянияОС.ПринятоКУчету);
				ВыборкаСостоянияОС = РегистрыСведений.СостоянияОСОрганизаций.Получить(СтруктураОтбора);
				ВыборкаСостояний.Вставить("ПринятоКУчету", ВыборкаСостоянияОС.ДатаСостояния);
				
				СтруктураОтбора.Вставить("Состояние", Перечисления.СостоянияОС.ВведеноВЭксплуатацию);
				ВыборкаСостоянияОС = РегистрыСведений.СостоянияОСОрганизаций.Получить(СтруктураОтбора);
				ВыборкаСостояний.Вставить("ВведеноВЭксплуатацию", ВыборкаСостоянияОС.ДатаСостояния);
				
				СтруктураОтбора.Вставить("Состояние", Перечисления.СостоянияОС.СнятоСУчета);
				ВыборкаСостоянияОС = РегистрыСведений.СостоянияОСОрганизаций.Получить(СтруктураОтбора);
				ВыборкаСостояний.Вставить("СнятоСУчета", ВыборкаСостоянияОС.ДатаСостояния);
				
				Для Каждого ЭлементСтруктуры Из ВыборкаСостояний Цикл
					Если СтруктураВидимыхКолонок.Свойство(ЭлементСтруктуры.Ключ)Тогда
						// не показывать дату 01010001
						Если НЕ (ТипЗнч(ЭлементСтруктуры.Значение) = Тип("Дата") И ЭлементСтруктуры.Значение = '00010101') Тогда
							ОформлениеСтроки.Ячейки[ЭлементСтруктуры.Ключ].Значение = ЭлементСтруктуры.Значение;
						КонецЕсли;
					КонецЕсли;
				КонецЦикла;
				
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЦикла;
	//<<<
	
КонецПроцедуры
...Показать Скрыть