我在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%之间。
您知道我如何执行此任务吗?
非常感谢您。
答案 0 :(得分:1)
为了便于代码阅读,我在此处显示的主要过程旁边使用了两个定制的function
。否则,这将是一个巨大的代码转储。
开始之前,您必须更改/检查这些数据字段。
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()
过程时,我们得到了预期的结果:
如有任何疑问,请告诉我:)