web-dev-qa-db-ja.com

Excelで複数の行の値を1つの行に組み合わせる方法は?

Excelに、2つの異なる値の年間顧客データで構成されるデータダンプがあります。データには、毎年および顧客ごとに値の個別の行が提供されました。つまり次のようになります。

enter image description here

2009年の値Aの顧客1の行と同じの値Bの別の行同じの顧客で立ち往生しています。年。

場合によっては、値Aも値Bもありません。上の例では、顧客1には2011年の値Bがないため、その行は生成されていません。また、例には示されていませんが、一部のクライアントには、1年のいずれの値のデータもありません(したがって、その年のその顧客の行はありません)。その状況では、その年にその顧客の列がなくても問題ありません。

これを、毎年および顧客のboth値の1行があるワークシートに入れたいと思います。つまり、データを次のようにする必要があります。

enter image description here

その結果を生み出す最も効果的な方法は何ですか?

10
Greg R.

これはVBA、またはシートで実行できるマクロです。ヒットする必要があります alt+F11 Visual Basic for Applicationプロンプトを表示するには、ワークブックに移動し、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は完全に不要ですが、誰にも害はありません。

2014年2月28日改訂

誰かがこの答えを別の 質問 で使用し、戻ったとき、私はこの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

2016年5月4日再訪

もう一度尋ねます 複数の行の値を1つの行に組み合わせる方法?モジュールはありますが、変数の説明が必要です そして、これはかなり貧弱です。

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
6
Raystafarian

別のオプション:

  1. 列Bを選択し、 CTRL+G -> Special-> Blanks-> OK
  2. =」と入力します 、その後 CTRL+ENTER
  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を持ちます。

2
zx8754

誰もがこのために多くのVBAコードまたは複雑な関数を使用しています。私は実装に1秒かかる方法がありますが、他のさまざまな可能性に応じて、はるかに理解しやすく、調整が非常に簡単です。

上記の例では、これらの(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行が存在するたびに1行のデータを生成し、1行は影響を受けません。 E-F-G-H列の値を(数式を削除するために)特別な場所に貼り付け、顧客別に並べ替えて余分な行をすべて削除します。

0
Kindlin

これを行う最も効果的な方法は、すべてのデータをピボットテーブルにダンプし、「顧客」を行ラベルにドロップしてから、他の列をフォローアップすることです。年ごとの内訳を表示したい場合は、「年」を列ヘッダーにドロップできます。

ピボットテーブルはExcel 2010の[挿入]にあります

0
xXPhenom22Xx

圧縮されたデータを使用して別のテーブルを作成する手順は次のとおりです。

  1. テーブル全体をコピーして、新しいシートに貼り付けます。
  2. 新しいテーブルを選択し、列CustomerYearの重複を削除します(データリボン->重複を削除)。これにより、圧縮されたテーブルのフレームワークが提供されます。
  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_列も入力してください。出来上がり!

いくつかのメモ:

  • もちろん、データに合わせてアドレスを調整する必要があります。参考までに、Sheet1は列A〜Dの元のデータです。
  • 私は、データ(またはヘッダー)が1行目から始まると想定しています。これがデータダンプである場合、これはおそらく当てはまります。そうでない場合は、式を調整する必要があります。
  • テーブルの行数が100万未満であると想定しています。どういうわけかそれを超える場合は、式の_1000000_ sを行数よりも大きいものに変更します。
  • テーブルに数千行(100,000以上)がある場合は、配列数式が大きな配列で途方に暮れる可能性があるため、代わりにVBAソリューションの使用を検討してください。
0
Excellll