"Легкая" задачка

1. Leon75 20.05.21 22:35 Сейчас в теме
"Задача:
Создать обработку с табличной частью.
Программно удалить только те строк, номера которых пользователь
задал в виде фильтра в шапке обработки. Фильтр универсальный: равно,
список, больше, меньше и т.п."

Коллеги, я иногда задаюсь двумя вопросами:
1.Что за профессор Мориарти делает такие задачи?
2.Может все-таки я слишком усложняю и у подобных задач есть решение?

Идем от фильтра:
"Универсальный отбор" - это как я понимаю Отбор в ОФ и ОтборКомпоновкиДанных в УФ.
в ОФ отбор по номеру строки невозможен. Поэтому всякие акробатические этюды с ПостроителемЗапроса не выйдут.
В УФ ОтборКомпоновкиДанных доступен для Динамического списка и собственно в СКД.
Динамическим списком не обратишься к табличной части Обработки.
Свойство ОтборСтрок это только вид сравнения Равно, там свойством является
Фиксированная Структура. В качестве ключа используется имя реквизита табличной части, а в качестве значения - значение, по которому осуществляется отбор.
Ну и собственно где может быть решение?
Создать собственные элементы "псевдофильтр" в виде значения, списка значений и вида сравнения?
Ну как-бы это не очень стыкуется с "Фильтр универсальный: равно,
список, больше, меньше и т.п."

