【问题标题】:Excel Visual Basic Macro to merge cells in a selected areaExcel Visual Basic 宏用于合并选定区域中的单元格
【发布时间】:2016-09-06 23:39:11
【问题描述】:

我有一个 excel 电子表格,我想将每个单元格与其中的值合并到它下面的每个空单元格,直到该列中的下一个单元格具有值。

目前我有这个:

Sub mergemainbody()    
    lrow = ActiveSheet.UsedRange.Rows.Count - 2        
    On Error Resume Next  
    Application.DisplayAlerts = False  
    For col = 1 To 50  
       For Each ar In Cells(3, col).Resize(lrow).SpecialCells  (xlCellTypeBlanks).Areas  
          ar.Resize(ar.Rows.Count + 1).Offset(-1).Merge  
       Next  
    Next  
 End Sub

这适用于整个工作表,但我希望宏仅适用于选定区域。然而,简单地将For col = 1 to 50 更改为For Each cell In Selection 会使宏看起来什么都不做。

数据示例:

Heading | Heading   | Heading   | Heading   |      
1456262 | 270520    | 574038    | 583059    |    
Words   | --------- | --------- | --------- |  
586048  | --------- | --------- | --------- |        
Words   | 694574    | 856738    | 068438    |    

其中 --- 表示单元格为空。

【问题讨论】:

  • 你能否详细说明停止工作它是如何停止工作的,它什么也不做,你有没有收到错误代码或什么?
  • 您是否尝试过先根据您的选择设置一个范围,然后在该范围内循环?
  • @litelite 对不起,它什么也没做,没有错误代码!
  • @CallumDA33 我的问题是,理想情况下,随着更多数据添加到电子表格中,我希望我的同事将此宏用于不同区域,因此我不希望它仅用于固定区域如果这有意义吗?还是我误解了你的问题?
  • @BruceWayne 不幸的是,我不需要合并 - 我也认为这是一个坏主意,但我没有选择遗憾。您是否尝试使用“选择中的每个单元格”或“col = 1 到 50”?

标签: vba excel macros


【解决方案1】:

这是一个粗略的方法,可以根据您的要求合并您的选择。请注意,如果第一个单元格中没有值,这将无法按照您的预期方式工作

Sub MergeDown()
    Dim rng As Range, r As Range
    Dim i As Integer

    Set rng = Selection
    For Each r In rng
        If r.Value <> "" Then
            i = 1
            While r.Offset(i, 0).Value = "" And Not Intersect(r.Offset(i, 0), rng) Is Nothing
                i = i + 1
            Wend
            r.Resize(i, 1).Merge
        End If
    Next r
End Sub

【讨论】:

  • 谢谢!很有帮助
  • @ElinB - 请注意,您的主要原始错误是由于您没有正确(或根本没有)声明变量而引起的。这个解决方案当然有效,但不要忽视这个事实。确保始终声明您的变量。我建议始终将Option Explicit 添加到您的代码中,以确保它们被声明。
【解决方案2】:

我假设您不想将第二行与标题行合并。

在使用 Range.CurrentRegion propertyRange.Resize / Range.Offset 属性将数据块中从 A1 向外辐射的第 3 行隔离到最后使用的行之后,将 Range.SpecialCells methodxlCellTypeBlanks 一起使用.当您循环浏览 Range.Areas property 时,请在合并前调整大小和偏移量。

Dim c As Long, a As Long
With ActiveSheet
    'work on the block of data radiating out from A1
    With .Cells(1, 1).CurrentRegion
        'move off the header row and first row of data
        With .Resize(.Rows.Count - 2, .Columns.Count).Offset(2, 0)
            'work through the columns
            For c = 1 To .Columns.Count
                'locate the blank cells in groups (aka Areas)
                With .Columns(c).Cells.SpecialCells(xlCellTypeBlanks)
                    'cycle through the areas (blank cell groups)
                    For a = 1 To .Areas.Count
                        'work with each Area in turn
                        With .Areas(a).Cells
                            'resize one row larger and offset one row up
                            .Resize(.Rows.Count + 1, 1).Offset(-1, 0).Merge
                            'optionally center the value in the newly merged cells
                            .VerticalAlignment = xlCenter
                        End With
                    Next a
                End With
            Next c
        End With
    End With
End With

【讨论】:

  • 你觉得CurrentRegion 工作得很好,经常使用吗?它如何决定CurrentRegion 是什么?在这种情况下,它是.Selection 的替代品吗?或者它是否对列范围执行.End(xlRight),对最后一行执行.End(xlDown)
  • 每当有数据“孤岛”时,我都会经常使用它。从原点开始,.CurrentRegion 向各个方向辐射,直到遇到工作表的末尾、完全空白的行或完全空白的列。当前区域内可以有空白单元格,但不能有完全空白的行或列。可以通过点击[ctrl]+A一次手动模拟。
【解决方案3】:

我相信您的问题是从未声明变量,因此 VBA 正在猜测它们是什么。使用此代码,看看是否有任何错误:

Option Explicit
Sub mergemainbody()
Dim selRange As Range
Dim lRow    As Long
Dim ar As Range, col As Range

Set selRange = Selection
lRow = selRange.Rows.Count - 2    ' Why -2?
'On Error Resume Next
Application.DisplayAlerts = False

For Each col In selRange.Columns
    For Each ar In Cells(3, col.Column).Resize(lRow).SpecialCells(xlCellTypeBlanks).Areas
        ar.Resize(ar.Rows.Count + 1).Offset(-1).Merge
    Next
Next col
End Sub

它可能抛出的唯一错误是没有更多SpecialCells(xlCellTypeBLanks)之后的错误,这意味着它成功地运行了所有单元格。

【讨论】:

  • 确实可以正常工作,谢谢!问题是我不希望它在整个工作表上工作,我希望它只在选定的单元格上工作(所以我的同事可以在将更多数据添加到工作表时使用它)。有没有办法让它做到这一点?
  • @ElinBarrett - 查看编辑。它应该遍历 selected 范围内的所有列。
【解决方案4】:

取出“On Error Resume Next”,这是隐藏任何错误的可靠方法..

【讨论】:

  • 感谢您的提示!当我这样做时,我只会得到一个“400”错误框
  • 这将显示错误,但不太可能是问题的答案。这更适合发表评论。
  • @BruceWayne - 它已经揭开了错误的面纱,所以它肯定是为什么它不起作用的一个答案 - 发生了一个正在被吞没的错误。
猜你喜欢
  • 1970-01-01
  • 2018-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-09
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
相关资源
最近更新 更多