Страницы: 1
RSS
Можно ли добавить в формулу отбора данных еще сортировку по значению в первой колонке источника?
 
Добрый день.

Есть старая формула, которая работает верой и правдой, и служит уже пару лет.

Она берет данные с листа t1, проверяет количество в колонке E, и если оно больше 0 - вытягивает именно эту строку в таблицу liste. Файл во вложении

Вот формула (она немного меняется в отличии от колонки и строки, можно посмотреть в файле)

Код
=IFERROR(INDEX('t1'!B:B,SMALL(IF(0<'t1'!$E$4:$E$200,ROW($E$4:$E$200)),ROW(A1))),"")

=ЕСЛИОШИБКА(ИНДЕКС('t1'!B:B;НАИМЕНЬШИЙ(ЕСЛИ(0<'t1'!$E$4:$E$200;СТРОКА($E$4:$E$200));СТРОКА(A1)));"")

Но появилась дополнительная задача, нужно не просто вытягивать данные, количество которых больше 0, а еще вытягивать их отсортированными уже по первой колонке gruppe, чтобы сначала была позиции из 1 группы, потом 2, 10, 22 и т.д.

Вопрос - можно ли это условие как-то еще "засунуть" в формулу или не получиться?

Goedenavond!
 
seggi, настраиваемая сортировка

или Power Query Вам не подходит?

Обязательно формулой?
Изменено: Maximich - 15.02.2024 13:40:50
Кто ясно мыслит, тот ясно излагает.
 
=IFERROR(INDEX('t1'!B:B;MOD(SMALL(IF(0<'t1'!$E$4:$E$200;'t1'!$B$4:$B$200+ROW($E$4:$E$200)%);ROW(A1));1)/1%+0,5);"")
По вопросам из тем форума, личку не читаю.
 
Дело в том, что список на листе  t1 формируется динамически из разных листов и стандартная сортировка не помогает. Я просто в файле-примере упростил это.

Я нашел костыль, просто создал дополнительный лист и туда кинул отсортированный через список и формулу =COPT, там правда десятки тысяч позиций и файл вырос в объеме, но работает.
Но если кто-то предложит все таки улучшенную формулу - был бы благодарен.  
Goedenavond!
 
Цитата
seggi написал:
правда десятки тысяч позиций и файл вырос в объеме, но работает.
ну вроде новые версии позволяют более простыми методами чем выше, но если по старинке, то показал, однако мое мнение, что нужно один раз вычислять индекс строки, а не несколько раз для каждого столбца.
По вопросам из тем форума, личку не читаю.
 
БМВ, спасибо, сейчас проверю

Работает  ;) , сначала ошибку выдал, но из-за ошибки переводчика формул из английского на немецкий.
Сяду как-нибудь вечером с пивом и чипсами, попытаюсь понять, как это работает.  :D  
Изменено: seggi - 15.02.2024 15:59:32
Goedenavond!
 
Спасибо все участвующим, но хочу еще раз попросить помощи клуба.

Я все сделал и проверил, все работает, но когда отдал людям в работу - выяснилась неприятная вещь. С файлом работают все через облако и все работает, но очень тормозит.

Загрузил новый файл примера. Значит есть куча отдельных листов в книге, в которых тысячи позиции, но структура одна и та же.
Колонка В - для номера группы, она меняется вручную, колонка С - номер артикула, она не меняется никогда и колонка D с количеством позиций, которая также вручную вводится.

У меня в файле примера  - эти отдельные страницы имеют имена s1, s2 , s3, s4 и s5.
Пользователи заходят на эти листы поочередно и вручную вводят количество и номер группы для тех позиций, которые имеют количество больше 0.


В конце нужно собрать на одном листе все позиции, что я сделал на отдельном листе all_lists, недолго думая простыми ссылками на диапазоны, т.к. это можно сделать в Office 365, т.е. в ячейку B2 вставляю просто формулу ='s1'!B3:D21 , смотрю, где заканчивается диапазон с листа s1 и под ним в ячейка B21 вставляю следующую ссылку на массив ='s2'!B3:D21 и так ссылки на 20 листов.  Дома у меня Excel 2019, поэтому показал просто цветами эти отдельные диапазоны.

А на листе liste  - собираю и сортирую все данные с количеством позиций больше 0 формулой БМВ.
На локальной машине все работало без проблем, а вот в облаке все тормозит очень, т.к. при каждом изменении обновляется динамические ссылки на листе all_liste на десятки тысяч ячеек.

Вопрос - какое решение может быть, чтобы избежать таких проблем?
Goedenavond!
 
seggi, первый макрос добавьте в модуль книги, второй куда угодно. Первый - автоматический перенос при изменении на общий лист, второй - перенос всех данных на общий лист.
Код
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    Dim ShOut As Worksheet, shNm$, shInd&, row&
    shNm = Sh.Name
    Set ShOut = Me.Sheets("all_lists")
    If Len(shNm) = 2 Then                   'если длина имени 2 знака
        If Asc(shNm) = 115 Then             'Asc("s") если первый символ имени "s"
            Select Case Target.Column
            Case 2 To 4                     'изменяемые столбцы 2-4
                shInd = Right(shNm, 1) - 1  'получаем индекс листа из его имени
                With Target
                  row = .row + 19 * shInd - 1
                  ShOut.Cells(row, .Column).Resize(.Rows.Count, .Columns.Count).Value = Target.Value 'копируем измененные значения на лист "all_lists"
                End With
            End Select
        End If
    End If
End Sub

