|
Проверить заполнение ячеек таблицы значений без перебора | ☑ | ||
---|---|---|---|---|
0
Dmitriy_
Kolesnikov 17.04.17
✎
18:04
|
Подскажите, как красиво решить задачу.
Есть ТЗ с большим количеством колонок (они формируются динамически, количество всегда разное) Мне надо узнать для каждой строки: заполнена ли хотя бы одна ячейка этой строки, начиная с пятой (например) колонки. Как это сделать красиво, не перебирая в цикле все колонки\ячейки подряд? Все значения типа число. |
|||
1
Любопытная
17.04.17
✎
18:10
|
А как формируются колонки?
В процессе формирования считать сумму всех ячеек по строке и отсеивать те, где сумма = 0. |
|||
2
Dmitriy_
Kolesnikov 17.04.17
✎
18:15
|
(1) сначала формируется таблица и выводится в табличное поле формы.
Потом юзер её заполняет числами. И только потом я должен проанализировать, что он там навводил. Как посчитать сумму всех ячеек по строке, начиная с пятой, не перебирая циклом все ячейки? |
|||
3
Любопытная
17.04.17
✎
18:16
|
(2) забирай ее в запрос и в запросе выкидывай строки, в которых везде нули
|
|||
4
Любопытная
17.04.17
✎
18:17
|
Только колонки должны быть типизированы для запроса
|
|||
5
youalex
17.04.17
✎
18:18
|
Можно использовать Вычислить(), но не уверен, что будет быстрее.
|
|||
6
mistеr
17.04.17
✎
18:26
|
(0) Что за аллергия на циклы? Что-то весеннее?
|
|||
7
Dmitriy_
Kolesnikov 17.04.17
✎
18:30
|
(6) некрасиво и громоздко. Почему я могу посчитать итог колонки одной строкой без цикла, но не могу посчитать итог строки?
|
|||
8
Dmitriy_
Kolesnikov 17.04.17
✎
18:35
|
(3) как мне определить в запросе, что в таблице нули во всех колонках?
|
|||
9
Dmitriy_
Kolesnikov 17.04.17
✎
18:41
|
v8: Как перебрать все значение колонок в таблице значений
Но тут тоже вложенный цикл, громоздко и некрасиво. |
|||
10
Buster007
17.04.17
✎
18:43
|
А не громоздко это как?
|
|||
11
mistеr
17.04.17
✎
18:43
|
(7) >посчитать итог колонки одной строкой без цикла
"Наивный чукотский юноша" (с) |
|||
12
Buster007
17.04.17
✎
18:44
|
+(10) 7 строк кода это громоздко?
|
|||
13
mistеr
17.04.17
✎
18:44
|
(7) Ну напиши функцию, чтоб было красиво.
|
|||
14
undertaker
17.04.17
✎
18:44
|
(2) сделать массив по количеству строк, по умолчанию там нули, в элемент массива по номеру строки при изменении в ячейке если не 0, то писать 1, потом анализировать массив
|
|||
15
lodger
17.04.17
✎
18:45
|
ха. ну подумай логически, тебе нужно от платформы узнать где что введено в таблице. угадай как она будет искать твои значения? правильно. циклом. только вот платформенные функции с ограниченными циклами во имя универсальности или заточенности под определенную задачу, типа как НайтиСтроки().
так что громозди свой Для Каждого Цикл. |
|||
16
Ildarovich
17.04.17
✎
22:45
|
Если числа в таблице - положительные, а строки - пронумерованы (ведь это табличное поле формы), то можно:
1) добавить в конец таблицы строку с нулями - образцовую незаполненную строку; 2) отсортировать ТЗ по колонкам, начиная с пятой, и далее - по колонке с номером; 3) найти номер Х образцовой строки в отсортированной таблице; 4) признаком заполненности строки будет то, что ее номер в отсортированной таблице будет больше Х. Все это можно сделать, не используя ни одного цикла. |
|||
17
Ildarovich
17.04.17
✎
22:58
|
+(16) Если числа могут быть и отрицательными, то придется добавлять ограничивающие строки и в начало и в конец таблицы. Незаполненные строки тогда окажутся между ограничивающими после соответствующей сортировки.
|
|||
18
Неверный Параметр И
18.04.17
✎
01:05
|
(2) Не хочешь циклы - пиши флаги в момент ввода. Ввел пользователь что-то в 6ю колонку, значит после 5й что-то есть.
|
|||
19
Злопчинский
18.04.17
✎
01:12
|
(18) +100
|
|||
20
skafandr
18.04.17
✎
09:25
|
(18)+500
|
|||
21
lodger
18.04.17
✎
09:45
|
(16) ни одного объявленного в коде цикла. зато неявных сразу 2 (это еще неизвестно каким образом платформа проводит сортировку по множеству колонок, может там циклы в цикле)
|
|||
22
Ildarovich
18.04.17
✎
09:53
|
+(16)+(17) Все, наверное, еще гораздо проще. Незаполненные строки легко найти отбором по структуре
СтруктураОтбора = Новый Структура("Колонка5, Колонка6, Колонка7, КолонкаИТД", 0, 0, 0, 0) А то, что предлагается делать в (18) в момент ввода значения, можно сделать по указанному отбору методом ЗаполнитьЗначения.
(21) ...это еще неизвестно... ...может там циклы в цикле... Практика показывает, что платформенная сортировка - быстрая операция. Обгоняет любой цикл. |
|||
23
Ildarovich
18.04.17
✎
10:11
|
(21) А вообще вопрос интересный. По поводу сортировки. Его можно переформулировать так: как быстрее найти минимум в колонке большой таблицы значений: через сортировку и выбор значения из первой строки отсортированной таблицы или путем обхода таблицы типа:
Для Каждого Строка Из ТЗ Цикл Х = Мин(Х, Строка.Значение)
Кто-нибудь знает ответ? |
|||
24
lodger
18.04.17
✎
10:12
|
||||
25
Ildarovich
18.04.17
✎
16:23
|
(24)+(22) В общем, эксперименты "на коллайдере" показали, что сортировка (из-за N Log N) начинает явно проигрывать циклу, начиная с таблиц размером 20 тысяч строк. Это к тому, что для небольших таблиц (а пользователь вряд-ли будет в диалоге работать с очень большой таблицей) прием из (16) вполне рабочий. Другое дело, что (22) еще лучше и проще.
Ну и более общий вывод, который можно сделать после экспериментов, что вопрос эффективности в данном случае не является актуальным: любой метод поиска пустых строк в ТЗ и с циклом и без цикла работает достаточно быстро, чтобы оператор не замечал этого времени и оптимизации не требовалось. |
|||
26
Вафель
18.04.17
✎
16:27
|
сортировка тз однако совсем не дешевая операция
|
|||
27
Dmitriy_
Kolesnikov 18.04.17
✎
20:13
|
(18) "Не хочешь циклы - пиши флаги в момент ввода. Ввел пользователь что-то в 6ю колонку, значит после 5й что-то есть" - уже плавали.
Всё хорошо, пока вы просто изменяете значения ячеек. Но как только вы начинаете добавлять и удалять строки - Элемент.ТекущаяСтрока начинает приобретать самые разные значения. То строка до удалённой, то после. И когда вы флагу в этой самой текущей строке начинаете что-то присваивать, то это не имеет отношения к реальности. &НаСервере Процедура РаспределениеСуммПоСчетамПриИзмененииНаСервере(НомерСтроки) Если НомерСтроки <> Неопределено и НомерСтроки <= (ЭтаФорма.РаспределениеСуммПоСчетам.Количество()-1) тогда ЭтаФорма.РаспределениеСуммПоСчетам[НомерСтроки].Изменена = Истина; КонецЕсли; КонецПроцедуры &НаКлиенте Процедура РаспределениеСуммПоСчетамПриИзменении(Элемент) Если Элемент.ТекущаяСтрока = Неопределено или Элемент.ТекущаяСтрока > (ЭтаФорма.РаспределениеСуммПоСчетам.Количество()-1) тогда Возврат; КонецЕсли; НомерСтроки = Элемент.ТекущаяСтрока; Если Элемент.ТекущийЭлемент.Имя <> "РаспределениеСуммПоСчетамИзменена" тогда РаспределениеСуммПоСчетамПриИзмененииНаСервере(НомерСтроки); КонецЕсли; КонецПроцедуры |
|||
28
Ildarovich
19.04.17
✎
13:13
|
Из (27) непонятно, подошел ответ из (22) или нет?
Там предлагалось сформировать структуру: ОтборНезаполненных = Новый Структура("Колонка5, Колонка6, Колонка7, ...", 0, 0, 0, ...) и находить незаполненные строки методом НезаполненныеСтроки = ТЗ.НайтиСтроки(ОтборНезаполненных) Структуру можно заполнить один раз при формировании колонок формы и хранить как переменную формы. Кажется, что это как раз то, что нужно. Или нет? |
|||
29
Dmitriy_
Kolesnikov 19.04.17
✎
18:21
|
(28) не подошел, потому что на самом деле:
1. Надо находить строки не только с нулевым значением, но и с -1. То есть либо 0, либо -1. 2. Количество колонок очень большое (около 60), и чтобы их засунуть в структуру отбора, всё равно нужен цикл. 3. Параллельно можно\нужно ещё засовывать данные в некую структуру. В итоге сделал двойной цикл. тзПИ = Новый ТаблицаЗначений; // потом добавил 4 колонки Для каждого стр из тзРППИИ цикл ДанныеЗаказа = новый Структура; ДанныеПИ.Очистить(); // СуммаПереводаБДС СчетИнкассации СуммаИнкассацииПлан СуммаИнкассацииФакт СтрокаСодержитЗначения = ложь; // если найдется хоть одно число, не равное 0 или -1, то строка заполнена Для каждого Колонка из тзРППИ.Колонки цикл Если НЕ СтрНачинаетсяС(Колонка.Имя, "СчетИнкассации") И НЕ СтрНачинаетсяС(Колонка.Имя, "СальдоСчетаИнкассации") И НЕ СтрНачинаетсяС(Колонка.Имя, "СуммаПеревода") И НЕ СтрНачинаетсяС(Колонка.Имя, "СуммаИнкассации") тогда ДанныеЗаказа.Вставить(Колонка.Имя, стр[Колонка]); Иначе //суффикс = ""; Если СтрНачинаетсяС(Колонка.Имя, "СчетИнкассации") тогда стрПИ = тзПИ.Добавить(); стрПИ.СчетИнкассации = стр[Колонка]; //если стр[Колонка] <> Справочники.БанковскиеСчетаОрганизаций.ПустаяСсылка() тогда СтрокаСодержитЗначения = Истина; КонецЕсли; ИначеЕсли СтрНачинаетсяС(Колонка.Имя, "СуммаПеревода") тогда стрПИ = тзПИ[тзПИ.Количество()-1]; стрПИ.СуммаПереводаБДС = стр[Колонка]; если стр[Колонка] <> 0 или стр[Колонка] <> -1 тогда СтрокаСодержитЗначения = Истина; КонецЕсли; ИначеЕсли СтрНачинаетсяС(Колонка.Имя, "СуммаИнкассацииП") тогда стрПИ = тзПИ[тзПИ.Количество()-1]; стрПИ.СуммаПереводаБДС = стр[Колонка]; если стр[Колонка] <> 0 или стр[Колонка] <> -1 тогда СтрокаСодержитЗначения = Истина; КонецЕсли; ИначеЕсли СтрНачинаетсяС(Колонка.Имя, "СуммаИнкассацииФ") тогда стрПИ = тзПИ[тзПИ.Количество()-1]; стрПИ.СуммаПереводаБДС = стр[Колонка]; если стр[Колонка] <> 0 или стр[Колонка] <> -1 тогда СтрокаСодержитЗначения = Истина; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; // если в строке есть значимые данные, то надо создать новый заказ или изменить имеющийся Если СтрокаСодержитЗначения тогда СоздатьИзменитьЗаказПоСтруктуреИТаблице(ДанныеЗаказа, ДанныеПИ); КонецЕсли; КонецЦикла; |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |