VERSION 5.00
Begin VB.UserControl ONSV_MGManager 
   ClientHeight    =   7560
   ClientLeft      =   0
   ClientTop       =   0
   ClientWidth     =   14160
   ScaleHeight     =   7560
   ScaleWidth      =   14160
   Begin Project1.ToolbarControl tlb_main 
      Height          =   690
      Left            =   3150
      TabIndex        =   2
      Top             =   150
      Width           =   10560
      _ExtentX        =   18627
      _ExtentY        =   1217
   End
   Begin VB.Frame frm_main 
      Height          =   6615
      Left            =   3165
      TabIndex        =   1
      Top             =   885
      Width           =   10725
      Begin VB.Frame frm_detail 
         Caption         =   "Detail"
         Height          =   4515
         Left            =   210
         TabIndex        =   5
         Top             =   1095
         Width           =   10260
         Begin Project1.ArmGrid grd_items 
            Height          =   2535
            Left            =   135
            TabIndex        =   14
            Top             =   1530
            Width           =   9420
            _ExtentX        =   16616
            _ExtentY        =   4471
         End
         Begin Project1.ArmCombobox cbo_HBM_Code 
            Height          =   345
            Left            =   5190
            TabIndex        =   6
            Tag             =   "HBM"
            Top             =   660
            Width           =   2325
            _ExtentX        =   4101
            _ExtentY        =   609
         End
         Begin Project1.ArmCombobox cbo_SBM_Code 
            Height          =   345
            Left            =   1395
            TabIndex        =   7
            Tag             =   "SBM"
            Top             =   660
            Width           =   2325
            _ExtentX        =   4101
            _ExtentY        =   609
         End
         Begin Project1.ArmCombobox cbo_BM_Code 
            Height          =   345
            Left            =   1395
            TabIndex        =   8
            Tag             =   "BM"
            Top             =   1065
            Width           =   2325
            _ExtentX        =   4101
            _ExtentY        =   609
         End
         Begin Project1.ArmCombobox cbo_MG_Code 
            Height          =   345
            Left            =   5190
            TabIndex        =   9
            Tag             =   "MG_CODE"
            Top             =   270
            Width           =   2325
            _ExtentX        =   4101
            _ExtentY        =   609
         End
         Begin Project1.ArmCombobox cbo_CG_Code 
            Height          =   345
            Left            =   1395
            TabIndex        =   15
            Tag             =   "CGCODE"
            Top             =   270
            Width           =   2325
            _ExtentX        =   4101
            _ExtentY        =   609
         End
         Begin VB.Label lbl_labels 
            Caption         =   "Category"
            Height          =   315
            Index           =   0
            Left            =   180
            TabIndex        =   16
            Top             =   300
            Width           =   1035
         End
         Begin VB.Label lbl_labels 
            Caption         =   "Material group"
            Height          =   315
            Index           =   4
            Left            =   3900
            TabIndex        =   13
            Top             =   300
            Width           =   1035
         End
         Begin VB.Label lbl_labels 
            Caption         =   "BM"
            Height          =   315
            Index           =   3
            Left            =   180
            TabIndex        =   12
            Top             =   1095
            Width           =   1035
         End
         Begin VB.Label lbl_labels 
            Caption         =   "SBM"
            Height          =   315
            Index           =   2
            Left            =   180
            TabIndex        =   11
            Top             =   690
            Width           =   1035
         End
         Begin VB.Label lbl_labels 
            Caption         =   "HBM"
            Height          =   315
            Index           =   1
            Left            =   3900
            TabIndex        =   10
            Top             =   690
            Width           =   1035
         End
      End
      Begin Project1.ArmGrid grd_lst 
         Height          =   6135
         Left            =   225
         TabIndex        =   4
         Top             =   300
         Width           =   10515
         _ExtentX        =   18547
         _ExtentY        =   10821
      End
   End
   Begin VB.Frame frm_filters 
      Caption         =   "Filters"
      Height          =   7320
      Left            =   120
      TabIndex        =   0
      Top             =   105
      Width           =   2910
      Begin Project1.ArmTreeView trw_filter 
         Height          =   6825
         Left            =   105
         TabIndex        =   3
         Top             =   315
         Width           =   2715
         _ExtentX        =   4789
         _ExtentY        =   12039
      End
   End
End
Attribute VB_Name = "ONSV_MGManager"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit


Private Const SCREEN_NAME As String = "ONSVMGManager"


Private Declare Function LockWindowUpdate Lib "user32" (ByVal hwnd As Long) As Long

Private Const SEP = "®©"
Private Const SEP1 As String = "®"
Private Const SEP2 As String = "©"
Private Const CL_COLOR_ENABLED As Long = &H80000005
Private Const CL_COLOR_DISABLED As Long = &H8000000F

Private Const C_TOOLBARFACE_ITEM_LST As String = "0"
Private Const C_TOOLBARFACE_ITEM_UPD As String = "1"
Private Const C_TOOLBARFACE_ITEM_ADD As String = "2"
Private Const C_TOOLBARFACE_ITEM_DELETE As String = "3"
Private Const C_TOOLBARFACE_ITEM_VIEW As String = "4"

Private mb_eventRunning As Boolean
Private mb_Initialized As Boolean
Private mo_Db As ArmDb
Private ms_Language_Code As String
Dim mu_ActiveMode As ArmScreenMode
Private ml_U_Code As Long
Private ml_newItemRow As Long                   ' current row for free matgrp combination

Public Event quit()
Private Enum ArmScreenMode
  smMain
  smAdd
  smUpdate
  smDelete
  smView
End Enum




Public Property Get Initialized() As Boolean
    Initialized = mb_Initialized
End Property


Public Property Let Visible(ByVal aVisible As Boolean)
    UserControl.Extender.Visible = aVisible
End Property
Public Property Get Visible() As Boolean
    Visible = UserControl.Extender.Visible
End Property

Public Sub Move(ByVal aLeft As Single, ByVal aTop As Single, ByVal aWidth As Single, ByVal aHeight As Single)
    Call UserControl.Extender.Move(aLeft, aTop, aWidth, aHeight - 2220)
    Call Resize
End Sub

Property Let Language_Code(AString As String)
On Error GoTo ErrHandler

  ms_Language_Code = AString
  Exit Property
ErrHandler:
  Call ErrorMessage("Language_Code.Let")
End Property

Property Let U_Code(ByVal al_U_Code As Long)
On Error GoTo ErrHandler

  ml_U_Code = al_U_Code
  Exit Property
ErrHandler:
  Call ErrorMessage("U_Code.Let")
End Property

Public Property Set ArmDb(ByRef lo_Db As Object)
On Error GoTo ErrHandler
  
  Set mo_Db = lo_Db
  Exit Property
ErrHandler:
  Call ErrorHandler("ArmDb.Set")
End Property


Public Sub Load_A_COM()
    
