diff --git a/app/TaskFlow/ClassConfig.vb b/app/TaskFlow/ClassConfig.vb index 70b53ac..f60faf7 100644 --- a/app/TaskFlow/ClassConfig.vb +++ b/app/TaskFlow/ClassConfig.vb @@ -22,7 +22,6 @@ Public Class ClassConfig ' Digital Data Settings Public Property UserManagerPath As String = "" - Public Property UserInheritance_ConfirmationByColumn As New List(Of UserInheritanceConfirmation) ' File Settings Public Property VersionDelimiter As String = "~" @@ -52,9 +51,4 @@ Public Class ClassConfig Public Property ShowFile As Boolean = True Public Property ShowSearchesDirect As Boolean = True End Class - - Public Class UserInheritanceConfirmation - Public Property ColumnName As String = "" - Public Property Count As Integer - End Class End Class diff --git a/app/TaskFlow/ClassControlCreator.vb b/app/TaskFlow/ClassControlCreator.vb index 86ef9f5..428cd5d 100644 --- a/app/TaskFlow/ClassControlCreator.vb +++ b/app/TaskFlow/ClassControlCreator.vb @@ -1,6 +1,5 @@ Imports System.ComponentModel Imports System.Text.RegularExpressions -Imports DD_LIB_Standards Imports DevExpress.Utils Imports DevExpress.XtraEditors Imports DevExpress.XtraEditors.Controls @@ -11,13 +10,10 @@ Imports DevExpress.XtraGrid.Columns Imports DevExpress.XtraGrid.Views.Base Imports DevExpress.XtraGrid.Views.Grid Imports DigitalData.Controls.LookupGrid -Imports DigitalData.Modules.Language.Utils Imports DigitalData.GUIs.Common Imports DigitalData.Modules.Logging -Imports DigitalData.Modules.Language Imports DigitalData.Modules.EDMI.API.DatabaseWithFallback Imports DigitalData.Modules.EDMI.API.Constants -Imports DigitalData.Modules.Language.DataTableEx Imports DigitalData.Modules.Base Public Class ClassControlCreator @@ -362,7 +358,7 @@ Public Class ClassControlCreator Try oControl.Text = row.Item("CTRL_CAPTION_LANG") Catch ex As Exception - Logger.Warn("Label [{0}] does not have a translation!", oControl.Name) + Logger.Warn("⚠️ Label [{0}] does not have a translation!", oControl.Name) oControl.Text = row.Item("CTRL_TEXT") End Try Dim oAlignment = row.ItemEx("TEXT_ALIGNMENT", "Near") diff --git a/app/TaskFlow/ClassFinalizeDoc.vb b/app/TaskFlow/ClassFinalizeDoc.vb index 430c253..151c3b3 100644 --- a/app/TaskFlow/ClassFinalizeDoc.vb +++ b/app/TaskFlow/ClassFinalizeDoc.vb @@ -156,7 +156,7 @@ Public Class ClassFinalizeDoc End If Return indexierung_erfolgreich Catch ex As Exception - LOGGER.Warn("Unvorhergesehener Fehler bei Indexiere_File: " & ex.Message.ToString) + LOGGER.Warn("⚠️ Unvorhergesehener Fehler bei Indexiere_File: " & ex.Message.ToString) Return False End Try diff --git a/app/TaskFlow/ClassInit.vb b/app/TaskFlow/ClassInit.vb index b0a5151..95d5228 100644 --- a/app/TaskFlow/ClassInit.vb +++ b/app/TaskFlow/ClassInit.vb @@ -1,11 +1,12 @@ -Imports DLLLicenseManager -Imports DigitalData.Modules.Logging +Imports System.Windows.Forms.VisualStyles.VisualStyleElement Imports DigitalData.Modules.Config -Imports DigitalData.Modules.EDMI.API -Imports DigitalData.Modules.EDMI.API.DatabaseWithFallback -Imports DigitalData.Modules.EDMI.API.Constants Imports DigitalData.Modules.Database -Imports System.Windows.Forms.VisualStyles.VisualStyleElement +Imports DigitalData.Modules.EDMI.API +Imports DigitalData.Modules.EDMI.API.Constants +Imports DigitalData.Modules.EDMI.API.DatabaseWithFallback +Imports DigitalData.Modules.Logging +Imports DLLLicenseManager +Imports DocumentFormat.OpenXml.Spreadsheet Public Class ClassInit Public _lizenzManager As ClassLicenseManager @@ -20,21 +21,16 @@ Public Class ClassInit My.Application.Info.CompanyName, My.Application.Info.ProductName) - LOGGER = LOGCONFIG.GetLogger("taskFLOW") - LOGGER.Info("## taskFLOW started - {0}", Now) Try Dim directory As New IO.DirectoryInfo(Application.LocalUserAppDataPath & "\Log") - For Each file As IO.FileInfo In directory.GetFiles If (Now - file.CreationTime).Days > 29 Then file.Delete() Else Exit For End If - - Next Catch ex As Exception @@ -59,6 +55,15 @@ Public Class ClassInit CONFIG = New ConfigManager(Of ClassConfig)(LOGCONFIG, oUserAppDataPath, oCommonAppDataPath, oStartupPath) LOGGER.Info("ConfigManager loaded") + LOGGER.Info($"oUserAppDataPath will be: {oUserAppDataPath}") + + If oStartupPath <> oCommonAppDataPath Then + LOGGER.Info($"oCommonAppDataPath will be: {oCommonAppDataPath}") + LOGGER.Info($"oStartupPath will be: {oStartupPath}") + Else + LOGGER.Info($"oStartupPath is the same as oCommonAppDataPath: {oCommonAppDataPath}") + End If + Try If CONFIG.Config.ConnectionStringTest <> String.Empty And CONFIG.Config.TestMode = True Then LOGGER.Debug("Test Connection String loaded") @@ -85,11 +90,11 @@ Public Class ClassInit LOGGER.Info($"EDMIAppServer [{CONFIG.Config.EDMIAppServer}] is active!") Else - LOGGER.Warn($"#### !!! Could not Connect to APPServer [{CONFIG.Config.EDMIAppServer}]!!! ###") + LOGGER.Warn($"#### ⚠️ !!! Could not Connect to APPServer [{CONFIG.Config.EDMIAppServer}]!!! ###") End If End If Catch ex As Exception - LOGGER.Warn($"Could not initialize the AppServer: {ex.Message}") + LOGGER.Warn($"⚠️ Could not initialize the AppServer: {ex.Message}") End Try Else @@ -244,12 +249,12 @@ Public Class ClassInit Try oLICDATE = CDate(split(1)) Catch ex As Exception - LOGGER.Warn($"Error Converting Value {split(1)} to DATE") + LOGGER.Warn($"⚠️ Error Converting Value {split(1)} to DATE") Try Dim expenddt As Date = Date.ParseExact(split(1), "dd.MM.yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo) oLICDATE = expenddt Catch ex1 As Exception - LOGGER.Warn($"Second Error Converting DATE with ParseExact - Setting Date = Today") + LOGGER.Warn($"⚠️Second Error Converting DATE with ParseExact - Setting Date = Today") oLICDATE = Now.Date End Try @@ -356,6 +361,7 @@ Public Class ClassInit USER_EMAIL = IIf(IsDBNull(DT_CHECKUSER_MODULE.Rows(0).Item("USER_EMAIL")), "", DT_CHECKUSER_MODULE.Rows(0).Item("USER_EMAIL")) USER_LANGUAGE = DT_CHECKUSER_MODULE.Rows(0).Item("USER_LANGUAGE") + USER_MODULE_ID = DT_CHECKUSER_MODULE.Rows(0).Item("MODULE_ID") USER_IN_MODULE = DT_CHECKUSER_MODULE.Rows(0).Item("MODULE_ACCESS") @@ -385,7 +391,7 @@ Public Class ClassInit USER_RIGHT_FILE_DELETE = IIf(IsDBNull(DT_CHECKUSER_MODULE.Rows(0).Item("USER_RIGHT_FILE_DEL")), False, DT_CHECKUSER_MODULE.Rows(0).Item("USER_RIGHT_FILE_DEL")) Catch ex As Exception - LOGGER.Warn("Error in USER_RIGHT_FILE_DELETE: " & ex.Message) + LOGGER.Warn("⚠️ Error in USER_RIGHT_FILE_DELETE: " & ex.Message) USER_RIGHT_FILE_DELETE = False End Try USER_DATE_FORMAT = DT_CHECKUSER_MODULE.Rows(0).Item("USER_DATE_FORMAT") @@ -525,7 +531,10 @@ Public Class ClassInit oSql = "SELECT * FROM TBDD_COLUMNS_FORMAT WHERE MODULE = 'taskFLOW' AND GRIDVIEW = 'GridViewWorkflows'" BASEDATA_TBDD_COLUMNS_FORMAT = DatabaseFallback.GetDatatable("TBDD_COLUMNS_FORMAT", New GetDatatableOptions(oSql, DatabaseType.ECM)) + + oStopWatch.Done() + Catch ex As Exception LOGGER.Error(ex) LOGGER.Info($"Unexpected Error in InitBasics - last Step [{oStep}]: {ex.Message}", True) @@ -546,6 +555,48 @@ Public Class ClassInit LOGGER.Warn($"no profiles for user: '{USER_USERNAME}' configured - Check SQL [{oSql}]!", False) End If + oSql = "SELECT KEY_NAME, VALUE_TEXT1 + FROM TBDD_USER_KEY_VALUE_PAIR + WHERE FK_USER_ID = " & USER_ID & " And [FK_MODULE_ID] = '" & USER_MODULE_ID & "'" + + Dim oDT_USER_KEY_VALUE_PAIR As DataTable = DatabaseFallback.GetDatatable(New GetDatatableOptions(oSql, DatabaseType.ECM)) + If UserInheritance_ConfirmationByColumn Is Nothing Then + UserInheritance_ConfirmationByColumn = New List(Of UserInheritanceConfirmation)() + End If + If Not IsNothing(oDT_USER_KEY_VALUE_PAIR) Then + For Each row As DataRow In oDT_USER_KEY_VALUE_PAIR.Rows + Dim keyName As String = row("KEY_NAME").ToString() + + ' Prüfe ob es sich um einen Inheritance-Key handelt + If keyName.StartsWith("INHERITANCE_CONFIRM_") Then + Dim columnName As String = keyName.Replace("INHERITANCE_CONFIRM_", "") + Dim countValue As Integer = Integer.Parse(row("VALUE_TEXT1").ToString()) + + Dim existingEntry = UserInheritance_ConfirmationByColumn.FirstOrDefault( + Function(e) String.Equals(e.ColumnName, columnName, StringComparison.OrdinalIgnoreCase)) + + If existingEntry IsNot Nothing Then + existingEntry.Count = countValue + Else + UserInheritance_ConfirmationByColumn.Add( + New UserInheritanceConfirmation With { + .ColumnName = columnName, + .Count = countValue + }) + End If + + LOGGER.Debug("Loaded inheritance confirmation for column [{0}] with count [{1}]", columnName, countValue) + End If + Next + Else + LOGGER.Warn("⚠️ oDT_USER_KEY_VALUE_PAIR is nothing") + End If + + + + + + oStopWatch.Done() Catch ex As Exception LOGGER.Error(ex) diff --git a/app/TaskFlow/ClassParamRefresh.vb b/app/TaskFlow/ClassParamRefresh.vb index 30d4bbb..31b9f2e 100644 --- a/app/TaskFlow/ClassParamRefresh.vb +++ b/app/TaskFlow/ClassParamRefresh.vb @@ -232,9 +232,12 @@ Public Class ClassParamRefresh Dim oParam = oMode.Replace("TF.InheritanceCalcReset=", "") Try If CBool(oParam) = True Then - LOGGER.Info("InheritanceMsgAmount wird auf 0 zurückgesetzt") + LOGGER.Info("Inheritance_Counts werden auf 0 zurückgesetzt bzw gelöscht") + Dim oDELETESQL = "DELETE FROM TBDD_USER_KEY_VALUE_PAIR + WHERE FK_USER_ID = " & USER_ID & " And [FK_MODULE_ID] = '" & USER_MODULE_ID & "' AND KEY_NAME LIKE 'INHERITANCE_CONFIRM_%'" + DatabaseECM.ExecuteNonQuery(oDELETESQL) - CONFIG.Config.UserInheritance_ConfirmationByColumn = Nothing + UserInheritance_ConfirmationByColumn = Nothing CONFIG.Save() End If Catch ex As Exception diff --git a/app/TaskFlow/ClassWindream_allgemein.vb b/app/TaskFlow/ClassWindream_allgemein.vb index 27cf4f3..14e3589 100644 --- a/app/TaskFlow/ClassWindream_allgemein.vb +++ b/app/TaskFlow/ClassWindream_allgemein.vb @@ -211,7 +211,7 @@ LOGGER.Error(ex) Public Function GetTypeOfIndex(ByVal indexname As String) As Integer Try If IsNothing(Me.oSession) Then - LOGGER.Warn("GetTypeOfIndex: WMSession is nothing") + LOGGER.Warn("⚠️ GetTypeOfIndex: WMSession is nothing") Return Nothing End If Dim oAttribute = Me.oSession.GetWMObjectByName(WINDREAMLib.WMEntity.WMEntityAttribute, indexname) @@ -272,7 +272,7 @@ LOGGER.Error(ex) Public Function GetIndicesByObjecttype(ByVal Objecttype_name As String) As String() Try If IsNothing(Me.oSession) Then - LOGGER.Warn("GetIndicesByObjecttype: WMSession is nothing") + LOGGER.Warn("⚠️ GetIndicesByObjecttype: WMSession is nothing") Return Nothing End If Dim oObjectType As WMObject @@ -325,7 +325,7 @@ LOGGER.Error(ex) Public Function GetObjecttypeByName(ByVal objekttypName As String) As WMObject Try If IsNothing(Me.oSession) Then - LOGGER.Warn("GetObjecttypeByName: WMSession is nothing") + LOGGER.Warn("⚠️ GetObjecttypeByName: WMSession is nothing") Return Nothing End If ' alle Objekttypen auslesen diff --git a/app/TaskFlow/ControlCreator/GridControl.vb b/app/TaskFlow/ControlCreator/GridControl.vb index 3b8a0bb..02593a9 100644 --- a/app/TaskFlow/ControlCreator/GridControl.vb +++ b/app/TaskFlow/ControlCreator/GridControl.vb @@ -70,7 +70,7 @@ Namespace ControlCreator Dim oConnectionId As Integer = oRow.ItemEx("CONNECTION_ID", 0) Dim oSqlCommand As String = oRow.ItemEx("SQL_COMMAND", "") - If oConnectionId > 0 And oSqlCommand <> "" Then + If oSqlCommand <> "" Then Try Dim oComboboxDataTable As DataTable = Nothing Dim oColumnName As String = oRow.Item("SPALTENNAME") @@ -93,7 +93,7 @@ Namespace ControlCreator _GridTables.Item(pControlId).Add(oColumnName, oRepositoryItem) End If Catch ex As Exception - _Logger.Warn("Could not load data for column {0} in control {1}", oRow.Item("SPALTENNAME"), pControlName) + _Logger.Warn("⚠️ Could not load data for column {0} in control {1}", oRow.Item("SPALTENNAME"), pControlName) _Logger.Error(ex) End Try End If @@ -321,7 +321,7 @@ Namespace ControlCreator End If Next Catch ex As Exception - _Logger.Warn("Error in CustomRowCellEdit for [{0}]", e.CellValue) + _Logger.Warn("⚠️ Error in CustomRowCellEdit for [{0}]", e.CellValue) _Logger.Error(ex) End Try End Sub @@ -484,16 +484,17 @@ Namespace ControlCreator End Try End Sub - Private Function GetInheritanceConfirmationEntry(columnName As String) As ClassConfig.UserInheritanceConfirmation - Dim entries = CONFIG.Config.UserInheritance_ConfirmationByColumn + Private Function GetInheritanceConfirmationEntry(columnName As String) As UserInheritanceConfirmation + Dim entries = UserInheritance_ConfirmationByColumn + If entries Is Nothing Then - entries = New List(Of ClassConfig.UserInheritanceConfirmation)() - CONFIG.Config.UserInheritance_ConfirmationByColumn = entries + entries = New List(Of UserInheritanceConfirmation)() + UserInheritance_ConfirmationByColumn = entries End If Dim entry = entries.FirstOrDefault(Function(item) String.Equals(item.ColumnName, columnName, StringComparison.OrdinalIgnoreCase)) If entry Is Nothing Then - entry = New ClassConfig.UserInheritanceConfirmation With { + entry = New UserInheritanceConfirmation With { .ColumnName = columnName, .Count = 0 } diff --git a/app/TaskFlow/ModuleRuntimeVariables.vb b/app/TaskFlow/ModuleRuntimeVariables.vb index 596a671..a321c72 100644 --- a/app/TaskFlow/ModuleRuntimeVariables.vb +++ b/app/TaskFlow/ModuleRuntimeVariables.vb @@ -1,10 +1,11 @@ -Imports WINDREAMLib -Imports DigitalData.Modules.Config -Imports DigitalData.Modules.Logging -Imports DigitalData.Modules.EDMI.API +Imports DigitalData.Modules.Config Imports DigitalData.Modules.Database -Imports DigitalData.Modules.ZooFlow +Imports DigitalData.Modules.EDMI.API +Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Windream +Imports DigitalData.Modules.ZooFlow +Imports taskFLOW.ClassConfig +Imports WINDREAMLib Module ModuleRuntimeVariables @@ -62,6 +63,7 @@ Module ModuleRuntimeVariables Public Property USER_IS_ADMIN As Boolean = False Public Property USER_ID = 0 + Public Property USER_MODULE_ID = 0 Public Property USER_PRENAME = "" Public Property USER_SURNAME = "" Public Property USER_SHORTNAME = "" @@ -80,6 +82,11 @@ Module ModuleRuntimeVariables Public Property USER_USERNAME_ORG As String = "" Public Property USER_GHOST_MODE_ACTIVE As Boolean = False Public Property USER_GHOST_MODE_USRNAME As String = "" + Public Class UserInheritanceConfirmation + Public Property ColumnName As String = "" + Public Property Count As Integer + End Class + Public Property UserInheritance_ConfirmationByColumn As New List(Of UserInheritanceConfirmation) Public Property FORCE_LAYOUT_OVERVIEW As Boolean = False Public Property SHOW_CHARTS As Boolean = True diff --git a/app/TaskFlow/Validator/Validator.vb b/app/TaskFlow/Validator/Validator.vb index a48fbe5..f942796 100644 --- a/app/TaskFlow/Validator/Validator.vb +++ b/app/TaskFlow/Validator/Validator.vb @@ -163,7 +163,7 @@ Public Class Validator ' Logger.Error(ex) ' Dim st As New StackTrace(True) ' st = New StackTrace(ex, True) - ' Logger.Warn("Unexpected error in Check_UpdateIndexe TextBox :" & ex.Message, True) + ' LOGGER.Warn("⚠️ Unexpected error in Check_UpdateIndexe TextBox :" & ex.Message, True) ' Return False ' End Try 'End Function diff --git a/app/TaskFlow/clsPatterns.vb b/app/TaskFlow/clsPatterns.vb index 9ba88a0..0001157 100644 --- a/app/TaskFlow/clsPatterns.vb +++ b/app/TaskFlow/clsPatterns.vb @@ -5,7 +5,6 @@ Imports DevExpress.XtraGrid Imports DevExpress.XtraGrid.Views.Grid Imports DevExpress.XtraGrid.Columns Imports DevExpress.XtraEditors -Imports DigitalData.Modules.Language ''' ''' Defines common Functions for Checking for and replacing placeholders. ''' This Class also includes a child class `Pattern` for passing around Patterns. @@ -72,7 +71,72 @@ Public Class clsPatterns _ControlLookupCache = Nothing LOGGER.Debug("Control cache cleared") End Sub + ''' + ''' Aktualisiert den Wert eines Controls im Cache + ''' + Public Shared Sub UpdateControlInCache(controlName As String, newValue As Object) + SyncLock _ControlLookupCache ' Thread-Safety + If _ControlLookupCache Is Nothing OrElse Not _ControlLookupCache.ContainsKey(controlName) Then + LOGGER.Warn($"Control [{controlName}] not found in cache for update") + Return + End If + ' Hole das Control aus dem Cache + Dim ctrl As Control = _ControlLookupCache(controlName) + + ' Aktualisiere den WERT des Controls basierend auf seinem Typ + Try + Select Case ctrl.GetType + Case GetType(TextEdit), GetType(MemoEdit) + DirectCast(ctrl, BaseEdit).EditValue = newValue + + Case GetType(LookupControl3) + Dim lookup = DirectCast(ctrl, LookupControl3) + If TypeOf newValue Is List(Of String) Then + lookup.Properties.SelectedValues = DirectCast(newValue, List(Of String)) + ElseIf TypeOf newValue Is String Then + lookup.Properties.SelectedValues = New List(Of String) From {newValue.ToString()} + End If + + Case GetType(Windows.Forms.ComboBox) + DirectCast(ctrl, ComboBox).Text = newValue?.ToString() + + Case GetType(CheckBox) + If TypeOf newValue Is Boolean Then + DirectCast(ctrl, CheckBox).Checked = CBool(newValue) + End If + + Case GetType(DateTimePicker) + If TypeOf newValue Is Date Then + DirectCast(ctrl, DateTimePicker).Value = CDate(newValue) + End If + + Case Else + LOGGER.Warn($"Unsupported control type for cache update: {ctrl.GetType.Name}") + End Select + + LOGGER.Debug($"Cache updated for control [{controlName}] with value type [{newValue?.GetType().Name}]") + + Catch ex As Exception + LOGGER.Error(ex) + LOGGER.Warn($"Failed to update control [{controlName}]: {ex.Message}") + End Try + End SyncLock + End Sub + + ''' + ''' Batch-Update für mehrere Controls + ''' + Public Shared Sub UpdateMultipleControlsInCache(updates As Dictionary(Of String, Object)) + If updates Is Nothing OrElse updates.Count = 0 Then Return + + SyncLock _ControlLookupCache + For Each kvp In updates + UpdateControlInCache(kvp.Key, kvp.Value) + Next + LOGGER.Debug($"Batch cache update completed for {updates.Count} controls") + End SyncLock + End Sub ''' ''' Wraps a pattern-type and -value in the common format: {#type#value} ''' @@ -206,14 +270,16 @@ Public Class clsPatterns End Sub Public Shared Function ReplaceControlValues(pInput As String, oPanel As DevExpress.XtraEditors.XtraScrollableControl, oIsSQL As Boolean) As String Dim oResult = pInput - ' Cache beim ersten Aufruf erstellen: - If _ControlLookupCache Is Nothing Then - _ControlLookupCache = New Dictionary(Of String, Control)() - For Each ctrl As Control In oPanel.Controls - RecursiveAddToCache(ctrl, _ControlLookupCache) - Next - LOGGER.Debug($"Control cache initialized with {_ControlLookupCache.Count} controls") - End If + ' Cache beim ersten Aufruf erstellen mit Lock + SyncLock GetType(clsPatterns) ' Class-Level Lock + If _ControlLookupCache Is Nothing Then + _ControlLookupCache = New Dictionary(Of String, Control)() + For Each ctrl As Control In oPanel.Controls + RecursiveAddToCache(ctrl, _ControlLookupCache) + Next + LOGGER.Debug($"Control cache initialized with {_ControlLookupCache.Count} controls") + End If + End SyncLock Try Dim oTryCounter = 0 @@ -236,14 +302,23 @@ Public Class clsPatterns End If LOGGER.Debug("Found placeholder for control [{0}].", oControlName) + ' Beim Cache-Zugriff Lock verwenden Dim oControl As Control = Nothing - If Not _ControlLookupCache.TryGetValue(oControlName, oControl) Then - LOGGER.Warn($"Control [{oControlName}] not found in cache!") - ' Fallback: Rekursive Suche als letzte Maßnahme + SyncLock _ControlLookupCache + If Not _ControlLookupCache.TryGetValue(oControlName, oControl) Then + LOGGER.Warn($"Control [{oControlName}] not found in cache!") + ' Fallback außerhalb des Lock + End If + End SyncLock + + ' Fallback außerhalb des Lock + If oControl Is Nothing Then oControl = oPanel.Controls.Find(oControlName, True).FirstOrDefault() If oControl IsNot Nothing Then - LOGGER.Info($"Control [{oControlName}] found via fallback search. Adding to cache.") - _ControlLookupCache(oControlName) = oControl + LOGGER.Info($"Control [{oControlName}] found via fallback. Adding to cache.") + SyncLock _ControlLookupCache + _ControlLookupCache(oControlName) = oControl + End SyncLock End If End If @@ -308,7 +383,7 @@ Public Class clsPatterns Dim oView As GridView = oGrid.FocusedView If oColumnName = String.Empty Then - LOGGER.Warn("Used placeholder for Table [{0}] but without Column Name!", oControlName) + LOGGER.Warn("⚠️ Used placeholder for Table [{0}] but without Column Name!", oControlName) oReplaceValue = ERROR_REPLACE_VALUE End If @@ -317,7 +392,7 @@ Public Class clsPatterns SingleOrDefault() If oColumn?.SummaryItem?.SummaryValue Is Nothing Then - LOGGER.Warn("Column [{0}] not found in Grid!", oColumnName) + LOGGER.Warn("⚠️ Column [{0}] not found in Grid!", oColumnName) oReplaceValue = ERROR_REPLACE_VALUE Else oReplaceValue = oColumn.SummaryItem.SummaryValue @@ -333,7 +408,7 @@ Public Class clsPatterns End If oResult = ReplacePattern(oResult, PATTERN_CTRL, oReplaceValue) Else - LOGGER.Warn("Could not get a Control for [{0}].", oControlName) + LOGGER.Warn("⚠️ Could not get a Control for [{0}].", oControlName) End If oTryCounter += 1 @@ -341,7 +416,7 @@ Public Class clsPatterns Return oResult Catch ex As Exception LOGGER.Error(ex) - LOGGER.Warn("Error in ReplaceControlValues:" & ex.Message) + LOGGER.Warn("⚠️ Error in ReplaceControlValues:" & ex.Message) Return oResult End Try End Function diff --git a/app/TaskFlow/frmMain.Designer.vb b/app/TaskFlow/frmMain.Designer.vb index 4de6182..b4318a4 100644 --- a/app/TaskFlow/frmMain.Designer.vb +++ b/app/TaskFlow/frmMain.Designer.vb @@ -246,7 +246,7 @@ Partial Class frmMain ' 'Panel1 ' - Me.Panel1.BackColor = System.Drawing.Color.WhiteSmoke + Me.Panel1.BackColor = System.Drawing.Color.Transparent Me.Panel1.Controls.Add(Me.GridControlWorkflows) Me.Panel1.Controls.Add(Me.Panel2) Me.Panel1.Controls.Add(Me.NavBarControl1) diff --git a/app/TaskFlow/frmMain.resx b/app/TaskFlow/frmMain.resx index 8df7c95..2a0f901 100644 --- a/app/TaskFlow/frmMain.resx +++ b/app/TaskFlow/frmMain.resx @@ -125,7 +125,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADw - CAAAAk1TRnQBSQFMAgEBAgEAAaABCwGgAQsBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + CAAAAk1TRnQBSQFMAgEBAgEAAbABCwGwAQsBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA diff --git a/app/TaskFlow/frmMain.vb b/app/TaskFlow/frmMain.vb index 1040c5b..b051831 100644 --- a/app/TaskFlow/frmMain.vb +++ b/app/TaskFlow/frmMain.vb @@ -111,6 +111,51 @@ Public Class frmMain End Try Return oCHANGED End Function + Public Sub SaveInheritanceConfirmationsToDatabase() + Try + LOGGER.Debug("Saving inheritance confirmations to database for user {0}", USER_ID.ToString) + + Dim entries = UserInheritance_ConfirmationByColumn + If entries Is Nothing OrElse entries.Count = 0 Then + LOGGER.Debug("No confirmation entries to save") + Return + End If + + For Each entry As UserInheritanceConfirmation In entries + Dim keyName As String = $"INHERITANCE_CONFIRM_{entry.ColumnName.ToUpperInvariant()}" + Dim valueText As String = entry.Count.ToString() + + SaveOrUpdateKeyValuePair(keyName, valueText) + Next + + LOGGER.Debug("Successfully saved {0} confirmation entries", entries.Count) + + Catch ex As Exception + LOGGER.Error("Error saving inheritance confirmations to database") + LOGGER.Error(ex) + End Try + End Sub + + Private Sub SaveOrUpdateKeyValuePair(keyName As String, valueText As String) + Try + ' Prüfen ob der Eintrag bereits existiert + Dim oSQL As String = String.Format("DECLARE @Out_PK_ID bigint + EXECUTE [dbo].[PRDD_TBDD_USER_KEY_VALUE_PAIR_Upsert] + {0} + ,'{1}' + ,'{2}' + ,{3} + ,@Out_PK_ID OUTPUT;", USER_ID, keyName, valueText, USER_MODULE_ID) + + If DatabaseFallback.ExecuteNonQueryECM(oSQL) Then + LOGGER.Debug("Saved/Updated key-value pair: {0} = {1}", keyName, valueText) + End If + + Catch ex As Exception + LOGGER.Error("Error saving key-value pair for key {0}", keyName) + LOGGER.Error(ex) + End Try + End Sub Private Sub frmMain_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing Try FormOpenClose = True @@ -122,6 +167,8 @@ Public Class frmMain LOGGER.Error(ex) LOGGER.Info("Error in Save FormLayout: " & ex.Message) End Try + SaveInheritanceConfirmationsToDatabase() + If IDB_ACTIVE = False Then Try If WINDREAM?.oSession?.aLoggedin = True Then @@ -132,6 +179,8 @@ Public Class frmMain End Try End If + + If INACTIVITYRecognized Then Exit Sub End If @@ -428,11 +477,11 @@ Public Class frmMain BarButtonItemFileLink.Visibility = DevExpress.XtraBars.BarItemVisibility.Always If Not IsNothing(WINDREAM.oSession) Then If WINDREAM.oSession.aLoggedin = False Then - LOGGER.Warn("You could not be logged in to windream") + LOGGER.Warn("⚠️ You could not be logged in to windream") MsgBox(S.Es_ist_keine_Windream_Session_vorhanden__Bitte_überprüfen_Sie_das_Log_, MsgBoxStyle.Critical) End If Else - LOGGER.Warn("Login on windream was not possible.") + LOGGER.Warn("⚠️ Login on windream was not possible.") MsgBox(S.Es_ist_keine_Windream_Session_vorhanden__Bitte_überprüfen_Sie_das_Log_, MsgBoxStyle.Critical) End If End If @@ -722,10 +771,10 @@ Public Class frmMain GridViewWorkflows.Columns.Clear() Catch ex As Exception If IsNothing(GridViewWorkflows) Then - LOGGER.Warn("Somehow GridViewWorkflows is nothing....") + LOGGER.Warn("⚠️ Somehow GridViewWorkflows is nothing....") Else If IsNothing(GridViewWorkflows.Columns) Then - LOGGER.Warn("Somehow GridViewWorkflows.Columns is nothing....") + LOGGER.Warn("⚠️ Somehow GridViewWorkflows.Columns is nothing....") End If End If @@ -773,8 +822,6 @@ Public Class frmMain Catch ex As Exception Try If oReducedColName <> "Zuletzt bearbeitet" Then - 'GridViewWorkflows.Columns("Zuletzt bearbeitet").DisplayFormat.FormatType = FormatType.DateTime - 'GridViewWorkflows.Columns("Zuletzt bearbeitet").DisplayFormat.FormatString = "dd.MM.yyyy HH:MM:ss" End If Catch ex1 As Exception LOGGER.Warn($"(ResetLayout)Column [{oReducedColName}] or [Zuletzt bearbeitet] not part of OverviewSQL") @@ -893,7 +940,6 @@ Public Class frmMain End If FRONTEND_ACTION = NAVBAR_CLICKED - Dim _tag = e.Link.Item.Tag Timer_Inactivity_Reset_Disable("navBar_LinkClicked") @@ -910,12 +956,11 @@ Public Class frmMain GRID_LOAD_TYPE = "PROFILE#" & _tag.ToString TimerRefresh.Stop() - GridViewWorkflows.ShowLoadingPanel() - Await Task.Delay(10) + ' LoadingPanel-Verwaltung erfolgt in Load_single_Profile DetailLinkActive = True + Me.Cursor = Cursors.WaitCursor Await Load_single_Profile(True) - ' Caption wird in Load_single_Profile aktualisiert - GridViewWorkflows.HideLoadingPanel() + Me.Cursor = Cursors.Default TimerRefresh.Start() Else CURRENT_CLICKED_PROFILE_TITLE = Nothing @@ -925,8 +970,6 @@ Public Class frmMain ElseIf _tag = "OVERVIEW" Then OverviewOrDEtail = "OVERVIEW" GRID_LOAD_TYPE = "OVERVIEW" - GridViewWorkflows.ShowLoadingPanel() - Await Task.Delay(10) TimerRefresh.Stop() Dim oForce As Boolean = False If DetailLinkActive = True Then @@ -934,16 +977,13 @@ Public Class frmMain DetailLinkActive = False OVERVIEW_ADDED_WHEN = "" End If + ' LoadingPanel-Verwaltung erfolgt in Load_Grid_Overview Await Load_Grid_Overview(False, True, True) - ' Caption wird in Load_Grid_Overview aktualisiert - GridViewWorkflows.HideLoadingPanel() TimerRefresh.Start() RefreshHelper.LoadViewInfo() If GridViewWorkflows.GroupCount = 0 And Not IsNothing(GridViewWorkflows.Columns("GROUP_TEXT")) Then LOGGER.Info("NO GROUPS AFTER CLICK OVERVIEW...CREATING GROUPS NEW...") Await Load_Grid_Overview(False, True, True) - GridViewWorkflows.HideLoadingPanel() - TimerRefresh.Start() RefreshHelper.LoadViewInfo() End If End If @@ -1077,7 +1117,7 @@ Public Class frmMain GridViewWorkflows.Columns.Clear() Catch ex As Exception LOGGER.Error(ex) - LOGGER.Warn("Could not clear GridViewWorkflows.Columns") + LOGGER.Warn("⚠️ Could not clear GridViewWorkflows.Columns") End Try ' Prüfen, ob TL_STATE-Spalte vorhanden ist @@ -1121,7 +1161,7 @@ Public Class frmMain LOGGER.Warn($"Could not set ICON values: {ex.Message}") End Try ElseIf TL_ICON = True AndAlso Not hasTLStateColumn Then - LOGGER.Warn("TL_ICON is enabled but TL_STATE column is missing in dataset") + LOGGER.Warn("⚠️ TL_ICON is enabled but TL_STATE column is missing in dataset") End If bindsourcegrid.DataSource = DT_CURR_WF_ITEMS @@ -1146,7 +1186,7 @@ Public Class frmMain Catch ex As Exception Try Catch ex1 As Exception - LOGGER.Warn("(CreateBasicView)Column [Last edited] or [Zuletzt bearbeitet] not part of OverviewSQL") + LOGGER.Warn("⚠️ (CreateBasicView)Column [Last edited] or [Zuletzt bearbeitet] not part of OverviewSQL") End Try End Try @@ -1159,7 +1199,7 @@ Public Class frmMain End If Catch ex As Exception If OverviewOrDEtail = "OVERVIEW" Then - LOGGER.Warn("ATTENTION: GROUP COLUMNS NOT PART OF GRID") + LOGGER.Warn("⚠️ ATTENTION: GROUP COLUMNS NOT PART OF GRID") End If End Try @@ -1326,13 +1366,19 @@ Public Class frmMain BringMonitor2Front() End Sub Private Async Function Decide_Load(pIsFormLoad As Boolean, Optional ForceReload As Boolean = False) As Tasks.Task + Dim perfStart As DateTime = DateTime.MinValue + Dim perfLastCheck As DateTime = DateTime.MinValue Dim refreshWasEnabled As Boolean = False - Dim showLoadingPanel As Boolean = False - Dim useWaitCursorApplied As Boolean = False - Dim previousMessage As String = bsiMessage.Caption + + If LOG_HOTSPOTS Then + perfStart = DateTime.Now + perfLastCheck = perfStart + LOGGER.Info($"[PERF Decide_Load] START - pIsFormLoad:[{pIsFormLoad}] ForceReload:[{ForceReload}] GRID_LOAD_TYPE:[{GRID_LOAD_TYPE}]") + End If Try - LOGGER.Debug($"Decide_Load: pIsFormLoad [{pIsFormLoad}] - ForceReload [{ForceReload}] - GRID_LOAD_TYPE [{GRID_LOAD_TYPE}] ") + LOGGER.Debug($"Decide_Load: pIsFormLoad [{pIsFormLoad}] - ForceReload [{ForceReload}] - GRID_LOAD_TYPE [{GRID_LOAD_TYPE}]") + If pIsFormLoad = True Then FormShown = False End If @@ -1349,25 +1395,23 @@ Public Class frmMain TimerRefresh.Enabled = False End If - If Me.UseWaitCursor = False Then - Me.UseWaitCursor = True - useWaitCursorApplied = True - End If - - bsiMessage.Caption = "Data loading..." - GridViewWorkflows.ShowLoadingPanel() - Await Task.Delay(10) - showLoadingPanel = True - TimerRefresh.Stop() FRONTEND_ACTION = "DECIDE_LOAD" + ' ========== HAUPTLADEVORGANG ========== If GRID_LOAD_TYPE = "OVERVIEW" Then + If LOG_HOTSPOTS Then + LOGGER.Info("[PERF Decide_Load] ruft Load_Grid_Overview auf...") + End If Await Load_Grid_Overview(pIsFormLoad, ForceReload, False) ElseIf GRID_LOAD_TYPE.StartsWith("PROFILE#") Then + If LOG_HOTSPOTS Then + LOGGER.Info("[PERF Decide_Load] ruft Load_single_Profile auf...") + End If Await Load_single_Profile(ForceReload) End If + ' ========== NACHBEARBEITUNG ========== If SHOW_MASS_VALIDATOR = False Then GridViewWorkflows.OptionsSelection.MultiSelect = False GridViewWorkflows.OptionsSelection.MultiSelectMode = GridMultiSelectMode.RowSelect @@ -1387,34 +1431,39 @@ Public Class frmMain COLUMNS_INVISIBLE() GridIsLoaded = True + Catch ex As Exception GridIsLoaded = True LOGGER.Error(ex) LOGGER.Info("Unexpected error in Decide_load: " & ex.Message) Finally FRONTEND_ACTION = FA_NONE - If showLoadingPanel Then - GridViewWorkflows.HideLoadingPanel() - End If - If useWaitCursorApplied Then - Me.UseWaitCursor = False - End If - bsiMessage.Caption = previousMessage + + ' LoadingPanel wird bereits in Load_Grid_Overview versteckt + ' Kein HideLoadingPanel() nötig! + If refreshWasEnabled Then TimerRefresh.Enabled = True End If + TimerRefresh.Start() + If pIsFormLoad = True Then FormShown = True End If + + If LOG_HOTSPOTS Then + LOGGER.Info($"[PERF Decide_Load] GESAMT: {(DateTime.Now - perfStart).TotalMilliseconds}ms") + End If End Try End Function - Private Sub ToolStripButton2_Click_2(sender As Object, e As EventArgs) frmAdminPasswort.ShowDialog() End Sub Public Sub New() + + Dim splash As New frmSplash() Try splash.ShowDialog() @@ -1422,6 +1471,8 @@ Public Class frmMain LOGGER.Error(ex) LOGGER.Info($"Error in Splash: {ex.Message}") End Try + ' LookAndFeel ZUERST global setzen + ConfigureGlobalLookAndFeel() Try If USER_LANGUAGE <> "" Then Dim cultureInfo As New System.Globalization.CultureInfo(USER_LANGUAGE) @@ -1444,6 +1495,7 @@ Public Class frmMain End Try End Sub + Private Sub TimerReminder_Tick(sender As Object, e As EventArgs) Handles TimerReminder.Tick Try @@ -1470,25 +1522,46 @@ Public Class frmMain End Function Sub Load_Profil_from_Grid(pProfilID As Integer) + Dim perfStart As DateTime = DateTime.MinValue + Dim useWaitCursorApplied As Boolean = False + Dim previousMessage As String = bsiMessage.Caption + Dim messageApplied As Boolean = False + + If LOG_HOTSPOTS Then + perfStart = DateTime.Now + LOGGER.Info($"[PERF Load_Profil_from_Grid START - pProfilID:[{pProfilID}]") + End If + Try CURRENT_ProfilGUID = pProfilID WM_AHWF_docPath = String.Empty + ' ========== UI-VORBEREITUNG ========== + Me.UseWaitCursor = True + useWaitCursorApplied = True + + bsiMessage.Caption = "Loading profile..." + messageApplied = True + If Not Application.OpenForms().OfType(Of frmValidator).Any Then + ' ========== TIMER MANAGEMENT ========== If TimerRefresh.Enabled Then TimerRefresh.Enabled = False End If + ' ========== FORM DESIGN CHECK ========== If CHANGES_FORM_DESIGN = True Then LoadCURRENT_DT_PROFILES() LoadVWPM_CONTROL_INDEX() CHANGES_FORM_DESIGN = False End If + ' ========== PROFILE DATA PREPARATION ========== Dim oExpression = $"GUID = {CURRENT_ProfilGUID}" - CURRENT_DT_PROFILE = Nothing '.Clear() + CURRENT_DT_PROFILE = Nothing CURRENT_DT_PROFILE = CURRENT_DT_PROFILES.Clone CURRENT_DT_PROFILES.Select(oExpression).CopyToDataTable(CURRENT_DT_PROFILE, LoadOption.PreserveChanges) + If CURRENT_DT_PROFILE.Rows.Count = 1 Then CURRENT_ProfilName = CURRENT_DT_PROFILE.Rows(0).Item("NAME") CURRENT_WMObjecttype = CURRENT_DT_PROFILE.Rows(0).Item("WD_OBJECTTYPE") @@ -1498,6 +1571,8 @@ Public Class frmMain MsgBox("Could not get a Profile - Check Your log!", MsgBoxStyle.Exclamation, ADDITIONAL_TITLE) Exit Sub End If + + ' ========== SEARCH DOCUMENTS PREPARATION ========== oExpression = $"PROFILE_ID = {CURRENT_ProfilGUID} " DT_FILTERED_PROFILE_SEARCHES_DOC = Nothing Dim rows = BASEDATA_DT_PROFILES_SEARCHES_DOC.Select(oExpression, "TAB_INDEX") @@ -1507,6 +1582,7 @@ Public Class frmMain DT_FILTERED_PROFILE_SEARCHES_DOC = BASEDATA_DT_PROFILES_SEARCHES_DOC.Clone() End If + ' ========== SEARCH SQL PREPARATION ========== BASEDATA_DT_PROFILE_SEARCHES_SQL = Nothing rows = BASEDATA_DT_PROFILES_SEARCHES_SQL.Select(oExpression, "TAB_INDEX") If rows.Length > 0 Then @@ -1515,8 +1591,12 @@ Public Class frmMain BASEDATA_DT_PROFILE_SEARCHES_SQL = BASEDATA_DT_PROFILES_SEARCHES_SQL.Clone() End If - + ' ========== VALIDATOR-FORM ÖFFNEN ========== Try + If LOG_HOTSPOTS Then + LOGGER.Info("[PERF Load_Profil_from_Grid öffnet frmValidator...") + End If + Dim oEnvironment = GetEnvironment() _FormValidator = New frmValidator(oEnvironment) AddHandler _FormValidator.FormClosed, AddressOf ValidatorClosed @@ -1532,6 +1612,7 @@ Public Class frmMain MsgBox(ex.Message, MsgBoxStyle.Critical, ADDITIONAL_TITLE) End Try + ' ========== ROW AUS ÜBERSICHT ENTFERNEN ========== Try Dim iterateIndex As Integer = 0 Dim oNewDataTable As DataTable = DT_CURR_WF_ITEMS.Copy @@ -1544,39 +1625,47 @@ Public Class frmMain End If Next Catch ex As Exception - LOGGER.Warn("Unexpected Error in Removing Row after Loading Record from Grid: " & ex.Message) + LOGGER.Warn("⚠️ Unexpected Error in Removing Row after Loading Record from Grid: " & ex.Message) End Try + + ' ========== TIMER RE-ENABLE ========== TimerRefresh.Enabled = True - ' th = New Threading.Thread(AddressOf Task_A) - ' th.SetApartmentState(ApartmentState.STA) - ' th.Start() Else LOGGER.Debug("Validator is already open...") - - Dim omsg = ClassAllgemeineFunktionen.GUI_LANGUAGE_INFO("WorkflowIsActive2") FormHelper.ShowInfoMessage(S.Es_existiert_bereits_ein_aktiver_Workflow_, omsgTitleAttention) - 'FormHelper.ShowInfoMessage(omsg, omsgTitleAttention) - End If - - - Catch ex As Exception LOGGER.Error(ex) MsgBox("Unexpected error in Load_Profil_from_Grid: " & ex.Message & vbNewLine & ADDITIONAL_TITLE & " will try to reload the overview - Please try again!", MsgBoxStyle.Information, ADDITIONAL_TITLE) Dim task = Decide_Load(False, True) + Finally + ' ========== UI AUFRÄUMEN ========== + If useWaitCursorApplied Then + Me.UseWaitCursor = False + End If + + If messageApplied AndAlso bsiMessage.Caption = "Loading profile..." Then + bsiMessage.Caption = previousMessage + End If + + If LOG_HOTSPOTS Then + LOGGER.Info($"[PERF Load_Profil_from_Grid GESAMT: {(DateTime.Now - perfStart).TotalMilliseconds}ms") + End If End Try End Sub + Private Async Function Item_Scope(startedFrom As String) As Task + Dim perfStart As DateTime = DateTime.MinValue + Dim useWaitCursorApplied As Boolean = False + Dim previousMessage As String = bsiMessage.Caption + Dim messageApplied As Boolean = False + + If LOG_HOTSPOTS Then + perfStart = DateTime.Now + LOGGER.Info($"[PERF Item_Scope] START - startedFrom:[{startedFrom}]") + End If - 'Public Sub Task_A() - ' Dim frmA = New frmValidator() ' Must be created on this thread! - ' Application.Run(frmA) - 'End Sub - Private Sub Item_Scope(startedFrom As String) - Dim showLoadingPanel As Boolean = False Try - LOGGER.Info("Starting Profile Loading") If Application.OpenForms().OfType(Of frmValidator).Any Then @@ -1584,17 +1673,18 @@ Public Class frmMain LOGGER.Info("Item Scope - Workflow open! - Exit") bsiMessage.ItemAppearance.Normal.BackColor = Color.Red bsiMessage.ItemAppearance.Normal.ForeColor = Color.Black - Exit Sub + Exit Function End If - ' ========== LOADING PANEL AKTIVIEREN (FRÜH) ========== - GridViewWorkflows.ShowLoadingPanel() - showLoadingPanel = True + + ' ========== UI-VORBEREITUNG ========== Me.UseWaitCursor = True + useWaitCursorApplied = True + bsiMessage.Caption = "Processing selection..." + messageApplied = True Dim hitInfo As GridHitInfo = GridViewWorkflows.CalcHitInfo(GridCursorLocation) - bsiMessage.Caption = "" - bsiMessage.ItemAppearance.Normal.BackColor = Color.Transparent Dim OItemScopeInfo = "No Item so far" + If startedFrom = "DOUBLECLICK" Then If hitInfo.InGroupRow Then LOGGER.Debug("User clicked group row.") @@ -1604,6 +1694,7 @@ Public Class frmMain startedFrom = "CMROW" End If End If + Dim oHitProfilID If hitInfo.InGroupRow Then oHitProfilID = GridViewWorkflows.GetRowCellValue(GridViewWorkflows.GetDataRowHandleByGroupRowHandle(hitInfo.RowHandle), GridViewWorkflows.Columns("PROFILE_ID")) @@ -1620,14 +1711,12 @@ Public Class frmMain LOGGER.Debug($"Item_Scope: oHitProfilID {oHitProfilID} <> CURRENT_CLICKED_PROFILE_ID {CURRENT_CLICKED_PROFILE_ID} ") CURRENT_CLICKED_PROFILE_ID = oHitProfilID End If - End If End If + ' ========== GRUPPE VERARBEITEN ========== If startedFrom = "CMGROUP" Then - LOGGER.Debug("Loading Child DocIds..") - Dim oIds As New List(Of Integer) Dim oGroupRowHandle = hitInfo.RowHandle Dim oChildRowCount = GridViewWorkflows.GetChildRowCount(oGroupRowHandle) @@ -1644,27 +1733,22 @@ Public Class frmMain If oIds.Count = 0 Then For index = 0 To GridViewWorkflows.RowCount Dim oRow = GridViewWorkflows.GetRow(index) - If oRow Is Nothing Then Continue For End If - Dim oProfileId = oRow.row.item("PROFILE_ID") - If oProfileId = CURRENT_CLICKED_PROFILE_ID Then oIds.Add(oRow.item("DocId")) End If Next End If - ' ----------------------------- - If oIds.Count = 0 Then Dim omsg = String.Format(S.System_konnte_die_Profilworkflows_nicht_auswerten_, vbNewLine) FormHelper.ShowInfoMessage(omsg, omsgTitleAttention) - 'MsgBox("System konnte die Profilworkflows nicht auswerten!" & vbNewLine & "Bitte wählen Sie ein Profil durch Klicken auf einen Beleg oder eine Überschrift!", MsgBoxStyle.Information, ADDITIONAL_TITLE) - Exit Sub + Exit Function End If + LOGGER.Debug("Cleaning up queued DocIds..") Dim oDelete = $"DELETE FROM TBPM_VALIDATION_PROFILE_GROUP_USER WHERE UserID = {USER_ID}" If DatabaseFallback.ExecuteNonQueryECM(oDelete) = True Then @@ -1675,10 +1759,8 @@ Public Class frmMain DatabaseFallback.ExecuteNonQueryECM(oInsert) Next End If - End If - 'GridViewWorkflows.EndSelection() CURRENT_JUMP_DOC_GUID = 0 If IsNothing(hitInfo) Then @@ -1686,32 +1768,26 @@ Public Class frmMain LOGGER.Info("Could not specify hitinfo via click event (CalcHitInfo)") bsiMessage.ItemAppearance.Normal.BackColor = Color.Red bsiMessage.ItemAppearance.Normal.ForeColor = Color.Black - Exit Sub + Exit Function End If + + ' ========== HITINFO VERARBEITEN ========== Dim groupRowText = "" If hitInfo.InGroupRow Then GridViewItem_Clicked = "GROUP" startedFrom = "CMGROUP" LOGGER.Debug($"Item_Scope: InGroupRow") - OItemScopeInfo = "InGroupRow" groupRowText = GridViewWorkflows.GetGroupRowDisplayText(hitInfo.RowHandle) - OItemScopeInfo = $"groupRowText {groupRowText}" LOGGER.Debug($"Item_Scope: groupRowText {groupRowText}") - ' oHitProfilID = GridViewWorkflows.GetRowCellValue(GridViewWorkflows.GetDataRowHandleByGroupRowHandle(hitInfo.RowHandle), GridViewWorkflows.Columns("PROFILE_ID")) ElseIf hitInfo.InDataRow Then GridViewItem_Clicked = "ROW" - OItemScopeInfo = "InDataRow" LOGGER.Debug($"Item_Scope: InDataRow") If GRID_LOAD_TYPE = "OVERVIEW" Then - OItemScopeInfo = $"GRID_LOAD_TYPE = OVERVIEW" LOGGER.Debug($"Item_Scope: GRID_LOAD_TYPE = OVERVIEW") groupRowText = GridViewWorkflows.GetGroupRowDisplayText(GridViewWorkflows.GetParentRowHandle(hitInfo.RowHandle)) - OItemScopeInfo = $"OVERVIEWgroupRowText {groupRowText}" LOGGER.Debug($"Item_Scope: OVERVIEWgroupRowText {groupRowText}") - ' oHitProfilID = GridViewWorkflows.GetRowCellValue(GridViewWorkflows.GetDataRowHandleByGroupRowHandle(GridViewWorkflows.GetParentRowHandle(hitInfo.RowHandle)), GridViewWorkflows.Columns("PROFILE_ID")) Else - OItemScopeInfo = $"NOT GRID_LOAD_TYPE = OVERVIEW" LOGGER.Debug($"Item_Scope: NOT GRID_LOAD_TYPE = OVERVIEW") If IsNothing(CURRENT_CLICKED_PROFILE_ID) = False Then If CURRENT_CLICKED_PROFILE_ID = 0 Then @@ -1720,44 +1796,44 @@ Public Class frmMain LOGGER.Debug($"Item_Scope: CURRENT_CLICKED_PROFILE_ID [{CURRENT_CLICKED_PROFILE_ID}]") oHitProfilID = CURRENT_CLICKED_PROFILE_ID Else - LOGGER.Warn("ItemScope: CURRENT_CLICKED_PROFILE_ID is nothing!!!") - Exit Sub + LOGGER.Warn("⚠️ ItemScope: CURRENT_CLICKED_PROFILE_ID is nothing!!!") + Exit Function End If - End If - Else - Exit Sub + Exit Function End If + + ' ========== PROFIL-TITEL EXTRAHIEREN ========== Dim PROFIL_TITLE If GRID_LOAD_TYPE = "OVERVIEW" Then Try groupRowText = groupRowText.ToString.Replace("Profile (Fixed): ", "").Trim() Catch ex As Exception - End Try - Dim _SPLIT As String() _SPLIT = groupRowText.Split("|") PROFIL_TITLE = _SPLIT(0).ToString.Trim() - Else - End If + If Len(PROFIL_TITLE) > 0 Then CURRENT_CLICKED_PROFILE_TITLE = PROFIL_TITLE.ToString.Replace("GROUP_TEXT:", "") End If - + ' ========== PROFIL LADEN ========== If Not IsNothing(CURRENT_CLICKED_PROFILE_ID) And IsNumeric(CURRENT_CLICKED_PROFILE_ID) Then LOGGER.Debug($"Item_Scope: Not IsNothing(PROFIL_ID) And IsNumeric(PROFIL_ID)") Dim oExpression As String oExpression = "PROFILE_ID = " & CURRENT_CLICKED_PROFILE_ID + If hitInfo.InGroupRow Or (startedFrom = "CMGROUP" And hitInfo.InDataRow) Then CURRENT_JUMP_DOC_GUID = 0 CURRENT_DOC_GUID = 0 CURRENT_ProfilGUID = CURRENT_CLICKED_PROFILE_ID LOGGER.Debug($"Item_Scope: hitInfo.InGroupRow...CURRENT_CLICKED_PROFILE_ID [{CURRENT_CLICKED_PROFILE_ID}]") + ' ========== SYNCHRONER AUFRUF - WARTEN ========== Load_Profil_from_Grid(CURRENT_CLICKED_PROFILE_ID) + ElseIf hitInfo.InDataRow Then LOGGER.Debug($"Item_Scope: hitInfo.InDataRow...") Dim oFocusedDocGUID @@ -1765,8 +1841,8 @@ Public Class frmMain oFocusedDocGUID = GridViewWorkflows.GetFocusedRowCellValue(GridViewWorkflows.Columns("GUID")) Catch ex As Exception FormHelper.ShowInfoMessage("Could not get DocGUID. Inform Your admin-team: Check Your View-Config", omsgTitleWarning) - End Try + Dim oFocusedDocID Try oFocusedDocID = GridViewWorkflows.GetFocusedRowCellValue(GridViewWorkflows.Columns("DocID")) @@ -1775,41 +1851,34 @@ Public Class frmMain End Try If IsNothing(oFocusedDocID) Then - LOGGER.Warn("In hitInfo.InDataRow: DocID is nothing!!!") + LOGGER.Warn("⚠️ In hitInfo.InDataRow: DocID is nothing!!!") bsiMessage.Caption = "Error getting DocID!" bsiMessage.ItemAppearance.Normal.BackColor = Color.Red bsiMessage.ItemAppearance.Normal.ForeColor = Color.Black - Exit Sub + Exit Function End If + If IsNothing(oFocusedDocGUID) Then - LOGGER.Warn("In hitInfo.InDataRow: oFocusedDocGUID is nothing!!!") + LOGGER.Warn("⚠️ In hitInfo.InDataRow: oFocusedDocGUID is nothing!!!") bsiMessage.Caption = "Error getting DocGUID!" bsiMessage.ItemAppearance.Normal.BackColor = Color.Red bsiMessage.ItemAppearance.Normal.ForeColor = Color.Black - Exit Sub + Exit Function End If + LOGGER.Debug($"Item_Scope: GotDocID {oFocusedDocID} and DocGUID {oFocusedDocGUID}") + If Not IsNothing(GridViewWorkflows.Columns(FullFilepatColName)) Then Dim DOC_PATH = GridViewWorkflows.GetFocusedRowCellValue(GridViewWorkflows.Columns(FullFilepatColName)) If IsNothing(DOC_PATH) Then - LOGGER.Warn("In hitInfo.InDataRow: FULL_FILE_PATH is nothing!!!") - Exit Sub + LOGGER.Warn("⚠️ In hitInfo.InDataRow: FULL_FILE_PATH is nothing!!!") + Exit Function End If DOC_PATH = DOC_PATH.Replace("W:\", "\\windream\objects\") DOC_PATH = DOC_PATH.Replace("K:\", "\\windream\objects\") - ' CURRENT_DOC_PATH = DOC_PATH End If - 'Checking if table really contains one record with profile-id and docid oExpression = oExpression & " AND DocID = " & oFocusedDocID - 'Dim TEMP_TABLE = CURR_DT_OVERVIEW - 'Dim foundRows() As DataRow - 'foundRows = TEMP_TABLE.Select(expression) - 'Dim result = 0 - 'For i = 0 To foundRows.GetUpperBound(0) - 'result += 1 - 'Next - 'If result = 1 Then CURRENT_DOC_ID = oFocusedDocID CURRENT_JUMP_DOC_GUID = oFocusedDocGUID CURRENT_DOC_GUID = CURRENT_JUMP_DOC_GUID @@ -1820,44 +1889,43 @@ Public Class frmMain If CBool(oResult) = True Then Load_Profil_from_Grid(CURRENT_CLICKED_PROFILE_ID) Else - - 'Dim omsg = ClassAllgemeineFunktionen.GUI_LANGUAGE_INFO("WFInWork") Dim omsg = S.Der_gewählte_Beleg_ist_durch_einen_anderen_Benutzer_bereits_in_Bearbeitung_oder_anderweitig_gesperrt_ FormHelper.ShowInfoMessage(omsg, omsgTitleAttention) - End If Catch ex As Exception - LOGGER.Warn($"Uenxpected error in Checking freefile - sql so far: {oSQL} - ") + LOGGER.Warn($"Unexpected error in Checking freefile - sql so far: {oSQL} - ") End Try - - 'Else - 'LOGGER.Warn($"Unable to load Object DocID {CURRENT_DOC_ID} and DocGUID {CURRENT_JUMP_DOC_GUID}: Expression returned 0 [{expression}]") - 'Exit Sub - 'End If - End If Else FormHelper.ShowInfoMessage("Could not get the ProfileID of file! - Check Your configuration of MainView!", omsgTitleWarning) End If + Catch ex As Exception LOGGER.Error(ex) bsiMessage.Caption = "Warning in Item_Scope: " & ex.Message bsiMessage.ItemAppearance.Normal.BackColor = Color.Red bsiMessage.ItemAppearance.Normal.ForeColor = Color.Black Finally - ' ========== LOADING PANEL DEAKTIVIEREN ========== - If showLoadingPanel Then - GridViewWorkflows.HideLoadingPanel() + ' ========== UI AUFRÄUMEN ========== + If useWaitCursorApplied Then + Me.UseWaitCursor = False End If - Me.UseWaitCursor = False bsiMessage.Caption = "" bsiMessage.ItemAppearance.Normal.BackColor = Color.Transparent + + If LOG_HOTSPOTS Then + LOGGER.Info($"[PERF Item_Scope] GESAMT: {(DateTime.Now - perfStart).TotalMilliseconds}ms") + End If End Try - End Sub + End Function Private Async Sub ValidatorClosed(sender As Object, e As FormClosedEventArgs) Try + ' LoadingPanel-Verwaltung erfolgt in Decide_Load Await Decide_Load(False, True) - If GridControlWorkflows.Visible = True And FormOpenClose = False Then RefreshHelper.LoadViewInfo() + + If GridControlWorkflows.Visible = True And FormOpenClose = False Then + RefreshHelper.LoadViewInfo() + End If Catch ex As Exception LOGGER.Error(ex) End Try @@ -1938,7 +2006,8 @@ Public Class frmMain End Try End Sub Async Function Load_Grid_Overview(pFormLoad As Boolean, pForceReload As Boolean, pNavbarClick As Boolean) As Tasks.Task - Dim oStopWatch As New RefreshHelper.SW("Load_Grid_Overview(LGO)") + Dim perfStart As DateTime = DateTime.MinValue + Dim perfStep As DateTime = DateTime.MinValue Dim gridUpdateStarted As Boolean = False Dim viewUpdateStarted As Boolean = False Dim layoutRestored As Boolean = False @@ -1947,25 +2016,58 @@ Public Class frmMain Dim useWaitCursorApplied As Boolean = False Dim previousMessage As String = bsiMessage.Caption Dim loadingMessageApplied As Boolean = False + Dim gridWasMadeVisible As Boolean = False + + If LOG_HOTSPOTS Then + perfStart = DateTime.Now + perfStep = perfStart + LOGGER.Info($"[PERF Load_Grid_Overview] START - pFormLoad:[{pFormLoad}] pForceReload:[{pForceReload}] pNavbarClick:[{pNavbarClick}]") + End If + + ' ========== LOADING PANEL UND UI-VORBEREITUNG ========== + ' SCHRITT 1: Grid sichtbar machen + If GridControlWorkflows.Visible = False Then + GridControlWorkflows.Visible = True + gridWasMadeVisible = True + End If - GridControlWorkflows_Visible() GRID_LOAD_TYPE = "OVERVIEW" CURRENT_CLICKED_PROFILE_ID = 0 - Try - If Me.UseWaitCursor = False Then - Me.UseWaitCursor = True - useWaitCursorApplied = True + ' SCHRITT 2: UI-Thread Zeit geben, das Grid zu rendern + Application.DoEvents() + Await Task.Delay(100) + + ' SCHRITT 3: LoadingPanel anzeigen (jetzt ist das Grid definitiv sichtbar!) + GridViewWorkflows.ShowLoadingPanel() + showLoadingPanel = True + + ' SCHRITT 4: UI-Thread Zeit zum Rendern des LoadingPanels geben + Application.DoEvents() + Await Task.Delay(50) + + If LOG_HOTSPOTS Then + Dim elapsed = (DateTime.Now - perfStep).TotalMilliseconds + If elapsed > 4000 Then + LOGGER.Warn($"[PERF LGO] ⚠️ UI-Vorbereitung LANGSAM: {elapsed}ms (Schwellwert: 4000ms)") + Else + LOGGER.Info($"[PERF LGO] UI-Vorbereitung: {elapsed}ms") End If + perfStep = DateTime.Now + End If - bsiMessage.Caption = "Overviewdata loading..." - loadingMessageApplied = True - - GridViewWorkflows.ShowLoadingPanel() - Await Task.Delay(10) - showLoadingPanel = True + ' WaitCursor setzen + If Me.UseWaitCursor = False Then + Me.UseWaitCursor = True + useWaitCursorApplied = True + End If + ' Statusmeldung aktualisieren + bsiMessage.Caption = "Overviewdata loading..." + loadingMessageApplied = True + Try + ' ========== GRID UPDATES VORBEREITEN ========== If GridControlWorkflows.Visible Then GridControlWorkflows.BeginUpdate() gridUpdateStarted = True @@ -1973,6 +2075,7 @@ Public Class frmMain viewUpdateStarted = True End If + ' ========== DATEN VALIDIEREN ========== If BASEDATA_DT_VW_PROFILE_USER.Rows.Count = 0 Then LOGGER.Info("Attention: No profiles for user: '" & USER_USERNAME & "' configured!", False) NO_WORKFLOWITEMS = True @@ -1980,25 +2083,36 @@ Public Class frmMain bsiMessage.ItemAppearance.Normal.BackColor = Color.Red bsiMessage.ItemAppearance.Normal.ForeColor = Color.Black GridControlWorkflows.Visible = False - Exit Function + Exit Try End If + If LOG_HOTSPOTS Then + LOGGER.Info($"[PERF LGO] Load_Profiles_for_User wird aufgerufen...") + End If - - Dim oStopWatch1 As New RefreshHelper.SW("LGO#Load_Profiles_for_User") Load_Profiles_for_User() - oStopWatch1.Done() - Dim oStopWatch2 As New RefreshHelper.SW("LGO#build CURR_DT_OVERVIEW") + If LOG_HOTSPOTS Then + Dim elapsed = (DateTime.Now - perfStep).TotalMilliseconds + If elapsed > 4000 Then + LOGGER.Warn($"[PERF LGO] ⚠️ Load_Profiles_for_User LANGSAM: {elapsed}ms (Schwellwert: 4000ms)") + Else + LOGGER.Info($"[PERF LGO] Load_Profiles_for_User: {elapsed}ms") + End If + perfStep = DateTime.Now + End If + + ' ========== SQL UND DATEN LADEN ========== Dim oSQLOverview = BASEDATA_DT_CONFIG.Rows(0).Item("SQL_PROFILE_MAIN_VIEW") + If IsDBNull(oSQLOverview) Then bsiMessage.Caption = "No SQL_PROFILE_MAIN_VIEW in Baseconfig" - Exit Function + Exit Try End If + If oSQLOverview.ToString.Contains("GROUP_TEXT") = False Then LOGGER.Info($"SQL SO FAR: {oSQLOverview} ") FormHelper.ShowInfoMessage("Incomplete Overview-Source (No Group-Columns). Column", omsgTitleWarning) - NO_WORKFLOWITEMS = True GridControlWorkflows.Visible = False bindsourcegrid.DataSource = Nothing @@ -2008,9 +2122,10 @@ Public Class frmMain Catch ex As Exception LOGGER.Error(ex) End Try - Exit Function + Exit Try End If + ' SQL-Platzhalter ersetzen oSQLOverview = clsPatterns.ReplaceInternalValues(oSQLOverview) oSQLOverview = clsPatterns.ReplaceUserValues(oSQLOverview) oSQLOverview = oSQLOverview.Replace("@USER_ID", USER_ID) @@ -2019,8 +2134,22 @@ Public Class frmMain oSQLOverview = oSQLOverview.Replace("@DATE", Now.ToShortDateString) oSQLOverview = oSQLOverview.Replace("@PROFILE_ID", CURRENT_CLICKED_PROFILE_ID) + If LOG_HOTSPOTS Then + LOGGER.Info($"[PERF LGO] SQL-Abfrage startet (Rows erwartet: {If(DT_CURR_WF_ITEMS IsNot Nothing, DT_CURR_WF_ITEMS.Rows.Count.ToString(), "N/A")})...") + End If + DT_CURR_WF_ITEMS = Await DatabaseFallback.GetDatatableECMAsync(oSQLOverview) - oStopWatch2.Done() + + If LOG_HOTSPOTS Then + Dim elapsed = (DateTime.Now - perfStep).TotalMilliseconds + Dim rowCount = If(DT_CURR_WF_ITEMS IsNot Nothing, DT_CURR_WF_ITEMS.Rows.Count, 0) + If elapsed > 4000 Then + LOGGER.Warn($"[PERF LGO] ⚠️ Datenbank-Abfrage Overview LANGSAM: {elapsed}ms ({rowCount} Zeilen) (Schwellwert: 4000ms) - SQL prüfen!") + Else + LOGGER.Info($"[PERF LGO] Datenbank-Abfrage Overview: {elapsed}ms ({rowCount} Zeilen)") + End If + perfStep = DateTime.Now + End If If IsNothing(DT_CURR_WF_ITEMS) Then NO_WORKFLOWITEMS = True @@ -2031,19 +2160,17 @@ Public Class frmMain Catch ex As Exception LOGGER.Error(ex) End Try - Exit Function + Exit Try End If LOGGER.Debug($"Datatable CURR_DT_OVERVIEW loaded: {DT_CURR_WF_ITEMS.Rows.Count} rows") + ' ========== DATEN ANALYSIEREN ========== Dim oADDED = GET_LAST_ADDED(DT_CURR_WF_ITEMS) Dim oChanged = GET_LAST_CHANGED(DT_CURR_WF_ITEMS) Dim oCOUNT = DT_CURR_WF_ITEMS.Rows.Count - ' Workflowitems-Status setzen NO_WORKFLOWITEMS = (oCOUNT = 0) - - ' Caption IMMER aktualisieren UpdateGridCaption() If NO_WORKFLOWITEMS Then @@ -2055,9 +2182,10 @@ Public Class frmMain Catch ex As Exception LOGGER.Error(ex) End Try - Exit Function + Exit Try End If + ' ========== ICON-SPALTE VORBEREITEN ========== If TL_ICON = True AndAlso DT_CURR_WF_ITEMS.Columns.Contains("ICON") = False Then Dim columnStateIcon As New DataColumn() With { .DataType = GetType(Image), @@ -2070,6 +2198,7 @@ Public Class frmMain RedDocuments = 0 YellowDocuments = 0 GreenDocuments = 0 + If TL_ICON = True Then For Each row As DataRow In DT_CURR_WF_ITEMS.Rows Dim State As Integer = row.Item("TL_STATE") @@ -2087,12 +2216,34 @@ Public Class frmMain Next End If + If LOG_HOTSPOTS Then + Dim elapsed = (DateTime.Now - perfStep).TotalMilliseconds + If elapsed > 4000 Then + LOGGER.Warn($"[PERF LGO] ⚠️ Icon-Verarbeitung LANGSAM: {elapsed}ms ({DT_CURR_WF_ITEMS.Rows.Count} Zeilen) (Schwellwert: 4000ms)") + Else + LOGGER.Info($"[PERF LGO] Icon-Verarbeitung: {elapsed}ms") + End If + perfStep = DateTime.Now + End If + + ' ========== GRID MIT DATEN FÜLLEN ========== bindsourcegrid.DataSource = DT_CURR_WF_ITEMS GridControlWorkflows.DataSource = bindsourcegrid GridControlWorkflows.ForceInitialize() Create_View_Caption() + If LOG_HOTSPOTS Then + Dim elapsed = (DateTime.Now - perfStep).TotalMilliseconds + If elapsed > 4000 Then + LOGGER.Warn($"[PERF LGO] ⚠️ Grid-DataSource-Zuweisung LANGSAM: {elapsed}ms (Schwellwert: 4000ms)") + Else + LOGGER.Info($"[PERF LGO] Grid-DataSource-Zuweisung: {elapsed}ms") + End If + perfStep = DateTime.Now + End If + + ' ========== LAYOUT WIEDERHERSTELLEN ODER ZURÜCKSETZEN ========== Dim oColNotPartofLayout As Boolean = False If pNavbarClick = False Then If pForceReload = True And (GridLayoutChanged() = True Or oColNotPartofLayout = True) Then @@ -2112,6 +2263,17 @@ Public Class frmMain Create_GroupBy_Parts() End If + If LOG_HOTSPOTS Then + Dim elapsed = (DateTime.Now - perfStep).TotalMilliseconds + If elapsed > 4000 Then + LOGGER.Warn($"[PERF LGO] ⚠️ Layout-Wiederherstellung LANGSAM: {elapsed}ms (Schwellwert: 4000ms)") + Else + LOGGER.Info($"[PERF LGO] Layout-Wiederherstellung: {elapsed}ms") + End If + perfStep = DateTime.Now + End If + + ' ========== ICON-SPALTE KONFIGURIEREN ========== If TL_ICON = True Then Try GridViewWorkflows.Columns.Item("ICON").MaxWidth = 24 @@ -2123,7 +2285,7 @@ Public Class frmMain End If If GridViewWorkflows.Columns.Count <= 5 Then - LOGGER.Info("GridViewWorkflows.Columns.Count <= 2 - Reset_Gridlayout will be forced...", False) + LOGGER.Info("GridViewWorkflows.Columns.Count <= 5 - Reset_Gridlayout will be forced...", False) Await Reset_GridLayout(pFormLoad) resetLayoutTriggered = True End If @@ -2134,6 +2296,7 @@ Public Class frmMain COLUMNS_INVISIBLE() + ' ========== SPALTENFORMATIERUNG ANWENDEN ========== Try For Each oColumn As DevExpress.XtraGrid.Columns.GridColumn In GridViewWorkflows.Columns For Each oRow As DataRow In BASEDATA_TBDD_COLUMNS_FORMAT.Rows @@ -2159,29 +2322,55 @@ Public Class frmMain Next Next Catch ex As Exception - LOGGER.Warn("Fehler beim Anwenden der Formatierung aus TBDD_COLUMNS_FORMAT: " & ex.Message) + LOGGER.Warn("⚠️ Fehler beim Anwenden der Formatierung aus TBDD_COLUMNS_FORMAT: " & ex.Message) End Try + If LOG_HOTSPOTS Then + Dim elapsed = (DateTime.Now - perfStep).TotalMilliseconds + If elapsed > 4000 Then + LOGGER.Warn($"[PERF LGO] ⚠️ Spaltenformatierung LANGSAM: {elapsed}ms (Schwellwert: 4000ms)") + Else + LOGGER.Info($"[PERF LGO] Spaltenformatierung: {elapsed}ms") + End If + End If + Catch ex As Exception LOGGER.Error(ex) LOGGER.Info("Load_Grid_Overview - Fehler: " & ex.Message) + Finally + ' ========== AUFRÄUMEN ========== + ' EndUpdate IMMER aufrufen (vor dem Verstecken des LoadingPanel) If viewUpdateStarted Then GridViewWorkflows.EndUpdate() End If If gridUpdateStarted Then GridControlWorkflows.EndUpdate() End If + + ' LoadingPanel SOFORT nach EndUpdate verstecken If showLoadingPanel Then GridViewWorkflows.HideLoadingPanel() End If + + ' WaitCursor entfernen If useWaitCursorApplied Then Me.UseWaitCursor = False End If - If loadingMessageApplied AndAlso bsiMessage.Caption = "Daten werden geladen..." Then + + ' Statusmeldung zurücksetzen + If loadingMessageApplied AndAlso bsiMessage.Caption = "Overviewdata loading..." Then bsiMessage.Caption = previousMessage End If - oStopWatch.Done() + + If LOG_HOTSPOTS Then + Dim totalElapsed = (DateTime.Now - perfStart).TotalMilliseconds + If totalElapsed > 4000 Then + LOGGER.Warn($"[PERF Load_Grid_Overview] ⚠️ GESAMT LANGSAM: {totalElapsed}ms (Schwellwert: 4000ms)") + Else + LOGGER.Info($"[PERF Load_Grid_Overview] GESAMT: {totalElapsed}ms") + End If + End If End Try End Function Private Sub tsmiValidationProfil_Click(sender As Object, e As EventArgs) Handles tsmiValidationProfil.Click @@ -2227,8 +2416,10 @@ Public Class frmMain InResetlayout = False End Function - Private Sub GridViewWorkflows_DoubleClick(sender As Object, e As EventArgs) Handles GridViewWorkflows.DoubleClick - Item_Scope("DOUBLECLICK") + Private Async Sub GridViewWorkflows_DoubleClick(sender As Object, e As EventArgs) Handles GridViewWorkflows.DoubleClick + Me.Cursor = Cursors.WaitCursor + Await Item_Scope("DOUBLECLICK") + Me.Cursor = Cursors.Default End Sub 'Private Sub GridViewWorkflows_CustomDrawGroupRow(sender As Object, e As Views.Base.RowObjectCustomDrawEventArgs) Handles GridViewWorkflows.CustomDrawGroupRow @@ -2506,9 +2697,9 @@ FROM VWPM_PROFILE_ACTIVE T WITH (NOLOCK) WHERE T.GUID IN (SELECT PROFILE_ID FROM End Try oStopWatch.Done() End Sub - Private Async Sub frmMain_Shown(sender As Object, e As EventArgs) Handles Me.Shown + Private Sub ConfigureGlobalLookAndFeel() If RIBBON_COLOR_SCHEME <> "" Then - Me.LookAndFeel.UseDefaultLookAndFeel = False + UserLookAndFeel.Default.UseDefaultLookAndFeel = False If RIBBON_COLOR_SCHEME = "Blue".ToUpper Then LookAndFeel.SetSkinStyle(SkinStyle.Office2019White, SkinSvgPalette.Office2019White.Yale) ElseIf RIBBON_COLOR_SCHEME = "Green".ToUpper Then @@ -2522,7 +2713,8 @@ FROM VWPM_PROFILE_ACTIVE T WITH (NOLOCK) WHERE T.GUID IN (SELECT PROFILE_ID FROM End If LOGGER.Debug($" RibbonControl1.ColorScheme [{RIBBON_COLOR_SCHEME}]") End If - + End Sub + Private Async Sub frmMain_Shown(sender As Object, e As EventArgs) Handles Me.Shown Me.Text = ADDITIONAL_TITLE CurrNavBarGroup = NavBarControl1.Groups(1) FormShown = True @@ -3100,12 +3292,16 @@ FROM VWPM_PROFILE_ACTIVE T WITH (NOLOCK) WHERE T.GUID IN (SELECT PROFILE_ID FROM GridViewWorkflows.ShowCustomization() End Sub - Private Sub BarButtonItem8_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItemWFSingle.ItemClick - Item_Scope("CMROW") + Private Async Sub BarButtonItem8_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItemWFSingle.ItemClick + Me.Cursor = Cursors.WaitCursor + Await Item_Scope("CMROW") + Me.Cursor = Cursors.Default End Sub - Private Sub BarButtonItemWFGroup_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItemWFGroup.ItemClick - Item_Scope("CMGROUP") + Private Async Sub BarButtonItemWFGroup_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItemWFGroup.ItemClick + Me.Cursor = Cursors.WaitCursor + Await Item_Scope("CMGROUP") + Me.Cursor = Cursors.Default End Sub Private Sub BarButtonItemFileLink_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItemFileLink.ItemClick diff --git a/app/TaskFlow/frmMassValidator.vb b/app/TaskFlow/frmMassValidator.vb index b46f9ca..34164c2 100644 --- a/app/TaskFlow/frmMassValidator.vb +++ b/app/TaskFlow/frmMassValidator.vb @@ -918,7 +918,7 @@ Public Class frmMassValidator Else 'not implemented - LOGGER.Warn("Depending_Control_Set_Result for [{0}] NOT IMPLEMENTED", displayboxname) + LOGGER.Warn("⚠️ Depending_Control_Set_Result for [{0}] NOT IMPLEMENTED", displayboxname) End If Else If oResultTable.Rows.Count = 1 Then @@ -929,7 +929,7 @@ Public Class frmMassValidator End If End If Else - LOGGER.Warn("Result Table is nothing!") + LOGGER.Warn("⚠️ Result Table is nothing!") End If Catch ex As Exception LOGGER.Info("Unexpected Ersror in Depending_Control_Set_Result - ERROR: " & ex.Message) diff --git a/app/TaskFlow/frmMonitor.vb b/app/TaskFlow/frmMonitor.vb index 5b948d3..7d86e3f 100644 --- a/app/TaskFlow/frmMonitor.vb +++ b/app/TaskFlow/frmMonitor.vb @@ -36,7 +36,7 @@ Public Class frmMonitor Try oDocID = GridView1.GetFocusedRowCellValue(GridView1.Columns("ObjectID")) Catch ex1 As Exception - LOGGER.Warn("Could not get Doc/ObjectReference: " & ex.Message) + LOGGER.Warn("⚠️ Could not get Doc/ObjectReference: " & ex.Message) MsgBox("Could not get Doc/ObjectReference: " & ex.Message, MsgBoxStyle.Critical, "Load_Detail") Exit Sub End Try diff --git a/app/TaskFlow/frmValidator.vb b/app/TaskFlow/frmValidator.vb index f3fb8f5..3f321ee 100644 --- a/app/TaskFlow/frmValidator.vb +++ b/app/TaskFlow/frmValidator.vb @@ -129,7 +129,8 @@ Public Class frmValidator Private _SqlControlsByGuid As Dictionary(Of Integer, List(Of DataRow)) Private _LookupControlsByRepository As Dictionary(Of RepositoryItemLookupControl3, LookupControl3) Private _CachedFinalIndexing As DataTable = Nothing - + Private _isUpdatingLookup As Boolean = False + Private _suppressLookupEvents As Boolean = False Private Class Translation_Strings Inherits My.Resources.frmValidator_Strings End Class @@ -186,7 +187,7 @@ Public Class frmValidator ' === MESSPUNKT 1: Start === Dim perfStart As DateTime = If(LOG_HOTSPOTS, DateTime.Now, Nothing) Dim perfLastCheck As DateTime = perfStart - If LOG_HOTSPOTS Then MyValidationLogger.Info($"[PERF] frmValidation_Load START") + If LOG_HOTSPOTS Then MyValidationLogger.Info($"[PERF frmValidation_Load] START") Try MyValidationLogger.Debug("###frmValidation_Load###") @@ -215,7 +216,7 @@ Public Class frmValidator If LOG_HOTSPOTS Then - MyValidationLogger.Info($"[PERF] Nach Initialisierung: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + MyValidationLogger.Info($"[PERF frmValidation_Load] Nach Initialisierung: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now End If @@ -257,7 +258,7 @@ Public Class frmValidator End If If LOG_HOTSPOTS Then - MyValidationLogger.Info($"[PERF] Nach Position/Size: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + MyValidationLogger.Info($"[PERF frmValidation_Load] Nach Position/Size: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now End If @@ -277,7 +278,7 @@ Public Class frmValidator DocumentViewer1.Init(LOGCONFIG, GDPICTURE_LICENSE, oDVSettings) If LOG_HOTSPOTS Then - MyValidationLogger.Info($"[PERF] Nach DocumentViewer.Init: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + MyValidationLogger.Info($"[PERF frmValidation_Load] Nach DocumentViewer.Init: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now End If @@ -295,7 +296,7 @@ Public Class frmValidator DTVWCONTROLS_INDEX.Select(oExpression, "Y_LOC, X_LOC").CopyToDataTable(DTVWCONTROL_INDEX, LoadOption.PreserveChanges) If LOG_HOTSPOTS Then - MyValidationLogger.Info($"[PERF] Nach DTVWCONTROL_INDEX laden ({DTVWCONTROL_INDEX.Rows.Count} Rows): {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + MyValidationLogger.Info($"[PERF frmValidation_Load] Nach DTVWCONTROL_INDEX laden ({DTVWCONTROL_INDEX.Rows.Count} Rows): {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now End If @@ -354,7 +355,7 @@ Public Class frmValidator CURRENT_PROFILE_LOG_INDEX = PROFIL_LOGINDEX If LOG_HOTSPOTS Then - MyValidationLogger.Info($"[PERF] Nach Profile-Properties: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + MyValidationLogger.Info($"[PERF frmValidation_Load] Nach Profile-Properties: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now End If @@ -382,7 +383,7 @@ Public Class frmValidator If profileLangUser.TryGetValue(notRespQKey, row) Then oProfileNotResponsibleQuestion = row.Item("STRING1") If LOG_HOTSPOTS Then - MyValidationLogger.Info($"[PERF] Nach Language-Loop ({CURRENT_DT_PROFILE_LANGUAGE.Rows.Count} Rows): {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + MyValidationLogger.Info($"[PERF frmValidation_Load] Nach Language-Loop ({CURRENT_DT_PROFILE_LANGUAGE.Rows.Count} Rows): {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now End If @@ -434,7 +435,7 @@ Public Class frmValidator MyValidationLogger.Debug("Buttontext validation loaded") If LOG_HOTSPOTS Then - MyValidationLogger.Info($"[PERF] Nach Button-Setup: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + MyValidationLogger.Info($"[PERF frmValidation_Load] Nach Button-Setup: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now End If @@ -521,7 +522,7 @@ Public Class frmValidator End If If LOG_HOTSPOTS Then - MyValidationLogger.Info($"[PERF] Nach Rejection/NR-Setup: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + MyValidationLogger.Info($"[PERF frmValidation_Load] Nach Rejection/NR-Setup: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now End If @@ -557,10 +558,10 @@ Public Class frmValidator MyValidationLogger.Debug("Right_Delete: " & USER_RIGHT_FILE_DELETE.ToString) ' === MESSPUNKT 10: Create_Controls (KRITISCH - wahrscheinlich größter Hotspot) === - If LOG_HOTSPOTS Then MyValidationLogger.Info($"[PERF] Vor Create_Controls") + If LOG_HOTSPOTS Then MyValidationLogger.Info($"[PERF frmValidation_Load] Vor Create_Controls") Create_Controls() If LOG_HOTSPOTS Then - MyValidationLogger.Info($"[PERF] Nach Create_Controls: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + MyValidationLogger.Info($"[PERF frmValidation_Load] Nach Create_Controls: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now End If End If @@ -570,7 +571,7 @@ Public Class frmValidator ' === MESSPUNKT 11: Gesamt-Zeit === If LOG_HOTSPOTS Then - MyValidationLogger.Info($"[PERF] GESAMT frmValidation_Load: {(DateTime.Now - perfStart).TotalMilliseconds}ms") + MyValidationLogger.Info($"[PERF frmValidation_Load] GESAMT frmValidation_Load: {(DateTime.Now - perfStart).TotalMilliseconds}ms") End If Catch ex As Exception @@ -581,6 +582,14 @@ Public Class frmValidator End Sub Private Sub frmValidation_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing + Dim perfStart As DateTime = DateTime.MinValue + Dim perfLastCheck As DateTime = DateTime.MinValue + If LOG_HOTSPOTS Then + perfStart = DateTime.Now + perfLastCheck = perfStart + MyValidationLogger.Info("[PERF frmValidation_FormClosing] START") + End If + Try _FormClosing = True @@ -589,6 +598,12 @@ Public Class frmValidator frmMessages.Close() End If End If + + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF frmValidation_FormClosing] nach Messages-Close: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If + Try ' Position und Größe speichern My.Settings.frmValidatorSize = Me.Size @@ -598,9 +613,24 @@ Public Class frmValidator MyValidationLogger.Error(ex) MyValidationLogger.Info("Error in Load FormLayout: " & ex.Message) End Try + + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF frmValidation_FormClosing] nach Settings.Save: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If + My.Settings.frmValidatorSize = Me.Size My.Settings.Save() - If INACTIVITY_DURATION <> 0 Then frmMain.Timer_Inactivity_Reset_Disable("FormClosing") + + If INACTIVITY_DURATION <> 0 Then + frmMain.Timer_Inactivity_Reset_Disable("FormClosing") + End If + + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF frmValidation_FormClosing] nach Timer-Reset: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If + Catch ex As Exception MyValidationLogger.Error(ex) End Try @@ -608,13 +638,20 @@ Public Class frmValidator Try Dim oSQL As String If CURRENT_DOC_GUID <> 0 Then + Dim oPRoc = String.Format("EXEC PRTF_PROFILE_FILES_WORK {0},{1},{2},'FreeFile'", CURRENT_DOC_ID, CURRENT_ProfilGUID, USER_ID) oSQL = $"DELETE FROM TBPM_DOCWALKOVER WHERE UserID = {USER_ID};" & vbNewLine & - $"UPDATE TBPM_PROFILE_FILES Set IN_WORK = 0, IN_WORK_WHEN = NULL, WORK_USER = NULL WHERE GUID = {CURRENT_DOC_GUID};" + oPRoc Else oSQL = $"DELETE FROM TBPM_DOCWALKOVER WHERE UserID = {USER_ID};" End If DatabaseFallback.ExecuteNonQueryECM(oSQL) + + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF frmValidation_FormClosing] nach DB-Cleanup: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If + Catch ex As Exception MyValidationLogger.Error(ex) MsgBox("Error in delete jumped files:" & vbNewLine & ex.Message, MsgBoxStyle.Critical) @@ -622,25 +659,43 @@ Public Class frmValidator Reset_CurrentReferences() + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF frmValidation_FormClosing] nach Reset_CurrentReferences: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If + Try If Not IsNothing(DocumentViewer1) Then DocumentViewer1.CloseDocument() DocumentViewer1.Done() End If + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF frmValidation_FormClosing] nach DocumentViewer.Done: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If + Catch ex As Exception MyValidationLogger.Warn($"Unexpected error in DocumentViewerValidator.Done: {ex.Message}") End Try Try _frmValidatorSearch.Close() + + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF frmValidation_FormClosing] nach ValidatorSearch.Close: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If + Catch ex As Exception MyValidationLogger.Error(ex) End Try + + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF frmValidation_FormClosing] GESAMT: {(DateTime.Now - perfStart).TotalMilliseconds}ms") + End If End Sub Sub Reset_CurrentReferences() - MyValidationLogger.Info("Attention: Reset_CurrentReferences....") - If Not IsNothing(DT_AdditionalSearches_Resultset_Docs) Then DT_AdditionalSearches_Resultset_Docs.Clear() End If @@ -858,7 +913,7 @@ Public Class frmValidator lookup.Properties.ValueMember = oDTContent.Columns.Item(0).ColumnName lookup.Properties.DisplayMember = oDTContent.Columns.Item(0).ColumnName Catch ex As Exception - MyValidationLogger.Warn("Error in LookUpLoadSQLData: " & ex.Message) + MyValidationLogger.Warn("⚠️ Error in LookUpLoadSQLData: " & ex.Message) End Try ElseIf TypeOf control Is DevExpress.XtraEditors.TextEdit Or TypeOf control Is MemoEdit Then @@ -870,7 +925,7 @@ Public Class frmValidator DirectCast(control, BaseEdit).EditValue = value oValue = value Catch ex As Exception - MyValidationLogger.Warn("Error in TextBoxLoadSQLData: " & ex.Message) + MyValidationLogger.Warn("⚠️ Error in TextBoxLoadSQLData: " & ex.Message) End Try ElseIf TypeOf control Is Windows.Forms.ComboBox Then Try @@ -887,7 +942,7 @@ Public Class frmValidator oMyComboBox.SelectedIndex = oselectedIndex Catch ex As Exception - MyValidationLogger.Warn("Error in ComboBoxLoadSQLData: " & ex.Message) + MyValidationLogger.Warn("⚠️ Error in ComboBoxLoadSQLData: " & ex.Message) End Try ElseIf TypeOf control Is GridControl Then @@ -913,7 +968,7 @@ Public Class frmValidator dataGridView.DataSource = oDataSource End If Catch ex As Exception - MyValidationLogger.Warn("Error in GridControlSQLData: " & ex.Message) + MyValidationLogger.Warn("⚠️ Error in GridControlSQLData: " & ex.Message) End Try End If Next @@ -1362,6 +1417,9 @@ Public Class frmValidator MyValidationLogger.Debug($"Control [{oMeta.Name}] marked as dirty") End If + ' *** NEU: Cache aktualisieren *** + clsPatterns.UpdateControlInCache(oTextbox.Name, oTextbox.EditValue) + SetControlValues_FromControl(oTextbox) Controls2beEnabled(oTextbox.Name) ControlCreator.GridTables_HandleControlValueChange(PanelValidatorControl, DT_COLUMNS_GRID_WITH_SQL_WITH_CTRL_PLACEHOLDER) @@ -1444,8 +1502,7 @@ Public Class frmValidator MyValidationLogger.Info("Unexpected Error in Eventhandler Variable SQL Result - ERROR: " & ex.Message) End Try If oTextBox.Name <> last_control.Name Then - SendKeys.Send("{TAB}") - _ControlHandleStarted = True + Me.SelectNextControl(oTextBox, True, True, True, True) End If End If End If @@ -1458,12 +1515,12 @@ Public Class frmValidator Dim oControlID = DirectCast(oButton.Tag, ClassControlCreator.ControlMetadata).Guid Dim oSQL = ControlCreator.GET_CONTROL_PROPERTY(DT_CONTROLS, oControlID, "SQL_UEBERPRUEFUNG") If IsNothing(oSQL) Then - MyValidationLogger.Warn("onCustomButtonClick - SQL_UEBERPRUEFUNG IS NOTHING") + MyValidationLogger.Warn("⚠️ onCustomButtonClick - SQL_UEBERPRUEFUNG IS NOTHING") Exit Sub End If If Check_UpdateIndexe() = False Then - MyValidationLogger.Warn("onCustomButtonClick - Check_UpdateIndexe = False >> Exit Click") + MyValidationLogger.Warn("⚠️ onCustomButtonClick - Check_UpdateIndexe = False >> Exit Click") Exit Sub End If Override_SQLCommand = ControlCreator.GET_CONTROL_PROPERTY(DT_CONTROLS, oControlID, "SQL2") @@ -1659,7 +1716,7 @@ Public Class frmValidator Public Sub onLookUpselectedValue(sender As Object, SelectedValues As List(Of String)) Try MyValidationLogger.Debug("onLookUpselectedValue") - If _FormLoaded = False Then + If _FormLoaded = False Or _suppressLookupEvents Then Exit Sub End If @@ -1668,38 +1725,61 @@ Public Class frmValidator Exit Sub End If - Dim oRepositoryItem As RepositoryItemLookupControl3 = sender - Dim oLookup As LookupControl3 = Nothing + ' *** WICHTIG: Auch hier globalen Guard setzen *** + _suppressLookupEvents = True + Try + Dim oRepositoryItem As RepositoryItemLookupControl3 = sender + Dim oLookup As LookupControl3 = Nothing - If _LookupControlsByRepository IsNot Nothing Then - _LookupControlsByRepository.TryGetValue(oRepositoryItem, oLookup) - End If + If _LookupControlsByRepository IsNot Nothing Then + _LookupControlsByRepository.TryGetValue(oRepositoryItem, oLookup) + End If - If oLookup Is Nothing Then - oLookup = TryCast(oRepositoryItem.OwnerEdit, LookupControl3) - End If + If oLookup Is Nothing Then + oLookup = TryCast(oRepositoryItem.OwnerEdit, LookupControl3) + End If - If oLookup Is Nothing Then - MyValidationLogger.Warn("onLookUpselectedValue: LookupControl not found for RepositoryItem") - Exit Sub - End If + If oLookup Is Nothing Then + MyValidationLogger.Warn("⚠️ onLookUpselectedValue: LookupControl not found for RepositoryItem") + Exit Sub + End If - LookupControl_DependingControls(oLookup, SelectedValues) - LookupControl_EnablingControls(oLookup, SelectedValues) - LookupControl_DependingColumn(oLookup, SelectedValues) + LookupControl_DependingControls(oLookup, SelectedValues) + LookupControl_EnablingControls(oLookup, SelectedValues) + LookupControl_DependingColumn(oLookup, SelectedValues) + + Finally + _suppressLookupEvents = False + End Try Catch ex As Exception - MyValidationLogger.Warn("Unexpected error in onLookUpselectedValue - " + ex.Message) + MyValidationLogger.Warn("⚠️ Unexpected error in onLookUpselectedValue - " + ex.Message) MyValidationLogger.Error(ex) + _suppressLookupEvents = False ' Sicherheits-Reset End Try End Sub + Private _lookupUpdateDepth As Integer = 0 + Private Const MAX_LOOKUP_DEPTH As Integer = 5 + Public Sub LookupListChanged(sender As Object, SelectedValues As List(Of String)) If _FormLoaded = False Or PanelValidatorControl.Enabled = False Then Exit Sub End If + ' *** GLOBALER GUARD: Blockiert ALLE Lookup-Updates während Verarbeitung *** + If _suppressLookupEvents Then + MyValidationLogger.Debug("LookupListChanged suppressed (global guard active)") + Exit Sub + End If + ' *** DEPTH-GUARD: Verhindert extrem tiefe Rekursionen *** + If _lookupUpdateDepth >= MAX_LOOKUP_DEPTH Then + MyValidationLogger.Warn($"Lookup recursion depth exceeded ({_lookupUpdateDepth}). Aborting.") + Exit Sub + End If Try + _suppressLookupEvents = True ' <-- Globaler Guard aktivieren + _lookupUpdateDepth += 1 Dim oLookup As RepositoryItemLookupControl3 = sender Dim oLookupControl As LookupControl3 = Nothing @@ -1724,8 +1804,11 @@ Public Class frmValidator oMeta.IsDirty = True MyValidationLogger.Debug($"LookupControl [{oMeta.Name}] marked as dirty") listChangedLookup.Add(oLookupControl.Name) + ' *** Cache aktualisieren *** + clsPatterns.UpdateControlInCache(oLookupControl.Name, SelectedValues) Else listChangedLookup.Add(oLookup.Name) + clsPatterns.UpdateControlInCache(oLookup.Name, SelectedValues) End If ControlCreator.GridTables_HandleControlValueChange(PanelValidatorControl, DT_COLUMNS_GRID_WITH_SQL_WITH_CTRL_PLACEHOLDER) @@ -1744,10 +1827,13 @@ Public Class frmValidator Exit For End If Next + Catch ex As Exception MyValidationLogger.Error(ex) + Finally + _lookupUpdateDepth -= 1 + _suppressLookupEvents = False ' <-- Globaler Guard deaktivieren End Try - End Sub Private Sub GridView_CellValueChanged(sender As Object, e As DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs) Dim oView As GridView = sender @@ -1768,6 +1854,8 @@ Public Class frmValidator Dim oMeta As ClassControlCreator.ControlMetadata = oCheckbox.Tag oMeta.IsDirty = True MyValidationLogger.Debug($"CheckBox [{oMeta.Name}] marked as dirty") + ' *** NEU: Cache aktualisieren *** + clsPatterns.UpdateControlInCache(oCheckbox.Name, oCheckbox.Checked) Try CheckBox_DependingControls(oCheckbox) @@ -1855,7 +1943,7 @@ Public Class frmValidator Dim oControlId2Set As Integer 'If Not Integer.TryParse(oControl2Set, oControlId2Set) Then - ' Logger.Warn("Careful: the oControl2Set contains no CONTROL_GUID") + ' LOGGER.Warn("⚠️ Careful: the oControl2Set contains no CONTROL_GUID") ' Exit Sub 'End If @@ -1991,7 +2079,7 @@ Public Class frmValidator Case Else - MyValidationLogger.Warn("SetControlData used on unsupported control") + MyValidationLogger.Warn("⚠️ SetControlData used on unsupported control") End Select @@ -2011,36 +2099,38 @@ Public Class frmValidator Next End Sub Private Sub LookupControl_DependingControls(LookupControl As LookupControl3, SelectedValues As List(Of String)) - Dim oLOOKUPValue = SelectedValues.Item(0 - ) + Dim oLOOKUPValue = SelectedValues.Item(0) Dim oLOOKUPName = LookupControl.Name MyValidationLogger.Debug($"oLOOKUPValue Is [{oLOOKUPValue}]!") + Dim oControlID = DirectCast(LookupControl.Tag, ClassControlCreator.ControlMetadata).Guid Dim oFilteredDatatable As DataTable = DT_CONTROLS.Clone() Dim oExpression = $"SQL_UEBERPRUEFUNG Like '%#CTRL#{oLOOKUPName}%'" DT_CONTROLS.Select(oExpression).CopyToDataTable(oFilteredDatatable, LoadOption.PreserveChanges) + If oFilteredDatatable.Rows.Count > 0 Then MyValidationLogger.Debug($"We got {oFilteredDatatable.Rows.Count} depending controls!!") Else MyValidationLogger.Debug($"Sorry NO depending controls!!") End If + For Each oRowDependingControl As DataRow In oFilteredDatatable.Rows Dim oDEPENDING_GUID = oRowDependingControl.Item("GUID") Dim oDEPENDING_CtrlName = oRowDependingControl.Item("NAME") MyValidationLogger.Debug($"Control {oDEPENDING_CtrlName} is depending on lookUp {oLOOKUPName}..") + If _DependingControl_In_Action = True Then MyValidationLogger.Info($"..but _dependingControl_in_action = True ==> Exit Sub!") Exit Sub End If + If Not IsDBNull(oRowDependingControl.Item("CONNECTION_ID")) And Not IsDBNull(oRowDependingControl.Item("SQL_UEBERPRUEFUNG")) Then Dim oSqlCommand = IIf(IsDBNull(oRowDependingControl.Item("SQL_UEBERPRUEFUNG")), "", oRowDependingControl.Item("SQL_UEBERPRUEFUNG")) oSqlCommand = clsPatterns.ReplaceAllValues(oSqlCommand, PanelValidatorControl, True) _DependingControl_In_Action = True - 'Dim oDTDEPENDING_RESULT As DataTable = ClassDatabase.Return_Datatable_ConId(oSqlCommand, oRowDependingControl.Item("CONNECTION_ID"), $"LookupControl_DependingControls - oControlID: {oControlID}") - 'Dim oDTDEPENDING_RESULT As DataTable = DatabaseFallback.GetDatatable(New GetDatatableOptions(oSqlCommand, DatabaseType.ECM) With { - ' .ConnectionId = oRowDependingControl.Item("CONNECTION_ID") - '}) + Dim oDTDEPENDING_RESULT As DataTable = GetCachedDatatable(oSqlCommand, oRowDependingControl.Item("CONNECTION_ID")) + If Not IsNothing(oDTDEPENDING_RESULT) Then Try Dim oFound As Boolean = False @@ -2049,72 +2139,78 @@ Public Class frmValidator If DirectCast(oControl.Tag, ClassControlCreator.ControlMetadata).Guid = oDEPENDING_GUID Then oFound = True MyValidationLogger.Debug($"Got the depending control ID:{oDEPENDING_GUID}..Setting the values..") - Select Case True - Case oControl.GetType() = GetType(DevExpress.XtraEditors.TextEdit) Or oControl.GetType() = GetType(MemoEdit) - Try - Dim oValue As Object = oDTDEPENDING_RESULT.Rows(0).Item(0) - MyValidationLogger.Debug(String.Format("Setting EditValue with value [{0}]", oValue)) - oValue = ObjectEx.NotNull(Of Object)(oValue, Nothing) + + ' *** WICHTIG: Während Suppress-Modus Updates durchführen *** + Dim wasSuppressed = _suppressLookupEvents + _suppressLookupEvents = True + + Try + Select Case True + Case oControl.GetType() = GetType(DevExpress.XtraEditors.TextEdit) Or oControl.GetType() = GetType(MemoEdit) Try - 'oControl.Text = oValue - DirectCast(oControl, DevExpress.XtraEditors.TextEdit).EditValue = oValue + Dim oValue As Object = oDTDEPENDING_RESULT.Rows(0).Item(0) + MyValidationLogger.Debug(String.Format("Setting EditValue with value [{0}]", oValue)) + oValue = ObjectEx.NotNull(Of Object)(oValue, Nothing) + Try + DirectCast(oControl, DevExpress.XtraEditors.TextEdit).EditValue = oValue + Catch ex As Exception + MyValidationLogger.Warn($"Unexpected error in Checking oTEXT: {ex.Message}") + End Try Catch ex As Exception - MyValidationLogger.Warn($"Unexpected error in Checking oTEXT: {ex.Message}") + MyValidationLogger.Warn($"Unexpected error in Dim oTEXT = oDTDEPENDING_RESULT.Rows(0).Item(0): {ex.Message}") End Try - - Catch ex As Exception - MyValidationLogger.Warn($"Unexpected error in Dim oTEXT = oDTDEPENDING_RESULT.Rows(0).Item(0): {ex.Message}") - End Try - - Dim oColor - Try - oColor = System.Drawing.Color.FromName(oDTDEPENDING_RESULT.Rows(0).Item("BackgroundColor")) - oControl.BackColor = oColor - Catch ex As Exception - oControl.BackColor = Color.White - End Try - Try - Dim btntext = oDTDEPENDING_RESULT.Rows(0).Item("btnFinishCaption") - btnSave.Text = btntext & " (F2)" - Catch ex As Exception - - End Try - Try - oColor = System.Drawing.Color.FromName(oDTDEPENDING_RESULT.Rows(0).Item("btnFinishColor")) - btnSave.BackColor = oColor - Catch ex As Exception - btnSave.BackColor = Color.Transparent - End Try - Case oControl.GetType() = GetType(LookupControl3) - Dim oDependingLookup As LookupControl3 = oControl - oDependingLookup.Properties.DataSource = oDTDEPENDING_RESULT - oDependingLookup.Properties.ValueMember = oDTDEPENDING_RESULT.Columns.Item(0).ColumnName - oDependingLookup.Properties.DisplayMember = oDTDEPENDING_RESULT.Columns.Item(0).ColumnName - Case oControl.GetType() = GetType(GridControl) - 'ClassControlCreator.GridTables - Case oControl.GetType() = GetType(CheckBox) - Try - Dim oCheckState = CBool(oDTDEPENDING_RESULT.Rows(0).Item(0)) - Dim oDependingChk As CheckBox = oControl - oDependingChk.CheckState = oCheckState Dim oColor Try oColor = System.Drawing.Color.FromName(oDTDEPENDING_RESULT.Rows(0).Item("BackgroundColor")) oControl.BackColor = oColor Catch ex As Exception - + oControl.BackColor = Color.White + End Try + Try + Dim btntext = oDTDEPENDING_RESULT.Rows(0).Item("btnFinishCaption") + btnSave.Text = btntext & " (F2)" + Catch ex As Exception + End Try + Try + oColor = System.Drawing.Color.FromName(oDTDEPENDING_RESULT.Rows(0).Item("btnFinishColor")) + btnSave.BackColor = oColor + Catch ex As Exception + btnSave.BackColor = Color.Transparent End Try - Catch ex As Exception - MyValidationLogger.Warn($"Unexpected error in Checking oCheckBoxDependingControlLOOKUP: {ex.Message}") - End Try + Case oControl.GetType() = GetType(LookupControl3) + Dim oDependingLookup As LookupControl3 = oControl + oDependingLookup.Properties.DataSource = oDTDEPENDING_RESULT + oDependingLookup.Properties.ValueMember = oDTDEPENDING_RESULT.Columns.Item(0).ColumnName + oDependingLookup.Properties.DisplayMember = oDTDEPENDING_RESULT.Columns.Item(0).ColumnName + + Case oControl.GetType() = GetType(GridControl) + ' GridControl-Handling + + Case oControl.GetType() = GetType(CheckBox) + Try + Dim oCheckState = CBool(oDTDEPENDING_RESULT.Rows(0).Item(0)) + Dim oDependingChk As CheckBox = oControl + oDependingChk.CheckState = oCheckState + Dim oColor + Try + oColor = System.Drawing.Color.FromName(oDTDEPENDING_RESULT.Rows(0).Item("BackgroundColor")) + oControl.BackColor = oColor + Catch ex As Exception + End Try + Catch ex As Exception + MyValidationLogger.Warn($"Unexpected error in Checking oCheckBoxDependingControlLOOKUP: {ex.Message}") + End Try + End Select + Finally + ' Restore previous state + _suppressLookupEvents = wasSuppressed + End Try - End Select _DependingControl_In_Action = False Exit For End If - Next If oFound = False Then @@ -2127,19 +2223,10 @@ Public Class frmValidator Else MyValidationLogger.Warn($"Datatable for Depending Controls was nothing! Check the SQL [{oSqlCommand}]") End If - - SendKeys.Send("{TAB}") - _ControlHandleStarted = True Else MyValidationLogger.Debug($"Error: Check CoNN ID and SQL on NULL VALUES!") End If - - Next - If oFilteredDatatable.Rows.Count = 1 Then - - - End If End Sub Private Sub CheckBox_DependingControls(pCheckbox As CheckBox) Dim oCheckboxname = pCheckbox.Name @@ -2249,8 +2336,7 @@ Public Class frmValidator MyValidationLogger.Warn($"Error while setting depending control-value for [{oDEPENDING_CtrlName}]: " & ex.Message) _DependingControl_In_Action = False End Try - SendKeys.Send("{TAB}") - _ControlHandleStarted = True + Else MyValidationLogger.Debug($"Error: Check CoNN ID and SQL on NULL VALUES!") End If @@ -2360,6 +2446,8 @@ Public Class frmValidator If oCombobox.SelectedIndex <> -1 And _Indexe_Loaded = True Then Dim oMeta As ClassControlCreator.ControlMetadata = oCombobox.Tag oMeta.IsDirty = True + ' *** NEU: Cache aktualisieren *** + clsPatterns.UpdateControlInCache(oCombobox.Name, oCombobox.Text) MyValidationLogger.Debug($"ComboBox [{oMeta.Name}] marked as dirty") If oCombobox.Name = last_control.Name Then 'Abschluss() @@ -2588,7 +2676,7 @@ Public Class frmValidator Else 'not implemented - MyValidationLogger.Warn("Depending_Control_Set_Result for [{0}] NOT IMPLEMENTED", displayboxname) + MyValidationLogger.Warn("⚠️ Depending_Control_Set_Result for [{0}] NOT IMPLEMENTED", displayboxname) End If Else If oResultTable.Rows.Count = 1 Then @@ -2599,7 +2687,7 @@ Public Class frmValidator End If End If Else - MyValidationLogger.Warn("Result Table is nothing!") + MyValidationLogger.Warn("⚠️ Result Table is nothing!") End If Catch ex As Exception MyValidationLogger.Info("Unexpected Ersror in Depending_Control_Set_Result - ERROR: " & ex.Message) @@ -2771,7 +2859,7 @@ Public Class frmValidator MyValidationLogger.Debug($"Get_Next_GUID: Amount_Docs2Validate [{Amount_Docs2Validate}]...") Catch ex As Exception Amount_Docs2Validate = 0 - MyValidationLogger.Warn("Amount_Docs2Validate Error: " & ex.Message) + MyValidationLogger.Warn("⚠️ Amount_Docs2Validate Error: " & ex.Message) End Try Else MyValidationLogger.Info($">> Attention: GetNextGUID - Could not get the next GUID - SQL [{oSQL}]") @@ -2848,7 +2936,7 @@ Public Class frmValidator Dim oDT As DataTable = DatabaseFallback.GetDatatableECM(oSQL) If oDT Is Nothing OrElse oDT.Rows.Count = 0 Then - MyValidationLogger.Warn("GetDocPathWindows: No result for file paths!") + MyValidationLogger.Warn("⚠️ GetDocPathWindows: No result for file paths!") Return False End If @@ -2907,6 +2995,7 @@ Public Class frmValidator Sub Load_Next_Document(first As Boolean) + Dim oMilliseconts As Double clsPatterns.ClearControlCache() ' Cache-Invalidierung Dim perfStart As DateTime = DateTime.MinValue @@ -2980,7 +3069,7 @@ Public Class frmValidator perfLastCheck = DateTime.Now End If If IsNothing(IDB_DT_DOC_DATA) Then - MyValidationLogger.Warn("ATTENTION: IDB-Data is nothing. Check the IDB_DOC_DATA_SQL Variable Source") + MyValidationLogger.Warn("⚠️ ATTENTION: IDB-Data is nothing. Check the IDB_DOC_DATA_SQL Variable Source") Exit Sub Else If IDB_DT_DOC_DATA.Rows.Count = 1 Then @@ -2993,10 +3082,7 @@ Public Class frmValidator MyValidationLogger.Info($"[PERF LND] Nach CreateWMObject/Load_IDB_DOC_DATA: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now End If - - Dim sql = $"UPDATE TBPM_PROFILE_FILES Set IN_WORK = 1, IN_WORK_WHEN = GETDATE(), WORK_USER = '{USER_USERNAME}' WHERE GUID = {CURRENT_DOC_GUID}" - DatabaseFallback.ExecuteNonQueryECM(sql) - + PRTF_PROFILE_FILES_WORK("InWork") If LOG_HOTSPOTS Then MyValidationLogger.Info($"[PERF LND] Nach IN_WORK-UPDATE: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now @@ -3059,14 +3145,25 @@ Public Class frmValidator End If If LOG_HOTSPOTS Then - MyValidationLogger.Info($"[PERF LND] Nach LoadDocument_DDViewer: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + oMilliseconts = (DateTime.Now - perfLastCheck).TotalMilliseconds + If oMilliseconts > 6000 Then + MyValidationLogger.Warn($"[PERF LND] ⚠️ LoadDocument_DDViewer lasted far to long: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + Else + MyValidationLogger.Info($"[PERF LND] Nach LoadDocument_DDViewer: {oMilliseconts}ms") + End If perfLastCheck = DateTime.Now End If FillIndexValues(first) If LOG_HOTSPOTS Then - MyValidationLogger.Info($"[PERF LND] Nach FillIndexValues: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + oMilliseconts = (DateTime.Now - perfLastCheck).TotalMilliseconds + If oMilliseconts > 6000 Then + MyValidationLogger.Warn($"[PERF LND] ⚠️ FillIndexValues lasted far to long: {oMilliseconts}ms") + Else + MyValidationLogger.Info($"[PERF LND] Nach FillIndexValues: {oMilliseconts}ms") + End If + perfLastCheck = DateTime.Now End If @@ -3182,7 +3279,13 @@ Public Class frmValidator MyValidationLogger.Error(ex) End Try If LOG_HOTSPOTS Then - MyValidationLogger.Info($"[PERF LND] Nach Show_WF_Messages: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + oMilliseconts = (DateTime.Now - perfLastCheck).TotalMilliseconds + If oMilliseconts > 6000 Then + MyValidationLogger.Warn($"[PERF LND] ⚠️ Show_WF_Messages lasted far to long: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + Else + MyValidationLogger.Info($"[PERF LND] Nach Show_WF_Messages: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + End If + perfLastCheck = DateTime.Now End If Controls2B_EnDisabled() @@ -3260,7 +3363,7 @@ Public Class frmValidator End Try If ActiveWorkflowType = ConstAHWorkflow_BlindFile Or PROFILE_SHOW_DOCUMENT = False Then If PROFILE_SHOW_DOCUMENT = False And ActiveWorkflowType <> ConstAHWorkflow_BlindFile Then - MyValidationLogger.Warn("PROFILE_SHOW_DOCUMENT = False - DocumentViewer won't be displayed. Configuration error?") + MyValidationLogger.Warn("⚠️ PROFILE_SHOW_DOCUMENT = False - DocumentViewer won't be displayed. Configuration error?") End If SplitContainer1.Panel2Collapsed = True If Not IsNothing(DocumentViewer1) Then @@ -3280,6 +3383,7 @@ Public Class frmValidator ' Load Document in Document Viewer Dim oFileName = $"{CURRENT_DOC_ID}.{Current_Document.Extension}" If Not IsNothing(DocumentViewer1) Then + MyValidationLogger.Info("LoadDocument_DDViewer - Current_Document.FullPath: " & Current_Document.FullPath) If (OPERATION_MODE_FS = ClassConstants.OpModeFS_PWM Or OPERATION_MODE_FS = ClassConstants.OpModeFS_IDBWM) Then DocumentViewer1.LoadFile_FromPath(Current_Document.FullPath) 'Erstmal auskommentiert @@ -3617,17 +3721,26 @@ Public Class frmValidator Dim oIndexName As String Dim oControName As String Dim oIDBOverride As Boolean = False + Try + ' ========== OPTIMIERUNG 1: Einmalige Gruppierung ========== + Dim columnsByControl As Dictionary(Of Integer, DataTable) = Nothing + If DT_COLUMNS_GRID IsNot Nothing AndAlso DT_COLUMNS_GRID.Rows.Count > 0 Then + columnsByControl = New Dictionary(Of Integer, DataTable)() + + For Each groupRow In DT_COLUMNS_GRID.AsEnumerable().GroupBy(Function(r) r.Field(Of Integer)("CONTROL_ID")) + Dim controlId As Integer = groupRow.Key + Dim dt = groupRow.OrderBy(Function(r) r.Field(Of Integer)("SEQUENCE")).CopyToDataTable() + columnsByControl(controlId) = dt + Next + End If + ' ========== ENDE OPTIMIERUNG ========== + + + If DTVWCONTROL_INDEX.Rows.Count > 0 Then Dim oCount As Integer = 0 For Each oControl As Control In Me.PanelValidatorControl.Controls - 'If SingleAttribute <> "" Then - ' oIDBOverride = True - ' If SingleAttribute <> oControl.Name Then - ' Continue For - ' End If - 'End If - Dim oValueFromSource Dim oFormattedValue As String = "" Dim oControlId = DirectCast(oControl.Tag, ClassControlCreator.ControlMetadata).Guid @@ -3859,8 +3972,17 @@ Public Class frmValidator If LOG_PERF Then PerformanceLogger.Info("FillIndexValues/GridControl") oControlType = "DevExpress.XtraGrid.GridControl" - Dim oMyGridControl As GridControl = oControl - Dim oDTColumnsPerDevExGrid As DataTable = DT_COLUMNS_GRID.Clone() + Dim oMyGridControl As GridControl = oControl ' + ' ========== OPTIMIERUNG: Dictionary-Lookup statt Select() ========== + Dim oDTColumnsPerDevExGrid As DataTable = Nothing + If columnsByControl IsNot Nothing AndAlso columnsByControl.TryGetValue(oControlId, oDTColumnsPerDevExGrid) Then + MyValidationLogger.Debug($"Grid [{oControl.Name}]: {oDTColumnsPerDevExGrid.Rows.Count} Spalten aus Cache geladen") + Else + ' Fallback (sollte nicht auftreten) + oDTColumnsPerDevExGrid = DT_COLUMNS_GRID.Clone() + MyValidationLogger.Warn($"Grid [{oControl.Name}]: Keine Spalten-Definition gefunden!") + End If + ' ========== ENDE OPTIMIERUNG ========== Try If oSourceIndexName = "" Then @@ -3885,8 +4007,8 @@ Public Class frmValidator Select Case oTyp 'Tabellendarstellung Case "TABLE" - Dim oExpression = $"CONTROL_ID = {oControlId}" - DT_COLUMNS_GRID.Select(oExpression, "SEQUENCE").CopyToDataTable(oDTColumnsPerDevExGrid, LoadOption.PreserveChanges) + 'Dim oExpression = $"CONTROL_ID = {oControlId}" + 'DT_COLUMNS_GRID.Select(oExpression, "SEQUENCE").CopyToDataTable(oDTColumnsPerDevExGrid, LoadOption.PreserveChanges) Dim oColValuesfromSource As String() MyValidationLogger.Debug($"DevExpressGrid: {oDTColumnsPerDevExGrid.Rows.Count} Columns configured for control {oControlId}.") @@ -3927,7 +4049,7 @@ Public Class frmValidator End If Catch ex As Exception ' Ausführliches Logging bei Fehlern inkl. aktuell bekannter Metadaten - MyValidationLogger.Warn("Grid row assign FAILED RowIdx = {0}, ColIdx={1}, ColName={2}, ColType={3}, RawValue=[{4}]", + MyValidationLogger.Warn("⚠️ Grid row assign FAILED RowIdx = {0}, ColIdx={1}, ColName={2}, ColType={3}, RawValue=[{4}]", oDataSource.Rows.Count, index, colName, colType, rawValue) MyValidationLogger.Error(ex) ' Optional: weitere Kontexthilfe – z.B. ob Spalte DBNull erlaubt @@ -3951,7 +4073,7 @@ Public Class frmValidator oColValuesfromSource = Split(oValueFromSource.ToString, PMDelimiter) If oColValuesfromSource.Length > 8 Then - MyValidationLogger.Warn("Fill Grid Error - Max 8 columns can be configured!") + MyValidationLogger.Warn("⚠️ Fill Grid Error - Max 8 columns can be configured!") End If Dim oRowData As New List(Of Object) @@ -3993,7 +4115,7 @@ Public Class frmValidator oColValuesfromSource = Split(oRow.Item(0).ToString, PMDelimiter) If oColValuesfromSource.Length > 8 Then - MyValidationLogger.Warn("Fill Grid With DatatableSplit Error - Max 8 columns can be configured!") + MyValidationLogger.Warn("⚠️ Fill Grid With DatatableSplit Error - Max 8 columns can be configured!") End If MyValidationLogger.Debug($"oColValuesfromSource splitted - Length ({oColValuesfromSource.Length.ToString})") Dim oRowData As New List(Of Object) @@ -4050,23 +4172,22 @@ Public Class frmValidator End If End If Try - 'Dim oFilteredDatatable As DataTable = DTGRID_COLUMNS.Clone() - 'Dim oExpression = $"CONTROL_ID = {oControlRow.Item("GUID")}" - 'DTGRID_COLUMNS.Select(oExpression, "SEQUENCE").CopyToDataTable(oFilteredDatatable, LoadOption.PreserveChanges) Dim oMyGridView As DevExpress.XtraGrid.Views.Grid.GridView = oMyGridControl.MainView oMyGridView.OptionsView.ColumnAutoWidth = False - 'AddHandler oMyGridView.ColumnWidthChanged, AddressOf GridControlColumnWidthChanged - For Each oRow As DataRow In oDTColumnsPerDevExGrid.Rows - For Each oActGridColumn As DevExpress.XtraGrid.Columns.GridColumn In oMyGridView.Columns - Dim oGridDXFieldName = oActGridColumn.FieldName - Dim GridDXColumnEditName = oActGridColumn.ColumnEditName - If oRow.Item("SPALTENNAME") = oGridDXFieldName Then - oActGridColumn.Width = oRow.Item("SPALTENBREITE") - Exit For - End If + ' ========== OPTIMIERUNG: Dictionary statt doppelter Loop ========== + If oDTColumnsPerDevExGrid IsNot Nothing AndAlso oDTColumnsPerDevExGrid.Rows.Count > 0 Then + Dim columnsByName = oMyGridView.Columns.Cast(Of GridColumn)().ToDictionary(Function(c) c.FieldName, StringComparer.OrdinalIgnoreCase) + For Each oRow As DataRow In oDTColumnsPerDevExGrid.Rows + Dim columnName = oRow.Item("SPALTENNAME").ToString() + Dim column As GridColumn = Nothing + + If columnsByName.TryGetValue(columnName, column) Then + column.Width = oRow.Item("SPALTENBREITE") + End If Next - Next + End If + ' ========== ENDE OPTIMIERUNG ========== Dim i = 0 ' RestoreDevExpressGridControl_Layout(CURRENT_CLICKED_PROFILE_ID, oControlId, oMyGridView) @@ -4813,7 +4934,7 @@ Public Class frmValidator ' End If 'End If Else - MyValidationLogger.Warn("ATTENTION: DYNAMIC VALUE IS NOTHING!") + MyValidationLogger.Warn("⚠️ ATTENTION: DYNAMIC VALUE IS NOTHING!") Continue For End If End If @@ -4865,7 +4986,7 @@ Public Class frmValidator MyValidationLogger.Debug("...as single indexing") If oValue.ToUpper = "SQL-Command".ToUpper Then MsgBox("Something went wrong while final-indexing. Check Your log and inform the admin-team!", MsgBoxStyle.Critical, ADDITIONAL_TITLE) - MyValidationLogger.Warn("Something went wrong while final-indexing") + MyValidationLogger.Warn("⚠️ Something went wrong while final-indexing") Exit For End If Dim oFIResult As Boolean = False @@ -5119,7 +5240,7 @@ Public Class frmValidator If oErrorOcurred = True Then MsgBox("Unhandled error occured in Finish Workflow-Step...Please check your log!", MsgBoxStyle.Exclamation, ADDITIONAL_TITLE) Else - 'PRTF_PROFILE_FILES_WORK("Worked") + PRTF_PROFILE_FILES_WORK("Worked") MyValidationLogger.Debug("Validation of document ended successfully!") Dim oPROCSQL = $"EXEC PRPM_CHECK_NEXT_WF {CURRENT_DOC_GUID}" If DatabaseFallback.ExecuteNonQueryECM(oPROCSQL) = False Then @@ -5645,7 +5766,7 @@ Public Class frmValidator MyValidationLogger.Error(ex) Dim st As New StackTrace(True) st = New StackTrace(ex, True) - MyValidationLogger.Warn("Unexpected error in Check_UpdateIndexe TextBox :" & ex.Message, True) + MyValidationLogger.Warn("⚠️ Unexpected error in Check_UpdateIndexe TextBox :" & ex.Message, True) OpenfrmError(oErrMsgMissingInput) ' Nach Fehler: Dirty-Flag zurücksetzen @@ -6018,7 +6139,7 @@ Public Class frmValidator Next ' End For Each oControl If oMissing = True Then - MyValidationLogger.Warn("Check_UpdateIndexe: ERROR or Missing Indexing - returning False") + MyValidationLogger.Warn("⚠️ Check_UpdateIndexe: ERROR or Missing Indexing - returning False") Return False Else MyValidationLogger.Debug("Check_UpdateIndexe: Everything OK - returning True") @@ -6290,8 +6411,8 @@ Public Class frmValidator Try MyValidationLogger.Debug("Skipping document....(Datei_ueberspringen)") - - Dim oSQL = $"UPDATE TBPM_PROFILE_FILES SET IN_WORK = 0, IN_WORK_WHEN = NULL, WORK_USER = NULL WHERE GUID = {CURRENT_DOC_GUID};" & vbNewLine & + Dim oPRoc = String.Format("EXEC PRTF_PROFILE_FILES_WORK {0},{1},{2},{3}", CURRENT_DOC_ID, CURRENT_ProfilGUID, USER_ID, "FreeFile") + Dim oSQL = oPRoc & vbNewLine & $"EXECUTE PRPM_FILES_NOT_INDEXED '{USER_USERNAME}',{CURRENT_ProfilGUID},'{WMDocPathWindows}',{CURRENT_DOC_GUID};" DatabaseFallback.ExecuteNonQueryECM(oSQL) @@ -6692,7 +6813,7 @@ Public Class frmValidator Dim oConverter As New PDFConverter(LOGCONFIG) If oConverter.ConvertPDFADocumentToPDFDocument(WMDocPathWindows, oTempFullFilename) = False Then - MyValidationLogger.Warn("File [{0}] could not be converted to plain PDF!", WMDocPathWindows) + MyValidationLogger.Warn("⚠️ File [{0}] could not be converted to plain PDF!", WMDocPathWindows) oFile2Export = WMDocPathWindows Else MyValidationLogger.Info("File [{0}] successfully converted to plain PDF!", oTempFullFilename) @@ -6700,11 +6821,11 @@ Public Class frmValidator oFile2Export = oTempFullFilename End If Else - MyValidationLogger.Warn("No converting as File [{0}] not ending with pdf [{1}]", WMDocPathWindows, oExtension.ToLower) + MyValidationLogger.Warn("⚠️ No converting as File [{0}] not ending with pdf [{1}]", WMDocPathWindows, oExtension.ToLower) oFile2Export = WMDocPathWindows End If Else - MyValidationLogger.Warn("No converting as barbtnitmExport.Tag.ToString <> Convert to PDF") + MyValidationLogger.Warn("⚠️ No converting as barbtnitmExport.Tag.ToString <> Convert to PDF") oFile2Export = WMDocPathWindows End If Else diff --git a/app/TaskFlow/frmValidatorSearch.vb b/app/TaskFlow/frmValidatorSearch.vb index 5b58514..e76a649 100644 --- a/app/TaskFlow/frmValidatorSearch.vb +++ b/app/TaskFlow/frmValidatorSearch.vb @@ -442,7 +442,7 @@ Public Class frmValidatorSearch .ShowSettingButton = True }) Catch ex As Exception - LOGGER.Warn("Error initializing DocViewDocsValdiatorSearch: " & ex.Message) + LOGGER.Warn("⚠️ Error initializing DocViewDocsValdiatorSearch: " & ex.Message) End Try OperationMode = GetOperationMode() @@ -631,7 +631,7 @@ Public Class frmValidatorSearch End If Else - LOGGER.Warn("Attention: RESULT_DOC_PATH is nothing") + LOGGER.Warn("⚠️ Attention: RESULT_DOC_PATH is nothing") End If Catch ex As Exception MsgBox("Unexpected Error in File_SYSOPEN:" & vbNewLine & ex.Message & vbNewLine & RESULT_DOC_PATH & vbNewLine & "DocID: " & DocID, MsgBoxStyle.Critical) diff --git a/app/TaskFlow/taskFLOW.vbproj b/app/TaskFlow/taskFLOW.vbproj index 12fafb7..e3b8c89 100644 --- a/app/TaskFlow/taskFLOW.vbproj +++ b/app/TaskFlow/taskFLOW.vbproj @@ -1078,7 +1078,6 @@ FinalIndexDataSet.xsd - MyApplicationCodeGenerator