eBMC – Budget model

Declaration of the ribbon for the eBMC - Budget interface also known as the input sheet or the matrix.

Take a look on the getVisible property which allow to show a feature to only ... (a list of persons f.i.). The function behind is defined in VBA and you just need to return true (make the feature visible) or false (hide the feature).

eBMC_Budget 1

The first group at the left side has !!!DEV!!! as label: this group will be make visible to only people identified as developer of the application.

The getVisible attribute is the callback to use for this.

<group id="grpeBMC_CAVO" label="!!!DEV!!!" getVisible="Toolbar.getVisibleOnlyAdmin">

The getVisibleOnlyAdmin is defined like this:

Sub getVisibleOnlyAdmin(control As IRibbonControl, ByRef returnedVal)
    returnedVal = cCAVOSettings.isAdmin()
End Sub

Because there are a lot of features in the ribbon, User interface isn’t displayed but we need to click on it to show it.

eBMC_Budget 2

Same for Matrix's management center - only for administrators

eBMC_Budget 3

1. Manifest

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="Toolbar.Ribbon_onLoad">
   <ribbon startFromScratch="false">
      <tabs>
         <tab idMso="TabFile" visible="true" /> 
         <tab id="eBMC" label="eBMC" insertBeforeMso="TabHome">
            <group id="grpeBMC_CAVO" label="!!!DEV!!!" getVisible="Toolbar.getVisibleOnlyAdmin">               
               <button id="btnEPMStoreBudgetCAVO" label="Store" onAction="Toolbar.clickEPMStoreBudgetCAVO" imageMso="FileSave" 
                  supertip="Sauve le fichier Budget_CAVO.xlsm dans EPM -> Input -> Budget_Begroting "/>  
               <button id="btnSaveLocalBudgetCAVO" label="Local" onAction="Toolbar.clickSaveLocalBudgetCAVO" getVisible="Toolbar.getVisibleOnlyCAVO" imageMso="FileSave" 
                  supertip="Sauve *EN LOCAL* le fichier Budget_CAVO.xlsm"/> 
               <button id="btnEPMEditBudgetCAVO" label="Edit" onAction="Toolbar.clickEPMEditBudgetCAVO" imageMso="TableDrawTable" 
                  supertip="Ouvre l'?cran d'?dition du rapport EPM "/>
               <toggleButton id="btnProtectSheet" label="Protect" imageMso="Lock" 
                  onAction="Toolbar.clickProtectSheet" getPressed="Toolbar.pressedProtectSheet" getVisible="Toolbar.getVisibleOnlyAdmin"
                  supertip="Toggle the protection of the worksheet" />  
               <button id="btnEPMOpenDebugLog" label="Log" onAction="Toolbar.clickEPMOpenDebugLog" image="bug" supertip="Ouvre le fichier de LOG"/>  
            </group>
            <group id="grpeBMC_Params" label="Parameters">
               <dropDown id="cbxMatrixBudgetCycle" label="Budget cycle" sizeString="xxxxxxxxxxxxxxxxxxxxx" tag="eBMCLanguage"
                  screentip="Please select the budget cycle" 
                  supertip="Please select the desired budget cycle" 
                  onAction="Toolbar.onChangecbxMatrixBudgetCycle" getItemCount="Toolbar.cbxMatrixBudgetCycleItemCount" 
                  getItemLabel="Toolbar.cbxMatrixBudgetCycleListItem" getSelectedItemIndex="Toolbar.cbxMatrixBudgetCycleItemIndex"
            getVisible="Toolbar.getVisiblecbxMatrixBudgetCycle"
                  getItemScreentip="Toolbar.cbxMatrixBudgetCycleItemScreentip" />  
               <dropDown id="cbxMatrixPhase" label="Phases"  sizeString="xxxxxxxxxxxxxxxxxxxxx" tag="eBMCLanguage"
                  screentip="Please select a phase; the matrix will then be called and the layout of the sheet will then be modified to display only data_sources for that phase" 
                  supertip="If you want to limit the report for a specific OIP / ION, please select the entity here" 
                  onAction="Toolbar.onChangecbxMatrixPhase" getItemCount="Toolbar.cbxMatrixPhaseItemCount" 
                  getItemLabel="Toolbar.cbxMatrixPhaseListItem" getSelectedItemIndex="Toolbar.cbxMatrixPhaseItemIndex"
            getVisible="Toolbar.getVisiblecbxMatrixPhase"
                  getItemScreentip="Toolbar.cbxMatrixPhaseItemScreentip" />
               <separator id="grpeBMC_Params_Sep01" getVisible="Toolbar.getVisiblecbxMatrixPhase"/>            
               <dropDown id="cbxMatrixYears" label="Budget year"   sizeString="xxxxxxxxxxxxxxx"
                  screentip="Please select the budget year" 
                  supertip="Select a budget year.  The number of years depends on the selected BudgetCycle.  For somes cycles, there will be two, three or more years to fill in" 
                  onAction="Toolbar.onChangecbxMatrixYears" getItemCount="Toolbar.cbxMatrixYearsItemCount" 
                  getItemLabel="Toolbar.cbxMatrixYearsListItem" getSelectedItemIndex="Toolbar.cbxMatrixYearsItemIndex" getItemID="Toolbar.cbxMatrixYearsGetItemID"
                  getItemScreentip="Toolbar.cbxMatrixYearsItemScreentip" />
               <dropDown id="cbxMatrixCredTyp" label="Credit type" sizeString="xxxxxxxxxxxxxxx" tag="eBMCLanguage"
                  screentip="Please select the credit type" 
                  supertip="Select a credit type, expenses or incomes" 
                  onAction="Toolbar.onChangecbxMatrixCredType" getItemCount="Toolbar.cbxMatrixCredTypeItemCount" 
                  getItemLabel="Toolbar.cbxMatrixCredTypeListItem" getSelectedItemIndex="Toolbar.cbxMatrixCredTypeItemIndex"
                  getItemScreentip="Toolbar.cbxMatrixCredTypeItemScreentip" />
               <dropDown id="cbxMatrixCodeFIN" label="Code fin"   sizeString="xxxxxxxxxxxxxxx" tag="eBMCLanguage"
                  screentip="Please select the code FIN" 
                  supertip="Select a financial code, the origin of the financement" 
                  onAction="Toolbar.onChangecbxMatrixCodeFIN" getItemCount="Toolbar.cbxMatrixCodeFINItemCount" 
                  getItemLabel="Toolbar.cbxMatrixCodeFINListItem" getSelectedItemIndex="Toolbar.cbxMatrixCodeFINItemIndex"
                  getItemScreentip="Toolbar.cbxMatrixCodeFINItemScreentip" />
               <dropDown id="cbxMatrixCredSort" label="Credit sort" sizeString="xxxxxxxxxxxxxxx" tag="eBMCLanguage"
                  screentip="Please select the credit sort" 
                  supertip="Select a credit sort, limitative or not, or both" 
                  onAction="Toolbar.onChangecbxMatrixCredSort" getItemCount="Toolbar.cbxMatrixCredSortItemCount" 
                  getItemLabel="Toolbar.cbxMatrixCredSortListItem" getSelectedItemIndex="Toolbar.cbxMatrixCredSortItemIndex"
                  getItemScreentip="Toolbar.cbxMatrixCredSortItemScreentip" />               
            </group>
            <group id="grpeBMC_EPM" label="Actions">

               <button id="btnEPMRefresh" label="Refresh" size="large" onAction="Toolbar.clickEPMRefresh" imageMso="DataRefreshAll" tag="EPM"
                  getEnabled="Toolbar.enableEPMRefresh" getVisible="Toolbar.getVisibleEPMRefresh" 
                  supertip="Get the newer version of the information from the database.  Be carefull : if you've made changes without saving them, by refreshing the sheet, yours changes will be lost.&#xD;&#xD;Shortcut : CTRL-r"/>
               <button id="btnEPMSubmit" label="Save data" size="large" onAction="Toolbar.clickEPMSubmit" imageMso="DatabaseSqlServer" tag="EPM" 
                  getEnabled="Toolbar.enableEPMSubmit" getVisible="Toolbar.getVisibleEPMSubmit" 
                  supertip="Submitting your changes will store them in the central database; figures will then be available to others&#xD;&#xD;Shortcut : CTRL-s"/>
               <separator id="grpeBMC_EPM_Sep02"/>
               <toggleButton id="btnEPMInsertRow" label="Add new row" imageMso="SharingOpenNotesFolder" 
                  getEnabled="Toolbar.enableEPMInsertRow" getPressed="Toolbar.pressedEPMInsertRow" getVisible="Toolbar.getVisibleEPMInsertRow" 
                  onAction="Toolbar.clickEPMAddNewRow"
                  supertip="Insert a new entry in the input sheet; allow you to input figures on a new entry" />
               <button id="btnEPMDeleteRow" label="Delete row" onAction="Toolbar.clickEPMDeleteRow" imageMso="CellsDelete" 
                  getEnabled="Toolbar.enableEPMDeleteRow" getVisible="Toolbar.getVisibleEPMDeleteRow" 
                  supertip="First click on the row to suppress then click on this button to delete that entry" />
            </group>
            <group id="grpeBMC_GUID" label="User interface">
               <dropDown id="cbxLanguage" label="Language" onAction="Toolbar.onChangecbxLanguage" getSelectedItemID="Toolbar.cbxLanguageItemIndex"
                  screentip="Please select the desired language for your report" 
                  supertip="By default, this language is set to match your own preference (defined in the BPC user's profile). Select an another language if you wish to switch labels of the report in that language">
                  <item id="nl" label="Dutch"/>
                  <item id="fr" label="French"/>
               </dropDown>
               <separator id="grpeBMC_GUID_Sep01"/> 
               <toggleButton id="btnShowDescription" size="large" label="Show descriptions" imageMso="MacroNames" 
                  onAction="Toolbar.clickShowDescription" getPressed="Toolbar.pressedShowDescription" getVisible="Toolbar.getVisibleShowDescription"
                  supertip="Toggle the visibility of the columns with the descriptions of the used codes" />
               <toggleButton id="btnShowLittera" size="large" label="Show littera" imageMso="MacroNames" 
                  onAction="Toolbar.clickShowLittera" getPressed="Toolbar.pressedShowLittera" getVisible="Toolbar.getVisibleShowLittera"
                  supertip="Toggle the visibility of the columns with the descriptions of the littera" />
               <toggleButton id="btnSilentMode" size="large" label="Silent mode" imageMso="CreateQueryInDesignView" 
                  onAction="Toolbar.clickSilentMode" getPressed="Toolbar.pressedSilentMode"
                  supertip="Toggle the silent mode i.e. the display of warnings" />
               <toggleButton id="btnAutoRefresh" size="large" label="Auto-refresh" imageMso="Refresh" 
                  onAction="clickAutoRefresh" getPressed="pressedAutoRefresh"
                  supertip="By selecting a value from the eBMC ribbon, the worksheet will be automatically refreshed. By disabling the auto-refresh function, you'll be able to change severall values in one time and refresh the sheet manually to reflect changes."/>
            </group>
            <group id="grpeBMC_Matrix" label="Matrix's management center - only for administrators" getVisible="Toolbar.getVisibleOnlyAdmin">               
               <dropDown id="cbxMatrixBudgetProcess" label="Budget process"   sizeString="xxxxxxxxxxxxxxxxxxx" tag="eBMCLanguage"
                  screentip="Please select the budget process" 
                  supertip="Select a budget process flow" 
                  onAction="Toolbar.onChangecbxMatrixBudgetProcess" getItemCount="Toolbar.cbxMatrixBudgetProcessItemCount" 
                  getItemLabel="Toolbar.cbxMatrixBudgetProcessListItem" getSelectedItemIndex="Toolbar.cbxMatrixBudgetProcessItemIndex"                  getItemScreentip="Toolbar.cbxMatrixBudgetProcessItemScreentip" />
               <separator id="grpeBMC_Matrix_Sep01"/>
               <button id="eBMCMatrix_ShowForm" tag="eBMCMatrix" size="large" label="Show form" onAction="Toolbar.clickShowMatrixForm" 
                  imageMso="FilePrepareMenu" 
                  supertip="Show the matrix in a friendly way; allowing quick parametrization"/>
               <button id="eBMCMatrix_ShowMatrix" tag="eBMCMatrix" size="large" label="Show datatable" onAction="Toolbar.clickShowMatrixDataTable" 
                  imageMso="ChartShowData" 
                  supertip="Show the matrix as a table"/>
               <button id="eBMCMatrix_SubmitMatrixForm" tag="eBMCMatrix" size="large" label="Submit definition" onAction="Toolbar.clickSubmitMatrixForm" 
                  imageMso="DatabaseSqlServer" getEnabled="Toolbar.enableSubmitMatrixForm"
                  supertip="Submit yours changes"/>               
               <separator id="grpeBMC_Matrix_Sep02" />
               <button id="eBMCMatrix_RefreshMatrixFormComments" tag="eBMCMatrix" size="large" label="Refresh comments" onAction="Toolbar.clickRefreshMatrixFormComments" 
                  imageMso="ExchangeFolder" getEnabled="Toolbar.enableRefreshMatrixFormComments"
                  supertip="Update fields's comment"/>
               <toggleButton id="eBMCMatrix_FilterMatrixDataTable" size="large" label="Auto filter" getEnabled="Toolbar.enableFilterMatrixDataTable" 
                  onAction="Toolbar.clickFilterMatrixDataTable" 
                  imageMso="Filter" 
                  supertip="Filter the matrix based on the selected parameters.  Show which rules will be applied to the fields's state (Read, Read/Write or Hidden).   The last row displayed when the table is filtered is the row with the rules that will be used (the most accurate rules)"/>              
            </group>
            <group id="grpeBMC_About" getLabel="getLabelAbout">               
               <button id="btneBMCAbout" label="About" onAction="clickShowAbout" imageMso="BlogHomePage" />
            </group>

         </tab>
      </tabs>
   </ribbon>
</customUI>

2. VBA

Associated VBA code (in a module called Toolbar, thats why callbacks starts with Toolbar)

Attribute VB_Name = "Toolbar"
' -----------------------------------------------------------------------------------------------------------------------------------------------------------
'
' Author       : AVONTURE Christophe
'
' Aim          : Toolbar's event handler
'
' Written date : February 2016
'
' Last modification
' 2017-10-25 : AVONTURE Christophe - See comments in the code
'
' -----------------------------------------------------------------------------------------------------------------------------------------------------------

Option Explicit
Option Compare Text
Option Base 1

Public Sub Ribbon_onLoad(ribbon As IRibbonUI)

   Call cCAVOLog.Log("Toolbar::Ribbon_onLoad - Start")

   'Debug.Print Format(Now, "yyyy-mm-dd HH:MM:SS") &amp; " - Toolbar::Ribbon_onLoad - Start"

   Application.EnableCancelKey = XlEnableCancelKey.xlDisabled

   If Not cDevelopmentMode Then Application.ScreenUpdating = False
   Application.Cursor = xlWait

   cToolbar.ribbon = ribbon

   ' Try to remember the ribbon object
   Set Variables.p_ribbon = ribbon

   cCAVOSettings.Ready = False

   Application.Cursor = xlDefault

   ' SAP engineers are saying that the Budget.xlsm is running twice
   ' the EPM refresh features and suggest to do only once; therefore
   ' disable the refresh here below (in the ribbon part) and keep only
   ' the second refresh, to get the Input and Report sheets.
   '
   '                            IT'S A BAD IDEA.
   '
   ' If I do this, the ribbon is therefore not initialized, all dropdown
   ' lists will be empty and nothing will be initialized.
   '
   ' The main issue regarding EPM refresh is the fact that, in 2017, it takes
   ' 15 seconds (approximatively) to SAP for the refresh (and just for that)
   ' and 12 seconds for the second refresh while this full VBA code takes 33 seconds
   ' (so 27 for SAP himself and 6 for the full VBA)
   '
   ' ===> OPTIMIZATION SHOULD BE DONE NOT HERE BUT IN THE SAP BACKEND
   '
   ' Don't comment the following line
   Call cEPM.Refresh

   Call cCAVOLog.Log("Toolbar::Ribbon_onLoad - End")

   'Debug.Print Format(Now, "yyyy-mm-dd HH:MM:SS") &amp; " - Toolbar::Ribbon_onLoad - End"

End Sub

' ------------------------------------------------------------------------------
'
' Protect or unprotect the EPM sheet (EPM protection!!!)
'
' ------------------------------------------------------------------------------

Sub clickProtectSheet(control As IRibbonControl, pressed As Boolean)

   If ActiveSheet.ProtectContents Then
      Call cCAVOEPM.UnProtectSheet(ActiveSheet)
   Else
      Call cCAVOEPM.ProtectSheet(ActiveSheet)
   End If

End Sub

' ------------------------------------------------------------------------------
'
' The toggle ProtectSheet depends on the actual state of ProtectContents
'
' ------------------------------------------------------------------------------

Sub pressedProtectSheet(control As IRibbonControl, ByRef pressed)
   pressed = ActiveSheet.ProtectContents
End Sub

' ------------------------------------------------------------------------------
'
' By left-clicking on the toggle button, Show/Hide the columns with the descriptions
'
' The rule is "Look at any named range starting with '_rngDescription' as name and toggle its visibility"
'
' ------------------------------------------------------------------------------

Sub clickShowDescription(control As IRibbonControl, pressed As Boolean)

Dim bScreenUpdating As Boolean, bIsProtected As Boolean, bSheetModified As Boolean
Dim nm As Name
Dim sName As String
Dim sh As Worksheet

   bScreenUpdating = Application.ScreenUpdating
   If Not cDevelopmentMode Then Application.ScreenUpdating = False

   For Each sh In ActiveWorkbook.Worksheets

      bSheetModified = False

      For Each nm In sh.Names

         sName = nm.Name

         If InStr(sName, "!") > 0 Then sName = Mid(sName, InStr(sName, "!") + 1, Len(sName))

         If (Left(sName, Len("_rngDescription")) = "_rngDescription") Then
            If (cCAVOFunctions.in_array(sName, Array("_rngDescriptionLitteraFR_Save", "_rngDescriptionLitteraNL_Save")) = -1) Then

               bIsProtected = sh.ProtectContents

               If bIsProtected Then
                  bSheetModified = True
                  Call cCAVOEPM.UnProtectSheet(sh)
               End If

               sh.Range(sName).EntireColumn.Hidden = Not pressed

            End If
         End If

      Next nm

      If bSheetModified Then Call cCAVOEPM.ProtectSheet(sh)

   Next sh

   If Not cDevelopmentMode Then Application.ScreenUpdating = bScreenUpdating

End Sub

Sub clickShowLittera(control As IRibbonControl, pressed As Boolean)

Dim bScreenUpdating As Boolean, bIsProtected As Boolean, bSheetModified As Boolean
Dim nm As Name
Dim sName As String
Dim sh As Worksheet

   bScreenUpdating = Application.ScreenUpdating
   If Not cDevelopmentMode Then Application.ScreenUpdating = False

   For Each sh In ActiveWorkbook.Worksheets

      bSheetModified = False

      For Each nm In sh.Names

         sName = nm.Name

         If InStr(sName, "!") > 0 Then sName = Mid(sName, InStr(sName, "!") + 1, Len(sName))

         If (cCAVOFunctions.in_array(sName, Array("_rngColLitteraDescriptionFR", "_rngColLitteraDescriptionNL", "_rngColPrintIfNoBudget")) <> -1) Then

            bIsProtected = sh.ProtectContents

            If bIsProtected Then
               bSheetModified = True
               Call cCAVOEPM.UnProtectSheet(sh)
            End If

            sh.Range(sName).EntireColumn.Hidden = Not pressed

         End If

      Next nm

      If bSheetModified Then Call cCAVOEPM.ProtectSheet(sh)

   Next sh

   If Not cDevelopmentMode Then Application.ScreenUpdating = bScreenUpdating

End Sub

' ------------------------------------------------------------------------------
'
' On the workbook's opening, the ShowHide Hidden ranges toggle button should not be pressed
' i.e. rows and columns with technical informations (with yellow background) should remains hidden
'
' ------------------------------------------------------------------------------

Sub pressedShowDescription(control As IRibbonControl, ByRef pressed)
   pressed = False
End Sub

Sub pressedShowLittera(control As IRibbonControl, ByRef pressed)
   pressed = Not (shInput.Range("_rngColLitteraDescriptionFR").EntireColumn.Hidden)
End Sub

' ------------------------------------------------------------------------------
'
' Set the SilentMode mode
'
' ------------------------------------------------------------------------------

Sub clickSilentMode(control As IRibbonControl, pressed As Boolean)

   cCAVOSettings.SilentMode = pressed

End Sub

' ------------------------------------------------------------------------------
'
' On the workbook's opening, initialize the SilentMode button
'
' ------------------------------------------------------------------------------

Sub pressedSilentMode(control As IRibbonControl, ByRef pressed)
   pressed = cCAVOSettings.SilentMode
End Sub

' ------------------------------------------------------------------------------
'
' Set the AutoRefresh mode
'
' ------------------------------------------------------------------------------

Sub clickAutoRefresh(control As IRibbonControl, pressed As Boolean)
   cEPM.AutoRefresh = pressed
End Sub

' ------------------------------------------------------------------------------
'
' On the workbook's opening, initialize the AutoRefresh button
'
' ------------------------------------------------------------------------------

Sub pressedAutoRefresh(control As IRibbonControl, ByRef pressed)
   pressed = cEPM.AutoRefresh
End Sub

Sub clickEPMStoreBudgetCAVO(control As IRibbonControl)

Dim p_EPM As New EPMAddInAutomation

   p_EPM.SaveToServerRootFolder

End Sub

Sub getVisibleOnlyCAVO(control As IRibbonControl, ByRef returnedVal)
   returnedVal = cCAVOSettings.isChristophe
End Sub

Sub getVisibleEPMRefresh(control As IRibbonControl, ByRef returnedVal)
   returnedVal = True
End Sub

' Only on the Input Sheet
Sub getVisibleEPMSubmit(control As IRibbonControl, ByRef returnedVal)
   returnedVal = (ActiveSheet Is shInput)
End Sub

' Only on the Input Sheet
Sub getVisibleEPMInsertRow(control As IRibbonControl, ByRef returnedVal)
   returnedVal = (ActiveSheet Is shInput)
End Sub

' Only on the Input Sheet
Sub getVisibleEPMDeleteRow(control As IRibbonControl, ByRef returnedVal)
   returnedVal = (ActiveSheet Is shInput)
End Sub

' Only on the Input Sheet
Sub getVisibleShowDescription(control As IRibbonControl, ByRef returnedVal)
   returnedVal = (ActiveSheet Is shInput)
End Sub

Sub getVisibleShowLittera(control As IRibbonControl, ByRef returnedVal)
   returnedVal = (ActiveSheet Is shInput)
End Sub

Sub clickSaveLocalBudgetCAVO(control As IRibbonControl)

Dim bWarnings As Boolean

   If (cCAVOSettings.isChristophe) Then

      If (ActiveWorkbook.FullName = cLocalDevFolder &amp; "BUDGET_CAVO.xlsm") Then
         bWarnings = Application.DisplayAlerts
         Application.DisplayAlerts = False
         ActiveWorkbook.Save
         Application.DisplayAlerts = bWarnings
      Else
         ActiveWorkbook.SaveAs cLocalDevFolder &amp; "BUDGET_CAVO.xlsm"
     End If

      Application.StatusBar = "Saved to " &amp; ActiveWorkbook.FullName

   Else

      MsgBox "Only for Christophe, save the Budget file on the local hard disk"

   End If

End Sub

Sub clickEPMEditBudgetCAVO(control As IRibbonControl)

Dim p_EPM As New EPMAddInAutomation

   p_EPM.OpenEditReport

End Sub

Sub clickEPMOpenDebugLog(control As IRibbonControl)

   Call cCAVOLog.OpenFile

End Sub

' ------------------------------------------------------------------------------
'
' Shortcut to the Refresh button of the EPM toolbar.  Refresh the active sheet
'
' ------------------------------------------------------------------------------

Sub clickEPMRefresh(control As IRibbonControl)

Dim sEntity As String
Dim wCalcMode As XlCalculation
Dim bContinue As Boolean

   bContinue = (cCAVOEPM.IsConnected)

   If (bContinue And shInput.enableEPMSubmit) Then
      If (ActiveSheet Is shInput) Then
         ' Display a warning only on the Input sheet
         bContinue = (MsgBox(UserDefinedFunctions.GetText("REFRESH_DATA_NOT_SAVED"), vbInformation + vbOKCancel + vbDefaultButton2, Variables.sApplicationTitle) = vbOK)
      End If
   End If

   If bContinue Then

       ' Be sure the matrix is reflecting the user's choice

       sEntity = cCAVOEPM.GetContextMember("ENTITY", , True)

       If (InStr(sEntity, "[ENH_ALL]") > 0) Then

          ' The matrix should be able to retrieve the Budget Process from the Entity (f.i. EN_62001).
          ' The Budget process is indeed an hierarchy that is specified on the entity base level (each organism is attached to a
          ' specific budget process)

          Call cCAVOMessage.Show("Toolbar::clickEPMRefresh()", "Please first select an entity", info, , , , False)

       Else

          wCalcMode = Application.Calculation
          Application.Calculation = xlCalculationManual

          ' To be sure that the matrix correspond to the selected BudgetYear/BudgetCycle/Phase/...
          cEPM.isMatrixNeedRefresh = True

          Call cEPM.GetMatrix

          ' Get the first base member and set it on the Params sheet for the Workstatus field
          shParams.Range("_ParamsWorkStatusDS").Value = cEPM.MatrixGetFirstBaseMember()

          ' Force to refresh the Input sheet and the report
          Call cEPM.Refresh(bRefreshWorksheetOnly:=False)

          ' Special case : the Intro sheet is displayed and not the Input one => display the input sheet
          If (shIntro.visible = xlSheetVisible) And (shInput.visible <> xlSheetVisible) Then
              Call cCAVOSheet.Hide(sh:=shIntro, shKeepVisible:=shInput)
          End If

          Application.Calculation = wCalcMode

       End If

    Else

       Application.StatusBar = "Refreshed cancelled"

    End If ' If bContinue Then

End Sub

' ------------------------------------------------------------------------------
'
' User's ease : by pressing CTRL-r (lower), the current worksheet will be refreshed.
' CTRL-r will have the same effect that clicking on the eBMC Refresh button
'
' ------------------------------------------------------------------------------

Public Sub KeyCTRLr()
   Call clickEPMRefresh(Nothing)
End Sub

' ------------------------------------------------------------------------------
'
' Submit the matrix
'
' ------------------------------------------------------------------------------

Sub clickSubmitMatrixForm(control As IRibbonControl)
   'If Not (wbeBMC Is Nothing) And (wbeBMC Is ThisWorkbook) Then
   If (ActiveSheet Is shMatrixForm) Then
       Call cEPM.MatrixSubmit
   Else
      Call cCAVOMessage.Show("Toolbar::clickSubmitMatrixForm", "This button should be used only when the matrix form is the active sheet", info)
   End If

End Sub

' ------------------------------------------------------------------------------
'
' Shortcut to the Submit button of the EPM toolbar.  Save data and refresh the worksheet
'
' ------------------------------------------------------------------------------

Sub clickEPMSubmit(control As IRibbonControl)
   If (shInput.enableEPMSubmit) Then
      Call cEPM.Submit
   Else
      Application.StatusBar = "There is no nothing to submit, no changes have been made"
   End If
End Sub

' ------------------------------------------------------------------------------
'
' User's ease : by pressing CTRL-s (lower), the workbook won't be saved but well
' the data.  CTRL-s will have the same effect that clicking on the eBMC Save Data button
'
' ------------------------------------------------------------------------------

Public Sub KeyCTRLs()
   Call clickEPMSubmit(Nothing)
End Sub

' ------------------------------------------------------------------------------
'
' Show the user's form to allow manipulate field's state easier to going into
' the _Matrix sheet.
'
' ------------------------------------------------------------------------------

Sub clickShowMatrixForm(control As IRibbonControl)

Dim wCalcMode  As XlCalculation

   wCalcMode = Application.Calculation
   Application.Calculation = xlCalculationManual

   Call cEPM.MatrixFormPrepare
   Call cCAVOSheet.Show(shMatrixForm, , , , True)
   shMatrixForm.Calculate

   Application.Calculation = wCalcMode

   If (cToolbar.ribbon Is Nothing) And Not (Variables.p_ribbon Is Nothing) Then Set cToolbar.ribbon = Variables.p_ribbon
   If Not (cToolbar.ribbon Is Nothing) Then Call cToolbar.ribbon.Invalidate

End Sub

' ------------------------------------------------------------------------------
'
' The user has fill in the matrix's form.  Submit changes
'
' ------------------------------------------------------------------------------

Sub clickShowMatrixDataTable(control As IRibbonControl)

   Call cCAVOSheet.Show(shMatrix, , , , True)
   Call cToolbar.RefreshRibbon

   'If Not (Toolbar.ribbon Is Nothing) Then Call Toolbar.ribbon.Invalidate("")

End Sub

' ------------------------------------------------------------------------------
'
' Display the About sheet
'
' ------------------------------------------------------------------------------

Sub clickShowAbout(control As IRibbonControl)

   Application.EnableCancelKey = XlEnableCancelKey.xlDisabled

   shAbout.Show

End Sub

' ------------------------------------------------------------------------------
'
' Get label for the BPC addin
'
' ------------------------------------------------------------------------------

Sub getLabelAbout(control As IRibbonControl, ByRef returnedVal)

Dim bEvents As Boolean

   bEvents = Application.EnableEvents
   Application.EnableEvents = False

   ' getLabelAbout is the last event / subroutine executed during the load of the ribbon.

   If Not cDevelopmentMode Then Application.ScreenUpdating = True
   Application.Cursor = xlDefault
   Application.EnableEvents = True

   On Error Resume Next
   returnedVal = "eBMC v" &amp; cCAVOWorkbook.GetCustomProperty("Version", "0.1", ActiveWorkbook)
   Err.Clear
   On Error GoTo 0

   ' Just after the loading, a lot of changes have been made in the workbook like hiding rows/columns, ...
   ' Excel will consider that the file has been modified while, in fact, it isn't the case.
   ActiveWorkbook.Saved = True

   Application.EnableEvents = bEvents

   Call cCAVODebug.Log("End", "Toolbar::getLabelAbout")

   cCAVOSettings.Ready = True

End Sub

' ------------------------------------------------------------------------------
'
' The user has selected a value from the Phase combobox
'
' ------------------------------------------------------------------------------

Sub onChangecbxMatrixPhase(control As IRibbonControl, selectedId As String, selectedIndex As Integer)

Dim sValue As String

   Call cCAVODebug.Log("Start", "Toolbar::onChangecbxMatrixPhase")

   sValue = shMatrixConfig.Range("_tblPhases").Cells(selectedIndex + 1, 1).Value
   Application.StatusBar = "Filter on " &amp; sValue

   'If (cCAVOEPM.IsConnected) Then

      shParams.Range("_paramsPhase").Value = sValue
      ' Refresh the report only when cEPM.AutoRefresh is set
      Call cEPM.SetReport("DATA_SOURCE", sValue, cEPM.AutoRefresh)

      DoEvents
      Application.Calculate

      'Call cEPM.GetMatrix
      'Call cEPM.Refresh

   'Else
   '   Call cCAVOMessage.Show("Toolbar::onChangecbxMatrixPhase", "Please first connect to EPM", Error)
   'End If

   Call cCAVODebug.Log("End", "Toolbar::onChangecbxMatrixPhase")

End Sub

' ------------------------------------------------------------------------------
'
' The user has selected a value from the Budget Process combobox
'
' ------------------------------------------------------------------------------

Sub onChangecbxMatrixBudgetProcess(control As IRibbonControl, selectedId As String, selectedIndex As Integer)

   Call cCAVODebug.Log("", "Toolbar::onChangecbxMatrixBudgetProcess")

   Application.StatusBar = "Filter on " &amp; shMatrixConfig.Range("_tblBudgetProcess").Cells(selectedIndex + 1, 1).Value
   shParams.Range("_paramsBudgetProcess").Value = shMatrixConfig.Range("_tblBudgetProcess").Cells(selectedIndex + 1, 1).Value

   ' -------------------------------------------------------------------------------------------------
   ' - 2017-10-25 : Be sure formula's on the sheet are correct
   ' -------------------------------------------------------------------------------------------------

   ActiveSheet.Calculate

   If (ActiveSheet Is shMatrixForm) Then Call cEPM.MatrixFormPrepare

End Sub

' ------------------------------------------------------------------------------
'
' The user has selected a value from the Budget cycle combobox
'
' ------------------------------------------------------------------------------

Sub onChangecbxMatrixBudgetCycle(control As IRibbonControl, selectedId As String, selectedIndex As Integer)

Dim sValue As String

Debug.Print "Toolbar::onChangecbxMatrixBudgetCycle"

   sValue = shMatrixConfig.Range("_tblCycles").Cells(selectedIndex + 1, 1).Value

   Application.StatusBar = "Filter on " &amp; sValue
   shParams.Range("_paramsBudgetCycle").Value = sValue

   ' Refresh the report only when cEPM.AutoRefresh is set
   Call cEPM.SetReport("CYCLE", sValue, cEPM.AutoRefresh)

   ' By modifying the BudgetCycle, the BudgetYear combo needs to be refreshed
   Call cToolbar.ribbon.InvalidateControl("cbxMatrixYears")

   If (ActiveSheet Is shMatrixForm) Then Call cEPM.MatrixFormPrepare

End Sub

' ------------------------------------------------------------------------------
'
' The user has selected a value from the Budget year combobox
'
' ------------------------------------------------------------------------------

Sub onChangecbxMatrixYears(control As IRibbonControl, selectedId As String, selectedIndex As Integer)

Dim wYear As Integer
Dim sValue As String, sCycle As String
Dim wCalcMode  As XlCalculation

   wCalcMode = Application.Calculation
   Application.Calculation = xlCalculationManual

If cCAVODebug.Enabled Then Debug.Print "Toolbar::onChangecbxMatrixYears"

   Application.StatusBar = "Filter on " &amp; selectedId

   shParams.Range("_paramsBudgetYear").Value = selectedId

   ' Refresh the report only when cEPM.AutoRefresh is set
   Call cEPM.SetReport("TIME", selectedId &amp; ".12", cEPM.AutoRefresh)

   If (ActiveSheet Is shMatrixForm) Then Call cEPM.MatrixFormPrepare

   Application.Calculation = wCalcMode

End Sub

' ------------------------------------------------------------------------------
'
' The user has selected a value from the Code_FIN combobox
'
' ------------------------------------------------------------------------------

Sub onChangecbxMatrixCodeFIN(control As IRibbonControl, selectedId As String, selectedIndex As Integer)

Dim sValue As String

Debug.Print "Toolbar::onChangecbxMatrixCodeFIN"

   sValue = shMatrixConfig.Range("_tbl_CodeFIN").Cells(selectedIndex + 1, 1).Value
   Application.StatusBar = "Filter on " &amp; sValue

   'If (cCAVOEPM.IsConnected) Then

      shParams.Range("_paramsCodeFIN").Value = sValue

      ' Refresh the report only when cEPM.AutoRefresh is set
      Call cEPM.SetReport("CODE_FIN", sValue, cEPM.AutoRefresh)

   'Else
   '   Call cCAVOMessage.Show("Toolbar::onChangecbxMatrixPhase", "Please first connect to EPM", Error)
   'End If

End Sub

' ------------------------------------------------------------------------------
'
' The user has selected a value from the Cred_Type combobox
'
' ------------------------------------------------------------------------------

Sub onChangecbxMatrixCredType(control As IRibbonControl, selectedId As String, selectedIndex As Integer)

Dim sValue As String

Debug.Print "Toolbar::onChangecbxMatrixCredType"

   sValue = shMatrixConfig.Range("_tbl_CredType").Cells(selectedIndex + 1, 1).Value
   Application.StatusBar = "Filter on " &amp; sValue

   'If (cCAVOEPM.IsConnected) Then

      shParams.Range("_paramsCreditType").Value = sValue

      ' Refresh the report only when cEPM.AutoRefresh is set
      Call cEPM.SetReport("CRED_TYP", sValue, cEPM.AutoRefresh)

   'Else
   '   Call cCAVOMessage.Show("Toolbar::onChangecbxMatrixPhase", "Please first connect to EPM", Error)
   'End If

End Sub

Sub onChangecbxMatrixCredSort(control As IRibbonControl, selectedId As String, selectedIndex As Integer)

Dim sValue As String

Debug.Print "Toolbar::onChangecbxMatrixCredSort"

   sValue = shMatrixConfig.Range("_tbl_CredSort").Cells(selectedIndex + 1, 1).Value
   Application.StatusBar = "Filter on " &amp; sValue

   'If (cCAVOEPM.IsConnected) Then

      shParams.Range("_paramsCreditSort").Value = sValue

      ' Refresh the report only when cEPM.AutoRefresh is set
      Call cEPM.SetReport("CRED_SORT", sValue, cEPM.AutoRefresh)

   'Else
   '   Call cCAVOMessage.Show("Toolbar::onChangecbxMatrixPhase", "Please first connect to EPM", Error)
   'End If

End Sub

' ----------------------------------------------------------------
'
' The user has selected an another display language (text will be translated)
'
' ----------------------------------------------------------------

Sub onChangecbxLanguage(control As IRibbonControl, selectedId As String, selectedIndex As Integer)

   ' selectedId is either "nl" or "fr"
   If (cCAVOLanguage.Language <> UCase(selectedId)) Then

      cCAVOLanguage.Language = UCase(selectedId)
      shParams.Range("_UserLanguage").Value = cCAVOLanguage.Language

      Call cCAVOEPM.SetUserLanguage(cCAVOLanguage.Language)
      Call cEPM.Refresh(bRefreshWorksheetOnly:=True)

   End If

End Sub

' ------------------------------------------------------------------------------
'
' Determine if the Matrix's buttons can be enabled (depending of the active sheet)
'
' ------------------------------------------------------------------------------

Sub enableEPMRefresh(control As IRibbonControl, ByRef Enabled)
   ' The refresh button will be enabled as soon as the sheet contains an EPM report (Input or not)
   Enabled = cCAVOEPM.containsReport(ActiveSheet)
End Sub

' ------------------------------------------------------------------------------
'
' Does the Save data button should be enabled ?
'
' ------------------------------------------------------------------------------

Sub enableEPMSubmit(control As IRibbonControl, ByRef Enabled)
   ' Always false except for the Input sheet and, in that case, only if there is something to save
   Enabled = IIf(ActiveSheet Is shInput, shInput.enableEPMSubmit, False)
End Sub

' ------------------------------------------------------------------------------
'
' Enable/Disable the "Add new row" button
'
' ------------------------------------------------------------------------------

Sub enableEPMInsertRow(control As IRibbonControl, ByRef Enabled)

   ' The Add new row button can be enabled only when two conditions are met :
   '   1. the active sheet is the Input sheet
   '   2. the workstatus is not a closed one
   Enabled = (ActiveSheet Is shInput) And (Left(shParams.Range("_paramsWorkStatusChangesAllowed").Value, 1) <> "N")

End Sub

' ------------------------------------------------------------------------------
'
' Enable/Disable the "Delete row" button
'
' ------------------------------------------------------------------------------

Sub enableEPMDeleteRow(control As IRibbonControl, ByRef Enabled)

   ' The Delete row button can be enabled only when two conditions are met :
   '   1. the active sheet is the Input sheet
   '   2. the workstatus is not a closed one
   Enabled = (ActiveSheet Is shInput) And (Left(shParams.Range("_paramsWorkStatusChangesAllowed").Value, 1) <> "N")

End Sub

Sub enableSubmitMatrixForm(control As IRibbonControl, ByRef Enabled)
    Enabled = (ActiveSheet Is shMatrixForm)
    'Enabled = True
End Sub

Sub enableRefreshMatrixFormComments(control As IRibbonControl, ByRef Enabled)
   Enabled = (ActiveSheet Is shMatrix)
End Sub

Sub enableFilterMatrixDataTable(control As IRibbonControl, ByRef Enabled): Enabled = (ActiveSheet Is shMatrix): End Sub

' ------------------------------------------------------------------------------
'
' Get the number of entries in the different comboboxes
'
' ------------------------------------------------------------------------------

Sub cbxMatrixPhaseItemCount(control As IRibbonControl, ByRef returnedVal): returnedVal = cToolbar.GetCbxItemCount("_tblPhases"): End Sub
Sub cbxMatrixCodeFINItemCount(control As IRibbonControl, ByRef returnedVal): returnedVal = cToolbar.GetCbxItemCount("_tbl_CodeFIN"): End Sub
Sub cbxMatrixBudgetProcessItemCount(control As IRibbonControl, ByRef returnedVal): returnedVal = cToolbar.GetCbxItemCount("_tblBudgetProcess"): End Sub
Sub cbxMatrixBudgetCycleItemCount(control As IRibbonControl, ByRef returnedVal): returnedVal = cToolbar.GetCbxItemCount("_tblCycles"): End Sub
Sub cbxMatrixCredTypeItemCount(control As IRibbonControl, ByRef returnedVal): returnedVal = cToolbar.GetCbxItemCount("_tbl_CredType"): End Sub
Sub cbxMatrixCredSortItemCount(control As IRibbonControl, ByRef returnedVal): returnedVal = cToolbar.GetCbxItemCount("_tbl_CredSort"): End Sub

' ------------------------------------------------------------------------------
'
' Get the number of pluri for the BudgetCycle : there is an attribute called "NB_PLURI" in the
' Cycle dimension.  That attribute tells how many "pluri years" should be foreseen for a given cycle.
'
' For instance : the budget 2019 INI should be done and also two, three or four pluri (2020, 2021, 2022 or 2023)
'
' ------------------------------------------------------------------------------

Sub cbxMatrixYearsItemCount(control As IRibbonControl, ByRef returnedVal)

Dim wNbYears As Byte
Dim sCycle As String

   If (cCAVOEPM.IsConnected) Then

      ' Retrieve the current BudgetCycle; from the EPM context
      sCycle = cCAVOEPM.GetContextMember(sDimensionName:="CYCLE", sh:=shInput, bOnlyLastMember:=True)

      'Call CAVO_AddIn.Initialize

      ' Retrieve the value of the NB_PLURI of a given BudgetCycle.

      On Error Resume Next

      wNbYears = cCAVOEPM.GetAttributeValue(sCycle, "NB_PLURI", shInput)

      If Err.Number <> 0 Then

         Err.Clear
         wNbYears = 1

      Else

         ' The NB_PLURI attribute gives the number of pluri (f.i. 3).
         ' The number of items in the BudgetYear dropbox is thus that number (3) + 1 since the year of the budget (Cycle 2019) is also
         ' in the list

         wNbYears = wNbYears + 1

      End If

      On Error GoTo 0

      returnedVal = wNbYears

   'Else
   '   Call cCAVOMessage.Show("Toolbar::onChangecbxMatrixPhase", "Please first connect to EPM", Error)
   End If

End Sub

' ------------------------------------------------------------------------------
'
' Populate the comboboxes
'
' ------------------------------------------------------------------------------

Sub cbxMatrixPhaseListItem(control As IRibbonControl, index As Integer, ByRef returnedVal): returnedVal = cToolbar.GetCbxListItem("_tblPhases", index, 3, 4): End Sub
Sub cbxMatrixCodeFINListItem(control As IRibbonControl, index As Integer, ByRef returnedVal): returnedVal = cToolbar.GetCbxListItem("_tbl_CodeFIN", index, 2, 3): End Sub
Sub cbxMatrixCredTypeListItem(control As IRibbonControl, index As Integer, ByRef returnedVal): returnedVal = cToolbar.GetCbxListItem("_tbl_CredType", index, 2, 3): End Sub
Sub cbxMatrixCredSortListItem(control As IRibbonControl, index As Integer, ByRef returnedVal): returnedVal = cToolbar.GetCbxListItem("_tbl_CredSort", index, 2, 3): End Sub
Sub cbxMatrixBudgetProcessListItem(control As IRibbonControl, index As Integer, ByRef returnedVal): returnedVal = cToolbar.GetCbxListItem("_tblBudgetProcess", index, 2, 3): End Sub
Sub cbxMatrixBudgetCycleListItem(control As IRibbonControl, index As Integer, ByRef returnedVal): returnedVal = cToolbar.GetCbxListItem("_tblCycles", index, 3, 4): End Sub

' ------------------------------------------------------------------------------
'
' Populate the BudgetYear dropbox by taking the number of Pluri foreseen for the
' BudgetCycle (attribute NB_PLURI of the dimension)
'
' ------------------------------------------------------------------------------

Sub cbxMatrixYearsListItem(control As IRibbonControl, index As Integer, ByRef returnedVal)

Dim wYear As Integer
Dim sCycle As String
Dim wCalcMode As XlCalculation
Dim bEvents As Boolean

   bEvents = Application.EnableEvents
   Application.EnableEvents = False

   wCalcMode = Application.Calculation
   Application.Calculation = xlCalculationManual

   ' Reset the parameter in the Params sheet.  "_paramsPluriBudgetYears" will be used in the VBA code
   ' when, for instance, an action like "Add a row" should be done on all budget years (the current and all the pluri)

   If (index = 0) Then shParams.Range("_paramsPluriBudgetYears").Value = ""

   'If (index = 0) Then Call cCAVODebug.GetAttention("cbxMatrixYearsListItem Populate")

   ' Retrieve the current BudgetCycle; from the EPM context
   sCycle = cCAVOEPM.GetContextMember(sDimensionName:="CYCLE", sh:=shInput, bOnlyLastMember:=True)

   ' Get the associatied budget year (for current BudgetCycle f.i. the attribute Year will be '2019')

   On Error Resume Next
   wYear = cCAVOEPM.GetAttributeValue(sCycle, "YEAR", shInput)
   If Err.Number <> 0 Then
      Err.Clear
      wYear = Year(Now()) + 1
   End If

   If (shParams.Range("_paramsPluriBudgetYears").Value = "") Then
      shParams.Range("_paramsPluriBudgetYears").Value = CStr(wYear + index)
   Else
      shParams.Range("_paramsPluriBudgetYears").Value = shParams.Range("_paramsPluriBudgetYears").Value &amp; ";" &amp; CStr(wYear + index)
   End If

   Application.Calculation = wCalcMode
   Application.EnableEvents = bEvents

   'Debug.Print "cbxMatrixYearsListItem   Index=" &amp; index &amp; "  Value=" &amp; (wYear + index)
   returnedVal = CStr(wYear + index)

End Sub

Sub cbxMatrixYearsGetItemID(control As IRibbonControl, index As Integer, ByRef returnedVal)

Dim wYear As Integer
Dim sCycle As String

   'If (index = 0) Then Call cCAVODebug.GetAttention("cbxMatrixYearsListItem Populate")

   ' Retrieve the current BudgetCycle; from the EPM context
   sCycle = cCAVOEPM.GetContextMember(sDimensionName:="CYCLE", sh:=shInput, bOnlyLastMember:=True)

   ' Get the associatied budget year (for current BudgetCycle f.i. the attribute Year will be '2019')

   On Error Resume Next
   wYear = cCAVOEPM.GetAttributeValue(sCycle, "YEAR", shInput)
   If Err.Number <> 0 Then
      Err.Clear
      wYear = Year(Now()) + 1
   End If

   'Debug.Print "cbxMatrixYearsGetItemID   Index=" &amp; index &amp; "  Value=" &amp; (wYear + index)

   returnedVal = CStr(wYear + index)

End Sub

' ------------------------------------------------------------------------------
'
' Get the screen tip for each comboboxes
'
' ------------------------------------------------------------------------------

Sub cbxMatrixPhaseItemScreentip(control As IRibbonControl, index As Integer, ByRef screentip): screentip = cToolbar.GetCbxListItem("_tblPhases", index, 3, 4): End Sub
Sub cbxMatrixCodeFINItemScreentip(control As IRibbonControl, index As Integer, ByRef screentip): screentip = cToolbar.GetCbxListItem("_tbl_CodeFIN", index, 2, 3): End Sub
Sub cbxMatrixCredTypeItemScreentip(control As IRibbonControl, index As Integer, ByRef screentip): screentip = cToolbar.GetCbxListItem("_tbl_CredType", index, 2, 3): End Sub
Sub cbxMatrixCredSortItemScreentip(control As IRibbonControl, index As Integer, ByRef screentip): screentip = cToolbar.GetCbxListItem("_tbl_CredSort", index, 2, 3): End Sub
Sub cbxMatrixBudgetProcessItemScreentip(control As IRibbonControl, index As Integer, ByRef screentip): screentip = cToolbar.GetCbxListItem("_tblBudgetProcess", index, 2, 3): End Sub
Sub cbxMatrixBudgetCycleItemScreentip(control As IRibbonControl, index As Integer, ByRef screentip): screentip = cToolbar.GetCbxListItem("_tblCycles", index, 3, 4): End Sub

Sub cbxMatrixYearsItemScreentip(control As IRibbonControl, index As Integer, ByRef screentip)
'   screentip = cToolbar.GetCbxListItem("_tblYears", index, 1, 1)
End Sub

' ------------------------------------------------------------------------------
'
' Initialize the default, selected, value of each combobox.
'
' ------------------------------------------------------------------------------

Sub cbxMatrixBudgetProcessItemIndex(control As IRibbonControl, ByRef returnedVal)
   returnedVal = cToolbar.GetDefaultItemIndex("_tblBudgetProcess", "_paramsBudgetProcess")
End Sub
Sub cbxMatrixCodeFINItemIndex(control As IRibbonControl, ByRef returnedVal)
   returnedVal = cToolbar.GetDefaultItemIndex("_tbl_CodeFIN", "_paramsCodeFIN")
   Call cEPM.SetReport("CODE_FIN", shParams.Range("_paramsCodeFIN").Value, False)
End Sub
Sub cbxMatrixCredTypeItemIndex(control As IRibbonControl, ByRef returnedVal)
   returnedVal = cToolbar.GetDefaultItemIndex("_tbl_CredType", "_paramsCreditType")
   Call cEPM.SetReport("CRED_TYP", shParams.Range("_paramsCreditType"), False)
End Sub
Sub cbxMatrixCredSortItemIndex(control As IRibbonControl, ByRef returnedVal)
   returnedVal = cToolbar.GetDefaultItemIndex("_tbl_CredSort", "_paramsCreditSort")
   Call cEPM.SetReport("CRED_SORT", shParams.Range("_paramsCreditSort"), False)
End Sub
Sub cbxMatrixPhaseItemIndex(control As IRibbonControl, ByRef returnedVal)
   returnedVal = cToolbar.GetDefaultItemIndex("_tblPhases", "_paramsPhase")
   Call cEPM.SetReport("DATASOURCE", shParams.Range("_paramsPhase"), False)
End Sub
Sub cbxMatrixBudgetCycleItemIndex(control As IRibbonControl, ByRef returnedVal)
   returnedVal = cToolbar.GetDefaultItemIndex("_tblCycles", "_paramsBudgetCycle")
   Call cEPM.SetReport("CYCLE", shParams.Range("_paramsBudgetCycle"), False)
End Sub

Sub cbxMatrixYearsItemIndex(control As IRibbonControl, ByRef returnedVal)

Dim wYear As Integer, wParamsYear As Integer
Dim sCycle As String
Dim bEvents As Boolean

   bEvents = Application.EnableEvents

   Application.EnableEvents = False
   wParamsYear = shParams.Range("_paramsBudgetYear").Value

   ' Retrieve the current BudgetCycle; from the EPM context
   sCycle = cCAVOEPM.GetContextMember(sDimensionName:="CYCLE", sh:=shInput, bOnlyLastMember:=True)

   ' Get the associatied budget year (for current BudgetCycle f.i. the attribute Year will be '2019')

   On Error Resume Next
   wYear = cCAVOEPM.GetAttributeValue(sCycle, "YEAR", shInput)
   If Err.Number <> 0 Then
      Err.Clear
      wYear = Year(Now()) + 1
   End If

   Call cEPM.SetReport("TIME", wParamsYear &amp; ".12", False)

   Application.EnableEvents = bEvents

   Call cCAVODebug.GetAttention("cbxMatrixYearsItemIndex SET Default to " &amp; wYear)

   ' If the selected Year is f.i. 2020, we can't return 2020, we need to return the index (0, 1, 2, ...), not the value.
   ' The index is calculated by taking the start year (f.i. 2018 (variable wYear)) minus the selected year (f.i. 2020))

   returnedVal = (wParamsYear - wYear)

End Sub

' ----------------------------------------------------------------
'
' Define the default language
'
' ----------------------------------------------------------------

Public Sub cbxLanguageItemIndex(control As IRibbonControl, ByRef returnedVal As Variant)

Dim sLanguage As String

   sLanguage = UCase(IIf(shParams.Range("_UserLanguage").Value = "", cEPM.GetUserLanguage, shParams.Range("_UserLanguage").Value))

   ' Be sure that the language is supported
   If (sLanguage <> "FR") And (sLanguage <> "NL") Then sLanguage = "FR"

   cCAVOLanguage.Language = sLanguage
   returnedVal = LCase(sLanguage)

End Sub

' ------------------------------------------------------------------------------
'
' Who can see these part of the ribbon ?
'
' ------------------------------------------------------------------------------

Sub getVisibleChristophe(control As IRibbonControl, ByRef returnedVal)
  returnedVal = cCAVOSettings.isChristophe()
End Sub

Sub getVisibleOnlyAdmin(control As IRibbonControl, ByRef returnedVal)
   returnedVal = cCAVOSettings.isAdmin()
End Sub

Sub getVisiblecbxMatrixPhase(control As IRibbonControl, ByRef returnedVal)
   returnedVal = cCAVOSettings.isAdmin()
End Sub
Sub getVisiblecbxMatrixBudgetCycle(control As IRibbonControl, ByRef returnedVal)
   returnedVal = cCAVOSettings.isAdmin()
End Sub

' ------------------------------------------------------------------------------
'
' Define the label for the Connect button : connect or logout
'
' ------------------------------------------------------------------------------

Sub getLabelEPMConnect(control As IRibbonControl, ByRef returnedVal)

Dim bSilent As Boolean

   bSilent = cCAVOSettings.SilentMode
   cCAVOSettings.SilentMode = True

   If (cCAVOEPM Is Nothing) Then Set cCAVOEPM = New clsCAVOEPM

   returnedVal = IIf(cCAVOEPM.IsConnected, "Logout", "Connect")

   cCAVOSettings.SilentMode = bSilent

End Sub

' ------------------------------------------------------------------------------
'
' Connect to / Disconnect from EPM
'
' ------------------------------------------------------------------------------

Sub clickEPMConnect(control As IRibbonControl)

   If (cCAVOEPM Is Nothing) Then Set cCAVOEPM = New clsCAVOEPM

   If Not (cCAVOEPM.IsConnected) Then

      Call cCAVOEPM.Connect

   Else
      Call cCAVOEPM.Disconnect
   End If

   If Not (cToolbar.ribbon Is Nothing) Then Call cToolbar.ribbon.Invalidate

End Sub

' ------------------------------------------------------------------------------
'
' On the workbook's opening, the ShowHide Hidden ranges toggle button should not be pressed
' i.e. rows and columns with technical informations (with yellow background) should remains hidden
'
' ------------------------------------------------------------------------------

Sub pressedEPMInsertRow(control As IRibbonControl, ByRef pressed)
   pressed = Not shInput.Range("_rngAddNewRow").EntireRow.Hidden
End Sub

' ------------------------------------------------------------------------------
'
' The user has clicked on the Add new row button; display the range of the Input sheet with
' the quick selection and add button
'
' ------------------------------------------------------------------------------

Sub clickEPMAddNewRow(control As IRibbonControl, pressed As Boolean)

Dim wCalcMode As XlCalculation
Dim bScreenUpdating As Boolean, bEvents As Boolean, bIsProtected As Boolean
Dim sTemp As String

   If Left(shParams.Range("_paramsWorkStatusChangesAllowed").Value, 1) = "N" Then

      Call cCAVOMessage.Show("Toolbar::clickEPMAddNewRow", GetText("WORKSTATUS_NOT_OPENED"), info)

      Application.StatusBar = "The workstatus doesn't allow you to add a new row in the sheet"
      If Not (shInput.Range("_rngAddNewRow").EntireRow.Hidden) Then shInput.Range("_rngAddNewRow").EntireRow.Hidden = True

   Else

      wCalcMode = Application.Calculation
      Application.Calculation = xlCalculationManual

      If Not ActiveSheet Is shInput Then shInput.Activate

      bIsProtected = shInput.ProtectContents
      If bIsProtected Then Call cCAVOEPM.UnProtectSheet(shInput)
      shInput.Range("_rngAddNewRow").EntireRow.Hidden = Not shInput.Range("_rngAddNewRow").EntireRow.Hidden
      If bIsProtected Then Call cCAVOEPM.ProtectSheet(shInput)

      ' Only when the range is visible, initialize it
      If (shInput.Range("_rngAddNewRow").EntireRow.Hidden = False) Then

         bScreenUpdating = Application.ScreenUpdating
         If Not cDevelopmentMode Then Application.ScreenUpdating = False

         bEvents = Application.EnableEvents
         Application.EnableEvents = False

         With shInput

            ' Prefill the Credit type by the one selected in the eBMC ribbon
            .Range("_AddNew_CRED_TYPE").Value = cCAVOEPM.GetContextMember("CRED_TYP", shInput, True)

            ' Prefill the other values by the selected value in the eBMC ribbon but only if not a hierarchy
            sTemp = cCAVOEPM.GetContextMember("CODE_ECO", shInput, True)
            .Range("_AddNew_CODE_ECO").Value = IIf((Left(sTemp, 4) <> "CEH_"), sTemp, "")
            .Range("_addNew_CODE_ECO").Activate

            sTemp = cCAVOEPM.GetContextMember("CODE_FIN", shInput, True)
            .Range("_AddNew_CODE_FIN").Value = IIf((Left(sTemp, 4) <> "CFH_"), sTemp, "")

            sTemp = cCAVOEPM.GetContextMember("CRED_SORT", shInput, True)
            .Range("_AddNew_CRED_SORT").Value = IIf((Left(sTemp, 4) <> "CSH_"), sTemp, "")

            .Range("_AddNew_LITTERA").Value = ""

         End With

         Application.EnableEvents = bEvents

         If Not cDevelopmentMode Then Application.ScreenUpdating = bScreenUpdating

      End If

      Application.Calculation = wCalcMode

   End If

End Sub

Sub clickEPMDeleteRow(control As IRibbonControl)

Dim rng As Range, rngSelection As Range, rngEPMReport As Range
Dim bScreenUpdating As Boolean, bEnableEvents As Boolean, bAsk As Boolean, bDoDelete As Boolean
Dim bDoIt As Boolean, bForceSilent As Boolean
Dim sh As Worksheet
Dim wCalcMode As XlCalculation
Dim wBudget As Double
Dim sMsg As String, sBudgetYear As String
Dim sCodeECO As String, sCredType As String, sCredSort As String, sCodeFIN As String, sLittera As String, sKey As String
Dim arrYears As Variant
Dim I As Byte, wFirst As Byte, wLast As Byte
Dim p_EPM As New FPMXLClient.EPMAddInAutomation

   Application.EnableCancelKey = XlEnableCancelKey.xlDisabled

   bEnableEvents = Application.EnableEvents
   bScreenUpdating = Application.ScreenUpdating

   Application.EnableEvents = False
   Application.ScreenUpdating = False

   wCalcMode = Application.Calculation
   Application.Calculation = xlCalculationManual

   Set rngSelection = Selection

   bDoDelete = False
   Set rngEPMReport = shInput.Range(p_EPM.GetDataTopLeftCell(shInput, "000"), p_EPM.GetDataBottomRightCell(shInput, "001"))

   For Each rng In rngSelection.Rows

      If Not (Intersect(rngEPMReport, rng) Is Nothing) Then

         Set rng = shInput.Cells(rng.Row, shInput.Range("_rngColCreditType").Column)

         Set rng = rng.Resize(1, (shInput.Range("_rngColLittera").Column - shInput.Range("_rngColCreditType").Column) + 1)
         rng.Select

         On Error Resume Next
         wBudget = CDbl(shInput.Cells(rng.Row, shInput.Range("_rngColDSH_BUD_TOT").Column).Value)
         If Err.Number <> 0 Then Call cCAVODebug.GetAttention("DSH_BUD_TOT NOT NUMERIC")
         Err.Clear
         On Error GoTo 0

         If (wBudget <> 0) Then ' If (wBudget <> 0) Then

            If Not cCAVOSettings.SilentMode Then
               Call cCAVOMessage.Show(sSource:="Toolbar::clickEPMDeleteRow", sMessage:=GetText("ARTICLE_WITH_BUDGET_NO_DELETE"), MessageType:=Error, bOnlyOnce:=False)
            End If

         Else ' If (wBudget <> 0) Then

            ' Prepare the confirmation message
            sCredType = shInput.Cells(rng.Row, shInput.Range("_rngColCreditType").Column).Value
            sCodeECO = shInput.Cells(rng.Row, shInput.Range("_rngColCodeECO").Column).Value
            sCodeFIN = shInput.Cells(rng.Row, shInput.Range("_rngColCodeFIN").Column).Value
            sCredSort = shInput.Cells(rng.Row, shInput.Range("_rngColCreditSort").Column).Value
            sLittera = shInput.Cells(rng.Row, shInput.Range("_rngColLittera").Column).Value

            ' Get the current budget year that was selected from the eBMC ribbon
            sBudgetYear = shParams.Range("_paramsBudgetYear").Value

            sMsg = cCAVOFunctions.StringFormat(GetText("ARTICLE_DELETE_ROW"), _
               GetText("CRED_TYPE") &amp; " : " &amp; sCredType, GetText("CODE_ECO") &amp; " : " &amp; sCodeECO, _
               GetText("CODE_FIN") &amp; " : " &amp; sCodeFIN, GetText("CRED_SORT") &amp; " : " &amp; sCredSort, _
               GetText("LITTERA") &amp; " : " &amp; sLittera, sBudgetYear)

            sMsg = Replace(sMsg, "|", vbCrLf)

            ' And show it.  Ask if we need to delete the article

            If Not cCAVOSettings.SilentMode Then
               bDoDelete = (MsgBox(sMsg, vbQuestion + vbYesNo + vbDefaultButton2, Variables.sApplicationTitle) = vbYes)
            Else
               bDoDelete = True
            End If

            If bDoDelete Then

               With shInput
                  .Range("_AddNew_CRED_TYPE").Value = sCredType
                  .Range("_AddNew_CODE_ECO").Value = sCodeECO
                  .Range("_AddNew_CODE_FIN").Value = sCodeFIN
                  .Range("_AddNew_CRED_SORT").Value = sCredSort
                  .Range("_AddNew_LITTERA").Value = sLittera
               End With

               ' Generate the key, for debugging purpose only
               sKey = sCredType &amp; "#" &amp; sCodeECO &amp; "#" &amp; sCodeFIN &amp; "#" &amp; sCredSort &amp; "#" &amp; sLittera

               rng.Interior.ColorIndex = 3
               shInput.Cells(rng.Row, shInput.Range("_rngColPublished").Column).Value = 0

               ' -----------------------------------------------
               '
               ' Delete the article

               bForceSilent = False

               Set sh = ActiveSheet

               shEPMMD.Activate

               ' Stupid EPM, if the mode is manual, the SaveWorksheetData will not work.  Soooo stupid.
               Application.Calculation = xlCalculationAutomatic

               ' The Add row feature should insert the new budget article in the current BudgetYear but also for each
               ' pluri.  Get the list of all years from the Params sheet
               arrYears = Split(shParams.Range("_paramsPluriBudgetYears").Value, ";")

               wFirst = LBound(arrYears)
               wLast = UBound(arrYears)

               bDoIt = False

               ' Get the budget year from the Params sheet; that year is the selected year in the eBMC ribbon.
               ' If we're processing budget year 2018, the user has, perhaps, choice 2020 from the BudgetYear eBMC dropdown list
               ' so, sBudgetYear can be, in that case 2020 and not 2018.
               sBudgetYear = shParams.Range("_paramsBudgetYear").Value

               ' Force the silent mode so the "One row will be inserted" is displayed only once and not for each budget years
               If Not cCAVOSettings.SilentMode Then bForceSilent = p_EPM.GetUserOption("HideSubmitWarning")

               For I = wFirst To wLast

                  If (arrYears(I) = sBudgetYear) Then bDoIt = True

                  If bDoIt Then

                     Call cCAVOLog.Log("Toolbar::clickEPMDeleteRow - Delete the article " &amp; arrYears(I) &amp; "#" &amp; sKey)
                     Application.StatusBar = "Delete the article for " &amp; arrYears(I)

                     shEPMMD.Range("_EPMMD_ROWTIME").Value = arrYears(I) &amp; ".12"

                     ' Set the value for the DS_Published to false => will be understand like "the record is no more published" => deleted
                     shEPMMD.Range("_EPMMD_DSPublished").Value = "0"

                     Call cCAVOLog.Log("   Toolbar::clickEPMDeleteRow - p_EPM.RefreshActiveSheet")

                     Call p_EPM.RefreshActiveSheet
                     Call p_EPM.SaveWorksheetData

                     Call p_EPM.SetUserOption("HideSubmitWarning", True)

                  End If

               Next

               If Not cCAVOSettings.SilentMode Then Call p_EPM.SetUserOption("HideSubmitWarning", bForceSilent)

               sh.Activate

               Call cCAVOEPM.Refresh

               Set sh = Nothing

               Application.EnableEvents = True
               Application.Calculation = wCalcMode

            End If

         End If ' If (wBudget <> 0) Then

      End If

   Next rng

   Set rngEPMReport = Nothing

   ' Do we need to delete something ?  If so, do it.
   ' If bDoDelete Then Call cCAVOEPM.Submit

   Application.Calculation = wCalcMode

   Application.ScreenUpdating = bScreenUpdating
   Application.EnableEvents = bEnableEvents

End Sub