On Error GoTo ErrHandler

    If mb_Initialized Then Exit Sub
    
    mb_Initialized = True
    
    mb_eventRunning = True
    
    Dim lo_Control As Object
    Dim lo_ToolTip As Object
    
      For Each lo_Control In Controls
        Select Case UCase(TypeName(lo_Control))
        Case "ARMCOMBOBOX"
          Set lo_Control.ArmDb = mo_Db
          Call lo_Control.Load_A_COM
        Case "ARMPICKER"
          Set lo_Control.ArmDb = mo_Db
          Call lo_Control.Load_A_COM
        Case "TOOLBARCONTROL"
          lo_Control.Language = ms_Language_Code
'          Set lo_Control.ArmDb = mo_Db
          Call lo_Control.Load_A_COM
        Case "ARMGRID"
          Set lo_Control.ArmDb = mo_Db
          Call lo_Control.Load_A_COM
        Case "ARMTREEVIEW"
          Set lo_Control.ArmDb = mo_Db
          lo_Control.Language = ms_Language_Code
          Call lo_Control.Load_A_COM
        Case "ARMCHECKVIEW"
          Set lo_Control.ArmDb = mo_Db
          Call lo_Control.Load_A_COM
        Case "A_CALOCX"
          lo_Control.Language = ms_Language_Code
          Call lo_Control.reinit_cal
        Case "TOOLBR"
          Set lo_Control.ArmDb = mo_Db
          Call lo_Control.Load_A_COM
        End Select
      Next
    
    ' init toolbar
'336EESFGIDRW®05858®QE/BAC®CVVDGGEFFJTT
    Call tlb_Main.SetToolbarInfoStringParameters("001EESFGIDRW®011708®QE/BAC®AAABBBCCCHLLTTT®111708®QE/BAC®AHHBIITTT®211708®QE/BAC®AHHBIIGJJHKKTTT®311708®QE/BAC®AHHTTT®411708®QE/BAC®BBBCCCTTT", "001")
    
    ' INIT COMBOBOXES
    cbo_CG_Code.FirstBlankItem = False
    cbo_CG_Code.Request = "SELECT CG.CG_Code, CG.CG_Desc FROM [Categories] CG WHERE CG.Language_code='" & ms_Language_Code & "' ORDER BY 2"
    
    cbo_MG_Code.FirstBlankItem = False
    cbo_MG_Code.Request = "SELECT MG.MG_Code, MG.MG_Desc FROM ONSV_Material_Group MG WHERE MG.Language_code='E' ORDER BY MG.DESC_ORDER"
    
    cbo_BM_Code.FirstBlankItem = False
    cbo_BM_Code.Request = ""
    
    cbo_SBM_Code.FirstBlankItem = False
    cbo_SBM_Code.Request = ""

    ' init grig
    grd_lst.AllowExcelExport = True
    grd_lst.Title = "Material group assignement"
    grd_lst.MultiSelect = False
    
    
    If Not grd_lst.SetColumns(Array( _
                Join(Array("CG_CODE", 0, 1, "CGCODE", "#CGCODE"), SEP) _
                , Join(Array("SBM_CODE", 0, 1, "SBM", "#SBM"), SEP) _
                , Join(Array("BM_CODE", 0, 1, "BM", "#BM"), SEP) _
                , Join(Array("MG_CODE", 0, 0, "MG_CODE", "#MG"), SEP) _
                , Join(Array("HBM_CODE", 0, 0, "HBM", "#HBM"), SEP) _
                , Join(Array("CG_Desc", 1700, 0, "CG_Desc", "#Category", "String"), SEP) _
                , Join(Array("CATGRP", 1200, 0, "CATGRP", "#Material group"), SEP) _
                , Join(Array("BM_Desc", 3000, 0, "BM_Desc", "#Base material", "String"), SEP) _
                , Join(Array("HBM_Desc", 1100, 0, "HBM_Desc", "#Hyper material", "String"), SEP) _
                , Join(Array("SBM_Desc", 1300, 0, "SBM_Desc", "#Super material"), SEP) _
                )) Then
        MsgBox ("Grid not initialized!")
    End If
    
    grd_items.AllowExcelExport = True
    grd_items.Title = "Material group assignement items"
    grd_items.MultiSelect = False
    
    
    If Not grd_items.SetColumns(Array( _
                Join(Array("BI_SAP_Code", 1300, 1, "BI_SAP_Code", "#BI_SAP_Code"), SEP) _
                , Join(Array("BI_Desc", 5000, 0, "BI_Desc", "#Item description"), SEP) _
                , Join(Array("Origin", 1000, 0, "Origin", "#System origin"), SEP) _
                )) Then
        MsgBox ("Items grid not initialized!")
    End If
    
    Call InitFilterTreeView
    
    Call UpdateUI(ArmScreenMode.smMain)
    
    Call RefreshGrid
    
    mb_eventRunning = False
    
    Exit Sub
    
ErrHandler:
    
    Call ErrorHandler("Load_A_COM")
    
End Sub

Private Sub UpdateUI(ByVal au_Mode As ArmScreenMode)
On Error GoTo ErrHandler

    ' set active face
    mu_ActiveMode = au_Mode
    tlb_Main.Redraw = False
    

    ' apply face
    Dim lo_ctrl As Object

    ' hide all frames
    frm_detail.Visible = False
    grd_lst.Visible = False

    ' we have clean screen we can display proper controls
    Select Case mu_ActiveMode
        Case smMain
            Call EnableControl(grd_lst, True)
            Call SetEnabled(GetContainedControlsChain(frm_filters), True)
            Call SetEnabled(GetContainedControlsChain(frm_detail), False)
            
            grd_lst.Visible = True
            Call tlb_Main.DisplayFace(C_TOOLBARFACE_ITEM_LST)
        Case smUpdate
            ' we are in Update section
            Call EnableControl(grd_lst, False)
            Call SetEnabled(GetContainedControlsChain(frm_filters), False)
            Call SetEnabled(GetContainedControlsChain(frm_detail), True)
            Call EnableControl(cbo_CG_Code, False)
            Call EnableControl(cbo_HBM_Code, False)
            Call EnableControl(cbo_SBM_Code, False)
            Call EnableControl(cbo_BM_Code, False)
            
            
            frm_detail.Visible = True
            Call tlb_Main.DisplayFace(C_TOOLBARFACE_ITEM_UPD)
        
        Case smAdd
            ' we are in Update section
            Call EnableControl(grd_lst, False)
            Call SetEnabled(GetContainedControlsChain(frm_filters), False)
            Call SetEnabled(GetContainedControlsChain(frm_detail), True)
            Call EnableControl(cbo_HBM_Code, False)
            
            frm_detail.Visible = True
            Call tlb_Main.DisplayFace(C_TOOLBARFACE_ITEM_ADD)
'        Case smView
'            ' we are in PreView section
'            Call EnableControl(grd_lst, False)
            
        Case smDelete
            ' we are in PreView section
            Call EnableControl(grd_lst, False)
            Call SetEnabled(GetContainedControlsChain(frm_filters), False)
            Call SetEnabled(GetContainedControlsChain(frm_detail), False)
            Call EnableControl(grd_items, True)
            
            frm_detail.Visible = True
            Call tlb_Main.DisplayFace(C_TOOLBARFACE_ITEM_DELETE)
        Case smView
            Call EnableControl(grd_lst, False)
            Call SetEnabled(GetContainedControlsChain(frm_filters), False)
            Call SetEnabled(GetContainedControlsChain(frm_detail), False)
            Call EnableControl(grd_items, True)
            
            frm_detail.Visible = True
            Call tlb_Main.DisplayFace(C_TOOLBARFACE_ITEM_VIEW)
        Case Else
            Debug.Assert (False)
    End Select
    
    ' to display face immidiatelly
    tlb_Main.Redraw = True
    UserControl.Refresh
    Exit Sub
ErrHandler:
    Call ErrorHandler("UpdateUI()")
End Sub



Public Sub Unload_A_COM()
    
On Error GoTo ErrHandler
    mb_Initialized = False
    
    Dim lo_Control As Object

    For Each lo_Control In Controls
      Select Case UCase(TypeName(lo_Control))
      Case "ARMCOMBOBOX"
        Call lo_Control.Unload_A_COM
      Case "ARMPICKER"
        Call lo_Control.Unload_A_COM
      Case "TOOLBARCONTROL"
        Call lo_Control.Unload_A_COM
      Case "ARMGRID"
        Call lo_Control.Unload_A_COM
      Case "ARMTREEVIEW"
        Call lo_Control.Unload_A_COM
      Case "ARMCHECKVIEW"
        Call lo_Control.Unload_A_COM
      Case "TOOLBR"
        Call lo_Control.Unload_A_COM
      End Select
    Next
    Exit Sub
    
ErrHandler:
    
    Call ErrorHandler("UnLoad_A_Com")
    
End Sub

Public Sub Resize()
    Call InitCtrlSize
End Sub

Private Sub InitCtrlSize()
On Error GoTo ErrHandler
    If UserControl.Extender.Width < 11910 Then
        Exit Sub
    End If
    
    If UserControl.Extender.Height < 3500 Then
        Exit Sub
    End If
    
    Const SPACE As Long = 60
    Call tlb_Main.Move(SPACE, 0, UserControl.Extender.Width - 2 * SPACE - 30, tlb_Main.Height)
    
    Call frm_filters.Move(tlb_Main.Left, tlb_Main.Top + tlb_Main.Height)
    frm_filters.Height = UserControl.Extender.Height - 2 * SPACE - frm_filters.Top
    
    Call trw_filter.Move(SPACE, SPACE + 200, frm_filters.Width - 2 * SPACE, frm_filters.Height - 2 * SPACE - 200)
    
    Call frm_Main.Move(frm_filters.Left + frm_filters.Width + SPACE, frm_filters.Top, 0, frm_filters.Height)
    frm_Main.Width = tlb_Main.Width + SPACE - frm_Main.Left
    
    Call grd_lst.Move(SPACE, SPACE + 100, frm_Main.Width - 2 * SPACE, frm_Main.Height - 2 * SPACE - 100)
'    grd_lst.Height = UserControl.Extender.Height - frm_filters.Top - frm_filters.Height - 2 * SPACE - frm_detail.Height - 450
    
    Call frm_detail.Move(grd_lst.Left, grd_lst.Top, grd_lst.Width, grd_lst.Height)
    
    grd_items.Left = SPACE
    grd_items.Width = frm_detail.Width - 2 * SPACE
    grd_items.Height = frm_detail.Height - grd_items.Top - SPACE
    
    Exit Sub
ErrHandler:
    Call ErrorHandler("InitCtrlSize")
End Sub

' Standard error handler
Private Sub ErrorHandler(ByVal as_Fct As String)
    Err.Raise Err.Number, UserControl.Name & "." & UserControl.Ambient.DisplayName & "::" & as_Fct & SEP1 & Err.Source, Err.Description
End Sub



Private Function GetContainedControlsChain(ByVal ao_parent As Object) As Collection
On Error GoTo ErrHandler
    Dim lo_retCollection As New Collection
    Dim lo_Control As Object
    
    For Each lo_Control In Controls
        If Not TypeOf lo_Control.Container Is ONSV_MGManager Then
            If ao_parent.hwnd = lo_Control.Container.hwnd Then
                If TypeOf lo_Control Is Frame Then
                    Dim lo_aux_collection As New Collection
                    Dim ll_i As Long
                    Set lo_aux_collection = GetContainedControlsChain(lo_Control)
                    For ll_i = 1 To lo_aux_collection.Count
                        lo_retCollection.Add (lo_aux_collection.Item(ll_i))
                    Next
                Else
                    Call lo_retCollection.Add(lo_Control)
                End If
            End If
        End If
    Next
    Set GetContainedControlsChain = lo_retCollection
    Exit Function
ErrHandler:
    Call ErrorHandler(Extender.Name & ".GetContainedControlsChain()")
End Function

Private Sub UpdateGridAfterAction(ByVal ao_grid As ArmGrid, ByVal as_Action As String, ByVal av_Key As Variant)
On Error GoTo ErrHandler
    Dim ll_Index As Long
    Dim lo_Column As ArmColumn
    
    Select Case as_Action
    Case "Add"
        ' insert row at the end of grid
        Debug.Assert (ao_grid.Cols > 0)
        Dim lsa_newRow() As String
        'MS REDIMM
        Call SafeRedimPreserve(lsa_newRow, ao_grid.Cols - 1)
        Dim ll_KeyIndex As Long
        ll_KeyIndex = 0
        
        For ll_Index = 0 To ao_grid.Cols - 1
            Set lo_Column = ao_grid.Columns(ll_Index)
            If lo_Column.Key Then
                Debug.Assert (UBound(av_Key) >= ll_KeyIndex)
                lsa_newRow(ll_Index) = av_Key(ll_KeyIndex)
                ll_KeyIndex = ll_KeyIndex + 1
            Else
                lsa_newRow(ll_Index) = GetDataSrcForGrid(lo_Column)
            End If
        Next
        Call ao_grid.AddLine(lsa_newRow)
    Case "Upd"
        ' search and update row in the grid
        Debug.Assert (ao_grid.Cols > 0)
        
        If Not ao_grid.SearchKey(True, av_Key) Then
            Call Err.Raise(1, "ao_grid.SearchKey", "Cannot update grid.")
        End If
        
        For ll_Index = 0 To ao_grid.Cols - 1
            Set lo_Column = ao_grid.Columns(ll_Index)
            If Not lo_Column.Key Then
                If Not lo_Column.SetData(ao_grid.Row, GetDataSrcForGrid(lo_Column)) Then
                    Call Err.Raise(1, "lo_Column.SetData", "Cannot update grid.")
                End If
            End If
        Next
    Case "Del"
        ' remove row from grid
        If Not ao_grid.DeleteLine(av_Key) Then
            Call Err.Raise(1, "DeleteLine", "Cannot delete line.")
        End If
    Case Else
        Debug.Assert (False)
    End Select
    Exit Sub
