Страницы: 1
RSS
Обьединение нескольких списков без дубликатов с изменением перечня наименований в один по названию
 
Добрый день!

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

Ситуация следующая
Есть несколько (условно, 10) наборов, в которых прописаны наименования и количество. Позиции в этих наборах могут повторяться с разным количеством. Написание наименований может отличаться от набора к набору, без изменения сути. Вручную был создан список нормализованных названий.
Далее нам дается перечень этих наборов, объединенных в группы, которые нужно вытащить на отдельные листы.
Одна группа может объединять в себя несколько наборов.

В итоге необходимо объединить перечень позиций из имеющихся наборов в соответствии с присланным перечнем групп, без дубликатов позиций, с максимальным из всех наборов в группе количеством (если в одном наборе 4 чашки, а во втором 9, то пишем в итоговую группу 1 раз позицию "чашки" с количеством 9).

Для примера сформировала файл, во вложении.

С VBA пока не дружу, поэтому сейчас хотела бы реализовать эту задачу в рамках возможностей эксель до программирования, если это возможно.
Буду безмерна благодарна за идеи реализации этой задачи.
Спасибо!
Изменено: vikttur - 23.06.2021 16:12:03
 
На случай, если подружитесь с VBA
Код
Option Explicit

Dim wb As Workbook
Dim brr As Variant
Dim dic As Object
    
Sub Main()
    Dim arr As Variant
    arr = ActiveSheet.Range("A13:B35")
    brr = ActiveSheet.Range("A1:Q8")
    
    Set dic = CreateObject("Scripting.Dictionary")
    
    Dim y As Long
    For y = 1 To UBound(arr, 1)
        dic.Item(arr(y, 1)) = arr(y, 2)
    Next
    
    Set wb = Workbooks.Add(1)
    
    FormSet 2, 4
    FormSet 6
    FormSet 3, 1
    
    If wb.Sheets.Count > 1 Then
        Application.DisplayAlerts = False
        wb.Sheets(1).Delete
        Application.DisplayAlerts = True
    End If
    
    wb.Saved = True
    'wb.Close False
End Sub

Sub FormSet(ParamArray arr())
    Dim v As Variant
    Dim crr As Variant
    Dim diA As Object: Set diA = CreateObject("Scripting.Dictionary")
    diA.Item("Наименов.") = "Кол-во"
    Dim y As Long
    Dim x As Integer
    Dim s As String
    
    For Each v In arr
        x = 3 * (v - 1) + 1
        If x <= UBound(brr, 2) Then
            s = s & brr(1, x) & ", "
            For y = 3 To UBound(brr, 1)
                If brr(y, x) <> "" Then
                    If dic.Exists(brr(y, x)) Then
                        brr(y, x) = dic.Item(brr(y, x))
                    End If
                    If diA.Exists(brr(y, x)) Then
                        If diA.Item(brr(y, x)) < brr(y, x + 1) Then
                            diA.Item(brr(y, x)) = brr(y, x + 1)
                        End If
                    Else
                        diA.Item(brr(y, x)) = brr(y, x + 1)
                    End If
                End If
            Next
        End If
    Next
    s = Left(s, Len(s) - 2)
    
    Dim sh As Worksheet
    Set sh = wb.Sheets.Add(after:=wb.Sheets(wb.Sheets.Count))
    On Error Resume Next
    sh.Name = s
    On Error GoTo 0
    
    With sh.Cells(1, 1)
        .Cells(1, 1).Resize(diA.Count, 1) = Application.Transpose(diA.Keys())
        .Cells(1, 2).Resize(diA.Count, 1) = Application.Transpose(diA.Items())
    End With
End Sub
 
Как раз собираюсь подружиться в ближайший месяц:) К сожалению, решение этой задачи столько не ждет. Придется пока грубо, некрасиво, через ВПР и руками. А как только разберусь, буду переделывать уже по человечески. Так что огромное Вам спасибо! Совсем скоро очень пригодится!
 
если бы не разные написания то сводная справилась бы.
 
Да, скорее всего, попробую подтянуть ручной нормализованный список через впр к базовому и дальше сводной.
Если бы не 800 наименований, совсем хорошо было бы:)
Страницы: 1
Наверх