Дубликаты неровных массивов VBA

#arrays #excel #vba #duplicates #jagged-arrays

#массивы #excel #vba #дубликаты #неровные массивы

Вопрос:

Я новичок в программировании с помощью VBA и начинающий программист в целом. У меня есть следующая простая таблица (данные продолжают вводиться ежедневно, поэтому они меняются):

Элемент # Описание Дата Расположение Табличка Загрузить Тип Оценить Стоимость
0001 des1 30/1/21 Сайт ABC123 5 Один тип1 100
0002 des2 30/1/21 Офис ACB465 4 Один тип1 100
0003 des3 30/1/21 Офис ABC789 3 Один тип1 100
0004 des4 30/1/21 Сайт ABS741 5 Один тип1 100
0005 des4 31/1/21 Офис ABC852 2 Один тип1 100

Сначала я хотел бы отфильтровать эти данные по определенной дате, затем удалить дубликаты в местоположении при добавлении нагрузки для указанных дубликатов.

Например, если бы я хотел отфильтровать 30/1/21. В конечном итоге это будет выглядеть следующим образом:

Расположение Загрузить
Сайт 10
Офис 7

Затем я хотел бы поместить его в одну итоговую ячейку следующим образом:

Краткие сведения
10 Сайт, 7 Офис

Я смог отфильтровать исходную таблицу в неровные массивы. Код для этого:

 For j = numberSkipD To numberRowsD
    If Worksheets("Disposal Fees").Range("F" amp; j).Value = Worksheets("Daily Tracking").Range("B2").Value Then
        For k = numberDisposalInformationRaw To numberDisposalLocation
            ReDim Preserve disposalLocation(numberDisposalLocation)
            disposalLocation(numberDisposalLocation) = Worksheets("Disposal Fees").Range("I" amp; j).Value
 
        Next
        numberDisposalLocation = numberDisposalLocation   1
 
        For k = numberDisposalInformationRaw To numberDisposalLoad
            ReDim Preserve disposalLoad(numberDisposalLoad)
            disposalLoad(numberDisposalLoad) = Worksheets("Disposal Fees").Range("K" amp; j).Value
        Next
        numberDisposalLoad = numberDisposalLoad   1
    End If
Next
 

Затем я попытался выполнить вторую таблицу выше (удалив дубликаты и добавив значения для указанных дубликатов вместе), но это выдает мне ошибки, не уверен, как их решить. Я знаю, что это ошибки индекса, но не знаю, как их исправить. (Пожалуйста, помогите мне с этой частью, вот код)

 Dim disposalInformationRaw As Variant
    Dim disposalInformationCooked As Variant
    Dim FoundIndex As Variant, MaxRow As Long, m As Long
        
    ReDim disposalInformationCooked(1 To UBound(disposalInformationRaw, 1), 1 To UBound(disposalInformationRaw, 2))
    
    MaxRow = 0
    For m = 1 To UBound(disposalInformationRaw, 1)
        FoundIndex = Application.Match(disposalInformationRaw(m, 1), Application.Index(disposalInformationCooked, 0, 1), 0)

        If IsError(FoundIndex) Then
            MaxRow = MaxRow   1
            FoundIndex = MaxRow
            disposalInformationCooked(FoundIndex, 1) = disposalInformationRaw(m, 1)
        End If

        disposalInformationCooked(FoundIndex, 2) = Val(disposalInformationCooked(FoundIndex, 2))   Val(disposalInformationRaw(i, 2))
    Next m
    
    Range("G1").Resize(MaxRow, UBound(disposalInformationCooked, 2)).Value = disposalInformationCooked
 

Я не думаю, что у меня возникнут большие проблемы с завершением третьей части (резюме), но если вы знаете, как это сделать, пожалуйста, не стесняйтесь поделиться тем, как бы вы к этому подошли. В основном мне нужна помощь со второй частью. Я был бы более чем счастлив отредактировать и предоставить дополнительную информацию, если это необходимо. Заранее спасибо.

Комментарии:

1. Вам нужна вторая таблица или просто итоговое резюме?

2. Мне нужно получить окончательное резюме. Может быть, есть лучший способ приблизиться к этому, чем то, что я сделал, но я не уверен.

Ответ №1:

Вот один из подходов с использованием словаря.

 dim dict, rw as range, locn, k, msg, theDate

set dict= createobject("scripting.dictionary")

theDate = Worksheets("Daily Tracking").Range("B2").Value

'adjust table range as required
for each rw in worksheets("Disposal Fees").range("F6:K100").rows
   if rw.cells(3).Value = theDate Then              'date match?
       locn = rw.cells(4).Value                     'read location
       dict(locn) = dict(locn)   rw.cells(6).Value  'add load to sum
   end if
