#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