Может что-то есть еще? Кто подскажет? Помогите пожалуйста.
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Найденные решения
15. coollerinc 188 20.05.21 23:56 Сейчас в теме
(13) Я думаю это единственное правильное решение. Программно в СКД передать таблицу и выполнив СКД получить нужные строки, а все лишние удалить
Drivingblind; Leon75; +2 Ответить
18. SlavaKron 21.05.21 06:59 Сейчас в теме
(1) Можно сделать на основе компоновщика динамического списка. Запрос ДС сформировать на основе имен и типов полей табличной части.
	ТЗ = Объект.ТабличнаяЧасть1.Выгрузить();
	ПоляЗапроса = Новый Массив;
	Для Каждого Колонка Из ТЗ.Колонки Цикл
		
		Если Колонка.Имя = "ИсходныйНомерСтроки" Тогда
			Продолжить;
		КонецЕсли;
		
		Типы = Колонка.ТипЗначения.Типы();
		
		Если Типы.Количество() > 1 Тогда
			ПоляЗапроса.Добавить("Неопределено КАК " + Колонка.Имя);
			Продолжить;
		КонецЕсли;
		
		ТипКолонки = Типы[0];
		
		Если ТипКолонки = Тип("Строка") Тогда
			Длина = Колонка.ТипЗначения.КвалификаторыСтроки.Длина;
			Если Длина = 0 Тогда
				Длина = 1024;
			КонецЕсли;
			
			ПоляЗапроса.Добавить("ВЫРАЗИТЬ("""" КАК СТРОКА(" + XMLСтрока(Длина) + ")) КАК " + Колонка.Имя);
		ИначеЕсли ТипКолонки = Тип("Дата") Тогда
			ПоляЗапроса.Добавить("ДАТАВРЕМЯ(1,1,1) КАК " + Колонка.Имя);
		ИначеЕсли ТипКолонки = Тип("Число") Тогда
			Длина = Колонка.ТипЗначения.КвалификаторыЧисла.Разрядность;
			Точность = Колонка.ТипЗначения.КвалификаторыЧисла.РазрядностьДробнойЧасти;
			ПоляЗапроса.Добавить("ВЫРАЗИТЬ(0 КАК ЧИСЛО(" + Длина + ", " + Точность + ")) КАК " + Колонка.Имя);
		ИначеЕсли ТипКолонки = Тип("Булево") Тогда
			ПоляЗапроса.Добавить("ИСТИНА КАК " + Колонка.Имя);
		Иначе
			ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипКолонки);
			Если ОбъектМетаданных = Неопределено Тогда
				Продолжить
			КонецЕсли;
			ПоляЗапроса.Добавить("ЗНАЧЕНИЕ( " + ОбъектМетаданных.ПолноеИмя() + ".ПустаяСсылка) КАК " + Колонка.Имя);
		КонецЕсли;
		
	КонецЦикла;
	
	ТекстЗапроса = "ВЫБРАТЬ" + Символы.ПС + СтрСоединить(ПоляЗапроса, "," + Символы.ПС);

	ДС.ТекстЗапроса = ТекстЗапроса;
Показать
Прикрепленные файлы:
ОтборКТЧОбработки.epf
Sungang; Leon75; +2 Ответить
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
12. karamazoff 96 20.05.21 23:44 Сейчас в теме
(1)Насколько я понял, проблема в том, как сделать интерактивный универсальный отбор? В ОФ посмотрите как это сделано в групповой обработке данных, в УФ - групповая корректировка реквизитов.
17. Leon75 21.05.21 00:02 Сейчас в теме
(12)Спасибо. Там источник данных Запрос в СКД, передается имя Метаданных в виде параметра. Но мы не можем обратиться к ТабличнойЧасти Обработки через запрос к БД. Буду пробовать через источник данных Объект.
25. Drivingblind 228 21.05.21 13:18 Сейчас в теме
(1) Я бы попробовал программно создать СКД, в качестве источника данных установить туда Таблицу значений, а в качестве отбора -- отбор компоновки данных с формы. Строки, которые вернет результат выполнения СКД удалить из таблицы на форме методом НайтиСтроки()
26. FatPanzer 21.05.21 13:56 Сейчас в теме
(25) Дайте пример структуры, которую будете устанавливать в качестве отбора для НайтиСтроки().
33. Drivingblind 228 22.05.21 08:08 Сейчас в теме
(26) Ну СКД вернет нам таблицу значений. Если не менять структуру полей, то далее примерно так:

Для каждого Элемент из ТаблицаПослеОтбора Цикл
    Отбор = ОбщегоНазначения.СтрокаТаблицыЗначенийВСтруктуру(Элемент);
    НайденныеСтроки = ИсходнаяТаблица.НайтиСтроки(Отбор);
   
    Для каждого НайденнаяСтрока Из НайденныеСтроки Цикл
        ИсходнаяТаблица.Удалить(НайденнаяСтрока);
    КонецЦикла;

КонецЦикла;
Показать
34. FatPanzer 22.05.21 10:10 Сейчас в теме
(33) Бред. Засовывать строку таблицы в структуру, потом по этой структуре искать эту же строку в исходной таблице, а потом еще зачем то в цикле пытаться её удалить (прекрасно зная, что она там одна).

Проще тогда уже делать копию ТЗ, в цикле её обходить, проверять на условие и тогда уже сносить её в основной таблице.

Но нет, мы не ищем легких путей, нам подавай СКД, потому что без обращения к СУБД мы уже не можем обработать таблицу значений, которая находится в оперативной памяти...
35. FatPanzer 22.05.21 11:00 Сейчас в теме
(33) И, кстати, а если в ТЗ будет колонка с типом "ХранилищеЗначения"? Угадайте, на каком месте сломается ваш код?
39. Drivingblind 228 23.05.21 13:03 Сейчас в теме
(35) вы попросили пример структуры для отбора -- я привел пример структуры для отбора, а не пример оптимально работающего решения. Об этом не было речи.
Ничего не мешает исключить из полей структуры колонки с типом данных ХранилищеЗначения и заменить удаление в цикле на НайденныеСтроки[0].

Но нет, мы не ищем легких путей, нам подавай СКД

Всё зависит от того, насколько сложный отбор на форме. Если на форме фильтр осуществляется с помощью отбора компоновки данных, то выполнять его придется через СКД, в противном случае для корректного выполнения сложных условий придется городить куда более вырвиглазные костыли.
2. FatPanzer 20.05.21 22:40 Сейчас в теме
Ну и в чем проблема? Создать массив удаляемых строк, а потом их удалить в цикле.
Никаких компоновок и отборов - они предназначены только для визуального отображения, а не для изменения состава строк.

Циклом найти нужные строки, добавить в массив, а потом в цикле по массиву - удалять... Первый класс задачка.
3. Leon75 20.05.21 22:43 Сейчас в теме
(2)
Циклом найти нужные строки, добавить в массив, а потом в цикле по массиву - удалять... Первый класс задачка.

номера которых пользователь
задал в виде фильтра в шапке обработки

Я понимаю как их удалить, это действительно просто, я не понимаю как стыкуется
именно для визуального отображения. На уровне элемента формы.
4. FatPanzer 20.05.21 22:47 Сейчас в теме
(3) Что отображать? Отбор? Строка. С номерами через запятую. В задаче не сказано каким образом пользователь должен вводить отбор? Нет. Значит все на твое усмотрение.
Обычная строка не противоречит условиям задачи.
Ну или список с числами, если уж очень хочется.
5. Leon75 20.05.21 22:52 Сейчас в теме
(4)Универсальность прямо агонь.

В задаче приводится четкое описание на уровне всех сравнений отбора,
мы делаем строку. А, простите, равно, больше или равно. подобно, с /по
мы тоже все в одну строку вместе с значениями?
6. пользователь 20.05.21 23:02
Сообщение было скрыто модератором.
...
7. Leon75 20.05.21 23:05 Сейчас в теме
(6)преобразовать в необходимый параметр исходя из выбранного типа сравнения
Это первый класс?
Напишите пример, хоть для пары сравнений.
8. FatPanzer 20.05.21 23:25 Сейчас в теме
(7)
ЧисловойПараметр = Число(СтроковыйПараметр);

МассивСтроковыхПараметров = СтрРазделить(СтроковыйПараметр, ",");


Чо еще не умеешь?
9. Leon75 20.05.21 23:29 Сейчас в теме
(8)Во-первых что за тон?
Во-вторых задача не мной создана, и я сюда не издеваться пришел и не троллить.
В-третьих парсить строку ">=6", а тем более диапазоны
полученные парсом строки "C 19 По 21" разве просто?
Там еще условия "Не равно", "Не в списке" и т д
11. Sungang 56 20.05.21 23:43 Сейчас в теме
(9) Интересная задачка) Тоже жду ответа.
Вот посмотрел ссылки, может помогут отловить изменение отбора:
https://forum.mista.ru/topic.php?id=380962
https://its.1c.ru/db/metod8dev/content/2836/hdoc

Если получится получить что-то вроде ВидСравнение = Больше и т.п. - наверное это уже полдела.
Отладчиком воспользоваться и гуглом.
14. Leon75 20.05.21 23:49 Сейчас в теме
(11)Там Отбор не применишь ни в ОФ, ни в УФ.
НомерСтроки не отбирается в ОФ, в УФ из ДокументСсылка.ТабличнаяЧасть можно дин. списком, а если ОбработкаОбъект.ТабличнаяЧасть никак.
10. coollerinc 188 20.05.21 23:42 Сейчас в теме
Можно добавить реквизит с типом отчет из него вытащить отбор. Если пойти дальше, можно свой макет прикрутить и через СКД нужные строки получить
13. Leon75 20.05.21 23:45 Сейчас в теме
(10)Да, примерно так я думал. Засунуть ТЧ в источник данных объект СКД, вытащить Отбор из Компоновщика.
Фуухх. Спасибо. Аж отлегло.
15. coollerinc 188 20.05.21 23:56 Сейчас в теме
(13) Я думаю это единственное правильное решение. Программно в СКД передать таблицу и выполнив СКД получить нужные строки, а все лишние удалить
Drivingblind; Leon75; +2 Ответить
16. Leon75 20.05.21 23:59 Сейчас в теме
(15)Буду пробовать. Если завтра получится, с меня причитается.
18. SlavaKron 21.05.21 06:59 Сейчас в теме
(1) Можно сделать на основе компоновщика динамического списка. Запрос ДС сформировать на основе имен и типов полей табличной части.
	ТЗ = Объект.ТабличнаяЧасть1.Выгрузить();
	ПоляЗапроса = Новый Массив;
	Для Каждого Колонка Из ТЗ.Колонки Цикл
		
		Если Колонка.Имя = "ИсходныйНомерСтроки" Тогда
			Продолжить;
		КонецЕсли;
		
		Типы = Колонка.ТипЗначения.Типы();
		
		Если Типы.Количество() > 1 Тогда
			ПоляЗапроса.Добавить("Неопределено КАК " + Колонка.Имя);
			Продолжить;
		КонецЕсли;
		
		ТипКолонки = Типы[0];
		
		Если ТипКолонки = Тип("Строка") Тогда
			Длина = Колонка.ТипЗначения.КвалификаторыСтроки.Длина;
			Если Длина = 0 Тогда
				Длина = 1024;
			КонецЕсли;
			
			ПоляЗапроса.Добавить("ВЫРАЗИТЬ("""" КАК СТРОКА(" + XMLСтрока(Длина) + ")) КАК " + Колонка.Имя);
		ИначеЕсли ТипКолонки = Тип("Дата") Тогда
			ПоляЗапроса.Добавить("ДАТАВРЕМЯ(1,1,1) КАК " + Колонка.Имя);
		ИначеЕсли ТипКолонки = Тип("Число") Тогда
			Длина = Колонка.ТипЗначения.КвалификаторыЧисла.Разрядность;
			Точность = Колонка.ТипЗначения.КвалификаторыЧисла.РазрядностьДробнойЧасти;
			ПоляЗапроса.Добавить("ВЫРАЗИТЬ(0 КАК ЧИСЛО(" + Длина + ", " + Точность + ")) КАК " + Колонка.Имя);
		ИначеЕсли ТипКолонки = Тип("Булево") Тогда
			ПоляЗапроса.Добавить("ИСТИНА КАК " + Колонка.Имя);
		Иначе
			ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипКолонки);
			Если ОбъектМетаданных = Неопределено Тогда
				Продолжить
			КонецЕсли;
			ПоляЗапроса.Добавить("ЗНАЧЕНИЕ( " + ОбъектМетаданных.ПолноеИмя() + ".ПустаяСсылка) КАК " + Колонка.Имя);
		КонецЕсли;
		
	КонецЦикла;
	
	ТекстЗапроса = "ВЫБРАТЬ" + Символы.ПС + СтрСоединить(ПоляЗапроса, "," + Символы.ПС);

	ДС.ТекстЗапроса = ТекстЗапроса;
