Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
07 окт 2025, 01:19

Состав выпадающего списка выбора

Автор FearDog, Вчера в 16:19

0 Пользователей и 1 гость просматривают эту тему.

FearDog

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

ДанныеВыбора = ДанныеВыбораИнгредиентовНаСервере(Текст, Объект.Ссылка);
СтандартнаяОбработка = Ложь;

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

&НаСервере
Функция ДанныеВыбораИнгредиентовНаСервере(Текст, Номенклатура)

Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| 1 КАК Порядок,
| Ингредиенты.Ссылка КАК Ссылка
|ПОМЕСТИТЬ Ингредиенты
|ИЗ
| Справочник._Ингредиенты КАК Ингредиенты
|ГДЕ
| (НЕ Ингредиенты.Составной
| ИЛИ Ингредиенты.Номенклатура = &Номенклатура)
| И &НачинаетсяС
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| 2,
| Ингредиенты.Ссылка
|ИЗ
| Справочник._Ингредиенты КАК Ингредиенты
|ГДЕ
| (НЕ Ингредиенты.Составной
| ИЛИ Ингредиенты.Номенклатура = &Номенклатура)
| И &Подобно
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ ПЕРВЫЕ 10
| Ингредиенты.Ссылка КАК Ссылка
|ИЗ
| Ингредиенты КАК Ингредиенты
|
|УПОРЯДОЧИТЬ ПО
| Ингредиенты.Порядок,
| Ингредиенты.Ссылка.Наименование";

Запрос.УстановитьПараметр("Номенклатура", Номенклатура);

Если ПустаяСтрока(Текст) Тогда
Запрос.Текст = СтрЗаменить(Запрос.Текст, "И &НачинаетсяС", "");
Запрос.Текст = СтрЗаменить(Запрос.Текст, "И &Подобно", "");
Иначе
Запрос.Текст = СтрЗаменить(Запрос.Текст, "&НачинаетсяС", "Ингредиенты.Наименование Подобно ""%" + Текст + """");
Запрос.Текст = СтрЗаменить(Запрос.Текст, "&Подобно", "Ингредиенты.Наименование Подобно ""%" + Текст + "%""");
КонецЕсли;

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

ДанныеВыбораИнгредиентов = Новый СписокЗначений;

Если Не Результат.Пустой() Тогда

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

КонецЕсли;

Возврат ДанныеВыбораИнгредиентов;

КонецФункции
Но в список лезут какие-то левые строки:

В данных выборки только одна строка, но, почему-то, туда добавляется Творог (Составной).

Метод ОбработкаПолученияДанныхВыбора в справочнике Ингредиенты не отрабатывается (точка останова не срабатывает).
Откуда берется этот творог? =)

И при пустой строке: 10 строк мои, ниже строки не могу понять, откуда лезут:

fruitella

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

FearDog

fruitella, т.е. просто переопределить ДанныеВыбора недостаточно? А где его очищать? Проверил в методе СоставИнгредиентАвтоПодбор, значение Элементы.СоставИнгредиент.СписокВыбора пустое :mellow:

antoneus

Это не список выбора, это, скорее всего, история выбора при вводе. Попробуй у элемента поставить ее в "Не использовать".

LexaK

FearDog, а отдельно запрос в консоли запросов проверяли?
у творога в номенклатуре что

может вот это условие срабатывать
ИЛИ Ингредиенты.Номенклатура = &Номенклатура)
если помогло нажмите: Спасибо!

FearDog

Цитата: antoneus от Вчера в 20:14история выбора при вводе. Попробуй у элемента поставить ее в "Не использовать".
Оно самое  :lol:
Спасибо, теперь ничего лишнего)

FearDog

