2016-10-10 66 views
0

另一個棘手的問題。我有一個清理的數據集與另一個宏,我需要遍歷列標題和每一行,在第一列中合併具有相同標題名稱的列的值,由;當列標題相同時合併所有行中的值

示例數據:

Test Country  Test Country 
123  456   789  012 
abc  def   ghi  jkl 
mno  pqr   stu  vwx 

所需的輸出:

Test  Country 
123;789 456;012 
abc;ghi def;jkl 

我已經試過這樣的事情,這肯定沒有工作:

Dim i As Long 
i = 1 
j = 1 
Do Until Len(Cells(i, j).Value) = 0 
    If Cells(i, j).Value = Cells(i, j + 1).Value Then 
     Cells(i, j).Value = Cells(i, j).Value & ";" & Cells(i, j + 1).Value 

     Rows(j + 1).Delete 
    Else 
     i = i + 1 
     j = j + 1 
    End If 
Loop 
+0

你知道你的列與喜歡頭像嗎?如果您知道您的列範圍,請嘗試使用'.Offset()'。 (如果你知道A1是測試,C1是測試,你可以循環A中的所有內容並將它與C連接) – Tyeler

+0

謝謝,我不知道列範圍,它們沒有硬編碼,所以我需要循環並總是在名稱上匹配 – MJ95

+0

這可能會很有趣!你有沒有嘗試循環通過兩列for循環的列+行?像'For Each column in colRange' //'For Each row in rowRange'然後做一個比較/連接? – Tyeler

回答

1

約定閒話家常後...

Sub ForLoopPair() 

Dim lastRow As Integer: lastRow = Cells(xlCellTypeLastCell).Row  ' or w/e you had 
Dim lastCol As Integer: lastCol = Cells(xlCellTypeLastCell).Column ' or w/e you had 

For DestCol = 1 To lastCol 
    For ReadCol = DestCol + 1 To lastCol 
     If Cells(1, DestCol) = Cells(1, ReadCol) Then 
     For i = 2 To lastRow 
      If Cells(i, ReadCol) <> "" Then 
       Cells(i, DestCol) = Cells(i, DestCol) & ";" & Cells(i, ReadCol) 
      End If 
     Next i 
     End If 
    Next ReadCol 
Next DestCol 

For DestCol = 1 To lastCol 
    If Cells(1, DestCol) = "" Then Exit For 
    For ReadCol = lastCol To (DestCol + 1) Step -1 
     If Cells(1, DestCol) = Cells(1, ReadCol) Then 
     Columns(ReadCol).Delete 
     End If 
    Next 
Next 

End Sub 
+0

有一些故障:1)'xlCellTypeLastCell'不是獲取行或列中最後使用的單元格的正確方法。在SO中有關於如何在第一個循環中正確地獲取_last one_ 2)的帖子,您正在遍歷相同的單元格,而沒有檢查當前的「頭部」是否已經被處理過。3)Cells(1,DestCol) '內部'對於ReadCol'循環應該用一個變量替代,避免多次訪問同一個單元,而這個單元在那個循環中不會改變。 2)和3)嚴重影響宏的性能,因爲訪問單元格是非常耗時的活動 – user3598756

+0

@ user3598756 1)用戶正在使用您在其他帖子中引用的xlUp方法。對於乾淨的工作表來說,兩個函數是相同的。 2)首先要說的是'在經過很好的同意之後聊天',爲什麼你沒有看到我正在通過解決方案走路? 3)我已經在聊天中向用戶解釋了時間消耗和需要提高此代碼的性能。 4)學習某些東西時最好理解要做什麼然後進行優化。 5)感謝您的反饋! –

+0

我(我)並沒有閱讀所有的聊天,因爲有(並且仍然是)我接受的所有評論都是(並且仍然是)的_accepted_解決方案。 – user3598756

0

不知道什麼是對第一個答案不同,但是這個人是在Excel 2010()提供

分B瓶的數據測試

Dim DestCol As Integer 
    Dim ReadCol As Integer 

    DestCol = 1 
    ReadCol = 2 

    While ActiveSheet.Cells(1, DestCol) <> "" 
    If ActiveSheet.Cells(1, ReadCol) = ActiveSheet.Cells(1, DestCol) Then 
     For i = 2 To ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell).Row 
      If ActiveSheet.Cells(i, ReadCol) <> "" Then 
       ActiveSheet.Cells(i, DestCol) = ActiveSheet.Cells(i, DestCol) & ";" & ActiveSheet.Cells(i, ReadCol) 
      End If 
     Next i 
     ActiveSheet.Columns(ReadCol).Delete 
    ElseIf ActiveSheet.Cells(1, ReadCol + 1) <> "" Then 
     ReadCol = ReadCol + 1 
    Else 
     ReadCol = DestCol + 2 
     DestCol = DestCol + 1 
    End If 
    Wend 

末次

+0

我在這裏看到了區別,我刪除了ReadCol,而不是在之前的答案中刪除DestCol。 ReadCol = DestCol + 2是正確的,因爲您總是從目標右側的一列讀取,直到最後一列 –

+0

對不起,不起作用。它只適用於一次。例如,如果我在中間插入更多列,它不起作用 – MJ95

+0

好吧,我放棄了。你有鏈接到你當前的數據? –

0

試試這個(測試)

Option Explicit 

Sub Main() 
    Dim rng As Range, cell As Range, cell2 As Range, cell3 As Range, rngToDelete As Range 
    Dim txt As String 

    With Worksheets("myWorksheetName") 
     With .Range("A1", .Cells(1, .Columns.Count).End(xlToLeft)) 
      Set rngToDelete = .Offset(1).Resize(, 1) 
      For Each cell In .Cells 
       If Intersect(cell, rngToDelete) Is Nothing Then 
        Set rng = GetRange(cell, .Cells) 
        If Not rng Is Nothing Then 
         With Intersect(.Parent.UsedRange, cell.EntireColumn) 
         MsgBox .Offset(1).Resize(.Rows.Count - 1).SpecialCells(XlCellType.xlCellTypeConstants).Address        
          For Each cell2 In .Offset(1).Resize(.Rows.Count - 1).SpecialCells(XlCellType.xlCellTypeConstants) 
           txt = cell2.Value 
           For Each cell3 In rng 
            txt = txt & ";" & .Parent.Cells(cell2.row, cell3.Column) 
           Next cell3 
           cell2.Value = txt 
          Next cell2 
         End With 
         Set rngToDelete = Union(rng, rngToDelete) 
        End If 
       End If 
      Next cell 
      Intersect(.Cells, rngToDelete).EntireColumn.Delete 
     End With 
    End With 
End Sub 


Function GetRange(rngToSearchFor As Range, rngToSearchIn As Range) As Range 
    Dim f As Range 
    Dim firstAddress As String 

    With rngToSearchIn 
     Set f = .Find(What:=rngToSearchFor.Value, lookAt:=xlWhole, LookIn:=xlValues, After:=rngToSearchFor, SearchDirection:=xlNext) 
     If Not f Is Nothing Then 
      If f.Column > rngToSearchFor.Column Then 
       firstAddress = f.Address 
       Set GetRange = f 
       Do 
        Set GetRange = Union(GetRange, f) 
        Set f = .FindNext(f) 
       Loop While f.Column > rngToSearchFor.Column 
      End If 
     End If 
    End With 
End Function 
+0

不,這沒有合併任何東西,只是切斷了列標題中字符串的最後一部分 – MJ95

+0

我不是通過PC,所以只是寫下了一個想法。它編譯成功!我可以在10個小時內測試它。與此同時,你可以通過它(與F8),並嘗試看看它失敗的地方 – user3598756

+0

好吧,酷將做。謝謝 – MJ95

相關問題