Показать
Прикрепленные файлы:
ОтборКТЧОбработки.epf
Sungang; Leon75; +2 Ответить
19. FatPanzer 21.05.21 07:10 Сейчас в теме
Почему все уперлись в отбор? Про который нет ни слова в задаче? В задаче есть слово "фильтр". Слово "отбор" придумал ТС, и после этого все пошли по неправильному пути.
Задача - удалить строки, а не показать на экране отбор строк.

Зачем изобретать велосипед?
Элемент со списком видов сравнения и текстовая строка для правого значения. Потом формирование массива удаляемых строк на основании правого значения, потом удаление строк по сформированному массиву.
"Универсальный" <> "платформенный, типовой". Универсальный - это который подходит для всех видов сравнения (на единичное значение и на список). И всё!
unknown181538; +1 Ответить
20. SlavaKron 21.05.21 07:24 Сейчас в теме
(19) Формально задача простая. Думаю, у ТС нет вопросов как добавить поле ввода на форму и прочее для ее решения. Тут скорее повод поговорить об универсальном отборе, непривязанном к отчету. Платформенный станет универсальным, стоит лишь усложнить задачу. И решать ее через свою таблицу отборов со всей обработкой – вот где будет точно велосипед.
21. Leon75 21.05.21 07:35 Сейчас в теме
(20)Именно так. И велосипед недешевый.
22. Leon75 21.05.21 08:57 Сейчас в теме
(19)
В задаче есть слово "фильтр".

