【问题标题】:Excel VBA: Merging a range inside a loopExcel VBA:合并循环内的范围
【发布时间】:2017-06-06 10:41:24
【问题描述】:

我想按章节将重复的章节合并到一个单元格中。

这是我的代码执行循环的方式。

        Dim label As Control
        Dim itm As Object
        For ctr = 1 To InfoForm.Chapter.ListCount - 1
            For Each label In InfoForm.Controls
                If TypeName(label) = "Label" Then
                    With ActiveSheet
                        i = i + 1

                        lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row + IIf(i = 1, 1, 0)
                        lastColumn = .Cells(i, .Columns.Count).End(xlToLeft).Column

                        If label <> "Chapter" Then
                            .Cells(lastColumn, i).Value = "Chapter " & ctr

                            .Cells(lastRow, i).Value = label.Caption
                        End If
                    End With
                End If
            Next
        Next

我试过这样合并

.Range(Cells(1, lastColumn), Cells(1,i)).Merge

但它会将所有重复的章节合并到一个单元格中

预期结果:

【问题讨论】:

  • 你能提供一个预期输出的例子吗?
  • 这是我的预期结果
  • 我发现有关表单控件的代码有点令人困惑...您只是想合并一堆具有相同值的单元格,不是吗?
  • 我想将第 1 章的单元格合并为一个单元格。然后将第 2 章改成另一个,依此类推。
  • 第 1 章和第 2 章之间、第 2 章和第 3 章之间总是有一个空白列,等等?

标签: vba excel


【解决方案1】:

我的方法如下

   Dim label As Control
    Dim itm As Object
    For ctr = 1 To InfoForm.Chapter.ListCount - 1
        For Each label In InfoForm.Controls
            If TypeName(label) = "Label" Then
                With ActiveSheet
                    i = i + 1

                    lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row + IIf(i = 1, 1, 0)
                    lastColumn = .Cells(i, .Columns.Count).End(xlToLeft).Column

                    If label <> "Chapter" Then
                        .Cells(lastColumn, i).Value = "Chapter " & ctr

                        .Cells(lastRow, i).Value = label.Caption
                    End If
                End With
            End If
        Next
    Next

    'this is merge method
    Dim rngDB As Range, rng As Range, n As Integer

    Application.DisplayAlerts = False
    Set rngDB = Range("a1", Cells(1, Columns.Count).End(xlToLeft))
    For Each rng In rngDB
        If rng <> "" Then
            n = WorksheetFunction.CountIf(rngDB, rng)
            rng.Resize(1, n).Merge
            rng.HorizontalAlignment = xlCenter
        End If
    Next rng
    Application.DisplayAlerts = True

【讨论】:

  • 嗨@Dy.Lee,如果你没问题,我可以要求你解释一下你的代码。我的意思是发生了什么以及它是如何工作的。
  • @HydesYase:代码的原理很简单。合并单元格时,单元格为空。因此,其他具有相同值的单元格为空单元格,否则为第一个单元格。合并方法应用于第一个单元格。(如果 rng"")。在 range 中,您可以通过 worksheetfunctoion.countif 计算相同值的单元格。并且可以合并通过 resize(row,column) 方法计数的单元格。
  • 非常感谢您的解释
【解决方案2】:

这个怎么样?

With ActiveSheet
  firstCol = 1
  lastCol = .Cells(1, .Cells.Columns.Count).End(xlToLeft).Column
  For i = 1 To lastCol
    If .Cells(1, i) = "" Then GoTo NextCol 'skip blank cell

    If firstCol = 0 And .Cells(1, i) <> "" Then firstCol = i  'set first column

    If .Cells(1, i) = .Cells(1, i + 1) Then
        LastColDup = i  'remember last duplicate column
    Else
        Application.DisplayAlerts = False
        With .Range(Cells(1, firstCol), Cells(1, LastColDup + 1))
            .Merge
            .HorizontalAlignment = xlCenter
        End With
        Application.DisplayAlerts = True
        firstCol = 0
        LastColDup = 0
    End If
NextCol:
  Next i
End With

【讨论】:

    【解决方案3】:

    如果您事先知道范围,那么您可以调整下面的代码。我通过录制宏然后根据需要禁用/启用警报来创建它。我已经包含了一个将整数列值转换为 alph 等效项的函数。MainLoop Intcol1intcol2 将是您根据原始表单的输入提供的值。

    Sub MainLoop()
     Dim StrMycol_1 As String
     Dim StrMycol_2 As String
     Dim intcol1 As Integer
     Dim intcol2 As Integer
    
      intcol1 = 5: intcol2 = 7
    
      StrMycol_1 = WColNm(intcol1) ' mycell.column is numeric. Function returns integer
      StrMycol_2 = WColNm(intcol2) ' mycell.column is numeric. Function returns integer
    '
      do_merge_centre StrMycol_1, StrMycol_2
    End Sub
    
    Sub do_merge_centre(col1, col2)
    Range(col1 + "1:" + col2 + "1").Select
    Application.DisplayAlerts = False
    With Selection
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlBottom
        .WrapText = False
        .Orientation = 0
        .AddIndent = False
        .IndentLevel = 0
        .ShrinkToFit = False
        .ReadingOrder = xlContext
        .MergeCells = False
    End With
    Selection.Merge
    Application.DisplayAlerts = True
    End Sub
    '
    Public Function WColNm(ColNum) As String
        WColNm = Split(Cells(1, ColNum).Address, "$")(1)
    End Function
    

    【讨论】:

    • 我有一个用户表单,我正在循环访问其中的控件以确定范围。将来,我可能想向该用户表单添加更多控件,并且我认为如果每次都必须更改范围可能会很麻烦。这就是我循环控制控件的原因,它会自动执行此操作。
    • 好吧,如果你知道会有多少重复,那么你可以将上面的代码改编为子例程并传入所需的范围值(即将列号更改为等效的字母字符)
    • @HydesYase。请参阅将数字列转换为 alpha 列范围的更新答案
    猜你喜欢
    • 2015-08-03
    • 2018-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多