Вход | Регистрация


1С:Предприятие ::

Метки: 

Проверить заполнение ячеек таблицы значений без перебора

Я
   Dmitriy_ Kolesnikov
 
17.04.17 - 18:04
Подскажите, как красиво решить задачу.
Есть ТЗ с большим количеством колонок (они формируются динамически, количество всегда разное)
Мне надо узнать для каждой строки: заполнена ли хотя бы одна ячейка этой строки, начиная с пятой (например) колонки.
Как это сделать красиво, не перебирая в цикле все колонки\ячейки подряд?
Все значения типа число.
 
 
   Любопытная
 
1 - 17.04.17 - 18:10
А как формируются колонки?
В процессе формирования считать сумму всех ячеек по строке и отсеивать те, где сумма = 0.
   Dmitriy_ Kolesnikov
 
2 - 17.04.17 - 18:15
(1) сначала формируется таблица и выводится в табличное поле формы.
Потом юзер её заполняет числами.
И только потом я должен проанализировать, что он там навводил.

Как посчитать сумму всех ячеек по строке, начиная с пятой, не перебирая циклом все ячейки?
   Любопытная
 
3 - 17.04.17 - 18:16
(2) забирай ее в запрос и в запросе выкидывай строки, в которых везде нули
   Любопытная
 
4 - 17.04.17 - 18:17
Только колонки должны быть типизированы для запроса
   youalex
 
5 - 17.04.17 - 18:18
Можно использовать Вычислить(), но не уверен, что будет быстрее.
   mistеr
 
6 - 17.04.17 - 18:26
(0) Что за аллергия на циклы? Что-то весеннее?
   Dmitriy_ Kolesnikov
 
7 - 17.04.17 - 18:30
(6) некрасиво и громоздко. Почему я могу посчитать итог колонки одной строкой без цикла, но не могу посчитать итог строки?
   Dmitriy_ Kolesnikov
 
8 - 17.04.17 - 18:35
(3) как мне определить в запросе, что в таблице нули во всех колонках?
   Dmitriy_ Kolesnikov
 
9 - 17.04.17 - 18:41
v8: Как перебрать все значение колонок в таблице значений
Но тут тоже вложенный цикл, громоздко и некрасиво.
   Buster007
 
10 - 17.04.17 - 18:43
А не громоздко это как?
 
  Рекламное место пустует
   mistеr
 
11 - 17.04.17 - 18:43
(7) >посчитать итог колонки одной строкой без цикла

"Наивный чукотский юноша" (с)
   Buster007
 
12 - 17.04.17 - 18:44
+(10) 7 строк кода это громоздко?
   mistеr
 
13 - 17.04.17 - 18:44
(7) Ну напиши функцию, чтоб было красиво.
   undertaker
 
14 - 17.04.17 - 18:44
(2) сделать массив по количеству строк, по умолчанию там нули, в элемент массива по номеру строки при изменении в ячейке если не 0, то писать 1, потом анализировать массив
   lodger
 
15 - 17.04.17 - 18:45
ха. ну подумай логически, тебе нужно от платформы узнать где что введено в таблице. угадай как она будет искать твои значения? правильно. циклом. только вот платформенные функции с ограниченными циклами во имя универсальности или заточенности под определенную задачу, типа как НайтиСтроки().
так что громозди свой Для Каждого Цикл.
   Ildarovich
 
16 - 17.04.17 - 22:45
Если числа в таблице - положительные, а строки - пронумерованы (ведь это табличное поле формы), то можно:
1) добавить в конец таблицы строку с нулями - образцовую незаполненную строку;
2) отсортировать ТЗ по колонкам, начиная с пятой, и далее -  по колонке с номером;
3) найти номер Х образцовой строки в отсортированной таблице;
4) признаком заполненности строки будет то, что ее номер в отсортированной таблице будет больше Х.
Все это можно сделать, не используя ни одного цикла.
   Ildarovich
 
17 - 17.04.17 - 22:58
+(16) Если числа могут быть и отрицательными, то придется добавлять ограничивающие строки и в начало и в конец таблицы. Незаполненные строки тогда окажутся между ограничивающими после соответствующей сортировки.
   Неверный Параметр И
 
18 - 18.04.17 - 01:05
(2) Не хочешь циклы - пиши флаги в момент ввода. Ввел пользователь что-то в 6ю колонку, значит после 5й что-то есть.
   Злопчинский
 
19 - 18.04.17 - 01:12
(18) +100
   skafandr
 
20 - 18.04.17 - 09:25
(18)+500
   lodger
 
21 - 18.04.17 - 09:45
(16) ни одного объявленного в коде цикла. зато неявных сразу 2 (это еще неизвестно каким образом платформа проводит сортировку по множеству колонок, может там циклы в цикле)
   Ildarovich
 
