根据两个参数导出 Excel Table 的单元格值
Derive cell value of an Excel Table based on two parameters
我在 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
然后我有一个 Table,其中 F 列中有年份,行中有文字。
像这样(table 更大,年数达到 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%
等等(table 比这个大很多)。
所以我需要一个函数或快捷方式,对于 A 列中的给定比率和 B 列中的给定年份,它会在 C 列中为我提供相应的评级(AAA、AA+、AA 等.).
在 table 中,速率是最高的。因此,如果我有 A1=0.50%
和 B1=2
,那么我会去查看第 2 年 table 和相应的比率,即 0.74%
(因此是 AA),因为 AA+是 0.37%
并且太低了。
也就是说AA+和year 2都是0.16%到0.37%之间的利率。第 2 年的 AA 利率都在 0.37% 到 0.74% 之间。
你知道我如何完成这个任务吗?
非常感谢。
为了代码的可读性,我使用了两个定制的 function
s,以及此处显示的主要过程。否则将是一个巨大的代码转储。
开始之前,您必须change/check这些数据字段。
- (蓝色)数据table需要命名为“
scores
”(或将内码改成你自己的名字)
- 同样适用于(绿色)等级 table - 命名为“
grades
”并从 F1
开始
- 最后但同样重要的是,代码假定这两个 table 位于名为“
Sheet1
” 的 sheet 中
So all of this needs to be changed within the code, if the names do
not match!
现在进入程序:
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()
returns a Range
Object from the "grades
" table, in which we found
the matching year from our "scores
" table. If the desired year is not found, it returns the year closest to it (the last table row)
' 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()
returns a Range
Object from the "grades
" table. It compares individual cell ranges and returns upon a) if the sought percent from "scores
" is less or equal (<=
) then current cell percent or b) if we went through all the cells, it returns the last cell
(because it must be higher, than the maximum of specified interval)
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()
过程后,我们得到了预期的结果:
如有任何问题,请告诉我 :)
我在 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
然后我有一个 Table,其中 F 列中有年份,行中有文字。
像这样(table 更大,年数达到 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%
等等(table 比这个大很多)。
所以我需要一个函数或快捷方式,对于 A 列中的给定比率和 B 列中的给定年份,它会在 C 列中为我提供相应的评级(AAA、AA+、AA 等.).
在 table 中,速率是最高的。因此,如果我有 A1=0.50%
和 B1=2
,那么我会去查看第 2 年 table 和相应的比率,即 0.74%
(因此是 AA),因为 AA+是 0.37%
并且太低了。
也就是说AA+和year 2都是0.16%到0.37%之间的利率。第 2 年的 AA 利率都在 0.37% 到 0.74% 之间。
你知道我如何完成这个任务吗?
非常感谢。
为了代码的可读性,我使用了两个定制的 function
s,以及此处显示的主要过程。否则将是一个巨大的代码转储。
开始之前,您必须change/check这些数据字段。
- (蓝色)数据table需要命名为“
scores
”(或将内码改成你自己的名字) - 同样适用于(绿色)等级 table - 命名为“
grades
”并从F1
开始
- 最后但同样重要的是,代码假定这两个 table 位于名为“
Sheet1
” 的 sheet 中
So all of this needs to be changed within the code, if the names do not match!
现在进入程序:
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()
returns a
Range
Object from the "grades
" table, in which we found the matching year from our "scores
" table. If the desired year is not found, it returns the year closest to it (the last table row)
' 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()
returns a
Range
Object from the "grades
" table. It compares individual cell ranges and returns upon a) if the sought percent from "scores
" is less or equal (<=
) then current cell percent or b) if we went through all the cells, it returns the last cell (because it must be higher, than the maximum of specified interval)
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()
过程后,我们得到了预期的结果:
如有任何问题,请告诉我 :)