|
Вывод последней строки в таблице значений с условием | ☑ | ||
---|---|---|---|---|
0
Штурман
26.08.16
✎
07:58
|
Есть ТЗ:
Колонка1 Колонка2 Второе C Второе D Второе E Второе F Первое A Первое B Третье G Третье H Третье I Необходимо из этой ТЗ вывести последние строки в другую ТЗ или массив с условием, что значения первой колонки равны. Чтобы в итоге получилось такая таблица: Второе F Первое B Третье I Код такой примерно: тз = Новый ТаблицаЗначений; тз.Колонки.Добавить("Колонка1"); тз.Колонки.Добавить("Колонка2"); стр = тз.Добавить(); стр.Колонка1 = "Первое"; стр.Колонка2 = "A"; стр = тз.Добавить(); стр.Колонка1 = "Первое"; стр.Колонка2 = "B"; стр = тз.Добавить(); стр.Колонка1 = "Второе"; стр.Колонка2 = "C"; стр = тз.Добавить(); стр.Колонка1 = "Второе"; стр.Колонка2 = "D"; стр = тз.Добавить(); стр.Колонка1 = "Второе"; стр.Колонка2 = "E"; стр = тз.Добавить(); стр.Колонка1 = "Второе"; стр.Колонка2 = "F"; стр = тз.Добавить(); стр.Колонка1 = "Третье"; стр.Колонка2 = "G"; стр = тз.Добавить(); стр.Колонка1 = "Третье"; стр.Колонка2 = "H"; стр = тз.Добавить(); стр.Колонка1 = "Третье"; стр.Колонка2 = "I"; тз.Сортировать("Колонка1, Колонка2"); СтаршийИндекс = тз.Количество()-2; Для сч=0 по СтаршийИндекс цикл если тз[сч].Колонка1 = тз[сч+1].Колонка1 тогда ///////////////// конецесли; конеццикла; Подскажите, что написать вместо комментариев? |
|||
1
Рэйв
26.08.16
✎
08:05
|
До="!№#";
тз.Сортировать("Колонка1,Колонка2") Для Каждого Стр Из тз Цикл Если ДО<> "!№#" Стр.Колонка1<>ДО Тогда //Добавляем куда надо Стр.колонка1 и Стр.Колонка2 КонецЕсли; До=Стр.Колонка1; КонецЦикла; //Добавляем последний раз куда надо Стр.колонка1 и Стр.Колонка2 как то так... |
|||
2
Рэйв
26.08.16
✎
08:06
|
Обшибся немного:-) Вернее запомнаем не ДО_Колонка1 и ДоКолонка2
и их добавляем Я так давным давно итги выводил поэтому запарился по привычке:-) |
|||
3
Рэйв
26.08.16
✎
08:07
|
ну вобщем надеюсь смысл понятен:-)
|
|||
4
Горогуля
26.08.16
✎
08:24
|
группируешь по 1й выясняешь максимум номеров строк, соединяешь с исходной по номеру строки
|
|||
5
Штурман
26.08.16
✎
08:33
|
(2) не совсем понял, ДО что?
|
|||
6
Штурман
26.08.16
✎
08:33
|
(4) а если надо не совсем максимум последней колонки, а только последнее значение?
|
|||
7
Горогуля
26.08.16
✎
08:35
|
(6) вот и бери его из строки с максимальным номером
|
|||
8
Штурман
26.08.16
✎
08:37
|
(7) так метод Свернуть() только суммы вычисляет, а ты говоришь надо Максимум
Как его вычислить? |
|||
9
Горогуля
26.08.16
✎
08:41
|
(8) а соединение тебя не насторожило? я про запрос говорю
|
|||
10
Штурман
26.08.16
✎
08:45
|
(9) Зачем тз добавлять в запрос, а потом обратно в тз, неужели по-другому нельзя?
Попробовал сделать так: добавил в ТЗ еще одну колонку с именем "Максимум" код: СтаршийИндекс = тз.Количество()-2; Для сч=0 по СтаршийИндекс цикл если тз[сч].Колонка1 = тз[сч+1].Колонка1 тогда тз[сч].Максимум = сч; конецесли; конеццикла; Почему-то в результате выполнения у последних строк пропуски " " |
|||
11
Mauser
26.08.16
✎
08:48
|
Перебираешь в отсортированной табличке строки. На каждом шаге знаешь две строки - текущую и предыдущую. Если ключ в первой колонке в этих двух строках различен, то в предыдущей строке искомые данные, которые надо слить в результат.
Все. |
|||
12
Горогуля
26.08.16
✎
08:48
|
(10) не, ну можно и циклами сэмулировать то же. а зачем?
|
|||
13
Горогуля
26.08.16
✎
08:49
|
(11) сортировка похерит порядок второй колонки
|
|||
14
Mauser
26.08.16
✎
08:49
|
Хуже студентов, чессдово.
Особо в пятницу. |
|||
15
Mauser
26.08.16
✎
08:50
|
(13) а она там зачем?
|
|||
16
Штурман
26.08.16
✎
08:53
|
сделал так:
СтаршийИндекс = тз.Количество()-2; Для сч=0 по СтаршийИндекс цикл если тз[сч].Колонка1 = тз[сч+1].Колонка1 тогда тз[сч].Максимум = сч; конецесли; конеццикла; СтаршийИндекс = тз.Колонки.Количество() - 1; Индекс = тз.Количество() - 1; Пока Индекс >= 0 Цикл Для Сч = 0 По СтаршийИндекс Цикл Если ТипЗнч(тз[Индекс][Сч]) = Тип("Число") Тогда тз.Удалить(Индекс); Прервать; КонецЕсли; КонецЦикла; Индекс = Индекс - 1; КонецЦикла; как, нормально? |
|||
17
Mauser
26.08.16
✎
08:53
|
А чтобы не парится с выходом за границу добавляешь после сортировки в конец барьер - пустую строку
|
|||
18
Mauser
26.08.16
✎
08:54
|
Потом удаляешь
|
|||
19
Горогуля
26.08.16
✎
08:54
|
(15) ну ты ж предлагаешь сортирнуть и обходить
|
|||
20
Горогуля
26.08.16
✎
08:55
|
а у автора критерий последнести - максимальный номер строки
|
|||
21
Горогуля
26.08.16
✎
08:56
|
(16) нет. ибо тз.Удалить(Индекс). вчитываться не хочу
|
|||
22
Штурман
26.08.16
✎
08:56
|
(20) да, нужна самая последняя строка с учетов значения первой колонки
код из (16) вроде бы нормально все делает |
|||
23
Штурман
26.08.16
✎
08:56
|
(21) так все работает же и выводит то, что я хотел
|
|||
24
Горогуля
26.08.16
✎
08:57
|
(23) на любых входных данных?
|
|||
25
Горогуля
26.08.16
✎
08:58
|
пересунь колонку со вторым в конец, а с третьим в начало
|
|||
26
Горогуля
26.08.16
✎
08:58
|
*строку
|
|||
27
Штурман
26.08.16
✎
08:59
|
(25) так я же сортировку делаю заранее
тз.Сортировать("Колонка1, Колонка2"); |
|||
28
Горогуля
26.08.16
✎
09:02
|
тогда слушайся Маузера, если так хочется циклов. а ещё можно сразу получить таблицу нужного вида и не иметь головную мутотень с последующими сортировками и обходами
|
|||
29
Штурман
26.08.16
✎
09:07
|
(28) меня вообще-то правильный вариант интересует, типа как будет самым верным решением?
В принципе могу ТЗ засунуть в запрос, а там уже отбирать. Запросом будет правильнее? |
|||
30
Горогуля
26.08.16
✎
09:08
|
(29) красивше - однозначно. быстрее - почти наверняка. строк кода меньше - точно нет
|
|||
31
Garykom
гуру
26.08.16
✎
09:09
|
Вот и выросло поколение 1С-ников которые запросы знают лучше базовых алгоритмов программирования...
|
|||
32
Штурман
26.08.16
✎
09:11
|
(30) ок, попробую запросом
(31) так в конструкторе запроса кодинг в основном кликами мышки, в то время как алгоритмы надо думать как писать xD |
|||
33
Garykom
гуру
26.08.16
✎
09:11
|
(30) Запросом и красивше? Кому как, но тормознее это почти наверняка ибо без группировок не обойтись вместо простого одного цикла.
Сложность выше O(N) как минимум O(2N) будет с запросом. |
|||
34
Garykom
гуру
26.08.16
✎
09:12
|
(32) Чему тут думать то? Тебе же сказали в (11) как сделать!
|
|||
35
Горогуля
26.08.16
✎
09:13
|
(32) правильно! думать над запросами - признак слабоумия. писать текст запроса руками - повод для прострела коленки
|
|||
36
Горогуля
26.08.16
✎
09:14
|
(33) ты не путай сложность алгоритма со скоростью исполнения
|
|||
37
Штурман
26.08.16
✎
09:16
|
(34) я не совсем понял, что в (11) написано, т.е. мне надо таблицу обходить, проверяя равенство первой колонки и сравнивать значения второй колонки с предыдущей?
|
|||
38
Горогуля
26.08.16
✎
09:18
|
>Перебираешь в отсортированной табличке строки.
да, надо обходить >На каждом шаге знаешь две строки - текущую и предыдущую. это та, которая текущая и та, которая была перед ней > Если ключ в первой колонке в этих двух строках различен, отличаются ключи >то в предыдущей строке искомые данные, которые надо слить в результат. добавить текущую в результат |
|||
39
Рэйв
26.08.16
✎
09:21
|
||||
40
Garykom
гуру
26.08.16
✎
09:22
|
|
|||
41
Рэйв
26.08.16
✎
09:23
|
+(39) Это работающий модуль из обработки:
Процедура КнопкаВыполнитьНажатие(Кнопка) ДоКол1="ййй"; ДоКол2="ййй"; Для Каждого Стр из тз Цикл Если ДоКол1<>"ййй" Тогда Если ДоКол1<>Стр.Колонка1 Тогда Нов=тз2.Добавить(); Нов.Колонка1=ДоКол1; Нов.Колонка2=ДоКол2; КонецЕсли; КонецЕсли; ДоКол1=Стр.Колонка1; ДоКол2=Стр.Колонка2; Конеццикла; Нов=тз2.Добавить(); Нов.Колонка1=ДоКол1; Нов.Колонка2=ДоКол2; КонецПроцедуры Процедура ПриОткрытии() тз.Колонки.Добавить("Колонка1"); тз.Колонки.Добавить("Колонка2"); тз2.Колонки.Добавить("Колонка1"); тз2.Колонки.Добавить("Колонка2"); стр = тз.Добавить(); стр.Колонка1 = "Первое"; стр.Колонка2 = "A"; стр = тз.Добавить(); стр.Колонка1 = "Первое"; стр.Колонка2 = "B"; стр = тз.Добавить(); стр.Колонка1 = "Второе"; стр.Колонка2 = "C"; стр = тз.Добавить(); стр.Колонка1 = "Второе"; стр.Колонка2 = "D"; стр = тз.Добавить(); стр.Колонка1 = "Второе"; стр.Колонка2 = "E"; стр = тз.Добавить(); стр.Колонка1 = "Второе"; стр.Колонка2 = "F"; стр = тз.Добавить(); стр.Колонка1 = "Третье"; стр.Колонка2 = "G"; стр = тз.Добавить(); стр.Колонка1 = "Третье"; стр.Колонка2 = "H"; стр = тз.Добавить(); стр.Колонка1 = "Третье"; стр.Колонка2 = "I"; тз.Сортировать("Колонка1, Колонка2"); Элементыформы.тз.СоздатьКолонки(); Элементыформы.тз2.СоздатьКолонки(); КонецПроцедуры |
|||
42
Garykom
гуру
26.08.16
✎
09:24
|
(36) Не путаю но кто то написал "быстрее - почти наверняка" как оно будет быстрее запросом то?
|
|||
43
Горогуля
26.08.16
✎
09:25
|
(42) запросом оно будет быстрее. наверняка
|
|||
44
Штурман
26.08.16
✎
09:28
|
в общем, всем спасибо :)
|
|||
45
Garykom
гуру
26.08.16
✎
09:29
|
(43) Как хорошо... что пока есть такие всегда работа будет )) Такие кто выучил "запросы всегда быстрее" и все, дальше теорию изучать и практику не хочет )))
|
|||
46
Горогуля
26.08.16
✎
09:29
|
(45) всегда - это ты сам придумал
|
|||
47
Штурман
26.08.16
✎
09:30
|
(45) так почти везде в коде конфигураций 1с большей частью запросы, а вот всяких тз, массивов и тд не особо много
|
|||
48
Garykom
гуру
26.08.16
✎
09:32
|
(46) Готов поспорить на пиво что данная задачка будет быстрее на любых объемах быстрее "не запросами".
Если сравнивать на одном железе и одних данных, именно таких как приведены т.е. "простые строки". |
|||
49
Штурман
26.08.16
✎
09:33
|
Кстати, вот вроде неплохая статейка о работе в 1с с универсальными коллекциями:
http://курсы-по-1с.рф/articles/работа-с-универсальными-коллекциями/ |
|||
50
Горогуля
26.08.16
✎
09:33
|
(48) спорить я с тобой не собираюсь, репутацией не вышел ;)
|
|||
51
Garykom
гуру
26.08.16
✎
09:36
|
(50) Не понял только кто не вышел репутацией ))
Суть что если ТЗ сильно большая то только передача данных внутрь запроса в ВТ займет дофига времени как и получение данных из запроса. Но вот если исходные данные уже лежат в БД то логично использовать именно запросы для скорости получения данных, особенно если результат в ту же БД назад засунуть нуна. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |