如何加速Excel中的RANK()

在Excel中build立工具,作为练习的一部分,我需要根据市值来确定前50名证券。

这是使用RANK()方法的一个简单的事情,但是我已经得到了一个超过10,000的宇宙,而且一旦我在这10,000个条目上添加等级,处理一个本来轻而易举的快速工作簿就会变得迟缓。

我意识到缓慢至less部分是由于Excel需要对条目进行sorting以便对它们进行sorting,所以我想知道是否某种types的要sorting的值的索引可以加快速度? 有没有更好的方法来做到这一点,无论是通过我不熟悉的Excel函数或使用其他方法来加快速度?

你可以按照你想要的方式对值进行sorting,然后使用像ROW()这样的函数来按顺序分配排名(虽然你可能需要付出一些特别的努力来打破“关系”)。

如果你不想sorting的价值观,这取决于你需要什么…

案例1 – 您实际上不需要排名,但只需要确定前50个值。

假设您的值在单元格A1:A10000中。

在另一个单元格中,比如说E1,input一个计算前50个值的公式,例如=PERCENTILE($A$1:$A$10000,50/COUNT($A$1:$A$10000))

在单元格B1中,input一个公式,该公式返回A1中的值,如果它低于“cutoff”,或者是一个空string,否则像这样=IF(A1<=$E$1,A1,"")

将此公式下载到单元格B2到B10000。

列A中具有前50个值的行将在列B中具有非空值

如果有关系,可能会有超过50个这样的行。

情况2 – 你需要排名,但只有前50的值。

按照案例1的说明,然后在单元格C1中input一个计算列B中非空值的等级的公式,如下所示=IF(B1="","",RANK(B1,$B$1:$B$10000))

将此公式下载到单元格C2到C10000。

列A中前50个值的行将在列C中排列

再次,如果有关系,可能会有超过50个这样的行。 如果有联系,那么排名也会有差距。

情况3 – 您需要所有10000个值的排名。

像现在一样使用RANK。

生成Top 50列表的最快捷方式是在Excel中使用自动filter,这比您可以编写的任何循环都要快。

下面是一个如何做这个假设的例子:

  • 第1行是一个标题列
  • 在这个例子中,G列是具有市值的行

它是如何工作的:这是一个pipe道解决scheme,但是工作得很好。

  1. 将当前表单复制到名为“Top 50”的新表单中
  2. 应用自动筛选并按降序筛选(最高的数字在前)
  3. 删除第50个条目之后的所有行
  4. selectA1只是为了让它赏心悦目:)

有很多方法可以改进这些代码,例如:

  • 在列末尾的斜线假设
  • 添加一列排名并插入1到50

不过,我认为这个代码是一个很好的开始。 调整列G与列的数据,并试一试!

 Sub FilterbyDescending() ' filter row G in desceneding order Dim filter As Range Set filter = Range("A1:G100000") filter.Sort Key1:=Range("G2:G1000000"), _ Order1:=xlDescending, _ Header:=xlYes, _ Ordercustom:=1, _ MatchCase:=False, _ Orientation:=xlTopToBottom, _ DataOption1:=xlSortNormal End Sub Sub CreateBackup() Application.ScreenUpdating = False 'Create the Top 50 sheet, paste current sheet to it Dim top50sheet As Variant Application.ActiveSheet.Copy After:=Sheets(Application.Worksheets.Count) Set top50sheet = Application.ActiveSheet top50sheet.Name = "Top 50" Dim rowCount As Long Dim columCount As Long Call FilterbyDescending ' Time to delete everything after the top 50 Range("A52").CurrentRegion.Select rowCount = Selection.Rows.Count columnCount = Selection.Columns.Count Range(Cells(52, 1), Cells((rowCount), columnCount)).Delete Cells(1, 1).Select Application.ScreenUpdating = True End Sub