Функция отбора элементов коллекции быстрым условием

21.08.23

Разработка - Универсальные функции

Функция для компактного вызова отбора элементов коллекции произвольным БЫСТРЫМ (легким) условием

Скачать файл

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

Наименование SM По подписке [?]
Функция отбора элементов коллекции произвольным условием
.epf 7,96Kb
38
38
0 SM
Скачать

Нередко встречаются задачи обхода коллекции с целью - только отобрать из нее элементы по какому то условию.

Если это табличная коллекция, то обычно у нее есть метод НайтиСтроки(Структура), позволяющий задать для каждого свойства один элемент отбора на равенство. Для более сложных отборов в таких коллекциях можно применять компоновку данных, которая добавляет ощутимые накладные расходы, но эффективно обрабатывает обращения к БД через точку от ссылки.

Для более сложных отборов в общем случае обычно просто пишем цикл обхода коллекции и добавляем элементы в массив после проверки условия кодом.

Но все эти способы требуют писать относительно много повторяющегося кода.

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

Ближайшее к анонимным функциям, что у нас есть, это метод Выполнить() для выполнения динамического кода. Нам нужно обойти коллекцию и выполнить произвольное быстрое условие-параметр для каждого элемента. Если оно вернет Истина, то добавить элемент в массив результата. Для удобства итератор цикла назовем коротким именем "Э" и предусмотрим необязательные произвольные параметры "П<N>" для использования в условии.

Но большим недостатком метода Выполнить() являются большие накладные расходы на его вызов. Поэтому вызывать его в легком цикле - плохо. Вот почему мы целиком весь цикл сделаем динамическим кодом. Тогда затратный метод Выполнить() мы будет вызывать только один раз. Но для отладки это неудобно. Поэтому предусмотрим и легкую возможность во время отладки переключиться на минимальное использование динамического кода (флаг _РежимОтладки).

