2012-03-11 9 views
0

Excel内に複数の列幅と複数の行長のセル範囲があります。いくつかのセルは空白です。私は(VBAを使用して)非空白セルをリストにマージし、重複を削除し、アルファベット順にソートしたいと思います。例としてExcel範囲内のデータをマージして空白と重複を削除する

A 
B 
C 
D 
E 

次のソートされた出力が生成さ

- - A D - 
C - - A - 
- - B - D 
- - - - - 
A - - E - 

:(ダッシュは、この質問の目的のために空のセルを指定する)この入力所与例えば

、範囲内のいくつかの行と列にすべての空のセルが含まれる場合があります。

+0

[ExcelからVBA配列の中に一意の値を取り込み(http://stackoverflow.com/questions/5890257/populate-unique-values-inの可能重複-to-vba-array-excelより)。これは[以前に答えられました](http://stackoverflow.com/a/5896692/119775)。 –

答えて

5

これを行う方法の1つです。

CODE(実証済み)

Option Explicit 

Sub Sample() 
    Dim ws As Worksheet 
    Dim LastRow As Long, lastCol As Long, i as Long 
    Dim Rng As Range, aCell As Range 
    Dim MyCol As New Collection 

    '~~> Change this to the relevant sheet name 
    Set ws = Sheets("Sheet21") 

    With ws 
     LastRow = .Cells.Find(What:="*", After:=.Range("A1"), _ 
     Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, _ 
     SearchDirection:=xlPrevious, MatchCase:=False).Row 

     lastCol = .Cells.Find(What:="*", After:=.Range("A1"), _ 
     Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByColumns, _ 
     SearchDirection:=xlPrevious, MatchCase:=False).Column 

     Set Rng = .Range("A1:" & Split(.Cells(, lastCol).Address, "$")(1) & LastRow) 

     'Debug.Print Rng.Address 
     For Each aCell In Rng 
      If Not Len(Trim(aCell.Value)) = 0 Then 
       On Error Resume Next 
       MyCol.Add aCell.Value, """" & aCell.Value & """" 
       On Error GoTo 0 
      End If 
     Next 

     .Cells.ClearContents 

     For i = 1 To MyCol.Count 
      .Range("A" & i).Value = MyCol.Item(i) 
     Next i 

     '~~> OPTIONAL (In Case you want to sort the data) 
     .Columns(1).Sort Key1:=.Range("A1"), Order1:=xlAscending, Header:=xlGuess, _ 
     OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _ 
     DataOption1:=xlSortNormal 
    End With 
End Sub 

SNAPSHOTS

enter image description here

フォロー

私はちょうど3行を追加することは、よりTになることに気づい彼のコードは上記のコードよりも高速です。

Option Explicit 

Sub Sample() 
    Dim ws As Worksheet 
    Dim LastRow As Long, lastCol As Long, i As Long 
    Dim Rng As Range, aCell As Range, delRange As Range '<~~ Added This 
    Dim MyCol As New Collection 

    '~~> Change this to the relevant sheet name 
    Set ws = Sheets("Sheet1") 

    With ws 
     '~~> Get all the blank cells 
     Set delRange = .Cells.SpecialCells(xlCellTypeBlanks) '<~~ Added This 

     '~~> Delete the blank cells 
     If Not delRange Is Nothing Then delRange.Delete '<~~ Added This 

     LastRow = .Cells.Find(What:="*", After:=.Range("A1"), _ 
     Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, _ 
     SearchDirection:=xlPrevious, MatchCase:=False).Row 

     lastCol = .Cells.Find(What:="*", After:=.Range("A1"), _ 
     Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByColumns, _ 
     SearchDirection:=xlPrevious, MatchCase:=False).Column 

     Set Rng = .Range("A1:" & Split(.Cells(, lastCol).Address, "$")(1) & LastRow) 

     'Debug.Print Rng.Address 
     For Each aCell In Rng 
      If Not Len(Trim(aCell.Value)) = 0 Then 
       On Error Resume Next 
       MyCol.Add aCell.Value, """" & aCell.Value & """" 
       On Error GoTo 0 
      End If 
     Next 

     .Cells.ClearContents 

     For i = 1 To MyCol.Count 
      .Range("A" & i).Value = MyCol.Item(i) 
     Next i 

     '~~> OPTIONAL (In Case you want to sort the data) 
     .Columns(1).Sort Key1:=.Range("A1"), Order1:=xlAscending, Header:=xlGuess, _ 
     OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _ 
     DataOption1:=xlSortNormal 
    End With 
End Sub 

HTH

シド

+0

私はそうする方法だと思います。 +1必要に応じて、一時的なワークシートで並べ替えを行い、配列に戻すことができます。 –

+2

+1良い解決策。何も存在しない場合には、私は常に 'SpecialCells'でエラーテストをします。同様に、行と列を 'FInd'で直接設定するのではなく、直接テストセルにするのが好ましいです。 – brettdj

+0

' specialcells 'によるエラー処理の良い点。私はいつもそれを含める。なぜ私はここにそれを逃したかわからない:) –

関連する問題