next rw

'loop over the dictionary keys and build the output
for each k in dict
    msg = msg amp; IIf(len(msg) > 0, ", ", "") amp; dict(k) amp; " " amp; k
next k

debug.print msg 
 

Комментарии:

1.Я думаю, что это правильно, но я думаю, что я неправильно заполняю пробелы, которые я заполнил следующим образом, и получаю некоторые ошибки: [table range here как « worksheets («Утилизационные сборы»).range(«F6: K») « [location col] как worksheets("Disposal Fees").range("I6:I") [load col] как worksheets("Disposal Fees").range("K6:I") Рабочий лист, который я использую в качестве ссылки для этого, называется «Плата за утилизацию». Столбцы: F: дата I: Местоположение K: Загрузка

2. Для rw.cells([here]) просто поместите номер столбца в строку

Ответ №2:

Сумма уникальна

Плата за удаление

введите описание изображения здесь

Ежедневное отслеживание

введите описание изображения здесь

  • Отрегулируйте значения в разделе константы.

Код

 Option Explicit

Sub TESTsumByValue()
    
    ' Source
    Const srcName As String = "Disposal Fees"
    Const lCol As Long = 3
    Const kCol As Long = 4
    Const sCol As Long = 6
    Const SumFirst As Boolean = True
    Const KSDel As String = ":"
    Const IDel As String = ", "
    ' Destination
    Const dstName As String = "Daily Tracking"
    ' Define workbook.
    Dim wb As Workbook: Set wb = ThisWorkbook ' Workbook containing this code.
    
    ' Define Source Range (You may have to do something different).
    Dim srg As Range: Set srg = wb.Worksheets(srcName).Range("A1").CurrentRegion
    
    ' Write Criteria to variable.
    Dim drg As Range: Set drg = wb.Worksheets(dstName).Range("B2")
    Dim Criteria As Variant: Criteria = drg.Value
    
    ' Use function to get the result.
    Dim s As String
    s = sumByValue(Criteria, srg, lCol, kCol, sCol, SumFirst, KSDel, IDel)
    Debug.Print s ' "10:Site, 4:Bathroom, 4:Office"
    
    drg.Offset(, 3).Value = s ' writes to 'E2'
    
End Sub

Function sumByValue( _
    ByVal LookupValue As Variant, _
    rng As Range, _
    ByVal LookupColumn As Long, _
    ByVal KeyColumn As Long, _
    ByVal SumColumn As Long, _
    Optional ByVal SumFirst As Boolean = False, _
    Optional ByVal KeySumDelimiter As String = ": ", _
    Optional ByVal ItemsDelimiter As String = ", ") _
As String
    
    ' Validate range ('rng').
    If rng Is Nothing Then Exit Function
    
    ' Write values from range to Data Array ('Data').
    Dim Data As Variant: Data = rng.Value ' 2D one-based array
    
    ' Declare additional variables.
    Dim vKey As Variant ' Current Key Value
    Dim vSum As Variant ' Current Sum Value
    Dim i As Long ' Data Array Row Counter
    
    ' Create a reference to Unique Sum Dictionary (no variable).
    With CreateObject("Scripting.Dictionary")
        .CompareMode = vbTextCompare ' 'A = a'
        
        ' Loop through Data Array ('Data') and write and sumup unique values
        ' to Unique Sum Dictionary.
        For i = 1 To UBound(Data, 1)
            If Data(i, LookupColumn) = LookupValue Then
                vKey = Data(i, KeyColumn)
                If Not IsError(vKey) Then
                    If Len(vKey) > 0 Then
                        vSum = Data(i, SumColumn)
                        If IsNumeric(vSum) Then
                            .Item(vKey) = .Item(vKey)   vSum
                        Else
                            .Item(vKey) = .Item(vKey)   0
                        End If
                    End If
                End If
            End If
        Next i
        
        ' Validate Unique Sum Dictionary.
        If .Count = 0 Then Exit Function
        
        ' Redefine variables to be reused.
        ReDim Data(1 To .Count) ' Result Array: 1D one-based array
        i = 0 ' Result Array Elements Counter
        
        ' Write results to Result Array.
        If SumFirst Then
            For Each vKey In .Keys
                i = i   1
                Data(i) = .Item(vKey) amp; KeySumDelimiter amp; vKey
            Next vKey
        Else
            For Each vKey In .Keys
                i = i   1
                Data(i) = vKey amp; KeySumDelimiter amp; .Item(vKey)
            Next vKey
        End If
    
    End With
    
    ' Write the elements of Data Array to Result String.
    sumByValue = Join(Data, ItemsDelimiter)

End Function