4

これに対する答えを Stackoverflow と Google で検索してみましたが、まだ見つかりません。私の問題の一部は、私がやろうとしていることのキーワードが何であるかわからないことだと思います.

私のデータは次のようになります。

ID    Var1    Var2    Name
01    0001    0002    Bill
01    0001    0002    Jim
01    0001    0002    Sally
02    0003    0004    Sam
02    0003    0004    Kyle

同じ ID と同じ Var1 と Var2 を持つ複数の行があることがわかりますが、各行には一意の名前が付いています。行を「平坦化」して、ID ごとに 1 つの行だけが存在し、各行にはすべてのデータに適合するのに必要な数の「名前」列が含まれるようにします。

このような:

ID    Var1    Var2    Name1    Name2    Name3
01    0001    0002    Bill     Jim      Sally
02    0003    0004    Sam      Kyle

誰かがこれを行う方法またはそれが何と呼ばれているか知っていますか?

ありがとう!

コメントに基づく更新: 私のデータ ソースは .csv ファイルで、Excel で操作しようとしています。Excel マクロまたは VBA ソリューションが最適です。残念ながら、私の SQL は非常に初歩的なので、SQL ソリューションの適用方法を学ぶには時間がかかります。

4

3 に答える 3

2

このようなものは、バリアント配列と辞書オブジェクトを使用して非常に高速です

A1:Dxコードは からへの出力をダンプしますF1

更新: 名前の数字を修正

ここに画像の説明を入力

Sub ReCut()
Dim X
Dim Y
Dim C

Dim lngRow As Long
Dim lngCol As Collection
Dim lngCnt1 As Long
Dim lngCnt As Long
Dim objDic As Object

Set objDic = CreateObject("scripting.dictionary")
X = Range([a1], Cells(Rows.Count, "C").End(xlUp)).Value2
Y = X

ReDim Y(1 To UBound(Y), 1 To 100)

For lngCnt1 = 1 To (UBound(Y, 2) - 3)
Y(1, lngCnt1) = "Name" & lngCnt1
Next

For lngRow = 1 To UBound(X, 1)
    If objDic.exists(X(lngRow, 1) & X(lngRow, 2) & X(lngRow, 3)) Then
'find first blank entry in relevant array row
        C = Split(Join(Application.Index(Y, lngCnt), "| "), "|")
        Y(lngCnt, Application.Match(" ", C, 0)) = X(lngRow, 4)
    Else
        lngCnt = lngCnt + 1
        Y(lngCnt, 1) = X(lngRow, 1)
        Y(lngCnt, 2) = X(lngRow, 2)
        Y(lngCnt, 3) = X(lngRow, 3)
        Y(lngCnt, 4) = X(lngRow, 4)
        objDic.Add X(lngRow, 1) & X(lngRow, 2) & X(lngRow, 3), lngCnt
    End If
Next

[f1].Resize(UBound(Y, 1), UBound(Y, 2)) = Y

End Sub
于 2013-07-22T11:21:17.947 に答える
1

フォーミュラオンリーはかなり多くの説明を必要としますが、多くの人にとって個別に非常によく知られている一連の操作にすぎません。

  1. 4 つの列 (A:D など) を選択します。
  2. データ > アウトライン – 小計 変更ごとに: ID、関数を使用: Count、小計を追加: すべてチェック、チェックReplace current subtotalsSummary below dataてOK。
  3. A:E をフィルターし、ColumnAText Filtersで、Contains C、OK を選択します。
  4. B5に入力=B4してD5にコピー
  5. F5 で:

    =IF(COLUMN()<6+$E5,OFFSET($E5,COLUMN()-6-$E5,),"")

  6. F5 を横にコピーして Z5 とします (必要に応じてさらに右に)。
  7. B5:D5 と F5:Z5 を最後にグループ化された行までコピーします。
  8. フィルターを解除 (すべて選択)。
  9. シート全体をコピーし、[形式を選択して貼り付け]、[値] で上に貼り付けます。
  10. Remove All小計で。
  11. ColumnA をフィルター処理して選択しGrand Countます(Blanks)
  12. 青で番号付けされた行を削除します。
  13. 列 A を削除します。
  14. D1 を E1 にドラッグし、 を追加します1
  15. E1 を必要なだけ右にドラッグします。
  16. 列 D を削除します。

于 2013-07-19T20:16:47.093 に答える