8

我有许多范围可以独立连接,并将连接范围的值放入不同的单元格中。

我想:
连接范围 A1:A10 中的值并将结果放入 F1
然后连接范围 B1:B10 并将结果放入 F2
然后连接范围 C1:C10 并将结果放入 F3 等。

以下宏连接范围 A1:A10,然后将结果放入 F1 (这是我想要的)。然而,它还将第一个串联的信息存储到内存中,这样当它进行下一个串联时,在单元格 F2 中,我得到了 F1 和 F2 的串联结果。

Sub concatenate()

    Dim x As String
    Dim Y As String

For m = 2 To 5

    Y = Worksheets("Variables").Cells(m, 5).Value 

    'Above essentially has the range information e.g. a1:a10 in sheet variables

    For Each Cell In Range("" & Y & "") 'i.e. range A1:A10
        If Cell.Value = "" Then GoTo Line1 'this tells the macro to continue until a blank cell is reached
        x = x & Cell.Value & "," 'this provides the concatenated cell value
    Next

Line1:

    ActiveCell.Value = x

    ActiveCell.Offset(1, 0).Select

Next m

End Sub
4

9 回答 9

12

这是我的 ConcatenateRange。如果您愿意,它允许您添加分隔符。它经过优化以处理大范围,因为它通过将数据转储到变体数组中并在 VBA 中使用它来工作。

你会像这样使用它:

=ConcatenateRange(A1:A10)

编码:

Function ConcatenateRange(ByVal cell_range As range, _
                    Optional ByVal seperator As String) As String

Dim newString As String
Dim cellArray As Variant
Dim i As Long, j As Long

cellArray = cell_range.Value

For i = 1 To UBound(cellArray, 1)
    For j = 1 To UBound(cellArray, 2)
        If Len(cellArray(i, j)) <> 0 Then
            newString = newString & (seperator & cellArray(i, j))
        End If
    Next
Next

If Len(newString) <> 0 Then
    newString = Right$(newString, (Len(newString) - Len(seperator)))
End If

ConcatenateRange = newString

End Function
于 2013-04-09T07:25:24.020 回答
4

...我会以非常不同的方式这样做...为什么不按照以下方式创建一个函数:

Function ConcatMe(Rng As Range) As String

Dim cl As Range

   ConcatMe = ""

   For Each cl In Rng
      ConcatMe = ConcatMe & cl.Text
   Next cl

End Function

然后,例如,设置 F1 =ConcatMe(A1:A10)或,然后编写代码将函数分配给您想要的单元格......

或者,正如@KazJaw 在他的评论中提到的那样,只是x=""在重新循环之前设置。

希望这可以帮助

于 2013-04-08T20:49:16.963 回答
3

它与这里已经发布的想法相似。但是,我使用 for each 循环而不是带有嵌套 for 循环的数组设置。

Function ConcRange(ByRef myRange As Range, Optional ByVal Seperator As String = "")

ConcRange = vbNullString

Dim rngCell As Range

For Each rngCell In myRange
    If ConcRange = vbNullString Then
        If Not rngCell.Value = vbNullString Then
            ConcRange = CStr(rngCell.Value)
        End If
    Else
        If Not rngCell.Value = vbNullString Then
            ConcRange = ConcRange & Seperator & CStr(rngCell.Value)
        End If
    End If
Next rngCell


End Function

我想这会比设置的数组更快,因为每次运行此函数时都不会创建一个新数组。

于 2013-11-14T12:29:53.357 回答
2

在 Next m 之前插入简单语句:x="" – KazimierzJawor 2013 年 4 月 8 日 20:43

我花了几分钟才注意到这个答案在评论中:p

于 2015-06-06T14:15:39.527 回答
0

谢谢大家,出于我的目的,我修改了你的建议并修改了我的代码,因为它不太适合一个简洁的函数,因为我需要它更加动态。请参阅下面的代码。它正是我需要的。

Sub concatenate()

Dim x As String
Dim Y As String

For Q = 1 To 10 'This provides a column reference to concatenate - Outer For statement
For T = 1 To 10 'This provides a rows reference to concatenate - Inner for statement

For Each Cell In Cells(T, Q) 'provides rows and column reference
If Cell.Value = "" Then GoTo Line1   'this tells the macro to continue until a blank cell is reached
x = x & Cell.Value & ","   'This provides the concatenated cell value and comma separator
Next ' this loops the range

Next T  'This is the inner loop which dynamically changes the number of rows to loop until a blank cell is reached

Line1:
On Error GoTo Terminate 'Terminates if there are less columns (max 10) to concatenate