// Выбирает в массив данные элементов коллекции произвольным условием.
// Не следует использовать эту функцию для долгих (тяжелых) условий!
// Параметры:
//   Коллекция - Коллекция - произвольная коллекция
//   Условие - Строка - логическое выражение на встроенном языке, где параметр "Э" дает доступ к элементу коллекции, а параметры "П<N>" - к параметрам условия
//   ПутьКСвойству - Строка - путь к свойству, значение которого нужно извлечь из элемента коллекции и добавить в массив результата; если пусто, то добавляется сам элемент; например "ЭлементУправления.ЦветТекста"
//   П1 - Произвольное - параметр "П1" для использования в условии
//   П2 - Произвольное - параметр "П2" для использования в условии
//   П3 - Произвольное - параметр "П3" для использования в условии
// При малом числе элементов заметно медленнее чем статический код. При 100 элементах сопоставима по скорости с ним. При большем числе элементов даже быстрее него.
// Пример: ОтобратьКоллекциюУсловиемЛкс(Коллекция, "Э<>1 И Э<>П1",, Среднее)
// Возвращаемое значение:
//   Массив - элементов коллекции или значений их свойства
Функция ОтобратьКоллекциюУсловиемЛкс(Знач Коллекция, Знач Условие, Знач ПутьКСвойству = "", Знач П1 = 0, Знач П2 = 0, Знач П3 = 0) Экспорт 
	Результат = Новый Массив;  
	_РежимОтладки = Ложь;
	#Если ВебКлиент Или МобильныйКлиент Тогда 
		_РежимОтладки = Истина;
	#ИначеЕсли Не ТонкийКлиент Тогда
		УстановитьБезопасныйРежим(Истина);
	#КонецЕсли
	Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ПрЛкс(_РежимОтладки, 1, 1)     
		// Пассивный оригинал расположенного ниже кода. Выполняйте изменения синхронно в обоих вариантах.
		Для Каждого Э Из Коллекция Цикл
			//Если Э <> 0 Тогда // Для сравнения скорости со статическим кодом
			Если Вычислить(Условие) Тогда
				Результат.Добавить(?(ПустаяСтрока(ПутьКСвойству), Э, Вычислить("Э." + ПутьКСвойству)));
			КонецЕсли; 
		КонецЦикла;
	Иначе
		Попытка
			// Этот вариант кода использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах.
			Выполнить("// ДинамическийКод
			|Для Каждого Э Из Коллекция Цикл
			|	Если " + Условие + " Тогда
			|		Результат.Добавить(Э" + ?(ПустаяСтрока(ПутьКСвойству), "", "." + ПутьКСвойству) + ");
			|	КонецЕсли; 
			|КонецЦикла;");
		Исключение
			Ошибка = ОбработатьИсключениеВДинамическомКодеЛкс(ИнформацияОбОшибке());
			Если ЗначениеЗаполнено(Ошибка) Тогда
				ВызватьИсключение Ошибка;
			Иначе
				ВызватьИсключение;
			КонецЕсли;
		КонецПопытки;
	КонецЕсли;
	Возврат Результат;  

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

// Обход ошибки платформы в обычном клиентском приложении https://www.hostedredmine.com/issues/965445
// Позволяет перевыбросить исключение так, чтобы конфигуратор позволял быстрый переход к ближайшей строке статического кода из ошибки в динамическом коде.
// Динамический код должен начинаться с "// ДинамическийКод"
Функция ОбработатьИсключениеВДинамическомКодеЛкс(ИнформацияОбОшибке) Экспорт 
	
	#Если Сервер И Не Сервер Тогда
		ИнформацияОбОшибке = ИнформацияОбОшибке();
	#КонецЕсли
	Результат = Неопределено;
	Если Ложь
		Или ИнформацияОбОшибке.Причина = Неопределено 
		Или Найти(ИнформацияОбОшибке.Описание, "Ошибка компиляции") > 0
	Тогда
		Ошибка = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
		Позиция = Найти(Ошибка, "// ДинамическийКод");
		Если Позиция > 0 Тогда
			Результат = Лев(Ошибка, Позиция - 1);
		КонецЕсли;  
	КонецЕсли;
	Возврат Результат;

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

// Присваивает первому параметру второй.
// Удобно вызывать из отладчика через диалог "Вычислить выражение" (в 8.3 есть встроенный аналог) или в условной точке останова для модификации значения переменной без остановки.
// Параметры:
//  П1           - Произвольный - Указатель на переменную, которой присваиваем значение;
//  П2           - Произвольный - значение, которое присваиваем;
//  ВернутьЛожь  - Булево - если включено, то функция возвращает Ложь, что необходимо для использования в точке останова
//
// Возвращаемое значение:
//  Значение параметра П1 после присвоения, либо Ложь.
//
Функция ПрЛкс(п1, Знач п2 = Неопределено, Знач ВернутьЛожь = Ложь) Экспорт
    п1 = п2;
    Если ВернутьЛожь Тогда
        Возврат Ложь; // Чтобы в точке останова использовать
    Иначе
        Возврат п1;
    КонецЕсли;
КонецФункции

Вспомогательная функция ОбработатьИсключениеВДинамическомКодеЛкс нужна чтобы обойти жестокое удаление платформой связи с исходной строкой модуля в описании ошибки в обычном приложении.

Вспомогательная функция ПрЛкс нужна для автоматической установки флага _РежимОтладки в условной точке останова при каждом выполнении главной функции.

Все функции доступны в тонком клиенте.

 

Пример 1

Нужно отобрать из таблицы описания структуры хранения базы данных только строки описания таблиц табличных частей справочников

Сначала запишет традиционным полностью статическим кодом

Коллекция = ПолучитьСтруктуруХраненияБазыДанных();
Строки = Новый Массив;
Для Каждого Э Из Коллекция Цикл
	Если Найти(Э.Метаданные, "Справочник") И Найти(Э.Метаданные, "ТабличнаяЧасть") Тогда
		Строки.Добавить(Э);
	КонецЕсли;
КонецЦикла;
Таблица = Коллекция.Скопировать(Строки);

А теперь запишем через нашу функцию

Коллекция = ПолучитьСтруктуруХраненияБазыДанных();
Строки = ОтобратьКоллекциюУсловиемЛкс(Коллекция, "Найти(Э.Метаданные, П1) И Найти(Э.Метаданные, П2)",, "Справочник", "ТабличнаяЧасть");
Таблица = Коллекция.Скопировать(Строки);

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

 

Недостатки

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

Однако в процессе редактирования можно пойти на небольшую хитрость и временно делать этот код статическим. Тогда для него будут работать помощники ввода.

Рассмотрим другой пример. Тут мы выбираем из списка значений только элементы с пометкой и значением больше 3. Перед вызовом нашей функции вставим вспомогательную инструкцию для обозначения типа итератора "Э", используемого в условии. Для остальных параметров, задействованных в условии писать такие инструкции не придется, если давать им в текущем контексте те же имена, что и в условии.

Пример 2

Коллекция = Новый СписокЗначений;
Для Счетчик = 1 По 10 Цикл
	Коллекция.Добавить(Счетчик,, Счетчик % 2 = 0);  
КонецЦикла;
П1 = Новый Структура("Предел", 3);
#Если Сервер И Не Сервер Тогда
	Э = Коллекция[0];
#КонецЕсли
ф = ОтобратьКоллекциюУсловиемЛкс(Коллекция, "Э.Пометка И Э.Значение > П1.Предел ",, П1);

Теперь при редактировании временно удаляем начальный символ "двойная кавычка" и у нас начинают работать все помощники ввода в коде условия. Забыть вернуть обратно ее мы не сможем, т.к. будет ошибка компиляции модуля из-за конечной кавычки.

 

 

Корректность нашего условия будет проверяться только в момент его выполнения, т.к. компиляция динамическая. Поэтому даже явные ошибки не будут обнаруживаться при компиляции модуля.

При малом числе элементов выполнение этой функции медленнее чем полностью статический код из-за накладных расходов на единственный вызов Выполнить(). При 100+ элементах разница уже исчезает и дальше смещается в другую сторону.

Не следует использовать эту функцию для возможно долгих (тяжелых) условий особенно если они могут обращаться к БД, т.к. замер производительности будет привязывать выполнения всех различных условий к одной строке статического кода этой функции и будет сложно понять, какие конкретно условия дают бОльшую длительность. Тут уместна аналогия с вредом от выполнения различных запросов через единую функцию - замер производительности покажет что значительное время заняла строка выполнения запроса в этой функции, но понять какие именно запросы внесли наибольший вклад, будет очень сложно без техножурнала.

Короткие примеры

ИменаВидимыхКолонок = ОтобратьКоллекциюУсловиемЛкс(ТабличноеПоле.Колонки, "Э.Видимость И Не ПустаяСтрока(Э.Данные)", "Данные");
КолонкиВложенныхТаблиц = ОтобратьКоллекциюУсловиемЛкс(Колонки, "Э.ТипЗначения.СодержитТип(П1)", "Имя", Тип("РезультатЗапроса"));
СтрокиОдноименных = ОтобратьКоллекциюУсловиемЛкс(КоллекцияСтрок, "Э.Ключ = П1",, ТекущийПсевдоним);
СтрокиОдноименных = ОтобратьКоллекциюУсловиемЛкс(КоллекцияСтрок, "Э.Представление = П1",, ТекущийПсевдоним);
СтрокиОдноименных = ОтобратьКоллекциюУсловиемЛкс(КоллекцияСтрок, "Э.Имя = П1",, ТекущийПсевдоним);
КопияПорядка = ОтобратьКоллекциюУсловиемЛкс(НастройкаКомпоновки.Порядок.Элементы, "Э.Использование");
УдаляемыеКлючи = ОтобратьКоллекциюУсловиемЛкс(СтруктураКлюча, "ТипЗнч(Э.Значение) = П1", "Ключ", Тип("ОписаниеТипов"));
ЧислоНевидимых = ОтобратьКоллекциюУсловиемЛкс(ЭлементыФормы.ДинамическийСписок.Колонки, "Не Э.Видимость ").Количество();
ЧислоНевидимых = ОтобратьКоллекциюУсловиемЛкс(фОбъект.НастройкиКолонок, "Не Э.Видимость ").Количество();
Результат = ОтобратьКоллекциюУсловиемЛкс(МетаданныеДляРегистрации, "Э.Регистрировать", "ОбъектДляРегистрации");
СтрокиКУдалению = ОтобратьКоллекциюУсловиемЛкс(ДеревоТаблиц.Строки, "Э.Строки.Количество() = 0");
НепустыеСсылки = ОтобратьКоллекциюУсловиемЛкс(Расходы, "ЗначениеЗаполнено(Э.Рейс)", "Рейс");

Демо внешняя обработка

К статье приложена внешняя обработка со всеми функциями и примерами использования.

См. также

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Благодаря этим пяти строчкам можно больше не заморачиваться с загрузкой из внешних файлов. Пользуюсь везде, всегда и постоянно.

21.05.2024    11663    dimanich70    80    

124

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    3366    3    John_d    11    

57

Универсальные функции Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    8180    atdonya    22    

55

Универсальные функции Программист Платформа 1С v8.3 Бесплатно (free)

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

30.11.2023    4740    ke.92@mail.ru    16    

65

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    11432    YA_418728146    7    

153

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

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2822    43    progmaster    8    

4

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

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    17208    152    sapervodichka    112    

133
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. fatman78 17 24.06.23 21:14 Сейчас в теме
Спасибо Сергей. Как раз то, что надо... Отлично подойдет для таблиц значений где "НайтиСтроки" уже мало из-за ограничений отбора на равенство, а комбайн "компоновки данных" заводить не хочется...

P.S. в статье пропущено "не" в предложении "А у нас вроде бы пока ничего удобного появлялось."
2. mszsuz 330 25.06.23 05:34 Сейчас в теме
Спасибо за статью, теперь я точно знаю, что если бы и пришла в голову такая идея, то так делать не стоит.
К недостаткам ещё стоит добавить потерю прозрачности замера производительности и невозможность поставить точку останова в цикле перебора.
konstsv; dima_gsv; +2 Ответить
3. tormozit 7191 25.06.23 08:03 Сейчас в теме
(2)
потерю прозрачности замера производительности и невозможность поставить точку останова в цикле перебора

Видимо ты невнимательно читал статью. Я там писал, что в функции предусмотрен внутренний флаг _РежимОтладки (замедленный режим ее работы), который позволяет поставить точку останова на любом проходе цикла и более детально замерить производительность.
Если представить что в платформе бы появились лямбда-выражения, то допускаю что эти недостатки бы не исчезли и возможно даже усилились по отношению к _РежимОтладки, т.к. платформа не позволяет ставить точку останова внутри инструкции кода и дробить ее в замере производительности.
4. mszsuz 330 25.06.23 08:21 Сейчас в теме
(3) Видел. Получается я, например, делаю замер открытия формы, вижу что тормозит "лучший код", который вызывается 20 раз из разных мест, должен поставить в ней точку останова, снова запустить замер и 20 раз поменять режим отладки? И всё это ради экономии нескольких строчек кода?
5. tormozit 7191 25.06.23 08:44 Сейчас в теме
(4) В строке кода
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ПрЛкс(_РежимОтладки, 1, 1) 

Указан поясняющий комментарий. Он подсказывает, что можно создать условную точку останова для автоматической установки флага _РежимОтладки при каждом выполнении этой строки кода. Для этого нужна вспомогательная функция на подобие
// Присваивает первому параметру второй.
// Удобно вызывать из отладчика через диалог "Вычислить выражение" (в 8.3 есть встроенный аналог) или в условной точке останова для модификации значения переменной без остановки.
// Параметры:
//  П1           - Произвольный - Указатель на переменную, которой присваиваем значение;
//  П2           - Произвольный - значение, которое присваиваем;
//  ВернутьЛожь  - Булево - если включено, то функция возвращает Ложь, что необходимо для использования в точке останова
//
// Возвращаемое значение:
//  Значение параметра П1 после присвоения, либо Ложь.
//
Функция ПрЛкс(п1, Знач п2 = Неопределено, Знач ВернутьЛожь = Ложь) Экспорт
	п1 = п2;
	Если ВернутьЛожь Тогда
		Возврат Ложь; // Чтобы в точке останова использовать
	Иначе
		Возврат п1;
	КонецЕсли;
КонецФункции
Показать

Добавил эту функцию в статью.
Аналогичный прием активно применяет в методике однострочного кода https://infostart.ru/1c/articles/1732527/
sulfur17; +1 Ответить
23. sulfur17 65 26.06.23 09:54 Сейчас в теме
(5)
Функция ПрЛкс(п1, Знач п2 = Неопределено, Знач ВернутьЛожь = Ложь) Экспорт
п1 = п2;
Если ВернутьЛожь Тогда
Возврат Ложь; // Чтобы в точке останова использовать
Иначе
Возврат п1;
КонецЕсли;
КонецФункции


это же гениально!))
А зачем может понадобиться вызывать функцию с ВернутьЛожь = Ложь?
Я вообще правильно понял - это функция нужна чтобы включить режим отладки не обновляя конфигурацию?
25. tormozit 7191 26.06.23 11:58 Сейчас в теме
(23) Функция ПрЛкс принадлежит условному виду функций "Функции режима отладки". Основная задачи функции ПрЛкс - присвоение значения свойству/переменной в точке останова. Параметр п1 передается по ссылке, т.к. присвоение может выполняться свойству объекта с ограничениями типа. Поэтому важно прямо в окне "Вычислить выражение" сразу понять, какое значение установилось в это свойство. Для этого функция по умолчанию возвращает значение установленного свойства.
Подробнее о функциях режима отладки можно узнать из специальной формы подсистемы ИР https://www.hostedredmine.com/issues/928281
sulfur17; +1 Ответить
17. tormozit 7191 25.06.23 16:55 Сейчас в теме
(4) Дописал в статье про вред для долгих условий и в целом сделал бОльший акцент на быстрых условиях.
Не следует использовать эту функцию для возможно долгих (тяжелых) условий особенно если они обращаются к БД, т.к. замер производительности будет привязывать выполнения всех различных условий к одной строке статического кода этой функции и будет сложно понять, какие конкретно условия дают большУю длительность. Тут уместна аналогия с вредом от выполнения различных запросов через единую функцию - замер производительности покажет что значительное время заняла строка выполнения запроса в этой функции, но понять какие именно запросы внесли наибольший вклад, будет очень сложно без техножурнала.
6. PerlAmutor 130 25.06.23 10:04 Сейчас в теме
В статье написано "Выполнить()", а в коде используется "Вычислить()" (и Выполнить() отсутствует в Web-клиенте, что может ввести читателей статьи в заблуждение). Ну и Вычислить() - "В режимах запуска мобильного приложения метод не поддерживается в операционной системе iOS"
В ЯВУ таких как C++ все это дело называется Comparator. Там обычно передается указатель на функцию-компаратор в метод коллекции для сортировки например.

