ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: WYS67

[已解决] 按指定条件、指定序号忽略空格提取对应数据的自定义函数

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-1-14 12:56 | 显示全部楼层
yjh_27 发表于 2020-1-14 12:51
目前各参数是按单列处理,输出也是按单列处理。

如参数、输出都是单列或单行,找到识别能做到。

怎样才能使公式忽略数据源的行、列区分 ,无论在列区域,还是行区域输入数组公式,都能显示正确结果?

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-1-14 13:22 | 显示全部楼层
怎样才能使公式忽略数据源的行、列区分 ,无论在列区域,还是行区域输入数组公式,都能显示正确结果?

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-1-14 14:33 | 显示全部楼层
使公式能够忽略数据源的行、列区分 ,无论在列区域,还是行区域输入数组公式,都能显示正确结果?

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-1-14 16:57 | 显示全部楼层
怎样才能使公式忽略数据源的行、列区分 ,无论在列区域,还是行区域输入数组公式,都能显示正确结果?

TA的精华主题

TA的得分主题

发表于 2020-1-14 17:03 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
  1. Option Explicit

  2. Function ZDXHTQ(rgFind As Range, varFind As Variant, rgData As Range, varID As Variant) As Variant
  3.     Dim arrFind As Variant, arrData As Variant, arrID As Variant, arrReturn As Variant
  4.     Dim arrTemp As Variant, strTemp As String, strFind As String
  5.     Dim rgTemp As Range, lngRows As Long, lngCols As Long
  6.     Dim lngMaxID As Long, lngRid As Long, lngCid As Long
  7.     Dim lngMin As Long, lngMax As Long, lngTemp As Long
  8.    
  9.    
  10.     Dim intFindRowOrCol As Integer '条件区域为行还是列, 0 为列,1为行
  11.     Dim intDataRowOrCol As Integer '数据区域为行还是列, 0 为列,1为行
  12.     Dim intReturnRowOrCol As Integer '返回区域为行还是列, 0 为列,1为行

  13.     '判断公式所在区域的设置
  14.     '-------------------------------------------------------
  15.     Set rgTemp = Application.Caller
  16.     lngRows = rgTemp.Rows.Count
  17.     lngCols = rgTemp.Columns.Count
  18.     ReDim arrReturn(1 To lngRows, 1 To lngCols) As String
  19.     Set rgTemp = Nothing
  20.     If lngRows <> 1 And lngCols <> 1 Then
  21.         arrReturn(1, 1) = "公式区域有误!"
  22.         ZDXHTQ = arrReturn
  23.         Exit Function
  24.     End If
  25.     '列优先
  26.     If lngRows = 1 Then
  27.         intReturnRowOrCol = 1
  28.     End If
  29.     If lngCols = 1 Then
  30.         intReturnRowOrCol = 0
  31.     End If
  32.    
  33.     '判断条件区域的设置
  34.     '-------------------------------------------------------
  35.     arrFind = rgFind
  36.     lngRows = rgFind.Rows.Count
  37.     lngCols = rgFind.Columns.Count
  38.     If lngRows <> 1 And lngCols <> 1 Then
  39.         arrReturn(1, 1) = "条件区域有误!"
  40.         ZDXHTQ = arrReturn
  41.         Exit Function
  42.     End If
  43.     '列优先
  44.     If lngRows = 1 Then intFindRowOrCol = 1
  45.     If lngCols = 1 Then intFindRowOrCol = 0
  46.    
  47.     '判断查找值
  48.     '-------------------------------------------------------
  49.     If IsArray(varFind) Then
  50.         arrReturn(1, 1) = "查找值有误!"
  51.         ZDXHTQ = arrReturn
  52.         Exit Function
  53.     End If
  54.     strFind = Trim(varFind)
  55.     If strFind = "" Then
  56.         arrReturn(1, 1) = "查找值有误!"
  57.         ZDXHTQ = arrReturn
  58.         Exit Function
  59.     End If
  60.    
  61.    
  62.     '判断数据区域的设置
  63.     '-------------------------------------------------------
  64.     arrData = rgData
  65.     lngRows = rgData.Rows.Count
  66.     lngCols = rgData.Columns.Count
  67.     If lngRows <> 1 And lngCols <> 1 Then
  68.         arrReturn(1, 1) = "数据区域有误!"
  69.         ZDXHTQ = arrReturn
  70.         Exit Function
  71.     End If
  72.     '列优先
  73.     If lngRows = 1 Then intDataRowOrCol = 1
  74.     If lngCols = 1 Then intDataRowOrCol = 0
  75.    
  76.     '比对条件区域与数据区域,以最小行列数 为循环终止数
  77.     '-------------------------------------------------------
  78.     If intDataRowOrCol = 1 Then
  79.         lngMaxID = UBound(arrData, 2)
  80.     Else
  81.         lngMaxID = UBound(arrData)
  82.     End If
  83.     If intFindRowOrCol = 1 Then
  84.         If lngMaxID > UBound(arrFind, 2) Then lngMaxID = UBound(arrFind, 2)
  85.     Else
  86.         If UBound(arrFind, 2) > UBound(arrFind) Then lngMaxID = UBound(arrFind)
  87.     End If

  88.     '序号处理
  89.     '-------------------------------------------------------
  90.     arrTemp = varID
  91.     If IsArray(varID) Then
  92.         '如果是数组
  93.         On Error Resume Next '出错处理
  94.         lngRows = UBound(arrTemp)
  95.         lngCols = 0: lngCols = UBound(arrTemp, 2)
  96.         
  97.         Select Case lngCols
  98.             Case 0 '一维
  99.                 arrID = arrTemp
  100.             Case 1 '二维一列
  101.                 ReDim arrID(1 To lngRows) As String
  102.                 For lngRid = 1 To lngRows
  103.                     arrID(lngRid) = arrTemp(lngRid, 1)
  104.                 Next
  105.             Case Is > 1
  106.                 If lngRows <> 1 Then
  107.                     arrReturn(1, 1) = "序号区域有误!"
  108.                     ZDXHTQ = arrReturn
  109.                     Exit Function
  110.                 Else
  111.                     ReDim arrID(1 To lngCols) As String
  112.                     For lngCid = 1 To lngCols
  113.                         arrID(lngCid) = arrTemp(1, lngCid)
  114.                     Next
  115.                 End If
  116.         End Select
  117.     Else
  118.         '不是数组,判断是不是有冒号
  119.         If InStr(arrTemp, ":") > 0 Then
  120.             arrTemp = Split(arrTemp, ":")
  121.             lngMin = Val(arrTemp(0))
  122.             lngMax = Val(arrTemp(1))
  123.             lngTemp = Abs(lngMax - lngMin) + 1
  124.             ReDim arrID(1 To lngTemp) As String
  125.             lngTemp = 1
  126.             If lngMin < lngMax Then
  127.                 For lngRid = lngMin To lngMax
  128.                     arrID(lngTemp) = lngRid
  129.                     lngTemp = lngTemp + 1
  130.                 Next
  131.             Else
  132.                 For lngRid = lngMin To lngMax Step -1
  133.                     arrID(lngTemp) = lngRid
  134.                     lngTemp = lngTemp + 1
  135.                 Next
  136.             End If
  137.         Else
  138.             '没有,返回唯一值
  139.             ReDim arrID(1 To 1) As String
  140.             arrID(1) = Val(arrTemp)
  141.         End If
  142.     End If
  143.    
  144.    
  145.     '判断序号数量与公式所在区域是否匹配
  146.     '-------------------------------------------------------
  147.     If intReturnRowOrCol = 1 Then
  148.         lngCid = UBound(arrReturn, 2)
  149.     Else
  150.         lngCid = UBound(arrReturn)
  151.     End If
  152.    
  153.     If lngCid < UBound(arrID) Then
  154.         arrReturn(1, 1) = "公式区域小于序列数量!"
  155.         ZDXHTQ = arrReturn
  156.         Exit Function
  157.     End If
  158.    
  159.    
  160.     '查找运算
  161.     '-------------------------------------------------------
  162.     ReDim arrTemp(1 To lngMaxID): lngTemp = 1
  163.     Select Case intFindRowOrCol
  164.         Case 1
  165.             For lngCid = LBound(arrFind, 2) To lngMaxID
  166.                 If arrFind(1, lngCid) = strFind Then
  167.                     If intDataRowOrCol = 1 Then
  168.                         If arrData(1, lngCid) <> "" Then arrTemp(lngTemp) = arrData(1, lngCid): lngTemp = lngTemp + 1
  169.                     ElseIf intDataRowOrCol = 0 Then
  170.                         If arrData(lngCid, 1) <> "" Then arrTemp(lngTemp) = arrData(lngCid, 1): lngTemp = lngTemp + 1
  171.                     End If
  172.                 End If
  173.             Next
  174.             lngMaxID = lngTemp
  175.         Case 0
  176.             For lngRid = LBound(arrFind) To lngMaxID
  177.                 If arrFind(lngRid, 1) = strFind Then
  178.                     If intDataRowOrCol = 1 Then
  179.                         If arrData(1, lngRid) <> "" Then arrTemp(lngTemp) = arrData(1, lngRid): lngTemp = lngTemp + 1
  180.                     ElseIf intDataRowOrCol = 0 Then
  181.                         If arrData(lngRid, 1) <> "" Then arrTemp(lngTemp) = arrData(lngRid, 1): lngTemp = lngTemp + 1
  182.                     End If
  183.                 End If
  184.             Next
  185.             lngMaxID = lngTemp
  186.     End Select
  187.    
  188.     '根据序号提取值
  189.     '-------------------------------------------------------
  190.     For lngRid = LBound(arrID) To UBound(arrID)
  191.         lngTemp = (lngMaxID + Val(arrID(lngRid))) Mod lngMaxID
  192.         arrID(lngRid) = arrTemp(lngTemp)
  193.     Next
  194.         
  195.     '根据公式区域形式返回行或列
  196.     '-------------------------------------------------------
  197.     For lngRid = LBound(arrID) To UBound(arrID)
  198.         If intReturnRowOrCol = 1 Then
  199.             arrReturn(1, lngRid) = arrID(lngRid)
  200.         Else
  201.             arrReturn(lngRid, 1) = arrID(lngRid)
  202.         End If
  203.     Next
  204.    
  205.     '返回值
  206.     '-------------------------------------------------------
  207.     ZDXHTQ = arrReturn
  208. End Function
