2016-07-08 149 views
0

我有一個Excel工作表,看起來像第一張圖片,我想將其轉換爲第二個畫面: enter image description here移調Excel列到行

我寫了下面的代碼,但預期它不工作。它會刪除比預期更多的行。代碼有什麼問題?

Sub Trans3() 
Dim rng As Range, rng2 As Range 
Dim I As Long 
Dim J As Integer, Z As Integer, Q As Integer, T As Integer 

Set rng = Range("B1") 
While rng.Value <> "" 

For Each y In Range("A1:A10") 
    I = I + 1 
    J = I 
    Z = 1 
    Do While Cells(J + 1, 1).Value = Cells(J, 1).Value 
     J = J + 1 
    Loop      
    Set rng2 = Range("B" & I & ":B" & J) 

    If I > 1 Then 
     Z = J - I + 1 
    Else 
     Z = J 
    End If 

    rng2.Resize(Z).Copy 
    Range("C" & I).PasteSpecial Transpose:=True 
    T = I 

    Do While J > 1 
     Q = T + 1 
     Rows(Q).EntireRow.Delete 
     J = J - 1 
    Loop 

Next y 
Wend 

End Sub 

回答

1

所以我做了一些重構。我將所有東西都移動到了數組中以加快速度。

請參閱代碼中的說明以供參考。

Sub FOOO() 
Dim inArr() As Variant 
Dim outArr() As Variant 
Dim ws As Worksheet 
Dim cntrw As Long 
Dim cntclm As Long 
Dim i As Long 
Dim j As Long 
Dim k As Long 
Dim rng As Range 

Set ws = ActiveSheet 

With ws 
    Set rng = .Range("A1", .Cells(.Rows.Count, "A").End(xlUp)) 
    'find the max number column that will be needed in the output 
    cntclm = ws.Evaluate("MAX(COUNTIF(" & rng.Address & "," & rng.Address & "))") + 1 
    'find the number of rows that will be needed in the output. 
    cntrw = ws.Evaluate("SUM(1/COUNTIF(" & rng.Address & "," & rng.Address & "))") 
    'put the existing data into an an array 
    inArr = rng.Resize(, 2).Value 
    'resize output array to the extents needed 
    ReDim outArr(1 To cntrw, 1 To cntclm) 
    'put the first value in the first spot in the output 
    outArr(1, 1) = inArr(1, 1) 
    outArr(1, 2) = inArr(1, 2) 
    'these are counters to keep track of which slot the data should go. 
    j = 3 
    k = 1 
    'loop through the existing data rows 
    For i = 2 To UBound(inArr, 1) 
     'test whether the data in A has changed or not. 
     If inArr(i, 1) = inArr(i - 1, 1) Then 
      'if not put the value in B in the next slot and iterate to the next column 
      outArr(k, j) = inArr(i, 2) 
      j = j + 1 
     Else 
      'if change start a new line in the outarr and fill the first two slots 
      k = k + 1 
      j = 3 
      outArr(k, 1) = inArr(i, 1) 
      outArr(k, 2) = inArr(i, 2) 
     End If 
    Next i 
    'remove old data 
    .Range("A:B").Clear 
    'place new data in its place. 
    .Range("A1").Resize(UBound(outArr, 1), UBound(outArr, 2)).Value = outArr 
End With 
End Sub 

這要求該數據將A列

+0

This Works ... Thnx – Shank

+0

+針對數據集中所有唯一值由公式使用而投票選擇速度。 – cyboashu

0

柄,用你的代碼,我做了細微的修改排序,現在它刪除的行權數量和它的作品,試試吧出。

Sub Transpose() 

Dim sht As Worksheet 
Dim LastRow As Long 

Set sht = ThisWorkbook.Worksheets("Sheet_Name") ' modify here to your Worksheet name 
LastRow = sht.Cells(sht.Rows.count, "A").End(xlUp).row 

    For row = 1 To LastRow 
     If sht.Cells(row, 1) <> "" Then 
      i = i + 1 
      j = i 
      Z = 1 
      Do While Cells(j + 1, 1).Value = Cells(j, 1).Value 
       j = j + 1 
      Loop 

      Set rng2 = Range("B" & i & ":B" & j) 

      If i > 1 Then 
       Z = j - i + 1 
      Else 
       Z = j 
      End If 

      rng2.Resize(Z).Copy 
      Range("C" & i).PasteSpecial Transpose:=True 
      T = i 

      Do While j - row > 0 
       Q = T + 1 
       Rows(Q).EntireRow.Delete 
       j = j - 1 
      Loop 
     End If 
    Next 

End Sub 
+0

thnx tgis works ...所以基本上我刪除了你通過j-row解決的額外行。這是有幫助的LastRow = sht.Cells(sht.Rows.count,「A」)。End(xlUp).row For row = 1 To LastRow ....我不知道這個 – Shank

+0

@Shank歡迎您,請標記爲答案和upvote –

+0

FWIW,儘管這適用,但對於大型數據集,這將比陣列版本慢得多。 –

1

我對此存在疑問。

Sub test() 

    Dim lCtrRow_Raw  As Long 
    Dim lCtrRow_New  As Long 
    Dim lInst   As Long 

    Dim dctUniq   As New Dictionary 
    Dim sKey 
    Dim arrRaw 
    Dim arrNew() 

    '/ Specify your range here. Only two columns of data should be used. 
    arrRaw = Selection() ' ****Avoid using Selection in actual code****. 

    '/ Filter Duplicates. 
    For lCtrRow_Raw = LBound(arrRaw) To UBound(arrRaw) 
     If Not dctUniq.Exists(arrRaw(lCtrRow_Raw, 1)) Then 
      dctUniq.Add arrRaw(lCtrRow_Raw, 1), arrRaw(lCtrRow_Raw, 1) 
     End If 
    Next 

    '/ Start New Array 
    ReDim arrNew(1 To dctUniq.Count, 1 To 1) 

    '/ Seed IDs 
    For Each sKey In dctUniq.Keys 
     lCtrRow_New = lCtrRow_New + 1 
     arrNew(lCtrRow_New, 1) = dctUniq(sKey) 
    Next 

    '/ Loop and assign unique values 
    For lCtrRow_New = LBound(arrNew) To UBound(arrNew) 
     lInst = 1 
    For lCtrRow_Raw = LBound(arrRaw) To UBound(arrRaw) 
      If arrRaw(lCtrRow_Raw, 1) = arrNew(lCtrRow_New, 1) Then 
       lInst = lInst + 1 
       If lInst > UBound(arrNew, 2) Then 
        ReDim Preserve arrNew(1 To dctUniq.Count, 1 To lInst) 
       End If 

       arrNew(lCtrRow_New, lInst) = arrRaw(lCtrRow_Raw, 2) 
      End If 
     Next 
    Next 

    '/ Dump array in the data sheet. 
    'Sheet1.Range("A20").Resize(UBound(arrNew, 1), UBound(arrNew, 2)).Value = arrNew 
End Sub 
+0

我會對速度感興趣,與我的大型數據集相比,您的速度更快。你做了很多循環,但我有兩個公式。這將是有趣的,但不足以讓我測試。 :) –

+0

你在10,000行中獲勝,分爲26類,你幾乎是瞬間的,而我的則是4秒。 –

+2

我也做了一些測試。與26個字母和10000行相同。我贏了。但是,如果您將數據更改爲10000個唯一值,則您的代碼速度會提高一英里。所以你贏了。 :) – cyboashu