0

我在 excel 中有 2 列,A 和 B。在 AI 中有百分比(比率),在 B 中有整数(年)。

 rating PD  year
    0.39%   3
    0.88%   2
    1.32%   17
    0.88%   1
    0.26%   15
    0.17%   2
    0.17%   2
    0.59%   2
    0.59%   2

然后我有一个表格,其中在 FI 列中有年份,在行中有文本。

像这样(表要大得多,年数可达 30):

    Rating          
Year AAA     AA+      AA      AA-
1   0.003%  0.008%  0.018%  0.049%
2   0.016%  0.037%  0.074%  0.140%
3   0.041%  0.091%  0.172%  0.277%
4   0.085%  0.176%  0.318%  0.465%
5   0.150%  0.296%  0.514%  0.708%

依此类推(桌子比这大得多)。

因此,我需要一个函数或快捷方式,对于 A 列中的给定利率和 B 列中的给定年份,在 C 列中为我提供相应的评级(AAA、AA+、AA 等)。

表中的费率是最大值。因此,如果我有A1=0.50%B1=2,那么我会查看表格,第 2 年和相应的利率,即0.74%(因此是 AA),因为 AA+ 是0.37%而且太低了。

也就是说,AA+ 和第 2 年都是 0.16% 到 0.37% 之间的比率。第 2 年的 AA 都是 0.37% 到 0.74% 之间的比率。

你知道我怎么能完成这个任务吗?

非常感谢你。

4

1 回答 1

1

为了代码的可读性,我使用了两个定制的functions,以及此处显示的主要过程。否则这将是一个巨大的代码转储。

在开始之前,您必须更改/检查这些数据字段

在此处输入图像描述

  • (蓝色)数据表需要命名为“ scores”(或将内部代码更改为您自己的名称)
  • (绿色)成绩表也是如此 - 被命名为“ grades”并开始于F1
  • 最后但并非最不重要的一点是,代码假定这两个表位于名为“ Sheet1”的表中

因此,如果名称不匹配,所有这些都需要在代码中进行更改!

现在到程序:

Option Explicit
Private Sub run_through_scores()

    Dim scores As ListObject ' table from A1
    Dim grades As ListObject ' table from F1
    Set scores = Sheets("Sheet1").ListObjects("scores")
    Set grades = Sheets("Sheet1").ListObjects("grades")

    Dim cell As Range ' for "for" loop
    Dim inrow As Long ' will store in which row the year is
    Dim resultColumn As Integer ' will store in which column the percentage is

    'for every cell in second column of scores table (except header)
    For Each cell In scores.ListColumns(2).DataBodyRange
        inrow = get_year(cell).Row - 1
        ' ^ returns Row where result was found, -1 to accoutn for header

        'using our get_interval() function, _
         determines in which column is the sought percentage
        resultColumn = get_interval(cell.Offset(0, -1), inrow).Column
        cell.Offset(0, 1) = Sheets("Sheet1").Cells(1, resultColumn) 
        'write result in Column C   ^
    Next cell

End Sub

以及功能:

get_year()

从 " " 表返回一个Range对象grades,我们在其中从 " " 表中找到匹配的年份scores。如果未找到所需年份,则返回最接近它的年份(表的最后一行)

' Returns a Range (coordinates) for where to search in second table
Private Function get_year(ByVal year As Variant) As Range

    Dim grades As ListObject ' table from F1
    Set grades = Sheets("Sheet1").ListObjects("grades")

    Dim testcell As Range
    Set testcell = grades.ListColumns(1).DataBodyRange.Find(year, LookIn:=xlValues)

    'if found
    If Not testcell Is Nothing Then
        Set get_year = testcell
    Else
        Dim tbl_last_row As Long 'if year not found, return last row
        tbl_last_row = grades.ListColumns(1).DataBodyRange.Rows.Count
        Set get_year = grades.ListColumns(1).Range(tbl_last_row)
    End If

End Function

第二个功能:

get_interval()

从“ ”表中返回一个Range对象。grades它比较各个单元格范围并返回 a)如果从“ scores”中寻找的百分比小于或等于(<=)然后当前单元格百分比或 b)如果我们遍历所有单元格,它返回最后一个单元格 (因为它必须更高,大于指定间隔的最大值)

Private Function get_interval(ByVal what As Variant, ByVal inyear As Long) As Range

    Dim grades As ListObject ' table from F1
    Set grades = Sheets("Sheet1").ListObjects("grades")

    Dim cell As Range
    For Each cell In grades.ListRows(inyear).Range

    'check for interval 
        If what <= cell And cell.Column <> 6 Then 'we don't want to check year column
            Set get_interval = cell
            Exit Function
        End If
    Next cell

    ' if we arrived here, at this stage the result will always be the last cell
    Set get_interval = grades.ListRows(inyear).Range(, grades.ListColumns.Count)

End Function

在触发(调用)run_through_scores()过程后,我们得到了预期的结果:

在此处输入图像描述


如果您有任何问题,请告诉我:)

于 2018-08-10T11:15:06.627 回答