Excel 使用VBA(债券)计算摊余成本

Excel 使用VBA(债券)计算摊余成本,excel,vba,loops,finance,amortization,Excel,Vba,Loops,Finance,Amortization,我试图为摊销成本建立一个“会计”模型。我将制作一个包含实际付款日期的数组,一个包含“摊余成本”的数组,另一个显示报告日价值的数组(如31.12)。我已经手动完成了这项操作,但希望通过“单击”来执行这些操作,只需更改输入数据。我是VBA的新手(才几天),到目前为止,我还在为“付款日期”数组(显示债券上的现金流)苦苦挣扎 到目前为止,我有以下代码 Sub LoanAmortization() '----------------------------------------------------

我试图为摊销成本建立一个“会计”模型。我将制作一个包含实际付款日期的数组,一个包含“摊余成本”的数组,另一个显示报告日价值的数组(如31.12)。我已经手动完成了这项操作,但希望通过“单击”来执行这些操作,只需更改输入数据。我是VBA的新手(才几天),到目前为止,我还在为“付款日期”数组(显示债券上的现金流)苦苦挣扎

到目前为止,我有以下代码

Sub LoanAmortization()

'----------------------------------------------------------------------------------------------------------------------------------------------
'1)Define the arrays and variables that will be used along the process
'----------------------------------------------------------------------------------------------------------------------------------------------

'Dim Trends As Workbook                         'Variable to refer to the workbook

    Dim initLoanBal As Double         'Initial bond amount
    Dim DayCountBasis As Double       'Day count convention
    Dim BegDate As Date               'Date of bond repayment
    Dim MaturityDate As Date          'Date of bond repayment
    Dim TransCost As Double           'Transactioncosts on bonds
    Dim PayFreq As Double             'Frequency of coupon payments on bond (e.g. quarterly)
    Dim initRate As Double            'Interest rate on bond
    Dim CashFlowArray() As Integer    'Array of Cash flows on bond
    Dim CouponFreqString As String
    Dim NomRate As Double             'Rate used for cash flow calculation

    Dim i As Long
''----------------------------------------------------------------------------------------------------------------------------------------------
''2)Set variables for the calculation
''----------------------------------------------------------------------------------------------------------------------------------------------

    initLoanBal = ThisWorkbook.Worksheets("Amortisering").Range("D3").Value
    TransCost = Worksheets("Amortisering").Range("D4").Value
    initRate = Worksheets("Amortisering").Range("D5").Value
    Spread = Worksheets("Amortisering").Range("D6").Value
    DayCountBasis = Worksheets("Amortisering").Range("D7").Value
    CouponFreq = Worksheets("Amortisering").Range("E8").Value
    CouponFreqString = Worksheets("Amortisering").Range("D8").Value
    BegDate = Worksheets("Amortisering").Range("D9").Value
    MaturityDate = Worksheets("Amortisering").Range("D10").Value
    NomRate = initRate + Spread   

    '----------------------------------
    'Format variables for the calculation
    '----------------------------------
    Cells(5, 4).Select
    Selection.Value = initRate
    Selection.NumberFormat = "0.00%"


    Cells(6, 4).Select
    Selection.NumberFormat = "0.00%"


'-----------------------------------------------------------
'Set cash flows dates
'-----------------------------------------------------------
NoPeriods = DateDiff(CouponFreqString, BegDate, MaturityDate, vbMonday) 
' Number of periods ("payments") on the bond
    Range("G29") = BegDate
    Range("F31") = BegDate
    Range("G31").NumberFormat = "_(* #,##0_);_(* (#,##0);_(* ""-""??_);_(@_)"

                For i = 1 To NoPeriods
                    Cells(29, 7 + i) = DateAdd(CouponFreqString, i, BegDate)
                    Cells(31 + i, 6) = DateAdd(CouponFreqString, i, BegDate)
                Next i
'----------------------------------------------
'Set number of days dager
'----------------------------------------------

    For i = 1 To NoPeriods  ' No. days between payments (daycount convention)
           Cells(30, 7 + i) = WorksheetFunction.YearFrac(Cells(29, 6 + i), Cells(29, 7 + i), DayCountBasis)
    Next i
'----------------------------------------------
'Cash flow array
'----------------------------------------------
    For c = 1 To NoPeriods
        For i = 1 To NoPeriods
                Cells(30 + i, 7 + c) = initLoanBal * NomRate * Cells(30, 7 + c)
               Next i
    Next c


Range("G31") = -initLoanBal + TransCost

End Sub
目标

因此,问题出现在“现金流数组”部分。 1.最终目标是使用XIRR根据NomRate计算每个期间的实际利率

  • 我希望每个时期的利率都有所不同,因为浮动利率有变化

  • 我希望每行的最终付款等于利息付款和贷款还款(即initLoanBal)

  • 我希望第一个现金流等于上期计算的摊余成本

  • 我希望数组每次迭代减少1

  • 请参见图中的插图(绿色值是下一个数组中的“摊余成本值”,即摊余成本值),以了解我希望它的外观


    我建议您使用函数而不是宏来执行此操作

    该函数将用作Excel函数。例如,如果我使用名为TRIPLE的函数计算3*x,其中x是单元格编号,我可以使用excel中的TRIPLE(A1)来计算单元格A1中的TRIPLE

    在您的示例中,通过您的说明,我试图理解为您编写此代码的每个步骤,但是,复杂性并不能帮助我做到这一点

    但是我开始了一些事情。该函数的思想是指定所需的所有内容(以Hovedstol开头的单元格)、日期、税费和结果索引。如果你需要它,你可以根据我的指示添加任何内容。函数的结果是公式的计算

    示例:对于第一个结果,您应该在excel中编写:

    =LoanAmortization(B2,B3,B4,B5,B6,F2:F20,G2:G20,1)
    
    对于第二个结果:

    =LoanAmortization(B2,B3,B4,B5,B6,F2:F20,G2:G20,1)
    
    税收按G2:G20组织

    因此,代码需要在vba中的beggining处具有以下参数才能作为函数:

    Function LoanAmortization(A As Double, B As Double, C As Double, D As Double, E As Double, ByRef DatesRange As Excel.Range, ByRef TaxesRange As Excel.Range, MIndex As Integer) As Double
    End Function
    
    现在,您需要使用数组来做任何您想做的事情,您不需要格式化单元格,您可以多次创建您想做的任何工作表,代码仍然可以工作。 要创建数组,首先需要指定元素的数量,在本例中,您可以创建一个矩阵,其中有3列,从1到3(如果未指定,则以数字0开头),以及2行,以数字1开头(相同,如果未指定,则以数字0开头):

    您也可以重拨数组,但即使使用“保留”,也会丢失数据,无法更改变量类型。如果大小有一个变量值,则需要使用ReDim:

    ReDim ArrayExample(1 to 4, 0 to 3)
    
    要将excel.range转换为数组,只需在声明后使用以下命令:

    ArrayExample = ArrayRange.Value
    
    要使用矩阵,只需找到所需的行和列,例如:

    ArrayExample(3, 2) = 1
    i = ArrayExample(1) 'Just one column (have to be specified in declaration)
    ArrayExample(0, 0) = "test"
    
    要使用任何excel函数,如CountA函数,只需使用以下命令:

    Application.WorksheetFunction.CountA
    
    我就是这么做的:

    Function LoanAmortization(A As Double, B As Double, C As Double, D As Double, E As Double, ByRef DatesRange As Excel.Range, ByRef TaxesRange As Excel.Range, MIndex As Integer) As Double
    
        Dim qtd As Integer
        Dim Dates(), Taxes(), DatesDifference() As Double 'If bug, use Variant variable type
        qtd = Application.WorksheetFunction.CountA(DatesRange)
        ReDim DatesRange(1 to qtd), Taxes(1 to qtd), DatesDifference(1 to qtd - 1)
        For 1 to qtd - 1
            DatesDifference(i) = DatesRange(i + 1) - DatesRange(i)
        Next
    
    End Function
    

    有了这个,你应该可以继续代码了,抱歉帮不了你更多。如果您对如何执行更具体的操作有任何疑问,我会尽力帮助您。

    我建议您使用函数而不是宏来执行此操作

    该函数将用作Excel函数。例如,如果我使用名为TRIPLE的函数计算3*x,其中x是单元格编号,我可以使用excel中的TRIPLE(A1)来计算单元格A1中的TRIPLE

    在您的示例中,通过您的说明,我试图理解为您编写此代码的每个步骤,但是,复杂性并不能帮助我做到这一点

    但是我开始了一些事情。该函数的思想是指定所需的所有内容(以Hovedstol开头的单元格)、日期、税费和结果索引。如果你需要它,你可以根据我的指示添加任何内容。函数的结果是公式的计算

    示例:对于第一个结果,您应该在excel中编写:

    =LoanAmortization(B2,B3,B4,B5,B6,F2:F20,G2:G20,1)
    
    对于第二个结果:

    =LoanAmortization(B2,B3,B4,B5,B6,F2:F20,G2:G20,1)
    
    税收按G2:G20组织

    因此,代码需要在vba中的beggining处具有以下参数才能作为函数:

    Function LoanAmortization(A As Double, B As Double, C As Double, D As Double, E As Double, ByRef DatesRange As Excel.Range, ByRef TaxesRange As Excel.Range, MIndex As Integer) As Double
    End Function
    
    现在,您需要使用数组来做任何您想做的事情,您不需要格式化单元格,您可以多次创建您想做的任何工作表,代码仍然可以工作。 要创建数组,首先需要指定元素的数量,在本例中,您可以创建一个矩阵,其中有3列,从1到3(如果未指定,则以数字0开头),以及2行,以数字1开头(相同,如果未指定,则以数字0开头):

    您也可以重拨数组,但即使使用“保留”,也会丢失数据,无法更改变量类型。如果大小有一个变量值,则需要使用ReDim:

    ReDim ArrayExample(1 to 4, 0 to 3)
    
    要将excel.range转换为数组,只需在声明后使用以下命令:

    ArrayExample = ArrayRange.Value
    
    要使用矩阵,只需找到所需的行和列,例如:

    ArrayExample(3, 2) = 1
    i = ArrayExample(1) 'Just one column (have to be specified in declaration)
    ArrayExample(0, 0) = "test"
    
    要使用任何excel函数,如CountA函数,只需使用以下命令:

    Application.WorksheetFunction.CountA
    
    我就是这么做的:

    Function LoanAmortization(A As Double, B As Double, C As Double, D As Double, E As Double, ByRef DatesRange As Excel.Range, ByRef TaxesRange As Excel.Range, MIndex As Integer) As Double
    
        Dim qtd As Integer
        Dim Dates(), Taxes(), DatesDifference() As Double 'If bug, use Variant variable type
        qtd = Application.WorksheetFunction.CountA(DatesRange)
        ReDim DatesRange(1 to qtd), Taxes(1 to qtd), DatesDifference(1 to qtd - 1)
        For 1 to qtd - 1
            DatesDifference(i) = DatesRange(i + 1) - DatesRange(i)
        Next
    
    End Function
    

    有了这个,你应该可以继续代码了,抱歉帮不了你更多。如果您对如何做更具体的事情有任何疑问,我会尽力帮助您。

    在我早期的VBA工作中,我建立了一个贷款再付款计算器/计划程序作为一个学习项目。该程序从
    Userform
    获取输入参数,并计算贷款偿还计划。我将附上下面的文件供您查看。计算贷款支付计划的主要算法是
    二分法
    算法。它与Excel的目标搜索使用的相同

    注意:代码有点基本,因为正如我提到的