ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

   
EH云课堂-专业的职场技能充电站 Excel转在线管理系统,怎么做看这里 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
Excel不给力? 何不试试FoxTable! Excel 2016函数公式学习大典 高效办公必会的Office实战技巧 免费下载Excel行业应用视频
300集Office 2010微视频教程 Tableau-数据可视化工具 精品推荐-800套精选PPT模板,点击获取 ExcelHome出品 - VBA代码宝免费下载
你的Excel 2010实战技巧学习锦囊 欲罢不能, 过目难忘的 Office 新界面 Excel VBA经典代码实践指南
楼主: WYS67

[求助] 按数值从大到小返回前一二三名对应序号的自定义函数

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-1-8 08:14 | 显示全部楼层

恳请老师们帮忙扩展原代码数据列数或重新编写新代码!

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-1-8 12:15 | 显示全部楼层

恳请老师们帮忙扩展原代码数据列数或重新编写新代码!

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-1-8 14:59 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2019-1-8 16:30 | 显示全部楼层
本帖最后由 yjh_27 于 2019-1-8 22:14 编辑
WYS67 发表于 2019-1-7 22:27
恳请老师们帮忙扩展原代码数据列数或重新编写新代码!

结果多处与你的不符,请核对

按数值从大到小返回前一二三名对应序号的自定义函数.zip

25.88 KB, 下载次数: 6

评分

参与人数 1鲜花 +2 收起 理由
WYS67 + 2 优秀作品

查看全部评分

TA的精华主题

TA的得分主题

发表于 2019-1-8 16:36 来自手机 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-1-8 18:18 | 显示全部楼层
yjh_27 发表于 2019-1-8 16:30
结果多处与你的不符,请核对

老师:1.您写的代码里的参数设置和O27:O32里不同--如N列公式 =QSPW(A5:I31,-3,6),第三参数6代表结果显示的位数,那第二参数-3代表什么?  举例说明:在J5:J10000输入公式  =QSPW($A$5:$I$10000,1【或J4】),显示如J5:J31最大值的计算结果;
                   在K5:K10000输入公式  =QSPW($A$5:$I$10000,2【或K4】),显示如K5:K31出现次数居中的数据;
                   在L5:L10000输入公式  =QSPW($A$5:$I$10000,3【或L4】),显示如L5:L31出现次数最少或未出的数据。
            如果在M5:M10000输入公式 =QSPW($A$5:$I$10000),省略了第二参数,则显示如M5:M31那样,按前一、二、三序号合并后的数据。
是O29:O32里对第二参数的设置。对应于J4:L4的前1,2,3排名,省略第二参数则是J&K&L前1,2,3名的连接。
          麻烦您说一下:如果只需要显示排名前一的序号,应该怎样输入公式

           2.如果在N5:N10000里输入公式,而A列数据才输至A31,则N32以下应该全部屏蔽为空白才对【代表数据源没有数字】;

           3.您代码的计算结果,多处与我的模拟结果不符,是因为您没有怎样在意O16:O22运算规则的缘故:

二.特殊情况【即每行最大的三个数字全部或部分相同】的处理
1.当首行【本表为A5:I5】或首次出现最大值有相同两个或以上的,以靠右侧的为大【如E5和H5都等于“6”,则右边H5对应于H4的序号7为最多,E5为第二多】
2.从A:I数据列的第二行开始,当前三名的数值全部或部分相同时:
   最大值有两个或以上的解决办法:
   按上一行排名在前的填入J列,剩下的那个填入K列;如果上一行仍然相同,则再次上推一行,直至能够明确判断为止【详见A5:A31土黄色填充的单元格】。
   第二大值有两个或以上的解决办法:
   按上一行排名在前的填入K列,剩下的那个填入L列;如果上一行仍然相同,则再次上推一行,直至能够明确判断为止【详见A5:A31土黄色填充的单元格】

       粗蓝色字体显示的是第二次以后遇到前一、二、三名的数值全部或部分相同时的处理办法,您似乎是按--只要第一、二或第二、三名的数字大小相同,都以右边为大来处理的。所以才有了好几处与模拟结果不符的情况。下面截图里N列用土黄色标记的,就是差异之处:

20190108173947.png

请按附件里N15:N32里要求编写代码。

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-1-8 21:44 | 显示全部楼层
恳请老师们帮忙扩展原代码数据列数或重新编写新代码!

TA的精华主题

TA的得分主题

发表于 2019-1-8 22:16 | 显示全部楼层
WYS67 发表于 2019-1-8 18:18
老师:1.您写的代码里的参数设置和O27:O32里不同--如N列公式 =QSPW(A5:I31,-3,6),第三参数6代表结果显示 ...

14L已更新。

评分

参与人数 1鲜花 +2 收起 理由
WYS67 + 2 优秀作品

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-1-9 00:18 | 显示全部楼层


20190108225010.png
老师:检查后,发现:
    从截图O:Q列中,土黄色填充单元格里的序号与J:L列的差异,还是出现在对下面两项规则的理解不同上:
1.当首行【本表为A5:I5】或首次出现最大值有相同两个或以上的,以靠右侧的为大【如E5和H5都等于“6”,则右边H5对应于H4的序号7为最多,E5为第二多】
2.从A:I数据列的第二行开始,当前三名的数值全部或部分相同时:
   最大值有两个或以上的解决办法:
   按上一行排名在前【不是排名在前,正确的说法:应该是数值偏大】的填入J列,剩下的那个填入K列;如果上一行数值大小仍然相同,则再次上推一行,直至能够明确判断为止【详见A5:A31土黄色填充的单元格】。
   第二大值有两个或以上的解决办法:
   按上一行排名在前【不是排名在前正确的说法:应该是数值大】的填入K列,剩下的那个填入L列;如果上一行数值大小仍然相同,则再次上推一行,直至能够明确判断为止【详见A5:A31土黄色填充的单元格】。

   
    重要疏忽:完全是我的过错,忘了声明:当第三大值有两个或两个以上时,按照最大值和第二大值的规则处理!
如A6:I6中,第三大数字4,同时出现了F6与G6里,没有出现在A5:I5【首行】;而且F5=3,G5=1,数值大小也不同,所以应该按照规则2来处理:由于F5>G5,所以,第三大值应该是F4里的“5”,而不是G4的“6”!
    再比如:A31:I31中的最大值5出现了3次【A31,B31,H31】!最大值则选定A4的“0”【因为A30=4,大于B30和H30的2】,第二大值和第三大值由于B30和H30都等于2,B29和H29又都等于5,仍然无法判定,只得再次上推一行,B28=4,H28=6,由于H28>B28,所以以H31的5对应于H4里的7为第二大值,B31对应于B4的1为第三大值!这才是从前几行历史数据的回溯上推中,接近渐变趋势的排位!!!


  还有,  公式最好设置成  =QSPW(需要计算的数据区域,排位参数前N个排名合并参数) ,这样统计功能才更全面!假如仅需要返回排名第一的序号,则省略第三参数,在某一列选定区域,输入=QSPW(A5:I10000,1【或单元格调用】) ,显示的即是排名第一的序号;当仅需要返回排名第二的序号,则省略第三参数,在某一列选定区域,输入=QSPW(A5:I10000,2【或单元格调用】) ,显示的即是排名第二的序号;仅需要返回排名第三的序号,则省略第三参数,在某一列选定区域,输入=QSPW(A5:I10000,3【或单元格调用】) ,显示的即是排名第三的序号;
    如果仅需要返回排名前三的合并序号,则省略第二参数,在某一列选定区域,输入=QSPW(A5:I10000,,3) ,显示的即是排名前三的从高到低的合并序号;
   就像J:M列显示的那样,可以单独返回前1~3名的序号【当然,能够返回所有名次的序号功能更强大!考虑到代码更难写,只得退而但求能独立计算并显示前1~3名,也就心满意足了!】
     老师:以上就是需要修改和完善的要点,恳请您帮忙!

TA的精华主题

TA的得分主题

发表于 2019-1-9 09:23 | 显示全部楼层
  1. Option Explicit

  2. Function QSPW(rgData As Range, Optional arrIndex As Variant = 4) As Variant
  3.     Dim arrTitle As Variant, arrData As Variant, rgCur As Range
  4.     Dim lngRow As Long, lngCol As Long
  5.     Dim lngVal(1 To 9) As Long, strVal(1 To 9) As String
  6.     Dim arrResult As Variant, arrReturn As Variant, lngID As Long
  7.     Dim lngIndex As Long, strTemp(1 To 3) As String, strAll As String
  8.    
  9.     arrTitle = rgData.Offset(-1, 0).Resize(1) '标题区域是数据区域的上一行
  10.     arrData = rgData
  11.     lngID = arrIndex
  12.    
  13.     Set rgCur = Application.Caller
  14.     ReDim arrResult(1 To rgCur.Rows.Count, 1 To 4) As String
  15.     Set rgCur = Nothing
  16.    
  17.     For lngRow = LBound(arrData) To UBound(arrData)
  18.         If arrData(lngRow, 1) = "" Then Exit For
  19.         For lngCol = 1 To 9
  20.             strVal(lngCol) = arrData(lngRow, lngCol) & strVal(lngCol)
  21.             lngVal(lngCol) = Val(Trim(Mid(strVal(lngCol), 1, 7)) & arrTitle(1, lngCol))
  22.         Next
  23.         
  24.         lngIndex = lngIndex + 1: strAll = ""
  25.         For lngCol = 1 To 3
  26.             strTemp(lngCol) = Right(CStr(Application.WorksheetFunction.Large(lngVal, lngCol)), 1)
  27.             strAll = strAll & strTemp(lngCol)
  28.             arrResult(lngIndex, lngCol) = strTemp(lngCol)
  29.         Next
  30.         arrResult(lngIndex, 4) = strAll
  31.     Next
  32.    
  33.     arrReturn = Application.WorksheetFunction.Index(arrResult, 0, lngID)
  34.     QSPW = arrReturn
  35. End Function
复制代码

评分

参与人数 1鲜花 +2 收起 理由
WYS67 + 2 太强大了

查看全部评分

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

本版积分规则

关注官方微信,高效办公专列,每天发车

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

GMT+8, 2019-6-27 04:51 , Processed in 0.103208 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 2001-2017 Wooffice Inc.

   

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

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

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