Подведу итог: Определил два метода поля Ингредиент АвтоПодбор и ОкончаниеВводаТекста и выставил для него значение ИсторияВыбораПриВводе в Не использовать. Чуть доработал код, перенес получение данных выбора в модуль менеджера справочника Ингредиентов. и добавил подсветку результата) (Спасибо Сан Санычу https://infostart.ru/1c/articles/1365095/)

Вот такая красота получилась


Форма объекта Номенклатуры:
&НаКлиенте
Процедура СоставИнгредиентАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
    ДанныеВыбора = ДанныеВыбораИнгредиентовНаСервере(Текст, Объект.Ссылка);
    СтандартнаяОбработка = Ложь;
КонецПроцедуры

&НаКлиенте
Процедура СоставИнгредиентОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, СтандартнаяОбработка)
    ДанныеВыбора = ДанныеВыбораИнгредиентовНаСервере(Текст, Объект.Ссылка);
    СтандартнаяОбработка = Ложь;
КонецПроцедуры

&НаСервере
Функция ДанныеВыбораИнгредиентовНаСервере(Текст, Номенклатура)
    Возврат Справочники._Ингредиенты.ПолучитьДанныеВыбора(Новый Структура("СтрокаПоиска, Номенклатура", Текст, Номенклатура));
КонецФункции

