4

Существует отчет, который я извлекаю из нашей системы ERP, в котором перечислены подробности заказа. В нем будет указан номер заказа, код клиента, имя клиента, дата заказа, статус заказа, общая сумма заказа, код продукта, название продукта и количество заказанных, цена за единицу и расширенная цена. Если заказ имеет несколько строк, то информация заголовка указана несколько раз.

Вот как выглядят необработанные данные. OrderReportUnformatted

Я пытаюсь найти способ в Excel, чтобы предотвратить повторение строк заголовка для каждой строки строки детализации.

Я бы предпочел, чтобы данные выглядели так, когда я закончу. В основном каждая из строк повторяется под соответствующими строками заголовка. OrderReportFormatted1

Другой приемлемый формат может быть ниже. Я думаю, что это может быть проще. Я смог сделать это с помощью сводной таблицы.

Я не уверен, если это потребует VBA или нет. Я попытался выделить строки и использовать удаление дубликатов, но это сдвигает все строки вместе. Любая помощь будет принята с благодарностью.

3 ответа3

2

Я знаю, что это осуждается, но проблема звучит интересно, поэтому я просто написал VBA


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

Function CompressReport()

    'Settings for which columns are the header and details
    Const fHC As Long = 1   'First header column number
    Const lHC As Long = 6   'Last header column number
    Const fDC As Long = 7   'First detail column number
    Const lDC As Long = 11  'Last detail column number

    'Declarations
    Dim rStart&, rStop&, rNew As Long
    Dim r&, c As Long
    Dim ws As Worksheet
    Dim wsNew As Worksheet
    Dim s1$, s2 As String

    'Set the source worksheet to be compressed
    '(Here are a few methods to do this. Pick one.)
    Set ws = Sheet1
    Set ws = Worksheets(1)
    Set ws = Worksheets("Sheet1")

    'Add a new worksheet for our results
    Set wsNew = Worksheets.Add(After:=ws)

    With ws
        'Copy the first row of headers
        .Range(.Cells(1, fHC), .Cells(1, lHC)).Copy wsNew.Cells(1, 1)
        rNew = 2

        'Loop through all the rows
        For rStart = 2 To ws.UsedRange.Rows.Count

            'Copy the header information
            .Range(.Cells(rStart, fHC), .Cells(rStart, lHC)).Copy wsNew.Cells(rNew, 1)

            'Add a thick border (This wasn't in the OP but I recommend it)
            With wsNew.Range(wsNew.Cells(rNew, 1), wsNew.Cells(rNew, lHC - fHC + 1)).Borders(xlEdgeTop)
                .LineStyle = xlContinuous   'You could also try xlDouble
                .Weight = xlThick
            End With

            'Collect the header information into a single unique ID
            s1 = ""
            For c = fHC To lHC
                s1 = s1 & "|" & .Cells(rStart, c).Value
            Next

            'Find the next row with different information
            For rStop = rStart + 1 To .UsedRange.Rows.Count
                s2 = ""
                For c = fHC To lHC
                    s2 = s2 & "|" & .Cells(rStop, c).Value
                Next
                If s2 <> s1 Then Exit For
            Next
            rStop = rStop - 1

            'Copy the detail headers and information
            .Range(.Cells(1, fDC), .Cells(1, lDC)).Copy wsNew.Cells(rNew + 1, 2)
            .Range(.Cells(rStart, fDC), .Cells(rStop, lDC)).Copy wsNew.Cells(rNew + 2, 2)

            'Increase the row we're pasting in the new worksheet
            ' +1 for header data, +1 for detail headers, +n for detail information
            rNew = rNew + 1 + 1 + (rStop - rStart + 1)

            'Increase the row we're copying in the source worksheet
            rStart = rStop  'The FOR loop will iterate it +1

        Next

    End With

    'Formatting (feel free to add to this part)
    With wsNew
        .Columns.AutoFit
    End With

    'Cleanup
    Set wsNew = Nothing
    Set ws = Nothing

End Function
0

я кладу

                        Данные CSV в уценке; нажмите «Изменить» для доступа

в Sheet1, и я смог заставить Sheet2 выглядеть так:

Он использует два вспомогательных столбца, которые, конечно, вы можете перемещать вправо так далеко, как вам нужно (или нужно), и которые вы можете скрыть.

  • Установите A1 (на листе 2) на =Sheet1!A1 и перетащите вправо, чтобы покрыть столбцы, которые в противном случае дублировались бы в нескольких строках.  В вашем примере это будет столбец F (В моем примере это столбец C)
  • Установите Y2 на 2 и Z2 на 1 .  Значение в столбце Y указывает, из какой строки Sheet1 эта строка извлекает данные.  Столбец Z равен 1 если это строка заголовка (извлечение данных из левых столбцов Sheet1; т. Е. Ключевых полей), 2 если это строка подзаголовка, 3 если это строка подзаголовка (получение данных из правые столбцы Sheet1) и 0 если это пустая строка (ниже последней строки данных).
  • Установите для A2 значение =IF($Z2=1, INDEX(Sheet1!A:A, $Y2), "") .  Если применимо, перетащите вправо, чтобы покрыть столбцы, которые используются только для ключевых данных.  В вашем примере это не применимо, потому что у вас есть неключевые данные, начиная с столбца B (В моем примере это через столбец B)  Это реализует определения вспомогательных столбцов: если Z равен 1 , извлеките данные ключа из Sheet1, в противном случае оставьте пустым.
  • В моем примере я установил C2 на

    =CHOOSE($Z2+1, "", INDEX(Sheet1!C:C, $Y2), Sheet1!D$1, INDEX(Sheet1!D:D, $Y2))
    

    В вашем примере вы должны установить B2 на

    =CHOOSE($Z2+1, "", INDEX(Sheet1!B:B, $Y2), Sheet1!G$1, INDEX(Sheet1!G:G, $Y2))
    

    отражая два столбца Sheet1, из которых может извлекаться столбец Sheet2 B :

    • Столбец B («Код Cust») или
    • Колонка G («Код продукта»)

    Опять же, это просто делает то, что говорят вспомогательные столбцы.  Мы добавляем 1 к значению Z для отображения 0 , 1 , 2 и 3 к 1 , 2 , 3 и 4CHOOSE использует первый аргумент для индексации следующих аргументов, поэтому

    • Если Z равно 0 , пусто,
    • Если Z равен 1 , получить данные ключа,
    • Если Z равен 2 , получите заголовок из строки 1 листа 1 и
    • Если Z равен 3 , получить неключевые данные.
  • Установите Y3 в =IF($Z2<3, $Y2, $Y2+1) и Z3 в

    =IF($Z2=0, 0, IF($Z2<3, $Z2+1, IF(INDEX(Sheet1!A:A,$Y2+1)="", 0,
                        IF(INDEX(Sheet1!A:A,$Y2)=INDEX(Sheet1!A:A,$Y2+1), 3, 1))))
    

    (все в одной строке).  Они говорят, что если значение Z в предыдущей строке равно 1 или 2 (или 0), установите это значение Y равным значению предыдущей строки.  Это связано с тем, что каждая строка в вашей таблице базы данных (каждый набор уникальных значений в столбцах A - F на Sheet1) приводит к минимуму трем строкам на Sheet2.  В противном случае увеличьте значение Y , чтобы обратиться к следующей строке на Sheet1.

    Если предыдущее значение Z равно 0 , мы закончили и заполнили нулями.  Если предыдущее значение Z равно 1 или 2 , перейдите к следующему значению.  В противном случае посмотрите на данные ключа Sheet1.  Если оно пустое, предположим, что мы находимся в конце данных и установите Z в 0 .  Если это так же, как в предыдущем ряду, используйте 3 чтобы продолжить то, что мы делаем.  В противном случае мы получим новый набор уникальных значений, поэтому перезапустите цикл с 1 .

  • Перетащите вниз достаточно далеко, чтобы получить все свои данные.

Если ваши уникальные значения не являются индивидуально уникальными (например, если у вас может быть A4 = A5 но B4B5), разверните тесты в столбце Z чтобы проверить столько столбцов, сколько вам нужно (комбинируя их с AND(…)).

Очевидно, что я использовал условное форматирование с формулой =$Z2=2 , чтобы соответствующим образом отформатировать подзаголовки.

0

Вот маленький трюк для достижения вашей цели. Может применяться к ячейкам в любом столбце. Скажем, мы начнем с:

И мы хотим , чтобы не видеть все дополнительные Майка с, т.д.Мы нажмите на ячейку A2 и применить условное форматирование , так что если значение ячейки такой же , как в клетке над ним, чтобы сделать цвет шрифта так же , как цвет фона ячейки:

Затем мы копируем ячейку A2 и PasteSpecialFormats вниз по столбцу. Это "скрывает" повторяющиеся значения:

Фактические данные остались нетронутыми, изменился только дисплей!

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .