ExcelTip.Net留存知识帖 ---【注:附件之前被网盘供应商清空后,现已修复-现已修复-现已修复为本地下载!】
现在位置:首页 > E问E答 > Excel VBA > 如何定义返回多个区域唯一值的自定义函数?

如何定义返回多个区域唯一值的自定义函数?

作者:绿色风 分类: 时间:2022-08-17 浏览:128
楼主
BIN_YANG168
Q:怎样用自定义函数返回多个区域唯一值?
A:按Alt+F11,插入→模块→在VBE窗口中输入以下代码:


  1. Function GetUniqueList(mode As Integer, ParamArray Rngs() As Variant) '返回唯一值列表的函数
  2. Dim UniqueListCount As Long, i As Long, j As Long, k As Long, Cnt1 As Long, Cnt2 As Long, m As Integer
  3. Dim Wksht As Worksheet, singleArea As Range, cell As Range
  4. Dim ListArray() As Variant, Wkshtfun As WorksheetFunction
  5. Application.Volatile True '定义为易失函数
  6. Set Wkshtfun = Application.WorksheetFunction
  7. i = 0
  8. '求出各个区域中非空白单元格总数
  9. For j = 0 To UBound(Rngs)
  10.     i = i + Wkshtfun.CountA(Rngs(j))
  11. Next j
  12. '如果没有非空白单元格运行下段代码后结束
  13. If i = 0 Then
  14.     GetUniqueList = ""
  15.     Exit Function
  16. End If
  17. '如果有非空白单元格运行下面代码
  18. ReDim ListArray(1 To i)
  19. UniqueListCount = 0
  20. For m = 0 To UBound(Rngs) '循环每个区域
  21.     Set singleArea = Rngs(m)
  22.     Set Wksht = Rngs(m).Parent '定义引用区域的工作表
  23.     If Wkshtfun.CountA(singleArea) <> 0 Then
  24.         Set singleArea = Intersect(Wksht.UsedRange, singleArea) '定义引用范围中的已用区域
  25.         With singleArea
  26.             If mode = 0 Then
  27.                 Cnt1 = .Rows.Count: Cnt2 = .Columns.Count
  28.             Else
  29.                 Cnt1 = .Columns.Count: Cnt2 = .Rows.Count
  30.             End If
  31.             For i = 1 To Cnt1
  32.                 For j = 1 To Cnt2
  33.                     If mode = 0 Then
  34.                         Set cell = .Cells(i, j)
  35.                     Else
  36.                         Set cell = .Cells(j, i)
  37.                     End If
  38.                     If cell <> "" Then '非空白单元格才运行
  39.                         If UniqueListCount = 0 Then '列表的首个值才运行
  40.                             ListArray(1) = cell
  41.                             UniqueListCount = 1
  42.                             GoTo ExitLoop
  43.                         End If
  44.                         For k = 1 To UniqueListCount
  45.                             If ListArray(k) = cell Then GoTo ExitLoop '判别是否为重复值
  46.                         Next k
  47.                         UniqueListCount = UniqueListCount + 1
  48.                         ListArray(UniqueListCount) = cell
  49.                     End If
  50. ExitLoop:
  51.                 Next j
  52.             Next i
  53.         End With
  54.     End If
  55. Next m
  56. '求出多单元格数组公式输入区域的最大行或列数
  57. i = Wkshtfun.Max(Application.Caller.Rows.Count, Application.Caller.Columns.Count)
  58. '如果是输入在一个单元格中就返回完整的唯一值列表数组
  59. If i = 1 Then
  60.     ReDim Preserve ListArray(1 To UniqueListCount)
  61.     GetUniqueList = Wkshtfun.Transpose(ListArray)
  62.     Exit Function
  63. End If
  64. '如果是输入在一个多单元格区域中就返回一个与输入区域相适应的数组
  65. ReDim Preserve ListArray(1 To i) '重定义数组尺寸大小并保留已有的值
  66. If i > UniqueListCount Then '对超出唯一值列表数的部分赋空值
  67.     For j = UniqueListCount + 1 To i
  68.         ListArray(j) = ""
  69.     Next j
  70. End If
  71. GetUniqueList = Wkshtfun.Transpose(ListArray) '将数组作为函数的返回值
  72. End Function

自定义函数GetUniqueList(mode,ref1,ref2,...)

参数说明:

mode:各区域中值的顺序方式,0为先行后列方式,其他值为先列后行方式。

ref1等:表示对一个连续区域的引用,各参数间以“,”号分隔,可以引用整列。

函数返回:返回引用的所有区域中唯一值的列表数组,如公式输入在一个单元格中,

返回一个完整的唯一值列表;如输入在一个多单元格区域中,返回一个与输入区域

相适应的数组。

应该输入在一个单元格中,或按多单元格数组公式的输入方式输入在一个区域中

并按ctrl+shift+enter三键结束。

VBA返回数组的限制,以多单元格数组公式的方式输入时,输入区域不能多于5461行。

返回多个区域唯一值的自定义函数.rar
2楼
DJ_Soo
  1. Function Unique(Rng As Variant, Optional Num)
  2.     Dim Dict As Object
  3.     Dim Cnt As Long
  4.     Dim i As Long
  5.     Dim RngTmp 'As Range
  6.     Dim arr() As String
  7.     Dim arrTmp As Variant
  8.     Dim Str As String
  9.     Set Dict = CreateObject("scripting.dictionary")
  10.     Cnt = Application.CountA(Rng)
  11.     ReDim arr(Cnt) As String
  12.     i = 1
  13.     For Each RngTmp In Rng
  14.         If RngTmp <> "" Then
  15.             arr(i) = RngTmp
  16.             i = i + 1
  17.             If i = Cnt + 1 Then Exit For
  18.         End If
  19.     Next
  20.     For i = 1 To Cnt
  21.         Dict(arr(i)) = ""
  22.     Next
  23.     Cnt = Dict.Count
  24.     Str = Join(Dict.keys, "|")
  25.     arrTmp = Split(Str, "|")
  26.     ReDim Preserve arrTmp(1 To Cnt)
  27.     If IsMissing(Num) Then
  28.         Unique = arrTmp
  29.     ElseIf Num = 0 Then
  30.         Unique = Join(Dict.keys, ",")
  31.     Else
  32.         If Num > Cnt Then
  33.             Unique = ""
  34.         Else
  35.             Unique = arrTmp(Num)
  36.         End If
  37.     End If
  38. End Function
这个是我的代码,也发上来.
3楼
wise



study DJ

免责声明

有感于原ExcelTip.Net留存知识的价值及部分知识具有的时间限定性因素, 经与ExcelTip.Net站长Apolloh商议并征得其同意, 现将原属ExcelTip.Net的知识帖采集资料于本站点进行展示, 供有需要的人士查询使用,也慰缅曾经的论坛时代。 所示各个帖子的原作者如对版权有异议, 可与本人沟通提出,或于本站点留言,我们会尽快处理。 在此,感谢ExcelTip.Net站长Apolloh的支持,感谢本站点所有人**绿色风(QQ:79664738)**的支持与奉献,特此鸣谢!
------本人网名**KevinChengCW(QQ:1210618015)**原ExcelTip.Net总版主之一

评论列表
sitemap