Я новичок в Excel и его объектной модели VBA. У меня есть эта таблица (AD), отсортированная по A и B. Для каждой группы строк A-B я хочу найти значение MAX D (стоимость) и C (идентификатор продажи) этого максимального значения. Как и меньшая таблица (F1:J4). Я возился со сводной таблицей, но не смог получить Sale-ID. [Не обращайте внимания на форматирование, добавлено для удобства чтения]
В любом случае я ищу решение VBA. Я уверен, что у меня все получится, если я создам диапазон для каждой группы AB. Но как? Самое близкое, что я смог найти, это этот вопрос: Строки GroupBy и Sum с использованием нескольких столбцов в Excel, но это не дает мне значения идентификатора и кажется довольно неэлегантным.
Есть какие-нибудь указатели?
Надеюсь, этот фрагмент кода поможет.
Sub FindMaxCostForGroups()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("YOUR_WORKSHEET") ' Change to your sheet name
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim currentA As String, currentB As String
Dim maxCost As Double
Dim saleID As String
Dim outputRow As Long
outputRow = 1 ' Starting row for output, change as needed
Dim i As Long
For i = 2 To lastRow ' Assuming headers in row 1
If ws.Cells(i, 1).Value <> currentA Or ws.Cells(i, 2).Value <> currentB Then
' New group detected, output the previous group's results
If i > 2 Then
ws.Cells(outputRow, 6).Value = currentA
ws.Cells(outputRow, 7).Value = currentB
ws.Cells(outputRow, 8).Value = saleID
ws.Cells(outputRow, 9).Value = maxCost
outputRow = outputRow + 1
End If
' Initialize new group variables
currentA = ws.Cells(i, 1).Value
currentB = ws.Cells(i, 2).Value
maxCost = ws.Cells(i, 4).Value
saleID = ws.Cells(i, 3).Value
Else
' Same group, update max cost and sale ID if necessary
If ws.Cells(i, 4).Value > maxCost Then
maxCost = ws.Cells(i, 4).Value
saleID = ws.Cells(i, 3).Value
End If
End If
Next i
' Output the last group's results
ws.Cells(outputRow, 6).Value = currentA
ws.Cells(outputRow, 7).Value = currentB
ws.Cells(outputRow, 8).Value = saleID
ws.Cells(outputRow, 9).Value = maxCost
End Sub
В этом коде предполагается, что ваши данные начинаются со строки 2, а столбцы от A до D содержат ваши данные, а выходные данные начинаются со столбца F. При необходимости измените имя листа, начальную строку и ссылки на столбцы.
Как альтернатива; этот код ADO/SQL создает простую таблицу на «Листе1» без использования каких-либо циклов.
Sub Test()
Dim objConn As Object, RS As Object, strSQL As String, strArgs As String, j As Integer
Sheets("Sheet1").Range("M2:P" & Rows.Count).ClearContents
Set objConn = CreateObject("ADODB.Connection")
strArgs = "Driver = {Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)}; Readonly=False; DBQ = " & ThisWorkbook.FullName
objConn.Open strArgs
strSQL = " Select T1.[Name], T1.[Product], T1.[Sale ID], T1.[Cost] From [Sheet1$] As T1 " & _
" Left Join [Sheet1$] As T2 " & _
" On (T1.[Name]= T2.[Name] And T1.[Product]= T2.[Product] And T2.[Cost] > T1.[Cost]) Where T2.[Name] Is Null " & _
" Order By T1.[Name], T1.[Product]"
Set RS = objConn.Execute(strSQL)
Sheets("Sheet1").Range("M1:P1") = Array("Name", "Product", "Sale ID", "Cost")
Sheets("Sheet1").Range("M2").CopyFromRecordset RS
objConn.Close
Set objConn = Nothing
End Sub
УХ ТЫ. Немного перебор, нет? Ну, я думаю, это зависит от размера стола. Будет ли это работать, даже если в файле есть несохраненные изменения? Я ДОЛГО не смотрел на соединения с БД.
Я ЗНАЮ, что SQL может легко получить идентификатор из соединения. Я просто немного удивлен, что Excel-VBA не поддерживает это изначально.
Это не излишество, а скорее профессиональный подход к анализу данных.
Спасибо! Это хорошо ВЫПОЛНЯЕТ свою работу. Я вижу, что вы сделали это «трудным путем», со старым добрым расчетом. Полагаю, я мог бы добавить выходное значение COLUMN, чтобы получить нужный мне однострочный формат.