Если подходить формализовано, то возникает неоднозначность определения.

Набрал слово "фильтр" в СП, а потом в справке по платформе:
Общие объекты/DOM/ИтераторУзловDOM/Свойства/Фильтр
Общие объекты/DOM/ОбходДереваDOM/Свойства/Фильтр
Общие объекты/XBase/ИндексXBase/Свойства/Фильтр
Общие объекты/Работа с файлами/ДиалогВыбораФайла/Свойства/Фильтр
Общие объекты/Работа с файлами/ПараметрыДиалогаПомещенияФайлов/Свойства/Фильтр

Все.

(19)
а не показать на экране отбор строк.

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

Это как двумя словами можно обезобразить и усложнить задачу:
"возможность редактирования и добавления новых строк"
"возможность редактирования и добавления новых строк и столбцов"
Или как в фильме "Привидение" с Патриком Суэйзи:
"Поднять стакан воды"
"Поднять стакан воды будучи мертвым"
23. ptolomei 21.05.21 09:24 Сейчас в теме
А не проще было просто взять все таблицу и циклом по ней пройтись снизу-вверх и удалить те строки, которые удовлетворяют уловию? Если я правильно понял то там кода на 10-20 строк максимум
24. Leon75 21.05.21 09:30 Сейчас в теме
(23)Я думаю, если бы мы делали метод фонового задания, то да. Безусловно.
Но в условии фигурирует Пользователь, он там что-то задает в шапке обработки "и т.п."
27. FatPanzer 21.05.21 13:57 Сейчас в теме
(23) Так и я про то же. Все что нужно получить - это массив с номерами строк, которые надо удалить.
То есть это задача, которая вообще никакого отношения ни к отборам, ни к фильтрам не имеет.
Задача просто на умение пользоваться универсальными коллекциями (массивами и таблицами)
28. Leon75 21.05.21 15:13 Сейчас в теме
(27)Ну пока от вас только слова. Человек обработку работающую приложил.
Я убрал из нее Динамический список и текст запроса-типизатора, взял реквизит формы КомпоновщикНастроек, типизировал набор данных с таблицей одной колонкой, убрал массив для удаления (удаляю сразу в цикле обхода итоговой коллекции), сейчас вся обработка 71 строка. Со всеми видами сравнения. Их если что 10 для типа Число.
Ваш вариант в формате epf где?
29. FatPanzer 21.05.21 15:18 Сейчас в теме
(28)
Ваш вариант в формате epf где?
У тебя денег столько нет, чтобы я вместо тебя еще и задания делал.
30. Leon75 21.05.21 15:24 Сейчас в теме
(29)Да за меня и не надо. За себя сделайте.
31. ptolomei 21.05.21 15:56 Сейчас в теме
(30)Я такую задачу на собеседовании за себя делал )
32. Leon75 21.05.21 16:02 Сейчас в теме
36. Leon75 22.05.21 11:08 Сейчас в теме
Может кому пригодится.
Прикрепленные файлы:
УдалениеСтрокТЧ.epf
user785225; Sungang; Drivingblind; SlavaKron; +4 Ответить
37. SlavaKron 22.05.21 13:17 Сейчас в теме
(36) Ваш вариант однозначно лаконичнее и оптимальнее, чем мой. Про реквизит формы типа КомпоновщикНастроекКомпоновкиДанных я знал и думал использовать именно его, но не сообразил как правильно инициализировать.
38. Leon75 22.05.21 17:51 Сейчас в теме
(37)Спасибо Вам и всем кто общался в конструктивном русле.
40. user785225 17 31.08.22 18:22 Сейчас в теме +7 $m
(36) как сформировать КомпоновщикНастроекКомпоновкиДанных для САБЖа программно?

цель - отбираться по табличной части документа, дописав всего 2 строки:
- ПриСозданииНаСервере: ИнициализироватьСКД(...)
- КомпоновщикНастроекКомпоновкиДанныхНастройкиОтборПриИзменени­и: УдалитьСтроки(...)

(не добавляя ручками на форму компоновщик данных - собственно это делалется в одну строчку, получилось;
ЭтаФорма.ИзменитьРеквизиты(Массив(Новый РеквизитФормы("КомпоновщикНастроекКомпоновкиДанных_", Новый ОписаниеТипов("КомпоновщикНастроекКомпоновкиДанных"))))

не вынося ручками элемент с настройками - а вот это не получилось, подчиненные элементы настроек видимо при ручном добавлении инициализируются, а при программном - нет, и их тьма, см. рис.)
Прикрепленные файлы:
41. Sashares 34 31.08.22 18:25 Сейчас в теме
(40)Нет смысла добавлять в старые темы награждение. Награду ответу может назначить только ТС.
user785225; +1 Ответить
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот