ExcelTip.Net留存知识帖 ---【注:附件之前被网盘供应商清空后,现已修复-现已修复-现已修复为本地下载!】
现在位置:首页 > E文精选 > 综合应用 > 细品RibbonX(56):使用Visual Studio开发Excel商务应用程序(2)

细品RibbonX(56):使用Visual Studio开发Excel商务应用程序(2)

作者:绿色风 分类: 时间:2022-08-17 浏览:148
楼主
apolloh
让我们接着上文介绍,继续丰富已开发的应用程序。
下面,让应用程序执行更丰富的计算。例如,可能想计算一定范围内的抵押值,而不是单个值,以便为客户提供多种选择。在上例中,我们能够指导用户输入不同的值,执行相同的计算多次,然而这种方式往往会花费很多时间。因此,需要使用不同的方法使应用程序更好的执行任务。
较好的解决方案是使用对话框来输入计算范围,而使用对话框启动器来访问对话框。添加了对话框启动器的新界面如下图。

 
相应的XML代码如下:


  1.           <dialogBoxLauncher>
  2.             <button id="RedundantCalcsLaunch"
  3.                     screentip="多重计算"
  4.                     supertip="多次执行同一公式的计算."
  5.                     onAction="DisplayRedundantCalc"/>
  6.           </dialogBoxLauncher>

要实现本例的功能,需要:
  • 为每个等式创建不同的对话框,需要创建3个对话框。
  • 代码必须区分不同的等式。
  • 任何用于与用户交互的对话框需要与功能区中的信息相链接,功能区控件同样需要从对话框中更新。
  • 代码对所需的ThisAddIn方法作多次调用,填充单元格区域中的单元格。
  • 取决于你的需求,可以提供额外的信息,例如列标题和行标题,使输出更易理解。设计对话框
    本例限定用户选择两个范围,这样可以在表中显示输出。设计的“选择贷款范围”窗体如下图所示。

     
    “选择年金范围”窗体设计如下图所示。

     
    “选择有效利率范围”窗体设计如下图所示。

     
    注:设计功能区的目的是减少复杂性。如果由于一些多余的设计选择而增加了更多的复杂性,那么用户将不会感受到使用功能区的任何好处。
    创建计算代码
    执行一次或多次计算实质上是相同的,但稍有不同。代码如下:
    [/code]
        ' 计算贷款金额并包括位置数据    Public Sub CalculatePMT(ByVal Rate As Double, ByVal NPer As Int32, ByVal PV As Int32, ByVal X As Int32, ByVal Y As Int32)        ' 计算利率.        Dim PeriodicRate As Double = (Rate / 100) / 12         ' 计算期数.        Dim Periods As Int32 = NPer * 12         ' 执行计算.        Application.ActiveWindow.ActiveCell.Cells(X, Y) = _              "=PMT(" + PeriodicRate.ToString() + "," + _              Periods.ToString() + "," + PV.ToString() + ",0,0)"        Application.ActiveWindow.ActiveCell.Calculate()    End Sub     ' 计算年金金额并包括位置数据.    Public Sub CalculateFV(ByVal Rate As Double, ByVal NPer As Int32, ByVal PMT As Int32, ByVal PV As Int32, ByVal X As Int32, ByVal Y As Int32)        ' 计算利率.        Dim PeriodicRate As Double = (Rate / 100) / 12         ' 计算期数.        Dim Periods As Int32 = NPer * 12         ' 执行计算.        Application.ActiveWindow.ActiveCell.Cells(X, Y) = _           "=FV(" + PeriodicRate.ToString() + "," + _           Periods.ToString() + "," + PMT.ToString() + "," + _           PV.ToString() + ",0)"        Application.ActiveWindow.ActiveCell.Calculate()    End Sub     ' 计算有效利率并包括数据位置.    Public Sub CalculateEFFECT(ByVal Rate As Double, ByVal X As Int32, ByVal Y As Int32)        ' 计算利率.        Dim PeriodicRate As Double = (Rate / 100) / 12         ' 执行计算.        Application.ActiveWindow.ActiveCell.Cells(X, Y) = _           "=EFFECT(" + PeriodicRate.ToString() + ",12)"        Application.ActiveWindow.ActiveCell.Calculate()         ' 格式单元格.        Dim ThisRange As Excel.Range        ThisRange = Application.Cells(X, Y)        ThisRange.NumberFormat = "0.0000%"    End Sub[/code]

    可以将上述代码与前文中相应的示例代码比较。最大的不同在于,添加了两个额外的位置参数,使得可以在任何位置放置输出的值。
    定义对现有数据的链接
    为功能区应用程序创建对话框时,需要创建对话框与合适的功能区控件的链接,否则两个元素将不同步并且应用程序会显示错误的数据。要创建链接,需要:
  • 从功能区中获取信息
  • 在功能区中设置信息
  • 在XML中定义需要的回调创建链接的XML代码如下:


    1.           <editBox id="Rate"
    2.                    label="有效利率"
    3.                    onChange="GetRateText"
    4.                    getText="SetRateText"/>
    5.           <dropDown id="Term"
    6.                     label="期数"
    7.                     getVisible="TermVisible"
    8.                     getItemCount="TermCount"
    9.                     getItemID="TermItemID"
    10.                     getItemLabel="TermItemLabel"
    11.                     onAction="GetSelectedTerm"
    12.                     getSelectedItemIndex="SetSelectedTerm"/>
    13.           <editBox id="Payment"
    14.                    label="期初支付"
    15.                    getVisible="PaymentVisible"
    16.                    onChange="GetPaymentText"
    17.                    getText="SetPaymentText"/>
    18.           <editBox id="Amount"
    19.                    getLabel="AmountLabel"
    20.                    getVisible="AmountVisible"
    21.                    onChange="GetAmountText"
    22.                    getText="SetAmountText"/>
    用于实现链接的属性取决于控件类型。大多数控件使用getText属性,从应用程序中提取信息并在控件中显示(例如,本例中的文本框);一些控件需要使用其它属性,例如本例中的getSelectedItemIndex属性。回调代码如下:


    1.     Public Function SetRateText(ByVal control As Office.IRibbonControl) As String
    2.         ' 返回Rate变量的当前值.
    3.         Return Rate.ToString()
    4.     End Function

    5.     Public Function SetSelectedTerm(ByVal control As Office.IRibbonControl) As Int32
    6.         ' 设置贷款项.
    7.         If CalcType = "Loan" Then
    8.             Select Case Term
    9.                 Case 10
    10.                     Return 0
    11.                 Case 15
    12.                     Return 1
    13.                 Case 20
    14.                     Return 2
    15.                 Case 30
    16.                     Return 3
    17.             End Select
    18.         End If

    19.         ' 设置年金项.
    20.         If CalcType = "Annuity" Then
    21.             Select Case Term
    22.                 Case 5
    23.                     Return 0
    24.                 Case 7
    25.                     Return 1
    26.                 Case 10
    27.                     Return 2
    28.                 Case 15
    29.                     Return 3
    30.                 Case 20
    31.                     Return 4
    32.             End Select
    33.         End If

    34.         ' 提供缺省的返回值.
    35.         Return 0
    36.     End Function

    37.     Public Function SetPaymentText(ByVal control As Office.IRibbonControl) As String
    38.         ' 返回Payment变量的当前值.
    39.         Return Payment.ToString()
    40.     End Function

    41.     Public Function SetAmountText(ByVal control As Office.IRibbonControl) As String
    42.         ' 返回Amount变量的当前值.
    43.         Return Amount.ToString()
    44.     End Function
    执行更丰富的计算
    对话框启动器dialogBoxLauncher仅有一个onAction属性,因此任何计算的开始点都是该属性指向的方法DisplayRedundantCalc。当然,由于每个等式都不相同,因此都需要采用某种方式单独实现调用。


    1.     Public Sub DisplayRedundantCalc(ByVal control As Office.IRibbonControl)
    2.         ' 选择正确的过程.
    3.         Select Case CalcType
    4.             Case "Loan"
    5.                 PerformLoanRangeCalc()
    6.             Case "Annuity"
    7.                 PerformAnnuityRangeCalc()
    8.             Case "Effective Rate"
    9.                 PerformEffectiveRateRangeCalc()
    10.         End Select
    11.     End Sub
    代码根据所选择的项目不同,调用不同的对话框计算程序。


    1.     Private Sub PerformLoanRangeCalc()
    2.         ' 创建对话框.
    3.         Dim ThisSelection As LoanRangeSelection = New LoanRangeSelection()

    4.         ' 在对话框中添加已存在的变量.
    5.         ThisSelection.txtIntBeg.Text = Rate.ToString()
    6.         ThisSelection.txtIntEnd.Text = Rate.ToString()
    7.         ThisSelection.txtIntInc.Text = "1"
    8.         ThisSelection.cbTermBeg.Text = Term.ToString()
    9.         ThisSelection.cbTermEnd.Text = Term.ToString()
    10.         ThisSelection.txtLoanAmt.Text = Amount.ToString()

    11.         ' 显示对话框并且如果用户单击确定则处理数据.
    12.         If ThisSelection.ShowDialog() = DialogResult.OK Then
    13.             ' 转换数据值为Int32egers.
    14.             Rate = Int32.Parse(ThisSelection.txtIntBeg.Text)
    15.             Term = Int32.Parse(ThisSelection.cbTermBeg.Text)
    16.             Amount = Int32.Parse(ThisSelection.txtLoanAmt.Text)

    17.             ' 创建本地变量,包括计算数据.
    18.             Dim EndRate As Int32 = Int32.Parse(ThisSelection.txtIntEnd.Text)
    19.             Dim IncRate As Int32 = Int32.Parse(ThisSelection.txtIntInc.Text)
    20.             Dim EndTerm As Int32 = Int32.Parse(ThisSelection.cbTermEnd.Text)

    21.             ' 更新功能区中的值.
    22.             ribbon.InvalidateControl("Rate")
    23.             ribbon.InvalidateControl("Term")
    24.             ribbon.InvalidateControl("Amount")

    25.             ' 添加初始标题.
    26.             Globals.ThisAddIn.SetHeading("利息", 1, 1)

    27.             ' 执行计算.
    28.             Dim i As Int32
    29.             For i = Rate To EndRate

    30.                 ' 计算X和Y的位置值.
    31.                 Dim X As Int32 = i + 2 - Rate
    32.                 Dim Y As Int32 = 2

    33.                 ' 打印Int32erest利率.
    34.                 Globals.ThisAddIn.SetHeading(i.ToString() + "%", X, 1)

    35.                 ' 使用一系列if语句确定年设置.
    36.                 If Term = 10 And EndTerm >= 10 Then
    37.                     ' 执行计算.
    38.                     Globals.ThisAddIn.CalculatePMT(i, 10, Amount, X, Y)

    39.                     ' 打印标题.
    40.                     Globals.ThisAddIn.SetHeading("10年", 1, Y)

    41.                     ' 如果已经使用则增加Y.
    42.                     Y = Y + 1
    43.                 End If

    44.                 If Term <= 15 And EndTerm >= 15 Then
    45.                     ' 执行计算.
    46.                     Globals.ThisAddIn.CalculatePMT(i, 15, Amount, X, Y)

    47.                     ' 打印标题.
    48.                     Globals.ThisAddIn.SetHeading("15年", 1, Y)

    49.                     ' 如果已经使用则增加Y.
    50.                     Y = Y + 1
    51.                 End If

    52.                 If Term <= 20 And EndTerm >= 20 Then
    53.                     ' 执行计算.
    54.                     Globals.ThisAddIn.CalculatePMT(i, 20, Amount, X, Y)

    55.                     ' 打印标题.
    56.                     Globals.ThisAddIn.SetHeading("20年", 1, Y)

    57.                     ' 如果已经使用则增加Y.
    58.                     Y = Y + 1
    59.                 End If

    60.                 If Term <= 30 And EndTerm >= 30 Then
    61.                     ' 执行计算.
    62.                     Globals.ThisAddIn.CalculatePMT(i, 30, Amount, X, Y)

    63.                     ' 打印标题.
    64.                     Globals.ThisAddIn.SetHeading("30年", 1, Y)

    65.                     ' 如果已经使用则增加Y.
    66.                     Y = Y + 1
    67.                 End If
    68.             Next
    69.         End If
    70.     End Sub

    71.     Private Sub PerformAnnuityRangeCalc()
    72.         ' 创建对话框.
    73.         Dim ThisSelection As AnnuityRangeSelection = New AnnuityRangeSelection()

    74.         ' 在对话框中添加已存在的变量.
    75.         ThisSelection.txtIntBeg.Text = Rate.ToString()
    76.         ThisSelection.txtIntEnd.Text = Rate.ToString()
    77.         ThisSelection.txtIntInc.Text = "1"
    78.         ThisSelection.cbTermBeg.Text = Term.ToString()
    79.         ThisSelection.cbTermEnd.Text = Term.ToString()
    80.         ThisSelection.txtLoanAmt.Text = Amount.ToString()
    81.         ThisSelection.txtPayment.Text = Payment.ToString()

    82.         ' 显示对话框并且如果用户单击确定则处理数据.
    83.         If ThisSelection.ShowDialog() = DialogResult.OK Then

    84.             ' 转换数据值为Int32egers.
    85.             Rate = Int32.Parse(ThisSelection.txtIntBeg.Text)
    86.             Term = Int32.Parse(ThisSelection.cbTermBeg.Text)
    87.             Amount = Int32.Parse(ThisSelection.txtLoanAmt.Text)
    88.             Payment = Int32.Parse(ThisSelection.txtPayment.Text)

    89.             ' 创建本地变量以包含计算数据.
    90.             Dim EndRate As Int32 = Int32.Parse(ThisSelection.txtIntEnd.Text)
    91.             Dim IncRate As Int32 = Int32.Parse(ThisSelection.txtIntInc.Text)
    92.             Dim EndTerm As Int32 = Int32.Parse(ThisSelection.cbTermEnd.Text)

    93.             ' 更新功能区中的值.
    94.             ribbon.InvalidateControl("Rate")
    95.             ribbon.InvalidateControl("Term")
    96.             ribbon.InvalidateControl("Amount")
    97.             ribbon.InvalidateControl("Payment")

    98.             ' 添加初始标题.
    99.             Globals.ThisAddIn.SetHeading("利息", 1, 1)

    100.             ' 执行计算.
    101.             Dim i As Int32
    102.             For i = Rate To EndRate

    103.                 ' 计算X和Y的位置值.
    104.                 Dim X As Int32 = i + 2 - Rate
    105.                 Dim Y As Int32 = 2

    106.                 ' 打印Int32erest利率.
    107.                 Globals.ThisAddIn.SetHeading(i.ToString() + "%", X, 1)

    108.                 ' 使用一系列if语句决定年设置.
    109.                 If Term = 5 And EndTerm >= 5 Then
    110.                     ' 执行计算.
    111.                     Globals.ThisAddIn.CalculateFV(i, 5, Amount, Payment, X, Y)

    112.                     ' 打印标题.
    113.                     Globals.ThisAddIn.SetHeading("5年", 1, Y)

    114.                     ' 如果已经使用则增加Y.
    115.                     Y = Y + 1
    116.                 End If

    117.                 If Term <= 7 And EndTerm >= 7 Then
    118.                     ' 执行计算.
    119.                     Globals.ThisAddIn.CalculateFV(i, 7, Amount, Payment, X, Y)

    120.                     ' 打印标题.
    121.                     Globals.ThisAddIn.SetHeading("7年", 1, Y)

    122.                     ' 如果已经使用则增加Y.
    123.                     Y = Y + 1
    124.                 End If

    125.                 If Term <= 10 And EndTerm >= 10 Then
    126.                     ' 执行计算.
    127.                     Globals.ThisAddIn.CalculateFV(i, 10, Amount, Payment, X, Y)

    128.                     ' 打印标题.
    129.                     Globals.ThisAddIn.SetHeading("10年", 1, Y)

    130.                     ' 如果已经使用则增加Y.
    131.                     Y = Y + 1
    132.                 End If

    133.                 If Term <= 15 And EndTerm >= 15 Then
    134.                     ' 执行计算.
    135.                     Globals.ThisAddIn.CalculateFV(i, 15, Amount, Payment, X, Y)

    136.                     ' 打印标题.
    137.                     Globals.ThisAddIn.SetHeading("15年", 1, Y)

    138.                     ' 如果已经使用则增加Y.
    139.                     Y = Y + 1
    140.                 End If

    141.                 If Term <= 20 And EndTerm >= 20 Then
    142.                     ' 执行计算.
    143.                     Globals.ThisAddIn.CalculateFV(i, 20, Amount, Payment, X, Y)

    144.                     ' 打印标题.
    145.                     Globals.ThisAddIn.SetHeading("20年", 1, Y)

    146.                     ' 如果已经使用则增加Y.
    147.                     Y = Y + 1
    148.                 End If
    149.             Next
    150.         End If
    151.     End Sub

    152.     Private Sub PerformEffectiveRateRangeCalc()
    153.         ' 创建对话框.
    154.         Dim ThisSelection As EffectiveRateRangeSelection = New EffectiveRateRangeSelection()

    155.         ' 在对话框中添加已存在的变量.
    156.         ThisSelection.txtIntBeg.Text = Rate.ToString()
    157.         ThisSelection.txtIntEnd.Text = Rate.ToString()
    158.         ThisSelection.txtIntInc.Text = "1"

    159.         ' 显示对话框并且如果用户单击确定则处理数据.
    160.         If ThisSelection.ShowDialog() = DialogResult.OK Then

    161.             ' 转换数据值为Int32egers.
    162.             Rate = Int32.Parse(ThisSelection.txtIntBeg.Text)

    163.             ' 创建本地变量以包含计算数据.
    164.             Dim EndRate As Int32 = Int32.Parse(ThisSelection.txtIntEnd.Text)
    165.             Dim IncRate As Int32 = Int32.Parse(ThisSelection.txtIntInc.Text)

    166.             ' 更新功能区中的值.
    167.             ribbon.InvalidateControl("Rate")

    168.             ' 添加初始标题.
    169.             Globals.ThisAddIn.SetHeading("利息", 1, 1)
    170.             Globals.ThisAddIn.SetHeading("有效利率", 1, 2)

    171.             ' 执行计算.
    172.             Dim i As Int32
    173.             For i = Rate To EndRate
    174.                 ' 计算X和Y位置值.
    175.                 Dim X As Int32 = i + 2 - Rate

    176.                 ' 打印Int32erest利率.
    177.                 Globals.ThisAddIn.SetHeading(i.ToString() + "%", X, 1)

    178.                 ' 执行计算.
    179.                 Globals.ThisAddIn.CalculateEFFECT(i, X, 2)
    180.             Next
    181.         End If
    182.     End Sub
    考虑数据识别需求
    对输出结果添加有意义的标题。当执行多重计算时,为使数据意义明确,必须提供标题。代码如下:


    1.     Public Sub SetHeading(ByVal Heading As String, ByVal X As Int32, ByVal Y As Int32)
    2.         ' 添加所需要的标题.
    3.         Application.ActiveWindow.ActiveCell.Cells(X, Y) = Heading
    4.     End Sub
    现在,一切准备就绪。运行代码,在窗体中选择区域,输入相应数据,得到的输出结果如下图所示。

     
  • 2楼
    亡者天下
    自己还可以开发功能区啊!

    免责声明

    有感于原ExcelTip.Net留存知识的价值及部分知识具有的时间限定性因素, 经与ExcelTip.Net站长Apolloh商议并征得其同意, 现将原属ExcelTip.Net的知识帖采集资料于本站点进行展示, 供有需要的人士查询使用,也慰缅曾经的论坛时代。 所示各个帖子的原作者如对版权有异议, 可与本人沟通提出,或于本站点留言,我们会尽快处理。 在此,感谢ExcelTip.Net站长Apolloh的支持,感谢本站点所有人**绿色风(QQ:79664738)**的支持与奉献,特此鸣谢!
    ------本人网名**KevinChengCW(QQ:1210618015)**原ExcelTip.Net总版主之一

    评论列表
    sitemap