Ну и предусмотреть включение безопасного режима хорошо бы https://its.1c.ru/db/v8std#content:770:hdoc
7. tormozit 7191 25.06.23 10:22 Сейчас в теме
(6) В статье указана доступность функции для тонкого клиента, а не для веб и не для мобильного клиентов. Для них я не планирую поддерживать работу функции, но сделать это несложно - просто включать флаг _РежимОтладки.

Про функцию-параметр - решение очевидное, но заметно менее компактное и менее быстрое, т.к. функция будет вызываться для каждого элемента. Поэтому если условие отбора само компактное, то ради его передачи в качестве параметра - создавать функцию и описывать ее параметры - менее неудобно и замедлит работу для больших коллекций. Кстати в мою функцию передать функцию-параметр, вычисляющую условие тоже можно
ОтобратьКоллекциюУсловиемЛкс(Коллекция, "Условие1(Э,А)",, Среднее)
Функция Условие1(Элемент, Порог)
     Возврат Элемент > Порог;
КонецФункции

Преимущества здесь следуют из статической компиляции - легче отлаживать, замерять производительность, обеспечивать безопасность.
10. tormozit 7191 25.06.23 11:04 Сейчас в теме
(6) Включение безопасного режима добавил
8. PerlAmutor 130 25.06.23 10:31 Сейчас в теме
Кстати, если для проверки кода используете EDT, то рекомендую эту конструкцию таким образом записывать, чтобы уменьшить количество ложных срабатываний проверки на ошибки:

	#Если Сервер И Не Сервер Тогда //@skip-check code-never-compilied
		ИнформацияОбОшибке = ИнформацияОбОшибке();
	#КонецЕсли