22 - 18.04.17 - 09:53
+(16)+(17) Все, наверное, еще гораздо проще. Незаполненные строки легко найти отбором по структуре
СтруктураОтбора = Новый Структура("Колонка5, Колонка6, Колонка7, КолонкаИТД", 0, 0, 0, 0)
А то, что предлагается делать в (18) в момент ввода значения, можно сделать по указанному отбору методом ЗаполнитьЗначения.

(21) ...это еще неизвестно... ...может там циклы в цикле...

Практика показывает, что платформенная сортировка - быстрая операция. Обгоняет любой цикл.
   Ildarovich
 
23 - 18.04.17 - 10:11
(21) А вообще вопрос интересный. По поводу сортировки. Его можно переформулировать так: как быстрее найти минимум в колонке большой таблицы значений: через сортировку и выбор значения из первой строки отсортированной таблицы или путем обхода таблицы типа:
Для Каждого Строка Из ТЗ Цикл Х = Мин(Х, Строка.Значение) 
КонецЦикла
Кто-нибудь знает ответ?
   lodger
 
24 - 18.04.17 - 10:12
   Ildarovich
 
25 - 18.04.17 - 16:23
(24)+(22) В общем, эксперименты "на коллайдере" показали, что сортировка (из-за N Log N) начинает явно проигрывать циклу, начиная с таблиц размером 20 тысяч строк. Это к тому, что для небольших таблиц (а пользователь вряд-ли будет в диалоге работать с очень большой таблицей) прием из (16) вполне рабочий. Другое дело, что (22) еще лучше и проще.

Ну и более общий вывод, который можно сделать после экспериментов, что вопрос эффективности в данном случае не является актуальным: любой метод поиска пустых строк в ТЗ и с циклом и без цикла работает достаточно быстро, чтобы оператор не замечал этого времени и оптимизации не требовалось.
   Вафель
 
26 - 18.04.17 - 16:27
сортировка тз однако совсем не дешевая операция
   Dmitriy_ Kolesnikov
 
27 - 18.04.17 - 20:13
(18) "Не хочешь циклы - пиши флаги в момент ввода. Ввел пользователь что-то в 6ю колонку, значит после 5й что-то есть" - уже плавали.
Всё хорошо, пока вы просто изменяете значения ячеек.
Но как только вы начинаете добавлять и удалять строки - Элемент.ТекущаяСтрока начинает приобретать самые разные значения. То строка до удалённой, то после. И когда вы флагу в этой самой текущей строке начинаете что-то присваивать, то это не имеет отношения к реальности.

&НаСервере
Процедура РаспределениеСуммПоСчетамПриИзмененииНаСервере(НомерСтроки)
    Если НомерСтроки <> Неопределено  и НомерСтроки <= (ЭтаФорма.РаспределениеСуммПоСчетам.Количество()-1) тогда
        ЭтаФорма.РаспределениеСуммПоСчетам[НомерСтроки].Изменена = Истина;
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура РаспределениеСуммПоСчетамПриИзменении(Элемент)
    Если Элемент.ТекущаяСтрока = Неопределено или Элемент.ТекущаяСтрока > (ЭтаФорма.РаспределениеСуммПоСчетам.Количество()-1) тогда 
        Возврат;
    КонецЕсли;
    НомерСтроки = Элемент.ТекущаяСтрока;
    Если Элемент.ТекущийЭлемент.Имя <> "РаспределениеСуммПоСчетамИзменена" тогда
        РаспределениеСуммПоСчетамПриИзмененииНаСервере(НомерСтроки);
    КонецЕсли;
КонецПроцедуры
   Ildarovich
 
28 - 19.04.17 - 13:13
Из (27) непонятно, подошел ответ из (22) или нет?

Там предлагалось сформировать структуру:
ОтборНезаполненных = Новый Структура("Колонка5, Колонка6, Колонка7, ...", 0, 0, 0, ...)
и находить незаполненные строки методом
НезаполненныеСтроки = ТЗ.НайтиСтроки(ОтборНезаполненных)
Структуру можно заполнить один раз при формировании колонок формы и хранить как переменную формы. Кажется, что это как раз то, что нужно. Или нет?
   Dmitriy_ Kolesnikov
 
29 - 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 тогда СтрокаСодержитЗначения = Истина; КонецЕсли;
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;
        // если в строке есть значимые данные, то надо создать новый заказ или изменить имеющийся

        Если СтрокаСодержитЗначения тогда
            СоздатьИзменитьЗаказПоСтруктуреИТаблице(ДанныеЗаказа, ДанныеПИ);    
        КонецЕсли;
    КонецЦикла;



Список тем форума
Рекламное место пустует   Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует