10

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

Я застрял со строкой для клиента 1 для значения A в 2009 году и отдельной строкой для значения B для того же клиента в том же году.

В некоторых случаях нет значения A или значения B. В приведенном выше примере вы можете видеть, что у Customer 1 нет значения B в 2011 году, поэтому для этого не было создано ни одной строки. И хотя это не представлено в примере, некоторые клиенты не будут иметь данных ни для одного значения за год (и, следовательно, не будут строки для этого клиента в этом году). В этой ситуации не хватает скандала для этого клиента в этом году.

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

Каков наиболее эффективный способ создать такой результат?

5 ответов5

6

Это VBA или макрос, который вы можете запустить на своем листе. Вы должны нажать Alt+F11, чтобы вызвать приглашение Visual Basic для приложений, перейти к своей книге и right click - insert - module и вставить туда этот код. Затем вы можете запустить модуль из VBA, нажав F5. Этот макрос называется "тест"

Sub test()
'define variables
Dim RowNum as long, LastRow As long
'turn off screen updating
Application.ScreenUpdating = False
'start below titles and make full selection of data
RowNum = 2
LastRow = Cells.SpecialCells(xlCellTypeLastCell).Row
Range("A2", Cells(LastRow, 4)).Select
'For loop for all rows in selection with cells
For Each Row In Selection
    With Cells
    'if customer name matches
    If Cells(RowNum, 1) = Cells(RowNum + 1, 1) Then
        'and if customer year matches
        If Cells(RowNum, 4) = Cells(RowNum + 1, 4) Then
            'move attribute 2 up next to attribute 1 and delete empty line
            Cells(RowNum + 1, 3).Copy Destination:=Cells(RowNum, 3)
            Rows(RowNum + 1).EntireRow.Delete
        End If
     End If
    End With
'increase rownum for next test
RowNum = RowNum + 1
Next Row
'turn on screen updating
Application.ScreenUpdating = True

End Sub

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

Редактировать - вполне возможно, что мое with statement совершенно не нужно, но это никому не вредит ..

ПЕРЕСМОТРЕНО 28.02.14

Кто-то использовал этот ответ в другом вопросе, и когда я вернулся, я подумал, что этот VBA плохой. Я переделал это -

Sub CombineRowsRevisited()

Dim c As Range
Dim i As Integer

For Each c In Range("A2", Cells(Cells.SpecialCells(xlCellTypeLastCell).Row, 1))
If c = c.Offset(1) And c.Offset(,4) = c.Offset(1,4) Then
            c.Offset(,3) = c.Offset(1,3)
            c.Offset(1).EntireRow.Delete
End If

Next

End Sub

Пересмотрено 05/04/16

Спросил снова Как объединить значения из нескольких строк в одну строку?Есть модуль, но нужны переменные, объясняющие, и опять же, это довольно плохо.

Sub CombineRowsRevisitedAgain()
    Dim myCell As Range
    Dim lastRow As Long
    lastRow = Cells(Rows.Count, "A").End(xlUp).Row

    For Each myCell In Range(Cells("A2"), Cells(lastRow, 1))
        If (myCell = myCell.Offset(1)) And (myCell.Offset(0, 4) = myCell.Offset(1, 4)) Then
            myCell.Offset(0, 3) = myCell.Offset(1, 3)
            myCell.Offset(1).EntireRow.Delete
        End If
    Next
End Sub

Однако, в зависимости от проблемы, может быть лучше сделать step -1 для номера строки, чтобы ничего не пропускалось.

Sub CombineRowsRevisitedStep()
    Dim currentRow As Long
    Dim lastRow As Long
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row

    For currentRow = lastRow To 2 Step -1
        If Cells(currentRow, 1) = Cells(currentRow - 1, 1) And _
        Cells(currentRow, 4) = Cells(currentRow - 1, 4) Then
            Cells(currentRow - 1, 3) = Cells(currentRow, 3)
            Rows(currentRow).EntireRow.Delete
        End If
    Next

End Sub
2

Другой вариант:

  1. Выберите столбец B, нажмите CTRL+G -> Special -> Blanks -> OK
  2. Тип = нажмите , затем CTRL+ ВВОД
  3. Выберите Столбец C, нажмите CTRL+G -> Special -> Blanks -> OK
  4. Тип =IF( нажмите тип = нажмите нажмите тип , нажмите тип ,0) затем CTRL+ ENTER
  5. Выберите все данные и Copy и Paste Special as Values
  6. Удалить дубликаты.

РЕДАКТИРОВАТЬ:

Объяснение: Я пытаюсь использовать опцию GoTo Blanks . После того, как вы выбрали пробелы, вы можете ввести ту же формулу для всех выбранных пустых ячеек. Что касается вопроса OP, данные выглядят так, как будто они имеют согласованные пробелы, то есть: Значение Заготовки столбцов Value A имеют тот же CustomerID что и над непустой строкой. Таким же образом, заготовки столбца Value B имеют тот же CustomerID что и ниже непустой строки.

0

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

В приведенном выше примере вставьте эти (4) функции в ячейки, E2, F2, G2 и H2 соответственно (ссылки на функции F & G указаны выше):

=IF(D2=D3, A2,         IF(D2<>D1, A2,            ""))    
=IF(D2=D3, MAX(B2:B3), IF(D2<>D1, B2,            ""))    
=IF(D2=D3, MAX(B2:B3), IF(D2<>D1, IF(C2=0,"",C2),""))    
=IF(D2=D3, D2,         IF(D2<>D1, D2,            ""))

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

0

Наиболее эффективный способ сделать это - сбросить все данные в сводную таблицу и поместить «Клиент» в метки строк, а затем выполнить другие столбцы. Вы можете вставить «Год» в заголовок столбца, если хотите увидеть разбивку по годам.

Сводные таблицы можно найти в разделе «Вставка в Excel 2010».

0

Вот шаги для создания отдельной таблицы со сжатыми данными.

  1. Скопируйте всю таблицу и вставьте ее на новый лист.
  2. Выберите новую таблицу и выберите «Удалить дубликаты» (лента данных -> «Удалить дубликаты») в столбцах « Customer и « Year . Это обеспечит основу для сжатого стола.
  3. В B2 (первая запись для Value A) введите следующее:

    =IFERROR(INDEX(Sheet1!B$1:B$11,MIN(IF(Sheet1!$A$1:$A$11=$A2,IF(Sheet1!$D$1:$D$11=$D2,IF(Sheet1!B$1:B$11<>"",ROW(Sheet1!$A$1:$A$11),1000000),1000000),1000000))),"")

    Введите формулу в виде формулы массива, нажав Ctrl+Shift+Enter .

  4. Заполните формулу вниз по столбцу. Затем заполните, чтобы заполнить столбец Value B Вуаля!

Несколько заметок:

  • Вам, конечно, нужно настроить адреса в соответствии с вашими данными. Для справки: Лист1 - это исходные данные в столбцах от А до D.
  • Я предполагаю, что ваши данные (или заголовки) начинаются со строки 1. Это, вероятно, верно, если это дамп данных. Формула должна быть скорректирована, если это не так.
  • Я предполагаю, что в вашей таблице меньше миллиона строк. Если у вас есть что-то большее, замените 1000000 с в формуле на большее, чем количество строк.
  • Если в вашей таблице много тысяч строк (более 100 000), вы можете вместо этого использовать решение VBA, поскольку формулы массивов могут увязнуть с большими массивами.

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