P.S.: похоже разработчики EDT допустили орфографическую ошибку в слове "compilied", там видимо должно быть написано "compiled"
13. tormozit 7191 25.06.23 14:25 Сейчас в теме
(8) Это далеко от темы этой статьи, зато намного ближе к теме другой статьи на которую я тут указывал ссылку. Полезнее это написать там.
9. SeiOkami 3482 25.06.23 10:49 Сейчас в теме
Основное преимущество linq в том, чтобы оно проверялось на уровне компилятора. Тогда выходит не только короче, но и безопаснее. Проще не только писать, но и находить ошибки и поддерживать.

Не хватает поддержки на уровне платформы=(
11. пользователь 25.06.23 13:50
Сообщение было скрыто модератором.
...
12. пользователь 25.06.23 14:06
Сообщение было скрыто модератором.
...
16. пользователь 25.06.23 15:52
Сообщение было скрыто модератором.
...
14. пользователь 25.06.23 15:30
Сообщение было скрыто модератором.
...
15. пользователь 25.06.23 15:50
Сообщение было скрыто модератором.
...
18. MIracloid2000 25.06.23 23:06 Сейчас в теме
К сожалению, статические анализаторы кода не смогут понять код такого условия.


очень похоже на то, что я на них похож... статья о чем?
Andreyyy; CK3; +2 1 Ответить
19. caponid 26.06.23 00:35 Сейчас в теме
В режиме отладки не проще ли записать вместо
Вычислить("Э." + ПутьКСвойству)

просто
Э[ПутьКСвойству]
20. tormozit 7191 26.06.23 00:38 Сейчас в теме
(19) Сначала так и было. Но иногда нужно и через точку брать свойство, о чем написано в описании параметра.
21. caponid 26.06.23 00:55 Сейчас в теме
(20) может быть.. но на вскидку мне почему то такие ситуации "не моделируются".

а так имхо впечатление скорее отрицательное

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

вобщем меня мучают сомнения)
22. tormozit 7191 26.06.23 08:20 Сейчас в теме
(21)
если нужна наглядность и "воздушность" в отборах

