基于两个参数得出Excel表的单元格值

时间:2018-08-10 08:39:04

标签: excel vba excel-vba excel-tables

我在excel中有2列,A和B。在A中,我有百分比(比率),在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

然后我有一个表,其中F列中有年份,而行中有文本。

像这样(表更大,年份最多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,那么我要看表,第二年和相应的费率,即0.74%(以及AA),因为AA +为{{1 }}太低。

换句话说,AA +和2年级的比率都在0.16%和0.37%之间。而第二年的机管局利率均在0.37%至0.74%之间。

您知道我如何执行此任务吗?

非常感谢您。

1 个答案:

答案 0 :(得分:1)

为了便于代码阅读,我在此处显示的主要过程旁边使用了两个定制的function。否则,这将是一个巨大的代码转储。

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

enter image description here

  • (蓝色)数据表需要命名为“ 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()过程时,我们得到了预期的结果:

enter image description here


如有任何疑问,请告诉我:)