ErrHandler:
     Call ErrorHandler("UpdateGridAfterAction()")
End Sub

' when updating main grid from detail
Private Function GetDataSrcForGrid(ByVal ao_Column As ArmColumn) As String
On Error GoTo ErrHandler
    Select Case ao_Column.FieldName
        
        Case "MG_CODE"
            GetDataSrcForGrid = GetCboKey(cbo_MG_Code)
        Case "CATGRP"
            GetDataSrcForGrid = GetCboText(cbo_MG_Code)
        Case "HBM"
            GetDataSrcForGrid = GetCboKey(cbo_HBM_Code)
        Case "HBM_Desc"
            GetDataSrcForGrid = GetCboText(cbo_HBM_Code)
        Case "CG_Desc"
            GetDataSrcForGrid = GetCboText(cbo_CG_Code)
        Case "BM_Desc"
            GetDataSrcForGrid = GetCboText(cbo_BM_Code)
        Case "SBM_Desc"
            GetDataSrcForGrid = GetCboText(cbo_SBM_Code)
    End Select
    
    Exit Function
ErrHandler:
     Call ErrorHandler("GetDataSrcForGrid()")
End Function

Private Sub InitFilterTreeView()
On Error GoTo ErrHandler
    trw_filter.Levels = 3
    trw_filter.Images = Array(1, 1, 1)
    trw_filter.SelectedImages = Array(2, 2, 2)
    trw_filter.NodeRequests = Array("EXEC ONSV_MatGRP_tw1 '" & ms_Language_Code & "'", _
                                    "EXEC ONSV_MatGRP_tw2 $0$, '" & ms_Language_Code & "'", _
                                    "EXEC ONSV_MatGRP_tw3 $0@0$, $0$, '" & ms_Language_Code & "'")
    trw_filter.GridRequests = Array( _
        "EXEC ONSV_MatGRP_lst $0$, NULL, NULL, '" & ms_Language_Code & "'", _
        "EXEC ONSV_MatGRP_lst $1$, $0$, NULL, '" & ms_Language_Code & "'", _
        "EXEC ONSV_MatGRP_lst $0@0$, $1$, $0$, '" & ms_Language_Code & "'")
    
    Call trw_filter.LoadTree(LoadTypeChildsDemand)
    Exit Sub
ErrHandler:
     Call ErrorHandler("InitFilterTreeView()")
End Sub

Private Sub RefreshGrid()
On Error GoTo ErrHandler
    
    If trw_filter.SelectedItem Is Nothing Then
        grd_lst.Requests = ""
        Call grd_lst.ClearGrid
        Exit Sub
    End If
    
    If Not grd_lst.Load(trw_filter.SelectedNodeRequest, True, , , trw_filter.NodeInfo(trw_filter.SelectedItem).ml_Level <> trw_filter.Levels - 1) Then
        MsgBox ("Grid not loaded!")
    End If
    
    Call Item_Clear
    
    Exit Sub
ErrHandler:
     Call ErrorHandler("RefreshGrid()")
End Sub

Private Sub Item_Clear()
On Error GoTo ErrHandler
    Dim lo_Control As Control
    For Each lo_Control In Controls
        If lo_Control.Tag <> "" Then
            Select Case UCase(TypeName(lo_Control))
            Case "ARMCOMBOBOX"
                Set lo_Control.SelectedItem = Nothing
            Case "ARMPICKER"
            Case "TOOLBARCONTROL"
            Case "ARMGRID"
            Case "ARMTREEVIEW"
            Case "ARMCHECKVIEW"
            Case "A_CALOCX"
            Case "TOOLBR"
            Case "TEXTBOX"
                lo_Control.Text = ""
            Case "CHECKBOX"
                lo_Control.Value = vbUnchecked
            End Select
        End If
    Next
    Exit Sub
ErrHandler:
    Call ErrorHandler("Item_Load()")
End Sub


Private Sub cbo_BM_Code_ComboItemSelected()
On Error GoTo ErrHandler
    If mb_eventRunning Then Exit Sub
    
    Call LockScreen(True)
    
    Call Item_LoadGrid
    
    Call LockScreen(False)
    Exit Sub
ErrHandler:
    Call LockScreen(False)
    Call ErrorMessage("cbo_BM_Code_ComboItemSelected()")
End Sub

Private Sub cbo_CG_Code_ComboItemSelected()
On Error GoTo ErrHandler
    If mb_eventRunning Then Exit Sub
    
    Call LockScreen(True)
    
    Dim ls_CG_Code As String
    
    ls_CG_Code = GetCboKey(cbo_CG_Code)
    
    Set cbo_BM_Code.SelectedItem = Nothing
    cbo_BM_Code.Request = "SELECT BM.BM_Code, BM.BM_Desc + ' (' + BM.BM_Code  + ')' FROM [Base_Material] BM WHERE BM.Language_code='" & ms_Language_Code & "' AND BM.CG_Code='" & ls_CG_Code & "' AND BM.BM_Code not like 'M-%' ORDER BY 2"
    
    Set cbo_SBM_Code.SelectedItem = Nothing
    cbo_SBM_Code.Request = "SELECT SBM.SBM_Code, SBM.SBM_Desc, SBM.HBM_Code FROM [Super_Base_Material] SBM WHERE SBM.Language_code='" & ms_Language_Code & "' AND SBM.CG_Code='" & ls_CG_Code & "' AND SBM.SBM_Code not like 'M-%' ORDER BY 2"
    
    Set cbo_HBM_Code.SelectedItem = Nothing
    cbo_HBM_Code.Request = "SELECT HBM.HBM_Code, HBM.HBM_Desc FROM [Hyper_Base_Material] HBM WHERE HBM.Language_code='" & ms_Language_Code & "' AND HBM.CG_Code='" & ls_CG_Code & "' AND HBM.HBM_Code > 0 ORDER BY 2"
    Call cbo_HBM_Code.Load
    
    Call LockScreen(False)
    
    Call cbo_BM_Code_ComboItemSelected
    
    Exit Sub
ErrHandler:
    Call LockScreen(False)
    Call ErrorMessage("cbo_CG_Code_ComboItemSelected()")
End Sub

Private Sub cbo_HBM_Code_ComboItemSelected()
    Call cbo_BM_Code_ComboItemSelected
End Sub

Private Sub cbo_SBM_Code_ComboItemSelected()
    If mb_eventRunning Then Exit Sub
    
    Call cbo_BM_Code_ComboItemSelected
    
    ' load HBM
    Call SetComboBoxText(cbo_HBM_Code, cbo_SBM_Code.GetItemData(cbo_SBM_Code.SelectedItem.Key, "HBM_Code"), "")
    
End Sub

Private Sub grd_lst_DblClick()
On Error GoTo ErrHandler
    Call LockScreen(True)
    
    Call Item_ViewInit(grd_lst.SelectedKey(0))
    
    Call LockScreen(False)
    Exit Sub
ErrHandler:
    Call LockScreen(False)
    Call ErrorMessage("grd_lst_DblClick()")
End Sub

Private Sub tlb_Main_action(ByVal as_Role As String, as_Language As String)
On Error GoTo ErrHandler
    Call LockScreen(True)
    
    Dim lsa_id() As String
    Dim ls_bu As String
    Dim ls_buDesc As String
    Select Case as_Role
    Case "A"
        Call Item_AddInit
    Case "B"
        If grd_lst.SelectedCount = 1 Then
            Call Item_UpdateInit(grd_lst.SelectedKey(0))
        Else
            Call MsgBox(MsgText(9214, ms_Language_Code, "#Please, select single row"))
        End If
    Case "C"
        If grd_lst.SelectedCount = 1 Then
            Call Item_DeleteInit(grd_lst.SelectedKey(0))
        Else
            Call MsgBox(MsgText(9214, ms_Language_Code, "#Please, select single row"))
        End If
    Case "I"              ' reset changes
        Select Case mu_ActiveMode
        Case smAdd
            Call Item_AddInit
        Case smUpdate
            Debug.Assert (grd_lst.SelectedCount = 1)
            Call Item_UpdateInit(grd_lst.SelectedKey(0))
        End Select
    Case "H"              ' confirm changes
        Select Case mu_ActiveMode
        Case smAdd
            Call Item_Add
        Case smUpdate
            Call Item_Update
        Case smDelete
            Call Item_Delete
        End Select
    Case "K"            ' next free matgrp
        Call Item_NextNew
    Case "J"            ' previous free matgrp
        Call Item_PrevNew
    Case "L"        ' refresh grid
        Call RefreshGrid
    Case "G"              ' EXPORT TO GRID
    Case "V"              ' EXPORT TO PDF
    Case "F"            ' refresh
    Case "T"              ' QUIT
        If mu_ActiveMode = smMain Then
            RaiseEvent quit
        Else
            Call UpdateUI(smMain)
        End If
    End Select

    Call LockScreen(False)
    Exit Sub
ErrHandler:
    Call LockScreen(False)
    Call ErrorMessage("tlb_main_Action()")
End Sub

Private Sub trw_filter_NodeClick(ByVal Node As MSComctlLib.Node)
On Error GoTo ErrHandler
    Call LockScreen(True)
    
    Call RefreshGrid

    Call LockScreen(False)
    Exit Sub
ErrHandler:
    Call LockScreen(False)
    Call ErrorMessage("trw_filter_NodeClick()")
End Sub

Private Sub Item_ViewInit(ByVal as_detailKey As Variant)
On Error GoTo ErrHandler
    
    Call Item_Clear
    
    ' loading values
    Call Item_LoadValues(as_detailKey)
    
    Call UpdateUI(ArmScreenMode.smView)
    Exit Sub
ErrHandler:
    Call ErrorHandler(Extender.Name & ".Item_ViewInit")
End Sub

Private Sub Item_UpdateInit(ByVal as_detailKey As Variant)
On Error GoTo ErrHandler
    
    Call Item_Clear
    
    ' loading values
    Call Item_LoadValues(as_detailKey)
    
    Call UpdateUI(ArmScreenMode.smUpdate)
    Exit Sub
ErrHandler:
    Call ErrorHandler(Extender.Name & ".Item_UpdateInit")
End Sub

Private Function Item_Check() As Boolean
On Error GoTo ErrHandler
    Item_Check = False
    
    If GetCboKey(cbo_CG_Code) = "" Then
        Call MsgBox(Replace(MsgText(8300, ms_Language_Code, "The field is mandatory."), "$FIELD_NAME$", lbl_labels(0).Caption, , , vbTextCompare), vbInformation)
        Call cbo_CG_Code.SetFocus
        Exit Function
    End If
    
    If GetCboKey(cbo_MG_Code) = "" Then
        Call MsgBox(Replace(MsgText(8300, ms_Language_Code, "The field is mandatory."), "$FIELD_NAME$", lbl_labels(4).Caption, , , vbTextCompare), vbInformation)
        Call cbo_MG_Code.SetFocus
        Exit Function
    End If
    
    If GetCboKey(cbo_SBM_Code) = "" Then
        Call MsgBox(Replace(MsgText(8300, ms_Language_Code, "The field is mandatory."), "$FIELD_NAME$", lbl_labels(2).Caption, , , vbTextCompare), vbInformation)
        Call cbo_SBM_Code.SetFocus
        Exit Function
    End If
    
    If GetCboKey(cbo_BM_Code) = "" Then
        Call MsgBox(Replace(MsgText(8300, ms_Language_Code, "The field is mandatory."), "$FIELD_NAME$", lbl_labels(3).Caption, , , vbTextCompare), vbInformation)
        Call cbo_BM_Code.SetFocus
        Exit Function
    End If
    
    Item_Check = True
    
    Exit Function
ErrHandler:
    Call ErrorHandler(Extender.Name & ".Item_Check")
End Function

Private Sub Item_Add()
On Error GoTo ErrHandler
Const C_REQ As String = "EXEC ONSV_MatGRP_chk $CGCODE$, $SBM$, $BM$"
    If Not Item_Check Then
        Exit Sub
    End If

    Dim ll_Cursor As Long
    
    ll_Cursor = OpenSQLSafe(mo_Db, ReplacePlaceholders(C_REQ))
    
    If mo_Db.GetFields(ll_Cursor, "GRPCount") > 0 Then
        Call mo_Db.Close(ll_Cursor)
        ll_Cursor = 0
        Call MsgBox(MsgText(666, ms_Language_Code, "Record already exists in database."), , vbInformation)
        Exit Sub
    End If
    
    Call mo_Db.Close(ll_Cursor)
    ll_Cursor = 0
    
    Call Item_AddDB
    
    Call UpdateUI(smMain)
    
    Call UpdateGridAfterAction(grd_lst, "Add", Array(GetCboKey(cbo_CG_Code), GetCboKey(cbo_SBM_Code), GetCboKey(cbo_BM_Code)))
    Exit Sub
ErrHandler:
    If ll_Cursor > 0 Then
        Call mo_Db.Close(ll_Cursor)
        ll_Cursor = 0
    End If
    Call ErrorHandler(Extender.Name & ".Item_Add")
End Sub

Private Sub Item_Update()
On Error GoTo ErrHandler
    If Not Item_Check Then
        Exit Sub
    End If
    
    Call Item_UpdateDB
    
    Call UpdateUI(smMain)
    
    Call UpdateGridAfterAction(grd_lst, "Upd", Array(GetCboKey(cbo_CG_Code), GetCboKey(cbo_SBM_Code), GetCboKey(cbo_BM_Code)))
    Exit Sub
ErrHandler:
    Call ErrorHandler(Extender.Name & ".Item_Update")
End Sub

Private Sub Item_Delete()
On Error GoTo ErrHandler
    If Not Item_Check Then
        Exit Sub
    End If
    
    Call Item_DeleteDB
    
    Call UpdateUI(smMain)
    
    Call UpdateGridAfterAction(grd_lst, "Del", Array(GetCboKey(cbo_CG_Code), GetCboKey(cbo_SBM_Code), GetCboKey(cbo_BM_Code)))
    Exit Sub
ErrHandler:
    Call ErrorHandler(Extender.Name & ".Item_Delete")
End Sub

Private Sub Item_AddDB()
On Error GoTo ErrHandler
    Const C_REQ As String = "EXEC ONSV_MatGRP_ins $CGCODE$, $SBM$, $BM$, $MG_CODE$"
    
    Call ExecuteSQLSafe(mo_Db, ReplacePlaceholders(C_REQ), 1)
        
    Exit Sub
ErrHandler:
    Call ErrorHandler(Extender.Name & ".Item_AddDB")
End Sub

Private Sub Item_UpdateDB()
On Error GoTo ErrHandler
    Const C_REQ As String = "EXEC ONSV_MatGRP_upd $CGCODE$, $SBM$, $BM$, $MG_CODE$"
    
    Call ExecuteSQLSafe(mo_Db, ReplacePlaceholders(C_REQ), 1)
        
    Exit Sub
ErrHandler:
    Call ErrorHandler(Extender.Name & ".Item_UpdateDB")
End Sub

Private Sub Item_DeleteDB()
On Error GoTo ErrHandler
    Const C_REQ As String = "EXEC ONSV_MatGRP_del $CGCODE$, $SBM$, $BM$"
    
    Call ExecuteSQLSafe(mo_Db, ReplacePlaceholders(C_REQ), 1)
        
    Exit Sub
ErrHandler:
    Call ErrorHandler(Extender.Name & ".Item_DeleteDB")
End Sub

Private Function ReplacePlaceholders(ByVal as_req As String) As String
On Error GoTo ErrHandler

    as_req = Replace(as_req, "$MG_Code$", SqlStr(GetCboKey(cbo_MG_Code), 4), , , vbTextCompare)
    as_req = Replace(as_req, "$CGCODE$", SqlStr(GetCboKey(cbo_CG_Code), 10), , , vbTextCompare)
    as_req = Replace(as_req, "$SBM$", SqlStr(GetCboKey(cbo_SBM_Code), 10), , , vbTextCompare)
    as_req = Replace(as_req, "$BM$", SqlStr(GetCboKey(cbo_BM_Code), 10), , , vbTextCompare)

    ReplacePlaceholders = as_req
    Exit Function
ErrHandler:
    Call ErrorHandler(Extender.Name & ".ReplacePlaceholders")
End Function

Private Sub Item_DeleteInit(ByVal as_detailKey As Variant)
On Error GoTo ErrHandler
    
    Call Item_Clear
    
    ' loading values
    Call Item_LoadValues(as_detailKey)
    
    Call UpdateUI(ArmScreenMode.smDelete)
    Exit Sub
ErrHandler:
    Call ErrorHandler(Extender.Name & ".Item_DeleteInit")
End Sub

Private Sub Item_AddInit()
On Error GoTo ErrHandler
    
    Call Item_Clear
    
    ' loading values
    Call Item_LoadValues(Empty)
    
    Call UpdateUI(ArmScreenMode.smAdd)
    Exit Sub
ErrHandler:
    Call ErrorHandler(Extender.Name & ".Item_AddInit")
End Sub

' loads values from cursor into form. if cursor=0 then reset whole detail
Private Sub Item_LoadValues(ByVal av_Key As Variant)
On Error GoTo ErrHandler

    mb_eventRunning = True
    If Not IsEmpty(av_Key) Then
        Debug.Assert (IsArray(av_Key))
        If grd_lst.SelectedKey(0)(0) <> av_Key(0) Or grd_lst.SelectedKey(0)(1) <> av_Key(1) Or grd_lst.SelectedKey(0)(2) <> av_Key(2) Then
            If Not grd_lst.SearchKey(True, av_Key) Then
                mb_eventRunning = False
                Exit Sub
            End If
        End If
        Call SetComboBoxText(cbo_CG_Code, grd_lst.SelectedLine(0, "CG_CODE"), grd_lst.SelectedLine(0, "CG_DESC"))
        Call SetComboBoxText(cbo_SBM_Code, grd_lst.SelectedLine(0, "SBM_CODE"), grd_lst.SelectedLine(0, "SBM_DESC"))
        Call SetComboBoxText(cbo_HBM_Code, grd_lst.SelectedLine(0, "HBM_CODE"), grd_lst.SelectedLine(0, "HBM_DESC"))
        Call SetComboBoxText(cbo_BM_Code, grd_lst.SelectedLine(0, "BM_CODE"), grd_lst.SelectedLine(0, "BM_DESC"))
        Call SetComboBoxText(cbo_MG_Code, grd_lst.SelectedLine(0, "MG_CODE"), grd_lst.SelectedLine(0, "CATGRP"))
        
    Else
        ' load default values
        Call Item_LoadNew(0)
        
    End If
    
    Call Item_LoadGrid
    mb_eventRunning = False

    Exit Sub
ErrHandler:
    mb_eventRunning = False
    Call ErrorHandler(Extender.Name & ".Item_LoadValues")
End Sub

Private Sub Item_NextNew()
On Error GoTo ErrHandler
    mb_eventRunning = True
    ml_newItemRow = ml_newItemRow + 1
    Call Item_LoadNew(ml_newItemRow)
    Call Item_LoadGrid
    mb_eventRunning = False
    Exit Sub
ErrHandler:
    mb_eventRunning = False
    Call ErrorHandler(Extender.Name & ".Item_NextNew")
End Sub

Private Sub Item_PrevNew()
On Error GoTo ErrHandler
    mb_eventRunning = True
    ml_newItemRow = ml_newItemRow - 1
    Call Item_LoadNew(ml_newItemRow)
    Call Item_LoadGrid
    mb_eventRunning = False
    Exit Sub
ErrHandler:
    mb_eventRunning = False
    Call ErrorHandler(Extender.Name & ".Item_PrevNew")
End Sub

Private Sub Item_LoadNew(ByVal al_order As Long)
On Error GoTo ErrHandler
        
    Dim lo_eventsRunning As Boolean
    lo_eventsRunning = mb_eventRunning
    
    Dim ll_Cursor As Long
    Const C_REQ As String = "EXEC ONSV_MatGRP_new $LANGUAGE$"
    
    ll_Cursor = OpenSQLSafe(mo_Db, Replace(ReplacePlaceholders(C_REQ), "$LANGUAGE$", SqlStr(ms_Language_Code, 1), , , vbTextCompare))
    
    ml_newItemRow = al_order
    
    If ml_newItemRow < 0 Then
        ml_newItemRow = mo_Db.RowCount(ll_Cursor) - 1
    ElseIf ml_newItemRow >= mo_Db.RowCount(ll_Cursor) Then
        ml_newItemRow = 0
    End If
    
    
    
    mb_eventRunning = False
    Call SetComboBoxText(cbo_CG_Code, mo_Db.GetFieldsAt(ll_Cursor, ml_newItemRow, "CG_CODE"), mo_Db.GetFieldsAt(ll_Cursor, ml_newItemRow, "CG_DESC"))
    mb_eventRunning = lo_eventsRunning
    Call SetComboBoxText(cbo_SBM_Code, mo_Db.GetFieldsAt(ll_Cursor, ml_newItemRow, "SBM_CODE"), mo_Db.GetFieldsAt(ll_Cursor, ml_newItemRow, "SBM_DESC"))
    Call SetComboBoxText(cbo_HBM_Code, mo_Db.GetFieldsAt(ll_Cursor, ml_newItemRow, "HBM_CODE"), mo_Db.GetFieldsAt(ll_Cursor, ml_newItemRow, "HBM_DESC"))
    Call SetComboBoxText(cbo_BM_Code, mo_Db.GetFieldsAt(ll_Cursor, ml_newItemRow, "BM_CODE"), mo_Db.GetFieldsAt(ll_Cursor, ml_newItemRow, "BM_DESC"))
    
    Call mo_Db.Close(ll_Cursor)
    ll_Cursor = 0

    Exit Sub
ErrHandler:
    mb_eventRunning = lo_eventsRunning
    If ll_Cursor > 0 Then
        Call mo_Db.Close(ll_Cursor)
        ll_Cursor = 0
    End If
    Call ErrorHandler(Extender.Name & ".Item_LoadNew")
End Sub

Private Sub Item_LoadGrid()
On Error GoTo ErrHandler
Const C_REQ As String = "EXEC ONSV_MatGRP_items $CGCODE$, $SBM$, $BM$, $LANGUAGE$"
    Dim ls_req As String
    
    If GetCboKey(cbo_CG_Code) = "" Or _
        GetCboKey(cbo_SBM_Code) = "" Or _
        GetCboKey(cbo_BM_Code) = "" Then
        
        grd_items.Requests = ""
        Exit Sub
    End If

    ls_req = ReplacePlaceholders(C_REQ)
    ls_req = Replace(ls_req, "$LANGUAGE$", SqlStr(ms_Language_Code, 1), , , vbTextCompare)
    
    If Not grd_items.Load(ls_req, False, , , True) Then
        MsgBox ("Items grid not loaded!")
    End If
    Exit Sub
ErrHandler:
    Call ErrorHandler(Extender.Name & ".Item_loadGrid")
End Sub


'*********************************** support functions ******************************************
' display standard error message
Private Sub ErrorMessage(ByVal as_Fct As String)
    Dim ls_ErrSource As String
    Dim ls_errDescription As String
    Dim ls_Message As String
    
    ls_ErrSource = as_Fct & SEP1 & Err.Source
    ls_errDescription = Err.Description
    ls_Message = SCREEN_NAME & " exception. Nr:" & Err.Number & ",Desc: " & ls_errDescription & ",Src:" & ls_ErrSource & "@"
'    Call mo_Tools.LogMessage(mo_Db, ml_U_Code, SCREEN_NAME, ls_Message, "E")
    Call MsgBox("Error occured, please contact IT. Application will now shutdown." & vbCrLf & ls_ErrSource & vbCrLf & "Description: " & ls_errDescription, vbCritical, App.Title & " " & App.Major & "." & App.Minor & "." & App.Revision)
    End
End Sub

Private Sub EnableControl(ByVal ao_Control As Control, ByVal ab_Enabled As Boolean)
On Error GoTo ErrHandler

    Select Case UCase(TypeName(ao_Control))
        Case "FRAME", "LABEL", "MSFLEXGRID", "SHAPE", "ARMGRID", "ARMCHECKVIEW", "TABSTRIP"
            ao_Control.Enabled = ab_Enabled
            ' Do nothing !
        Case "LISTVIEW"
            ' Do nothing !
        Case "TEXTBOX"
            ao_Control.Locked = Not ab_Enabled
            ao_Control.BackColor = IIf(ab_Enabled, CL_COLOR_ENABLED, CL_COLOR_DISABLED)
            ao_Control.TabStop = ab_Enabled
        Case "OPTIONBUTTON"
            ao_Control.Enabled = ab_Enabled
        Case "ARMCOMBOBOX", "A_CALOCX", "OPTIONBUTTON", "ARMTREEVIEW", "LISTBOX", "PICTUREBOX", "CHECKBOX", "COMMANDBUTTON", "TOOLBARCONTROL"
            ao_Control.Enabled = ab_Enabled
            ao_Control.TabStop = ab_Enabled
        Case Else
          Debug.Print ao_Control.Name
    End Select
  Exit Sub
ErrHandler:
  Call ErrorHandler("EnableControl")
End Sub

Private Sub SetEnabled(ByVal ao_srcCtrl As Object, ByVal ab_Value As Boolean)
On Error GoTo ErrHandler
    Dim lo_ctrl As Object
    For Each lo_ctrl In ao_srcCtrl
        Call EnableControl(lo_ctrl, ab_Value)
    Next
    Exit Sub
ErrHandler:
     Call ErrorHandler("SetEnabled()")
End Sub


' translate string to sql format
' Params:
' as_Value (String)
' ab_EmptyNULL (Boolean = False)
Private Function SqlStr(ByVal as_Value As String, Optional ByVal al_MaxLen As Long = 8000, Optional ByVal ab_EmptyNULL As Boolean = False) As String
    If as_Value = "" And ab_EmptyNULL Then
        SqlStr = "NULL"
    Else
        SqlStr = "'" & Replace(Left(as_Value, IIf(Len(as_Value) <= al_MaxLen, Len(as_Value), al_MaxLen)), "'", "''") & "'"
    End If
End Function