Вроде бы я не обозначал такой цели, а обозначал цель "компактность".
то лучше использовать fluent подход

fluent это про экономию текста в последовательности выполнения операций над одним объектом. А эта статья про одну операцию.
24. 0x00 26.06.23 10:11 Сейчас в теме
Из недостатков метода можно отметить практическую невозможность его использования в технологии сервиса, где методы Выполнить() и Вычислить() запрещены https://1cfresh.com/articles/so_addprocess_fastaudit#:~:text=%D0%92%C2%A0%D0%B1%D0%B5%D0%B7%D0%BE%D0%BF%D0%B0%D1%81%­D0%BD%D0%BE%D0%BC%20%D1%80%D0%B5%D0%B6%D0%B8%D0%BC%D0%B5%20%­D0%B7%D0%B0%D0%BF%D1%80%D0%B5%D1%89%D0%B5%D0%BD%D1%8B,%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%B2%20%D0%92%D1%8B%D0­%BF%D0%BE%D0%BB%D0%BD%D0%B8%D1%82%D1%8C()%20%D0%B8%C2%A0%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B8%D1­%82%D1%8C()

Если просто относительно подхода, то я бы использовал отбор в запросе (что, конечно, имеет свои ограничения)
26. tormozit 7191 26.06.23 12:02 Сейчас в теме
(24) Запрос нельзя использовать для отбора элементов коллекций, содержащих неподдерживаемые запросом типы значений, а их очень немного. Зато можно использовать компоновку данных.
27. tormozit 7191 26.06.23 13:22 Сейчас в теме
(26) Уточнение. Типов значений, поддерживаемых запросами, очень немного. В объектной модели из значительно больше.
28. 0x00 26.06.23 16:23 Сейчас в теме
(27) Конечно, именно поэтому я и упомянул про ограничения) В моей практике запрос можно использовать в 80% случаев, что, конечно, обусловлено моей специализацией, и, скорее всего, у других это не так.
29. triviumfan 95 26.06.23 19:30 Сейчас в теме
За новизну, универсальность и смелость, однозначно, плюс.
С виду лаконичная и универсальная, но я боюсь её использовать, лучше по-старинке в цикле или запросом отберу :)
30. kser87 2452 26.06.23 20:29 Сейчас в теме
Интересная мысль. Но код делает непонятнее
dima_gsv; +1 Ответить
31. tormozit 7191 26.06.23 22:02 Сейчас в теме
(30) А лямбда-выражения в других языках делают его понятнее?
32. ubnkfl 26.06.23 23:06 Сейчас в теме
(31) Для рядового 1Сника точно не делают )). Тут еще убогость конфигуратора играет роль. После условного VS code с разноцветной подсветкой скобок и кучей плагинов для форматирования кода - вручную такие выражения городить и читать в 1С неудобно.
33. kalyaka 1085 07.07.23 11:18 Сейчас в теме
целиком весь цикл сделаем динамическим кодом
Отличная идея! Попробую в будущих версиях реализации абстрактного массива.
С абстрактным массивом код может быть такой:
Коллекция = ПолучитьСтруктуруХраненияБазыДанных();
Строки = РаботаСМассивом.АТДМассив(Коллекция)
    .Отобрать("СтрНайти(Элемент.Метаданные, 'Справочник') > 0 И СтрНайти(Элемент.Метаданные, 'ТабличнаяЧасть') > 0")
    .ВМассив()
;
Для Каждого Строка Из Строки Цикл
    Сообщить(Строка.Метаданные);
КонецЦикла;
34. tormozit 7191 21.08.23 16:11 Сейчас в теме
Еще один частый случай, где функцию эффективна - отбор только заполненных значений. Например надо отобрать только заполненные ссылки документов из колонки таблицы.
ОтобратьКоллекциюЛкс(Расходы, "ЗначениеЗаполнено(Э.Рейс)", "Рейс")
35. It-developer 24 09.11.23 14:55 Сейчас в теме
Спасибо! Отличные разработки для работы - добавлю в свой модуль работы с коллекциями.
Поменял бы названия функций.
Есть вопрос - Лкс - что означает аббревиатура?
36. It-developer 24 09.11.23 14:58 Сейчас в теме
В моей примере - обратный цикл: код с 7 строк стал 2-х строчным, но 1 из строк стала довольно длинной.
Но, как по мне, читаемость стала лучше

Было:
к  = тРезультат.Количество() - 1;
Пока к >= 0 Цикл
	Если тРезультат[к].КоличествоВРаботу / КоличествоМоделейВОдномНастиле = Цел(тРезультат[к].КоличествоВРаботу / КоличествоМоделейВОдномНастиле) Тогда
		тРезультат.Удалить(к);
	КонецЕсли;	
	к = к - 1;
КонецЦикла;	


Стало:
[1C-CODE]Строки = ОтобратьКоллекциюУсловиемЛкс(тРезультат, 
	"(Э.КоличествоВРаботу / КоличествоМоделейВОдномНастиле) <> Цел(Э.КоличествоВРаботу / КоличествоМоделейВОдномНастиле)",,
	"КоличествоМоделейВОдномНастиле" = КоличествоМоделейВОдномНастиле);
	тРезультат = тРезультат.Скопировать(Строки);
[/1C-CODE]
37. tormozit 7191 04.01.24 07:36 Сейчас в теме
Сделал в ИР контекстную подсказку для редактирования условия отбора прямо в строковом литерале. Она привязывается к имени метода https://www.hostedredmine.com/issues/977735 . Вместе с ИР адаптером для TurboConf будет работать и в конфигураторе.
Оставьте свое сообщение