Модуль менеджера справочника Ингредиентов;
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)

    СтрокаПоиска = СтрЗаменить(Параметры.СтрокаПоиска, """", ""); // нормализация
       
    Если СтрокаПоиска <> "" И Параметры.Свойство("Номенклатура") Тогда
       
        МаксимумСтрокРезультата = 15;
       
        МассивСловПоиска = СтрРазделить(СтрокаПоиска, " ", Ложь);
        КоличествоСловПоиска = МассивСловПоиска.Количество();
       
        Если КоличествоСловПоиска > 0 Тогда
           
            СтандартнаяОбработка = Ложь;       
            СписокВыбора = Новый СписокЗначений;
           
            Запрос = Новый Запрос;
           
            УсловияПоиска = "";
            ПриоритетСортировки = "";
            Для НомерСловаПоиска = 1 По КоличествоСловПоиска Цикл
               
                СловоПоиска = МассивСловПоиска[НомерСловаПоиска - 1];
                ДлинаСловаПоиска = СтрДлина(СловоПоиска);
               
                Запрос.УстановитьПараметр("СловоПоиска" + НомерСловаПоиска, "%" + СловоПоиска + "%");
                УсловияПоиска = УсловияПоиска + "
                    |    И Ингредиенты.Наименование ПОДОБНО &СловоПоиска" + НомерСловаПоиска;
               
                ПриоритетСортировки = ПриоритетСортировки + СтрШаблон("
                    |        КОГДА ПОДСТРОКА(Ингредиенты.Наименование, 1, %1) = ""%2""
                    |          ТОГДА %3", Формат(ДлинаСловаПоиска, "ЧГ="), СловоПоиска, НомерСловаПоиска);
               
            КонецЦикла;
           
            Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ " + МаксимумСтрокРезультата + "
                |    Ингредиенты.Ссылка КАК Ссылка,
                |    Ингредиенты.Наименование КАК Наименование,
                |    Ингредиенты.ПометкаУдаления КАК ПометкаУдаления,
                |    ВЫБОР" + ПриоритетСортировки + "
                |        ИНАЧЕ 9
                |    КОНЕЦ КАК ПриоритетСортировки
                |ИЗ
                |    Справочник._Ингредиенты КАК Ингредиенты
                |ГДЕ
                |    (НЕ Ингредиенты.Составной
                |            ИЛИ Ингредиенты.Номенклатура = &Номенклатура)
                |    " + УсловияПоиска + "
                |УПОРЯДОЧИТЬ ПО
                |    ПриоритетСортировки, Наименование";
           
            Запрос.УстановитьПараметр("Номенклатура", Параметры.Номенклатура);
           
            Выборка = Запрос.Выполнить().Выбрать();
            Пока Выборка.Следующий() Цикл
                СписокВыбора.Добавить(Новый Структура("Значение,ПометкаУдаления", Выборка.Ссылка, Выборка.ПометкаУдаления), ПодсветитьСлова(Выборка.Наименование, МассивСловПоиска));
            КонецЦикла;
           
            ДанныеВыбора = СписокВыбора;
           
        КонецЕсли;
       
    КонецЕсли;

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

Функция ПодсветитьСлова(ИсходнаяСтрока, МассивСловПодсветки, Знач ШрифтПодсветки = Неопределено, Знач ЦветПодсветки = Неопределено)
   
    МассивРезультирующихСтрок = Новый Массив;
   
    Если ШрифтПодсветки = Неопределено Тогда
        ШрифтПодсветки = Новый Шрифт(,, Истина); // жирный
    КонецЕсли;
   
    Если ЦветПодсветки = Неопределено Тогда
        ЦветПодсветки = Новый Цвет(0, 153, 0); // светло-зеленый из стандартной подсветки ввода по строке
    КонецЕсли;
   
    ИсходнаяСтрокаНормализованная = НРег(ИсходнаяСтрока); // нормализация
    ДлинаИсходнойСтроки = СтрДлина(ИсходнаяСтрокаНормализованная);
   
    // получим список диапазонов символов для подсветки
    СписокДиапазонов = Новый СписокЗначений;
    Для НомерСлова = 1 По МассивСловПодсветки.Количество() Цикл
        СловоПодсветки = НРег(МассивСловПодсветки[НомерСлова - 1]); // нормализация
        ПозицияНачалаСлова = 1;
        ДлинаСлова = СтрДлина(СловоПодсветки);
        Пока ПозицияНачалаСлова <> 0 И ПозицияНачалаСлова <= ДлинаИсходнойСтроки Цикл
            ПозицияНачалаСлова = СтрНайти(ИсходнаяСтрокаНормализованная, СловоПодсветки, , ПозицияНачалаСлова);
            Если ПозицияНачалаСлова > 0 Тогда
                МассивДиапазона = Новый Массив;
                МассивДиапазона.Добавить(ПозицияНачалаСлова);
                МассивДиапазона.Добавить(ПозицияНачалаСлова + ДлинаСлова - 1);
                СписокДиапазонов.Добавить(МассивДиапазона, Формат(ПозицияНачалаСлова, "ЧЦ=3; ЧВН="));
                ПозицияНачалаСлова = ПозицияНачалаСлова + ДлинаСлова;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
   
    // отсортируем список диапазонов по возрастанию начал диапазонов
    СписокДиапазонов.СортироватьПоПредставлению();
   
    // сформируем массив результирующих строк с разным оформлением (подсветкой)
    СтартоваяПозиция = 1;
    Для Каждого ЭлементДиапазона Из СписокДиапазонов Цикл
        НачалоДиапазона = ЭлементДиапазона.Значение[0];
        КонецДиапазона = ЭлементДиапазона.Значение[1];
        Если НачалоДиапазона > СтартоваяПозиция Тогда // часть строки без подсветки
            ЧастьБезВыделения = Сред(ИсходнаяСтрока, СтартоваяПозиция, НачалоДиапазона - СтартоваяПозиция);
            МассивРезультирующихСтрок.Добавить(Новый ФорматированнаяСтрока(ЧастьБезВыделения));
            СтартоваяПозиция = НачалоДиапазона;
        КонецЕсли;
        Если КонецДиапазона >= СтартоваяПозиция Тогда // часть строки с подсветкой
            ЧастьВыделяемая = Сред(ИсходнаяСтрока, СтартоваяПозиция, КонецДиапазона - СтартоваяПозиция + 1);
            МассивРезультирующихСтрок.Добавить(Новый ФорматированнаяСтрока(ЧастьВыделяемая, ШрифтПодсветки, ЦветПодсветки));
            СтартоваяПозиция = КонецДиапазона + 1;
        КонецЕсли;
    КонецЦикла;
   
    Если СтартоваяПозиция <= ДлинаИсходнойСтроки Тогда // "хвост" без выделения
        Хвост = Сред(ИсходнаяСтрока, СтартоваяПозиция, ДлинаИсходнойСтроки - СтартоваяПозиция + 1);
        МассивРезультирующихСтрок.Добавить(Новый ФорматированнаяСтрока(Хвост));
    КонецЕсли;
   
    Возврат Новый ФорматированнаяСтрока(МассивРезультирующихСтрок);
   
КонецФункции

P.S.: Правила глянул, ссылки вроде как не запрещены :mellow:

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск