2012-02-28 22:05:49 +0000 2012-02-28 22:05:49 +0000
10
10

Como combinar valores de várias filas numa única fila em Excel?

Tenho uma descarga de dados em Excel que consiste em dados anuais de clientes para dois valores diferentes. Os dados foram fornecidos com uma linha separada para valor para cada ano e para cada cliente. Isto é, tem o seguinte aspecto:

Estou preso com uma linha para o Cliente 1 para o Valor A em 2009 e uma separate row para o Valor B para o mesmo cliente no mesmo ano.

Em alguns casos não há nenhum Valor A ou Valor B. No exemplo acima, pode-se ver que o Cliente 1 não tem Valor B em 2011, pelo que não foi gerada uma fila para isso. E, embora não representados no exemplo, alguns clientes não terão dados para qualquer valor num ano (e portanto nenhuma fila para esse cliente nesse ano). Nessa situação, a ausência de uma fila para esse cliente nesse ano é suficiente.

Quero colocar isto numa folha de trabalho onde haja uma fila para ambos valores para cada ano e cliente. Ou seja, quero que os dados tenham este aspecto:

Qual é a forma mais eficaz de criar esse resultado?

Respostas (5)

6
6
6
2012-02-29 12:18:49 +0000

Isto é VBA, ou uma macro que pode correr na sua folha. Deve premir alt+F11 para trazer à tona a solicitação Visual Basic for Application, ir à sua pasta de trabalho e right click - insert - module e colar aí este código. Pode então executar o módulo a partir de VBA, premindo F5. Esta macro é denominada “teste”

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

Isto correrá através de uma sorted spreadsheet* e combinará linhas consecutivas que correspondam tanto ao cliente como ao ano e apagará a linha agora vazia. A folha de cálculo deve ser ordenada da forma como a apresentou, clientes e anos a subir, esta macro em particular não vai olhar para além de linhas consecutivas.

Editar - é inteiramente possível que a minha with statement seja completamente desnecessária, mas não está a magoar ninguém…

REVISITED 02/28/14

Alguém usou esta resposta noutra pergunta e quando voltei pensei que este VBA era pobre. Eu refiz -

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

REVISITADO 05/04/16

Perguntado novamente Como combinar valores de várias filas numa única fila? Tem um módulo, mas precisa das variáveis que explicam e, mais uma vez, é bastante pobre.

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

Contudo, dependendo do problema, pode ser melhor step -1 num número de fila para que nada seja ignorado.

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
2
2
2013-07-17 18:08:36 +0000

Outra opção:

  1. seleccionar a Coluna B, premir CTRL+G -> Special-> Blanks -> OK
  2. Digite =-> ↑, depois CTRL+ENTER -> 3. Seleccionar a coluna C, pressionar CTRL+G -> Special-> Blanks -> OK
  3. Tipo =IF(-> ← tipo =->> ← tipo ,-> ↓ tipo ,0)-> ↓ tipo Copy depois CTRL+ENTER -> 5. Seleccionar todos os dados e Paste Special as Values e Value A
  4. Remover duplicados.

EDIT:

Explicação: Estou a tentar fazer uso da opção GoTo Blanks . Uma vez seleccionados os espaços em branco, então pode introduzir a mesma fórmula para todas as células em branco seleccionadas. Relativamente à pergunta de OP, os dados parecem ter consistentes espaços em branco, ou seja: CustomerID espaços em branco na coluna têm a mesma Value B como acima da linha não em branco. Da mesma forma, os espaços em branco CustomerID coluna têm os mesmos 0x6& que abaixo da linha não em branco.

0
0
0
2012-02-29 18:12:36 +0000

Aqui estão os passos para a criação de uma tabela separada com os dados condensados.

  1. copie toda a sua tabela e cole-a numa nova folha.
  2. Seleccione a sua nova tabela e Remova Duplicatas (Fita de dados -> Remove Duplicatas) nas colunas Customer e Year. Isto fornecerá a estrutura para a tabela condensada.
  3. Em B2 (a primeira entrada para Value A) introduza o seguinte:

  4. Preencher a fórmula na coluna. Em seguida, preencher também a coluna Value B. Voilá!

Algumas notas:

  • É claro que terá de ajustar os endereços para se adequarem aos seus dados. Para referência, Folha1 são os dados originais nas colunas A a D.
  • Presumo que os seus dados (ou cabeçalhos) começam na Linha 1. Isto é provavelmente verdade se se tratar de uma descarga de dados. A fórmula terá de ser ajustada, se não for este o caso.
  • Presumo que a sua tabela tenha menos de um milhão de filas. Se de alguma forma tiver mais do que isso, altere o 1000000s na fórmula para algo maior do que o seu número de filas.
  • Se a sua tabela tem muitos milhares de linhas (100.000+), talvez queira considerar a utilização de uma solução VBA, uma vez que as fórmulas de matriz podem ficar atoladas com grandes matrizes.
0
0
0
2016-07-15 16:44:30 +0000

Todos estão a usar muito código VBA ou funções complicadas para isto. Tenho um método que demora um segundo a implementar mas é muito mais compreensível e muito fácil de ajustar, dependendo de várias outras possibilidades.

No exemplo que deu acima, cole estas (4) funções nas células, E2, F2, G2 e H2, respectivamente (as células de referência das funções F&G acima):

=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, ""))

Arraste estas fórmulas para baixo, tanto quanto necessário. Gera uma única linha de dados cada vez que 2 linhas estão presentes, deixando linhas únicas inalteradas. Colar especialmente os valores (para remover as fórmulas) das colunas E-F-G-H noutro local e ordená-los por cliente para remover todas as linhas extra.

0
0
0
2012-02-28 22:15:04 +0000

A forma mais eficaz de o fazer é deitar todos os dados numa Tabela Pivot e deitar ‘Cliente’ em Rótulos de Linha e depois seguir com as outras colunas. Pode largar o ‘Ano’ no cabeçalho da coluna se quiser ver a repartição por ano

Tabelas pivot podem ser encontradas em Inserir no Excel 2010