Sub ПереносДанных()
    Dim i&, shInd&, row&, shNm$
    Dim rngInp As Range, rngOut As Range, Sh As Worksheet, ShOut As Worksheet
    On Error Resume Next
    
    Set ShOut = ThisWorkbook.Sheets("all_lists")
    For Each Sh In ThisWorkbook.Sheets
        shNm = Sh.Name
        If Len(shNm) = 2 Then
            If Asc(shNm) = 115 Then
                shInd = Right(shNm, 1) - 1
                row = 2 + 19 * shInd
                Set rngInp = Range(Sh.Cells(3, 2), Sh.Cells(21, 4))
                Set rngOut = Range(ShOut.Cells(row, 2), ShOut.Cells(row + 18, 4))
                rngOut.Value = rngInp.Value
                rngOut.Select
            End If
        End If
    Next
End Sub
 
Цитата
testuser написал:
макрос добавьте в модуль книги, второй куда угодно
Цитата
seggi написал:
С файлом работают все через облако и все работает, но очень тормозит.
По вопросам из тем форума, личку не читаю.
 
Значить текстовую болванку на серверь закинуть и с помощью нее осуществлять обмен данными.
Там было слово "поочерёдно" кст. Кстати у меня в первом макросе ошибка, там надо проверку на вхождение таргета в 2-21 строки.
 
testuser, огромное спасибо, но хочу сразу извиниться, проблема в том, что названия листов книг не s1...s5, а естественно разнообразные, на немецком языке, с пробелами и и прочим. Я тут подумал, может по другому это сделать. Если кто-то сможет предложить решение - огромное спасибо.

В VBA все таблицы показываються c обычным именем, который видит пользователь и внутренним именем, в немецком это Tabelle1, Tabelle2 и т.д. Я картинку приложил, что я имею в виду,  имя отмеченное синим цветом, я имею в виду.

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

Можно ли сделать такой простой макрос, который делает следующую вещь

Шаг 1.  Удаляються все данные с листа all_temp

Шаг 2.  Макрос поочередно обходит все листы, которые записаны в список в самом макросе в виде такого вот списка ВНУТРЕННИХ имен листов- (Tabelle1, Tabelle2, Tabelle3 ...)

Ищет там позиции, в которых в колонке D есть числовое значение и оно больше нуля. Количество позиций на листе всегда меньше 1000, т.ч. можно искать с D1 по D1000, не больше.

Шаг 3. Если такая позиция найдена, то эта строка копируется начиная с колонки B по колонку D (т.е.  три ячейки в строке только) на лист all_temp в конец списка

Шаг 4. Как только все листы "обойдены" и других позиций не найдено, то на листе all_temp делается сортировка всех собранных данных по колонке B, там цифры от 1 до 99, по возрастанию.

Все.



 
Goedenavond!
 
Цитата
seggi написал:
внутренним именем, в немецком это Tabelle1, Tabelle2 и т.д
Это CodeName листов, в макросе они доступны, если включен доступ к объектной модели VBE (по умолчанию отключен, т.е. для универсальности лучше не использовать в коде)
Цитата
seggi написал:
Можно ли сделать такой простой макрос, который делает следующую вещь
Вообще-то, вроде типовая задача для PQ, но у ребят наверное выходной )
Код
Sub СборДанных()
    Dim shNames(), arrInp(), arrOut()
    Dim Sh As Worksheet, ShOut As Worksheet
    Dim r1&, r2&, lr&, shInd&, shNm
    
    shNames = Array("s1", "s2", "s3", "s4") 'имена всех листов с данными
    ReDim arrOut(1 To 5000, 1 To 3)
    
    With ThisWorkbook
      For Each shNm In shNames
          With .Sheets(shNm)
            lr = .UsedRange.Rows.Count + 1
            arrInp = Range(.Cells(3, 2), .Cells(lr, 4))
          End With
          For r1 = 1 To UBound(arrInp)
              If arrInp(r1, 3) Then
                  r2 = r2 + 1
                  arrOut(r2, 1) = arrInp(r1, 1)
                  arrOut(r2, 2) = arrInp(r1, 2)
                  arrOut(r2, 3) = arrInp(r1, 3)
              End If
          Next
      Next
      Set ShOut = .Sheets("all_lists")
    End With
    
    ShOut.Range("B:D").ClearContents
    With ShOut.Range("B2:D2").Resize(r2) 'вывод данных на лист "all_lists" со второй строки
        .Value = arrOut
        .Sort Key1:=.Cells(1)
    End With
End Sub
Изменено: testuser - 19.02.2024 13:36:16
 
Пишет ошибку "13"   - "Тип не переносимым"



 
Goedenavond!
 
Попробуйте
Код
If arrInp(r1, 3) <> 0 Then

или
Код
If Len(arrInp(r1, 3))> 0 Then
 
Код
Код
If Len(arrInp(r1, 3))> 0 Then

Отработал без проблем, но он перенес в том числе строку, где было  внесено в колонку D специально ошибочно не число, а символ "e". Можно ли пожалуйста проверку сделать, чтобы проверяло - цифра ли там в колонке D и больше ли она 0?

Я изменил строку на
Код
If Len(arrInp(r1, 3)) > 0 And IsNumeric(Len(arrInp(r1, 3))) Then

Но почему-то все равно переносит строки с текстом в D, не пойму - почему  
Goedenavond!
 
Еще вариант
Код
If VarType(arrInp(r1, 3)) = 5 Then

Если будут еще ошибки, то эту проверку надо поместить внутрь вышеуказаной
 
Совместил, все работает вроде, спасибо огромное.
Код
If Len(arrInp(r1, 3)) > 0 And VarType(arrInp(r1, 3)) = 5 Then
Goedenavond!
 
А просто (динамический массив) =СОРТ(ФИЛЬТР('t1'!B4:E200;'t1'!E4:E200>0;"")) не подойдет ?
Страницы: 1
Наверх