【问题标题】:How to check column for duplicate values, then merge adjacent columns if found?如何检查列是否有重复值,如果找到则合并相邻列?
【发布时间】:2019-02-02 03:47:16
【问题描述】:

我正在尝试创建一个宏来检查列中的重复值,然后在找到时合并这些行。

我尝试使用循环检查每个单元格和cell.Offset(1,0),如果它们相等,则合并它们。然后将格式从该列复制到相邻列。

这张图片显示了我想要完成的事情。

我只是想合并一列 (E),但问题是它一次只检查两个单元格,所以它不会合并 5 个相同的值。如果最后一行被合并,它也会搞砸。合并选中的列后,我只需将格式复制到相邻的相应列。

Sub Merge()

Dim lastRow As Long
lastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row

Application.DisplayAlerts = False

    For Each cell In Range("E1:E" & lastRow)
        If cell.Offset(1, 0).Value = cell.Value Then
           Range(cell, cell.Offset(1, 0)).Merge
        End If
    Next cell
End Sub

【问题讨论】:

  • 这个问题之前已经被很多人问过了。你试过看看吗?
  • 也许你可以调整这个Row Version
  • 到目前为止您尝试过任何代码吗?您何时考虑合并行?仅当项目 ID 和帐户相等时?如果是,其余列的差异如何?合并行时它们会发生什么?
  • @Storax 我刚刚添加了我尝试制作的代码。我只是想合并一列(E),但问题是它一次只检查两个单元格,所以它不会合并 5 个相同的值。如果最后一行被合并,它也会搞砸。
  • @urdearboy 是的,我查看了许多类似问题的页面,但无济于事。

标签: excel vba


【解决方案1】:

垂直合并单元格

此代码检查每行的单元格并垂直合并单元格,如果它们具有相同的值(还有具有相同结果值的公式!):

Sub MergeCellsVertically()
    Dim ws As Worksheet
    Dim currentRng As Range
    Dim usedRows As Long, usedColumns As Long
    Dim currentRow As Long, currentColumn As Long
    
    Set ws = ActiveSheet
    usedRows = ws.Cells.Find(What:="*", After:=ws.Cells(1), LookIn:=xlFormulas, _
        SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
    usedColumns = ws.Cells.Find(What:="*", After:=ws.Cells(1), LookIn:=xlFormulas, _
        SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
    
    Application.DisplayAlerts = False
    For currentColumn = 1 To usedColumns
        For currentRow = usedRows To 2 Step -1
            Set currentRng = ws.Cells(currentRow, currentColumn)
            If currentRng.Value <> "" Then
                If currentRng.Value = currentRng.Offset(-1, 0).Value Then
                    currentRng.Offset(-1, 0).Resize(2, 1).Merge
                End If
            End If
        Next currentRow
    Next currentColumn
    Application.DisplayAlerts = True
    
    Set currentRng = Nothing
    Set ws = Nothing
End Sub

由于您的示例显示了不统一的结构,这可能是一个很好的解决方案。如果您只想通过一行来决定要合并哪些相邻单元格,请记住,只有合并区域左上角单元格的内容才能“存活”。

如果要处理合并区域的内容,则currentRng.MergeArea.Cells(1) 将始终表示合并区域的第一个单元格,即内容所在的位置。

取消合并

Sub UnmergeCells()
    Dim ws As Worksheet
    Dim usedRows As Long, usedColumns As Long
    Dim currentRng As Range, tempRng As Range
    Dim currentRow As Long, currentColumn As Long
    
    Set ws = ActiveSheet
    usedRows = ws.UsedRange.Cells(1).Row + ws.UsedRange.Rows.Count - 1
    usedColumns = ws.UsedRange.Cells(1).Column + ws.UsedRange.Columns.Count - 1
    
    For currentRow = 1 To usedRows
        For currentColumn = 1 To usedColumns
            Set currentRng = ws.Cells(currentRow, currentColumn)
            If currentRng.MergeCells Then
               Set tempRng = currentRng.MergeArea
               currentRng.MergeArea.UnMerge
               currentRng.Copy tempRng
            End If
        Next currentColumn
    Next currentRow
    
    Set tempRng = Nothing
    Set currentRng = Nothing
    Set ws = Nothing
End Sub

由于Find 函数无法在合并单元格中查找最后使用的列或行,因此我改用标准的UsedRange。请注意,未合并(重复)的公式可能是意外的。

【讨论】:

  • 感谢您的帮助。我尝试了带有和不带有标题和过滤器的代码,但它在运行时似乎没有做任何事情。没有错误,它只是没有合并任何东西。此外,如果有助于解释我试图完成的工作,我会在我的原始帖子中添加更多信息。
  • 非常感谢!最后一个问题:我将如何修改它以仅检查一个已定义的列,而不是遍历每一列?
  • 如果你设置了 e. G。 currentColumn = 5开头,删除代码行For currentColumn = 1 To usedColumnsNext currentColumn,则只对E列有效。请考虑接受这个答案:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-26
相关资源
最近更新 更多