复制代码

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-1-14 17:31 | 显示全部楼层

经反复测试,老师编写的代码都能显示正确的结果,非常感谢老师!!!

祝老师新年快乐!

TA的精华主题

TA的得分主题

发表于 2020-1-14 19:47 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 lss001 于 2020-1-17 12:52 编辑
WYS67 发表于 2020-1-14 14:33
使公式能够忽略数据源的行、列区分 ,无论在列区域,还是行区域输入数组公式,都能显示正确结果?
提取对应数据.rar (73.07 KB, 下载次数: 3)




评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-1-14 21:10 | 显示全部楼层

感谢老师!祝老师新年快乐!
1.gif

提取对应数据.zip (206.19 KB, 下载次数: 1)

如果能够实现15楼代码具备的功能【见上面截图H4:AA11的计算结果】就更加完美和强大了!

1.当采取区域数组公式输入时,第四参数既可以用C5:C22的单元格指定,也可以直接输入带起止标志的连续序号范围【如"1:18",代表符合指定条件的、自上而下的第1~18个数据,"18:1"则是代表符合指定条件的、自上而下的第18~1个数据;而"-1:-18"代表符合指定条件的、自下而上的的第1~18个数据,"-18:-1"代表符合指定条件的、自下而上的的第18~1个数据】
2.公式忽略数据源的行、列区域差异 ,无论在列区域,还是行区域输入数组公式,都能显示正确结果。

TA的精华主题

TA的得分主题

发表于 2020-1-14 23:36 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-1-15 02:34 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
lss001 发表于 2020-1-14 23:36
参考楼上更新附件。。。

1.gif

提取对应数据 (2).zip (198.51 KB, 下载次数: 3)

很好,很强大!

不知为什么,第四参数调用单元格指定时,D5:D22【列区域输入】可以显示查询结果,而J5:AA5【行区域输入】除J5外,K5:AA5怎么显示空白?K9:AA9也显示空白?
选定J5:AA5,输入区域数组公式 { =ZDXHTQ($A$5:$A$100000,$J$3,$B$5:$B$100000,J4:AA4) ;
选定J9:AA9,输入区域数组公式 { =ZDXHTQ($A$5:$A$100000,$J$3,$B$5:$B$100000,J8:AA8) 。

按说第二、第四参数都是既可以直接输入指定条件和序号,也可以调用单元格指定:J5:AA5应该与J6:AA6显示同样的结果,J9:AA9应该与J10:AA10显示同样的结果才对。

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-5-20 00:46 , Processed in 0.042035 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表