Private Function SqlDate(ByVal av_Data As String) As String
On Error GoTo ErrHandler

    SqlDate = "NULL"
    If IsNull(av_Data) Then av_Data = ""
    If (Trim(CStr(av_Data)) <> "") And (CStr(av_Data) <> "0") Then
        SqlDate = "'" & Format(av_Data, "yyyy-mm-dd") & "'"
    End If
    Exit Function
ErrHandler:
End Function


Private Function SQLNum(ByVal as_str As String) As String
    SQLNum = Replace(as_str, ",", ".")
End Function

Private Function GetCboKey(ByRef ao_cbo As ArmCombobox) As String
On Error GoTo ErrHandler
    GetCboKey = ""
    If Not ao_cbo.SelectedItem Is Nothing Then
        GetCboKey = ao_cbo.SelectedItem.Key
    End If
    Exit Function
ErrHandler:
     Call ErrorHandler("GetCboKey()")
End Function

Private Function GetCboText(ByRef ao_cbo As ArmCombobox) As String
On Error GoTo ErrHandler
    GetCboText = ""
    If Not ao_cbo.SelectedItem Is Nothing Then
        GetCboText = ao_cbo.SelectedItem.DisplayText
    End If
    Exit Function
ErrHandler:
     Call ErrorHandler("GetCboText()")
End Function

' Sets combobox selected item
' Params:
' ao_ComboBox (ArmCombobox)
' as_Key (String)
' as_Desc (String)
Private Sub SetComboBoxText(ByRef ao_Combobox As ArmCombobox, ByVal as_Key As String, ByVal as_desc As String)
On Error GoTo ErrHandler
    If Not ao_Combobox.SearchItem(as_Key) Then
        ' key not found ... set value from parameter
        If as_Key = "" Or as_Key = "0" Then     ' zero or empty string is not valid key
            Set ao_Combobox.SelectedItem = Nothing
        Else
            Call ao_Combobox.AddItem(Array(as_Key, as_desc), True)
            ' to make vb raise event
            Call ao_Combobox.SearchItem(as_Key)
        End If
    End If
    Exit Sub
ErrHandler:
    Call ErrorHandler("SetComboBoxText")
End Sub

Private Sub LockScreen(ByVal ab_lock As Boolean)

    Dim ll_errNumber As Long, ls_ErrSrc As String, ls_ErrDesc As String
    ll_errNumber = Err.Number
    ls_ErrSrc = Err.Source
    ls_ErrDesc = Err.Description

On Error GoTo ErrHandler
    Static ll_Count As Long
    Static ll_Mousepointer As Long
    Static lb_Locked As Boolean
      
      
    ll_Count = ll_Count + IIf(ab_lock, 1, -1)
    Debug.Assert (ll_Count >= 0)
    
    ' First lock
    If Not lb_Locked And ab_lock Then
        ll_Mousepointer = Screen.MousePointer
        Screen.MousePointer = vbHourglass
        LockWindowUpdate UserControl.hwnd
        lb_Locked = True
    End If
    
    ' Unlock
    If ll_Count = 0 Then
        DoEvents ' Flush events
        LockWindowUpdate 0
        UserControl.Refresh
        Screen.MousePointer = ll_Mousepointer
        lb_Locked = False
    End If
    
    Err.Number = ll_errNumber
    Err.Source = ls_ErrSrc
    Err.Description = ls_ErrDesc
    
    Exit Sub
    
ErrHandler:
    Call ErrorHandler("LockScreen")
End Sub

Private Function OpenSQLSafe(ByVal ao_Db As ARMSYSCOMLib.ArmDb, ByVal as_Request As String, Optional ByVal al_RowExpectedCount = -1) As Long
On Error GoTo ErrHandler
    Dim lc_Data As Long
    lc_Data = ao_Db.OpenSQL(as_Request)
    If lc_Data = 0 Then
        Call Err.Raise(1, "ao_Db.OpenSQL - " & "SQL : " & as_Request, "SQL Error: " & GetDbError(ao_Db))
    End If
    
    If al_RowExpectedCount <> -1 Then
        ' Then check the rowcount
        If ao_Db.RowCount(lc_Data) <> al_RowExpectedCount Then
            Call Err.Raise(2, "SQL : " & as_Request, al_RowExpectedCount & "<>" & ao_Db.RowCount(lc_Data))
        End If
    End If
    OpenSQLSafe = lc_Data
    Exit Function
ErrHandler:
    Call ErrorHandler("OpenSQLSafe")
End Function

Private Sub ExecuteSQLSafe(ByVal ao_Db As ARMSYSCOMLib.ArmDb, ByVal as_Request As String, Optional ByVal al_RowAffectedCount = -1, Optional ab_DuplicityCheck As Boolean = False)
On Error GoTo ErrHandler

    ' First execute the request
    If Not ao_Db.ExecuteSQL(as_Request) Then
        If GetArrayValue(ao_Db.SQLErrorCodes, 0) = 547 Then
            Err.Raise 3, "SQL : " & as_Request, Join(ao_Db.SQLErrorCodes, SEP2) & SEP1 & Join(ao_Db.SQLErrorMessages, SEP2)
        End If
        Err.Raise 1, "SQL : " & as_Request, Join(ao_Db.SQLErrorCodes, SEP2) & SEP1 & Join(ao_Db.SQLErrorMessages, SEP2)
    End If

    If al_RowAffectedCount <> -1 Then
        ' Then check the rowcount
        If ao_Db.SQLRowsAffected <> al_RowAffectedCount Then
            
            If ab_DuplicityCheck Then
                Err.Raise 4, "SQL : " & as_Request, al_RowAffectedCount & "<>" & ao_Db.SQLRowsAffected
            Else
                Err.Raise 5, "SQL : " & as_Request, al_RowAffectedCount & "<>" & ao_Db.SQLRowsAffected
            End If
        End If
    End If
    
    Exit Sub

ErrHandler:
    Call ErrorHandler("ExecuteSQLSafe")
End Sub

Private Function GetDbError(ByVal lo_Db As ARMSYSCOMLib.ArmDb) As String
On Error GoTo ErrHandler
    If IsArray(lo_Db.SQLErrorMessages) Then
        Debug.Assert (IsArray(lo_Db.SQLErrorCodes))
        ' Display errors msgBox
        GetDbError = Join(lo_Db.SQLErrorCodes, ",") & vbCrLf & Join(lo_Db.SQLErrorMessages, vbCrLf)
    Else
        ' ExecuteSQL failed but no error message?
        GetDbError = "Unknown error"
    End If
    Exit Function
ErrHandler:
    Call ErrorHandler("GetDbError()")
End Function

Private Function GetArrayValue(ByRef ao_variantArray As Variant, ByVal al_Index As Long) As Variant
    If IsArray(ao_variantArray) Then
        If UBound(ao_variantArray) <= al_Index Then
            GetArrayValue = ao_variantArray(al_Index)
        Else
            GetArrayValue = 0
        End If
    Else
        GetArrayValue = 0
    End If
End Function