ActiveCell.Value = Mid(x, 1, Len(x) - 1) 'This basically removes the last comma from the last concatenated cell e.g. you might get for a range 2,3,4, << this formula removes the last comma to
'give 2,3,4

ActiveCell.Offset(1, 0).Select 'Once the concatenated result is pasted into the cell this moves down to the next cell, e.g. from F1 to F2

x = ""  'The all important, clears x value after finishing concatenation for a range before moving on to another column and range


Next Q 'After one range is done the second column loop kicks in to tell the macro to move to the next column and begin concatenation range again

Terminate: 'error handler
End Sub
于 2013-04-09T22:01:55.053 回答
0

@Issun 的解决方案不接受工作表数组公式的输出作为“cell_range”参数的参数。但是对@Issun 的代码稍作修改可以解决这个问题。我还添加了一个检查,该检查忽略值为FALSE.

Function ConcatenateRange( _
        ByVal cellArray As Variant, _
        Optional ByVal seperator As String _
            ) As String

    Dim cell As Range
    Dim newString As String
    Dim i As Long, j As Long

    For i = 1 To UBound(cellArray, 1)
        For j = 1 To UBound(cellArray, 2)
            If Len(cellArray(i, j)) <> 0 Then
                If (cellArray(i, j) <> False) Then
                    newString = newString & (seperator & cellArray(i, j))
                End If
            End If
        Next
    Next

    If Len(newString) <> 0 Then
        newString = Right$(newString, (Len(newString) - Len(seperator)))
    End If

    ConcatenateRange = newString

End Function

例如:

A       B       (<COL vROW)
------  ------  -----------------
one     1         3
two     1         4
three   2         5
four    2         6

在单元格 C1 中输入下面的公式,然后按 CTRL+ENTER 将公式存储为数组公式:

{=ConcatenateRange(IF(B3:B6=1,A3:A6),CHAR(10))}
于 2015-07-17T23:28:30.450 回答
0

ConcatenateRange如果它们不为空且为空“”字符串,则连接范围内的所有单元格的函数。

  Function ConcatenateRange(cellRange As Range, Optional Delimiter As String) As String
    Dim cel As Range, conStr As String

    conStr = ""
    If Delimiter <> "" Then
      For Each cel In cellRange
        If VarType(cel) <> vbEmpty And Trim(cel) <> "" Then conStr = conStr & cel & Delimiter
      Next
      ConcatenateRange = Left(conStr, Len(conStr) - Len(Delimiter))
    Else
      For Each cel In cellRange
        If VarType(cel) <> vbEmpty And Trim(cel) <> "" Then conStr = conStr & cel
      Next
      ConcatenateRange = conStr
    End If
End Function
于 2019-11-14T13:18:33.573 回答
0

我正在进一步寻找是否有更好的方法来编写连接函数并发现了这一点。似乎我们都有相同的功能工作原理。所以没关系。

但我的函数不同,它可以接受多个参数,结合范围、文本和数字。

我假设分隔符是强制性的,所以如果我不需要它,我只需将“”作为最后一个参数)。

我还假设不会跳过空白单元格。这就是为什么我希望函数采用多个参数的原因,所以我可以轻松地省略那些我不想在连接中使用的参数。

使用示例:

=JoinText(A1:D2,F1:I2,K1:L1,";")

您还可以在参数中同时使用文本和数字:

=JoinText(A1:D2,123,F1:I2,K1:L1,"PQR",";")

我很想听听任何可以改进的意见或建议。

这是代码。

Public Function JoinText(ParamArray Parameters() As Variant) As String
    Dim p As Integer, c As Integer, Delim As String

    Delim = Parameters(UBound(Parameters))

    For p = 0 To UBound(Parameters) - 1
        If TypeName(Parameters(p)) = "Range" Then
            For c = 1 To Parameters(p).Count
                JoinText = JoinText & Delim & Parameters(p)(c)
            Next c
        Else
            JoinText = JoinText & Delim & Parameters(p)
        End If
    Next p

    JoinText = Replace(JoinText, Delim, "", , 1, vbBinaryCompare)

End Function
于 2016-01-02T14:09:11.403 回答
-5

它非常简单的兄弟,从 Excel 中看出来。不需要所有繁琐的公式或 VBA。

只需复制您需要连接的所有单元格并将其粘贴到记事本中。现在只需选择行/列之间的空间(实际上是 TAB 空间)并找到并替换它.. 完成.. 所有单元格都连接起来。现在只需将其复制并粘贴到列中并验证.. 就是这样:) 享受。

我建议您为此使用 Notepad++ :) Koodos

Vimarsh 博士植物生物技术。 /

于 2014-04-17T06:28:31.873 回答