需要修改列连接VBA脚本以仅连接所选列,以及用逗号分隔连接的列

Need to modify column concatenate VBA script to join selected columns only instead as well as to separate joined columns with a comma

提问人:user16201107 提问时间:11/8/2023 最后编辑:Tim Williamsuser16201107 更新时间:11/9/2023 访问量:79

问:

我需要获取以下代码:

Sub ConcatColumns()

   Do While ActiveCell <> "" 


      ActiveCell.Offset(0, 1).FormulaR1C1 = _
         ActiveCell.Offset(0, -1) & " " & ActiveCell.Offset(0, 0)

      ActiveCell.Offset(1, 0).Select
   Loop

End Sub

我需要修改它,以便它不仅可以连接两列,而且最多可以连接 4 列,并且可以选择要连接的列。我还需要用逗号分隔连接的文本,由于这是 Excel,我想知道如果其中一列是日期,是否有办法添加一些格式?

例如,在使用 TEXTJOIN 时,我必须手动使用此公式来确保我的日期格式为 mm/dd/yyyy:

=TEXTJOIN(",",TRUE,IF(I4="","",(TEXT(I4,"mm/dd/yyyy"))),IF(J4="","",(TEXT(J4,"mm/dd/yyyy"))),IF(K4="","",(TEXT(K4,"mm/dd/yyyy"))))

这是我的数据的样子:

原始数据
enter image description here

这可以与多达 5-10 组其他 ID 及其日期一起进行。

这是我需要的结果,我现在必须用 =TEXTJOIN 做什么:

enter image description here

正如你所看到的,即使我尝试使用下拉列表来做,日期也没有格式化,所以我必须用我上面粘贴的公式添加一些=TEXT格式。

提前致谢!

Excel VBA 自动化 串联 TextJoin

评论

0赞 FunThomas 11/8/2023
为什么要使用VBA编写公式?
0赞 user16201107 11/8/2023
我想它不一定是 VBA,只要它做它应该做的事情?最烦人的是日期格式,有时我必须为不同的列集 TEXTJOIN 5-6 次,所以我想自动化它。
0赞 FunThomas 11/8/2023
问题是您是否需要一个公式(每次单元格内容更改时由 Excel 计算)或者它是否足以设置一次结果(使用纯 VBA)
0赞 user16201107 11/8/2023
我的数据设置没有任何公式。我想使用VBA宏来代替我每次都必须使用的公式来连接+格式化日期。
0赞 PeterT 11/8/2023
修改上面的代码以联接两列或多列非常简单。不清楚的是,解决方案的逻辑是,当您想要连接两列、三列或四列时。哪一列有日期字段?您究竟希望如何选择要连接的列?

答:

0赞 Tim Williams 11/9/2023 #1

这里有一种方法。它将按照选择单元格/区域的顺序连接选择单元格内容(幸运的是,当您进行多区域选择时,Excel 会跟踪这一点)。结果进入最后选择的单元格。

'When multiple cells in a row are selected, join the values from those cells with a comma,
'   and place the result in the last-selected cell
Sub JoinCells()
    Dim sel As Range, area As Range, c As Range, cDest As Range
    Dim addr As String, txt As String, sep As String, v

    Set sel = Selection

    'check that at least 3 cells are in the same row are selected...
    If sel.EntireRow.Cells.CountLarge > Rows(1).Count Or sel.Cells.Count < 3 Then
        MsgBox "Select at least 3 cells on the same row.", vbExclamation
        Exit Sub
    End If
    
    Do While Application.CountA(sel) > 0           'while any data in selected cells
        Set cDest = sel.Areas(sel.Areas.Count)     'last area selected
        Set cDest = cDest.Cells(cDest.Cells.Count) 'the last cell in that area is where the result goes
        addr = cDest.Address
        txt = ""    'reset result
        sep = ""    'reset separator
        For Each area In sel.Areas         'loop selected areas
            For Each c In area.Cells       'then cells within areas
                If c.Address <> addr Then  'not the "result" cell?
                    v = c.Value
                    If Len(v) > 0 Then     'any value to add?
                        txt = txt & sep & IIf(IsDate(v), Format(v, "mm/dd/yyyy"), v)
                        sep = ","          'add separator after first value
                    End If
                End If
            Next c
        Next area
        cDest.Value = txt       'populate the last selected cell
        Set sel = sel.Offset(1) 'next row down
    Loop
    
End Sub

示例:按住 Ctrl 键时按显示的顺序选择第 3 行上的单元格。确保选择最后一个空单元格作为结果的目标。
注意:只要它们有内容,宏就会在下面的行中向下移动,因此只需选择要处理的数据第一行上的单元格。

enter image description here

结果:
enter image description here

评论

0赞 user16201107 11/9/2023
非常感谢您抽出宝贵时间来做这件事,这是我需要的一个非常好的方法,我认为它可以完美地工作。但是,我认为我应该添加一些视觉效果,就像您处理我的数据一样,以便您更好地了解我正在处理的内容。我现在已将这些添加到我的原始帖子中。 原始数据是:[i.stack.imgur.com/BbEvR.png],我想要的结果是:[i.stack.imgur.com/e7RZv.png]。请注意,图片中没有日期格式,但我确实需要您已经添加到脚本中的日期。再次感谢你们!
0赞 Tim Williams 11/9/2023
上述方法适合您,但您需要分 3 个步骤完成......
0赞 user16201107 11/9/2023
你的意思是每次运行宏 3 行吗?
0赞 Tim Williams 11/9/2023
不,我的意思是选择第一行上的所有 ID 单元格,然后选择要在连接后放置这些单元格的单元格。运行宏,然后对 Eff Date 和 Exp Date 执行相同的过程
0赞 user16201107 11/9/2023
谢谢!我尝试运行它,但它在这里出错 imgur.com/DH0XvjT