Автофильтр с двойной петлей, это работает в Excel VBA? - PullRequest
0 голосов
/ 03 апреля 2019

У меня есть набор данных из базы данных, импортированных в файл Excel.Эти данные получены от станка для лазерной резки металла.Данные, которые у меня есть, включают в себя название материала, толщину листа и 2 разных времени (есть больше данных, но мне нужны именно эти 4).

Результат, который я хочу: сначала я хочу отфильтровать данные по имени материала,после этого я хочу отфильтровать данные о толщине пластины.В результатах этого второго фильтра я хочу СУММИТЬ время обоих временных полей и затем опубликовать результат этого на другом листе.Таким образом, результат на втором листе должен быть следующим: имя материала, толщина пластины, общее время результатов в столбце D, общее время результатов в столбце E (в других столбцах есть данные, которые для этого не важны)

Вот небольшой пример того, как выглядят данные (данные начинаются со строки 3):

Material name(col A)Plate Thickness(col B)Time1(col D)Time2(col E)
RVS 304             25mm                  00:18:14    00:21:48
RVS 304             25mm                  00:30:28    00:39:19
RVS 304             10mm                  00:12:10    00:14:25
S235                10mm                  00:48:32    00:13:33
S235                3mm                   00:10:31    00:02:22

Другая полезная информация: имя материала, на котором основан мой цикл, основано на моих результатах и ​​отфильтрованона дубликаты, поэтому название материала всегда существует.Толщина пластины имеет стандартное количество предметов, количество предметов в этом диапазоне составляет 19 разных размеров в миллиметрах.Мои списки критериев фильтрации начинаются с ячейки 2, поэтому целое число начинается с 2, а также.Результат обоих автофильтров может ничего не дать, так как не каждое имя материала соответствует разной толщине пластины.

Что-то, что можно добавить в мой текущий код: он почти выполняет свою работу, все это пропускает некоторые элементы в циклесписок названий материалов, и это не может подвести итог времени.Это также очень медленно, поэтому я хотел бы знать, смогу ли я заставить его работать быстрее.

Это мой код:

Sub TestSub()
On Error Resume Next
    Worksheets("InformatieData").ShowAllData
On Error GoTo 0
Dim iLoop As Integer

For iLoop = 1 To 20

Worksheets("InformatieData").Range("A2").AutoFilter Field:=1, Criteria1:=Worksheets("InformatieFormules").Cells(iLoop, 1).Value
If Worksheets("InformatieData").AutoFilter.Range.Columns(1).SpecialCells(xlCellTypeVisible).Count > 1 Then
    Dim mmLoop As Integer

    For mmLoop = 2 To 20
        Worksheets("InformatieData").Range("A2").AutoFilter Field:=2, Criteria1:=Worksheets("InformatieFormules").Cells(mmLoop, 2).Value
        If Worksheets("InformatieData").AutoFilter.Range.Columns(1).SpecialCells(xlCellTypeVisible).Count > 1 Then
            Worksheets("InformatieData").Range("A3:A10000,B3:B10000,D3:D10000,E3:E10000").Copy
            Worksheets("InformatieMMFilterResultaat").Cells(Cells.Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial (xlPasteValues)
        End If
    Next mmLoop
End If
Next iLoop
End Sub

1 Ответ

0 голосов
/ 03 апреля 2019

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

Option Explicit
Sub Test()

    Dim wsData  As Worksheet, wsOutput As Worksheet, arrData As Variant, SplitRange As Range, i As Long
    'You will need to check Microsoft Scripting Dictionary from your references for this to work:
    Dim DictColD As New Scripting.Dictionary, DictColE As New Scripting.Dictionary

    'Set the worksheets where we will work
    With ThisWorkbook
        Set wsData = .Sheets("InformatieData")
        Set wsOutput = .Sheets("InformatieMMFilterResultaat")
    End With

    'Fill an array with the source data
    arrData = wsData.UsedRange.Value 'this will get everything on the worksheet till the last used cell

    'Lets assume, as you said that the order and position of the columns is A to E
    For i = 2 To UBound(arrData) '2 because 1 is headers
        'if the material with the thickness doesn't exist yet, add it along with its time on column D
        If Not DictColD.Exists(arrData(i, 1) & "-" & arrData(i, 2)) Then
            DictColD.Add arrData(i, 1) & "-" & arrData(i, 2), arrData(i, 4) 'Column D value
        Else
        'If the material with the thickness already exists, then sum its time on column D
            DictColD(arrData(i, 1) & "-" & arrData(i, 2)) = DictColD(arrData(i, 1) & "-" & arrData(i, 2)) + arrData(i, 4)
        End If

        'Now the same for column E
        'if the material with the thickness doesn't exist yet, add it along with its time on column E
        If Not DictColE.Exists(arrData(i, 1) & "-" & arrData(i, 2)) Then
            DictColE.Add arrData(i, 1) & "-" & arrData(i, 2), arrData(i, 5) 'Column E value
        Else
        'If the material with the thickness already exists, then sum its time on column E
            DictColE(arrData(i, 1) & "-" & arrData(i, 2)) = DictColE(arrData(i, 1) & "-" & arrData(i, 2)) + arrData(i, 5)
        End If
    Next i

    Erase arrData

    'Now you've got 2 dictionaries along with all the data you need, you only need to throw it back to your sheet
    With wsOutput 'I'm going to assume you already have the headers there so only the data will be pasted
        .Cells(2, 1).Resize(DictColD.Count) = Application.Transpose(DictColD.Keys) 'Material & Thickness
        .Cells(2, 4).Resize(DictColD.Count) = Application.Transpose(DictColD.Items) 'Col D Times
        .Cells(2, 5).Resize(DictColE.Count) = Application.Transpose(DictColE.Items) 'Col E Times
        'Now we need to separate material & thickness into 2 columns
        Set SplitRange = .Range("A2", .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, 1))
        SplitRange.TextToColumns Destination:=SplitRange, DataType:=xlDelimited, _
        TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
        Semicolon:=False, Comma:=False, Space:=False, Other:=True, OtherChar _
        :="-", FieldInfo:=Array(Array(1, 1), Array(2, 1)), TrailingMinusNumbers:=True
    End With

End Sub

Это должно быть намного быстрее, чем ваш реальный код, так как он все работает в памяти.

...