【问题标题】:Excel user defined function to accept named range intsead of cell rangeExcel 用户定义函数接受命名范围而不是单元格范围
【发布时间】:2021-08-01 12:39:07
【问题描述】:

已按照一些说明创建用户定义函数以在最新版本的 Excel 中复制 TEXTJOIN 函数。它可以创建一个函数,然后您可以将其用作任何其他函数,将单元格范围的内容输出到单个单元格,以逗号分隔。

这很好用,但是我无法让这个函数接受命名范围而不是单元格范围。这可能吗?

语法如下: =My_Text_Join(“,”,1, name-of-namedrange)

Option Explicit
Function My_Text_Join(delimiter As String, ignore_empty As Boolean, text_range As Range) As String

Application.Volatile
Dim c As Range
Dim n As Long
n = 0
For Each c In text_range
 If ignore_empty = True Then
 If VBA.IsEmpty(c.Value) = False Then
 If n = 0 Then
 My_Text_Join = c.Value
 Else
 My_Text_Join = My_Text_Join & delimiter & c.Value
 End If
 n = n + 1
 End If
 
 Else
 
 If n = 0 Then
 My_Text_Join = c.Value
 Else
 My_Text_Join = My_Text_Join & delimiter & c.Value
 End If
 n = n + 1
 
 End If
Next

End Function

【问题讨论】:

  • 您可能会找到 MS doc。 Refer to Named Ranges 有帮助。
  • 我用一个命名的 ranged(命名为prueba)尝试了你的编码,它工作得很好。我用过=My_Text_Join(";";1;prueba)。你遇到了什么错误?你怎么称呼你的命名范围?
  • 你的代码没问题。您确定您定义的名称实际上返回了一个范围,并且您正确地传递了它 - 即 name-of-range 而不是 "name-of-range"
  • 我现在有这个工作。令人难以置信的是,它就像在分隔线周围使用的引号一样简单。我复制并粘贴了我遵循的示例中的语法,分别是 66 和 99 与直线!

标签: excel vba named-ranges


【解决方案1】:

试试这个代码(可以采用可变数量的不同类型的参数 - 连续或不连续的范围、名称、常量;例如 =TXTJOIN("/",THENAME,C1:C3,"Fourth",777)

编辑: 新增功能 - 如果一个参数可以被评估为 Range,它将被转换为 Range:如果名称 THENAME 被定义,=TXTJOIN("/","THENAME",C1:C3,"Fourth",777)=TXTJOIN("/",THENAME,C1:C3,"Fourth",777) 输出相同的结果

Option Explicit

Public Function TXTJOIN(Delimiter As String, ParamArray args() As Variant)
    Dim A As Variant, cl As Range
    TXTJOIN = vbNullString
    For Each A In args
        On Error Resume Next
        Set A = Names(A).RefersToRange    ' if an argument can be evaluated as Range, it will be converted to Range
        On Error GoTo 0
        Select Case TypeName(A)
            Case "Range"
                For Each cl In A
                    TXTJOIN = IIf(TXTJOIN = vbNullString, cl.Text, _
                              TXTJOIN & Delimiter & cl.Text)
                Next
            Case Else
                TXTJOIN = IIf(TXTJOIN = vbNullString, A, _
                          TXTJOIN & Delimiter & A)
        End Select
    Next
End Function

Edit2:已完成重构,添加了 skipEmpty,修复了 Names 问题

Option Explicit

Public Function TXTJOIN(Delimiter As String, skipEmpty As Boolean, ParamArray args() As Variant) As String
    Dim A As Variant, cl As Range, buffer As String
    For Each A In args
        If TypeName(A) = "String" Then ' if an *string* argument can be evaluated as Range, it will be done
            On Error Resume Next
            Set A = Names(A).RefersToRange
            On Error GoTo 0
        End If
        If TypeName(A) = "Range" Then
            For Each cl In A
                buffer = cl.text    ' buffer is used to minimize the number of cell reads
                If Not skipEmpty Or Len(buffer) > 0 Then _
                   TXTJOIN = TXTJOIN & Delimiter & buffer
            Next cl
        Else
            If Not skipEmpty Or Len(A) > 0 Then _
                TXTJOIN = TXTJOIN & Delimiter & A
        End If
    Next A
    TXTJOIN = Mid(TXTJOIN, Len(Delimiter) + 1) ' remove lead Delimiter occur
End Function 

【讨论】:

  • 我注意到一个问题。如果您使用数字,例如 1,它将显示第一个命名范围、2、第二个等。虽然顺序不一致,所以我不确定创建范围是否按顺序排列,或者.... .. 虽然像 777 这样的高数字显示为数字,因为它太高而无法引用任何命名范围。无论如何,在我的工作簿中。
  • @ayecee 因为Names是Collection,item可以通过数字或者key获取。见解决方案的Edit2
  • 第二次编辑中的某些内容使其无法正常工作。我得到一个#VALUE!错误。当我恢复到第一个代码时,它又可以工作了。
  • Сheck参数,第一个版本有2+,第二个版本有3+(skipEmpty添加)
  • 你的意思是我输入的参数和你写的完全一样吗?我已经复制粘贴了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-14
  • 1970-01-01
  • 2017-12-31
  • 1970-01-01
  • 2016-02-29
  • 2017-02-03
  • 2023-03-10
相关资源
最近更新 更多