From cde1511b753eeda11de780d9fb094f15a1b81293 Mon Sep 17 00:00:00 2001 From: Developer01 Date: Thu, 13 Aug 2026 11:12:58 +0200 Subject: [PATCH] Refactoring und Bugfixes in mehreren Modulen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hinzufügen der `Active`-Eigenschaft in `ModuleControlProperties`, um doppelte Definitionen zu vermeiden. Aktualisierung der Assembly-Version auf `3.3.0.0`. Refactoring in `frmMain`: - Einführung der Methoden `Clean_Up_Workload` und `Add_Workload` zur Verbesserung der Wiederverwendbarkeit und Lesbarkeit. - Entfernen direkter SQL-Logik. Optimierung in `frmValidator`: - Bugfix: Alte Werte in LookupControls werden nicht mehr beibehalten, wenn keine neuen Werte vorhanden sind. - Hinzufügen der Methode `ResetAllLookupSelections`, um LookupControl-Selektionen beim Dokumentwechsel zurückzusetzen. Allgemeine Verbesserungen: - Erweiterung des Loggings für besseres Debugging. - Verbesserte Fehlerbehandlung für robusteren Code. --- app/TaskFlow/ModuleControlProperties.vb | 5 +- app/TaskFlow/My Project/AssemblyInfo.vb | 2 +- app/TaskFlow/frmFormDesigner.vb | 2 +- app/TaskFlow/frmMain.vb | 82 +++++++-------- app/TaskFlow/frmValidator.vb | 128 ++++++++++++++++++++++-- 5 files changed, 165 insertions(+), 54 deletions(-) diff --git a/app/TaskFlow/ModuleControlProperties.vb b/app/TaskFlow/ModuleControlProperties.vb index e293816..34ec7e8 100644 --- a/app/TaskFlow/ModuleControlProperties.vb +++ b/app/TaskFlow/ModuleControlProperties.vb @@ -33,6 +33,8 @@ Public Module ModuleControlProperties Public Property Name() As String + + Public Property Active() As Boolean Public Property Location() As Point @@ -120,9 +122,6 @@ Public Module ModuleControlProperties Private _default_value Friend _set_control_data As String - - Public Property Active() As Boolean - Public Property Required() As Boolean diff --git a/app/TaskFlow/My Project/AssemblyInfo.vb b/app/TaskFlow/My Project/AssemblyInfo.vb index ac13e64..6010457 100644 --- a/app/TaskFlow/My Project/AssemblyInfo.vb +++ b/app/TaskFlow/My Project/AssemblyInfo.vb @@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices ' übernehmen, indem Sie "*" eingeben: ' - + diff --git a/app/TaskFlow/frmFormDesigner.vb b/app/TaskFlow/frmFormDesigner.vb index 140cd55..9fac217 100644 --- a/app/TaskFlow/frmFormDesigner.vb +++ b/app/TaskFlow/frmFormDesigner.vb @@ -589,7 +589,7 @@ Public Class frmFormDesigner obj.Size = New Size(row.Item("WIDTH"), row.Item("HEIGHT")) obj.ChangedAt = ClassAllgemeineFunktionen.NotNullDate(row.Item("CHANGED_WHEN"), Nothing) obj.ChangedWho = ClassAllgemeineFunktionen.NotNullString(row.Item("CHANGED_WHO"), "") - + obj.Active = StrToBool(row.Item("CONTROL_ACTIVE")) Dim oStyle As FontStyle = ClassAllgemeineFunktionen.NotNullString(row.Item("FONT_STYLE"), FontStyle.Regular) Dim oSize As Single = ClassAllgemeineFunktionen.NotNullString(row.Item("FONT_SIZE"), 10) Dim oFamilyString As String = ClassAllgemeineFunktionen.NotNullString(row.Item("FONT_FAMILY"), "Arial") diff --git a/app/TaskFlow/frmMain.vb b/app/TaskFlow/frmMain.vb index d58d3bb..01da54f 100644 --- a/app/TaskFlow/frmMain.vb +++ b/app/TaskFlow/frmMain.vb @@ -2496,9 +2496,6 @@ Public Class frmMain CURRENT_JUMP_DOC_GUID = 0 CURRENT_DOC_GUID = 0 CURRENT_DOC_ID = 0 - CURRENT_ProfilGUID = 0 - CURRENT_CLICKED_PROFILE_ID = 0 - DT_CURR_WF_ITEMS.Clear() End Sub Private Async Function Item_Scope(startedFrom As String) As Task ' ========== FRÜHE VALIDIERUNGEN (VOR UI-ÄNDERUNGEN) ========== @@ -2716,26 +2713,15 @@ Public Class frmMain Exit Function End If - ' ========== DB-OPERATIONEN ========== - 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 - LOGGER.Debug("Adding {0} queued DocIds..", oIds.Count) - - Dim oInsertBatch As New System.Text.StringBuilder() - oInsertBatch.AppendLine("INSERT INTO TBPM_VALIDATION_PROFILE_GROUP_USER ([PROFIL_ID],[DocID],[UserID],[ADDED_WHO]) VALUES") - - For i As Integer = 0 To oIds.Count - 1 - If i > 0 Then oInsertBatch.Append(",") - oInsertBatch.AppendLine($"({CURRENT_CLICKED_PROFILE_ID},{oIds(i)},{USER_ID},'{USER_USERNAME}')") - Next - - ' WICHTIG: Debug-Logging des Batch-Inserts - LOGGER.Debug(String.Format("Batch-Insert {0}", oInsertBatch.ToString)) - - DatabaseFallback.ExecuteNonQueryECM(oInsertBatch.ToString()) + If Clean_Up_Workload() Then + Add_Workload(oIds) + Else + LOGGER.Warn("ItemScope: Failed to clean up workload table") + FormHelper.ShowInfoMessage("ItemScope: Failed to clean up workload table", omsgTitleAttention) + Exit Function End If + + End If CURRENT_JUMP_DOC_GUID = 0 @@ -4775,7 +4761,7 @@ FROM VWPM_PROFILE_ACTIVE T WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_G LOGGER.Debug("ProcessTreeListNodeAsync: TYPE_ID is Nothing/DBNull - Folder node, skipping") Exit Function End If - + CURRENT_CLICKED_PROFILE_ID = 0 RibbonPageGroup7.Visible = False FRONTEND_ACTION = NAVBAR_CLICKED @@ -4816,7 +4802,7 @@ FROM VWPM_PROFILE_ACTIVE T WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_G ' ✅ NEU: Verifizieren Sie die Zuweisung LOGGER.Debug($"TreeList_Cockpit: COCKPIT_PROFILE_SQL after assignment: [{COCKPIT_PROFILE_SQL}]") LOGGER.Debug($"TreeList_Cockpit: COCKPIT_PROFILE_SQL.Length = [{COCKPIT_PROFILE_SQL.Length}]") - CURRENT_CLICKED_PROFILE_ID = 0 + CUSTOM_OVERVIEW_SQL = oSqlQuery.ToString() _lastUsedOverviewSQL = CUSTOM_OVERVIEW_SQL ' ← SQL merken BEVOR es gelöscht wird @@ -5078,6 +5064,31 @@ FROM VWPM_PROFILE_ACTIVE T WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_G LOGGER.Error(ex) End Try End Sub + Private Function Clean_Up_Workload() As Boolean + LOGGER.Debug("TreeList_Cockpit_DoubleClick: Cleaning up queued DocIds...") + Dim oDelete = $"DELETE FROM TBPM_VALIDATION_PROFILE_GROUP_USER WHERE UserID = {USER_ID}" + Return DatabaseFallback.ExecuteNonQueryECM(oDelete) + End Function + + Private Function Add_Workload(pIds As List(Of Integer)) + If pIds Is Nothing OrElse pIds.Count = 0 Then + LOGGER.Warn("Add_Workload: pIds is Nothing or empty - skipping insert") + Return False + End If + LOGGER.Debug("Adding {0} queued DocIds..", pIds.Count) + + Dim oInsertBatch As New System.Text.StringBuilder() + oInsertBatch.AppendLine("INSERT INTO TBPM_VALIDATION_PROFILE_GROUP_USER ([PROFIL_ID],[DocID],[UserID],[ADDED_WHO]) VALUES") + + For i As Integer = 0 To pIds.Count - 1 + If i > 0 Then oInsertBatch.Append(",") + oInsertBatch.AppendLine($"({CURRENT_CLICKED_PROFILE_ID},{pIds(i)},{USER_ID},'{USER_USERNAME}')") + Next + + ' WICHTIG: Debug-Logging des Batch-Inserts + LOGGER.Debug(String.Format("Batch-Insert {0}", oInsertBatch.ToString)) + DatabaseFallback.ExecuteNonQueryECM(oInsertBatch.ToString()) + End Function Private Async Sub TreeList_Cockpit_DoubleClick(sender As Object, e As EventArgs) Handles TreeList_Cockpit.DoubleClick Try @@ -5094,7 +5105,7 @@ FROM VWPM_PROFILE_ACTIVE T WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_G End If Dim oTypeIdInt As Integer = CInt(oTypeId) - + CURRENT_CLICKED_PROFILE_ID = 0 ' Nur bei Profil-Knoten (TYPE_ID = 1) Validator öffnen If oTypeIdInt = 1 Then Dim oFkProfileId As Object = oFocusedNode.GetValue("FK_PROFILE_ID") @@ -5170,22 +5181,13 @@ FROM VWPM_PROFILE_ACTIVE T WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_G End If ' ===== DB-OPERATIONEN: TABELLE LEEREN UND NEU BEFÜLLEN ===== - LOGGER.Debug("TreeList_Cockpit_DoubleClick: Cleaning up queued DocIds...") - Dim oDelete = $"DELETE FROM TBPM_VALIDATION_PROFILE_GROUP_USER WHERE UserID = {USER_ID}" - If DatabaseFallback.ExecuteNonQueryECM(oDelete) = True Then - LOGGER.Debug($"TreeList_Cockpit_DoubleClick: Adding [{oIds.Count}] queued DocIds...") - - Dim oInsertBatch As New System.Text.StringBuilder() - oInsertBatch.AppendLine("INSERT INTO TBPM_VALIDATION_PROFILE_GROUP_USER ([PROFIL_ID],[DocID],[UserID],[ADDED_WHO]) VALUES") - - For i As Integer = 0 To oIds.Count - 1 - If i > 0 Then oInsertBatch.Append(",") - oInsertBatch.AppendLine($"({oProfileId},{oIds(i)},{USER_ID},'{USER_USERNAME}')") - Next - - LOGGER.Debug($"TreeList_Cockpit_DoubleClick: Batch-Insert SQL: {oInsertBatch.ToString()}") - DatabaseFallback.ExecuteNonQueryECM(oInsertBatch.ToString()) + If Clean_Up_Workload() Then + Add_Workload(oIds) + Else + LOGGER.Warn("TreeList_Cockpit_DoubleClick: Failed to clean up workload table") + FormHelper.ShowInfoMessage("TreeList_Cockpit_DoubleClick: Failed to clean up workload table", omsgTitleAttention) + Exit Sub End If ' ===== VALIDATOR IM GRUPPEN-MODUS ÖFFNEN ===== diff --git a/app/TaskFlow/frmValidator.vb b/app/TaskFlow/frmValidator.vb index 7b0a6e4..ddf6d61 100644 --- a/app/TaskFlow/frmValidator.vb +++ b/app/TaskFlow/frmValidator.vb @@ -5696,18 +5696,17 @@ Public Class frmValidator oNewValues = New List(Of String) From {oValueFromSource.ToString} End If Else - ' ========== BUGFIX START: Wenn KEIN neuer Wert, alte Werte behalten ========== - If hadPreviousLUSelection AndAlso previousLUSelectedValues IsNot Nothing AndAlso previousLUSelectedValues.Count > 0 Then - MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: Kein neuer Wert von Quelle → alte Werte BEHALTEN") - oNewValues = previousLUSelectedValues - ElseIf oDefaultValue <> String.Empty Then - MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: Verwende DefaultValue = [{oDefaultValue}]") + ' ========== BUGFIX START: Wenn KEIN neuer Wert, SelectedValues LÖSCHEN ========== + If oDefaultValue <> String.Empty Then + MyValidationLogger.Debug($"[FillIndexValues] Lookup [{oLookupMeta.Name}]: Verwende DefaultValue = [{oDefaultValue}]") oNewValues = oDefaultValue.Split(",").ToList() Else - MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: KEINE Werte!") + ' WICHTIG: Keine alten Werte mehr übernehmen! → oNewValues bleibt Nothing + MyValidationLogger.Debug($"[FillIndexValues] Lookup [{oLookupMeta.Name}]: Kein Index-Wert vorhanden → SelectedValues werden gelöscht") + oNewValues = Nothing End If - ' ========== BUGFIX END: Wert-Beibehaltung ========== - End If + ' ========== BUGFIX END: Alte Werte werden NICHT mehr beibehalten ========== + End If ' ========== KRITISCH: DataSource-Backup erstellen BEVOR SelectedValues gelöscht wird ========== Dim savedDataSource = oLookup.Properties.DataSource @@ -8517,6 +8516,11 @@ Public Class frmValidator ' ========== WICHTIG: State-Variablen zurücksetzen vor neuem Dokument ========== previousLUSelectedValues = Nothing hadPreviousLUSelection = False + ' ========== NEU: LookupControl-Selektionen SOFORT zurücksetzen ========== + If LOG_HOTSPOTS Then + MyValidationLogger.Info("[RESET] Lösche alle LookupControl-Selektionen vor Dokumentwechsel") + End If + ResetAllLookupSelections() If LOG_HOTSPOTS Then ' ========== DIAGNOSE START ========== @@ -8577,7 +8581,113 @@ Public Class frmValidator Cursor = Cursors.Default End Sub + ''' + ''' Setzt alle LookupControl3-Selektionen zurück (kritisch für Dokumentwechsel) + ''' + Private Sub ResetAllLookupSelections() + Try + ' Temporär Lookup-Events unterdrücken während Reset + Dim oldSuppressState As Boolean = _suppressLookupEvents + _suppressLookupEvents = True + If LOG_HOTSPOTS Then + MyValidationLogger.Info("[RESET] ResetAllLookupSelections START") + End If + + ' Durchlaufe alle Controls im Form (Me.Controls statt pnlMain) + If Not Me.IsDisposed Then + For Each ctrl As Control In Me.Controls + ResetLookupControlRecursive(ctrl) + Next + End If + + ' Falls LookupControls separat gecacht sind + If _CachedLookupControlsByRepository IsNot Nothing Then + For Each kvp In _CachedLookupControlsByRepository.ToList() + Try + If kvp.Value IsNot Nothing AndAlso Not kvp.Value.IsDisposed Then + If LOG_HOTSPOTS AndAlso kvp.Value.Properties.SelectedValues IsNot Nothing AndAlso kvp.Value.Properties.SelectedValues.Count > 0 Then + MyValidationLogger.Info($"[RESET] Lookup [{kvp.Value.Name}]: SelectedValues = {String.Join(",", kvp.Value.Properties.SelectedValues)} → wird gelöscht") + End If + kvp.Value.Properties.SelectedValues = New List(Of String)() + End If + Catch ex As Exception + ' Einzelnes Control ignorieren bei Fehler + If LOG_HOTSPOTS Then + MyValidationLogger.Warn($"[RESET] Fehler bei Lookup-Reset: {ex.Message}") + End If + End Try + Next + End If + + ' Zusätzlich: Controls aus Cache durchgehen + If _CachedControlsByGuid IsNot Nothing Then + For Each kvp In _CachedControlsByGuid.ToList() + Try + If TypeOf kvp.Value Is LookupControl3 Then + Dim lookup As LookupControl3 = DirectCast(kvp.Value, LookupControl3) + If Not lookup.IsDisposed AndAlso lookup.Properties.SelectedValues IsNot Nothing AndAlso lookup.Properties.SelectedValues.Count > 0 Then + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[RESET] Lookup aus Cache [{lookup.Name}]: SelectedValues = {String.Join(",", lookup.Properties.SelectedValues)} → wird gelöscht") + End If + lookup.Properties.SelectedValues = New List(Of String)() + End If + End If + Catch ex As Exception + ' Einzelnes Control ignorieren + If LOG_HOTSPOTS Then + MyValidationLogger.Warn($"[RESET] Fehler bei Cache-Reset: {ex.Message}") + End If + End Try + Next + End If + + If LOG_HOTSPOTS Then + MyValidationLogger.Info("[RESET] ResetAllLookupSelections ENDE") + End If + + ' Restore suppress state + _suppressLookupEvents = oldSuppressState + + Catch ex As Exception + MyValidationLogger.Error($"[ERROR] ResetAllLookupSelections: {ex.Message}") + MyValidationLogger.Error($"[ERROR] StackTrace: {ex.StackTrace}") + ' Event-Unterdrückung auf jeden Fall zurücksetzen + _suppressLookupEvents = False + End Try + End Sub + + ''' + ''' Rekursive Hilfsmethode zum Finden und Zurücksetzen von LookupControls + ''' + Private Sub ResetLookupControlRecursive(parent As Control) + If parent Is Nothing OrElse parent.IsDisposed Then Return + + Try + ' Prüfe ob es ein LookupControl3 ist + If TypeOf parent Is LookupControl3 Then + Dim lookup As LookupControl3 = DirectCast(parent, LookupControl3) + If lookup.Properties.SelectedValues IsNot Nothing AndAlso lookup.Properties.SelectedValues.Count > 0 Then + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[RESET] Lookup [{lookup.Name}]: SelectedValues = {String.Join(",", lookup.Properties.SelectedValues)} → wird gelöscht") + End If + lookup.Properties.SelectedValues = New List(Of String)() + End If + End If + + ' Rekursiv durch Child-Controls + If parent.HasChildren Then + For Each child As Control In parent.Controls + ResetLookupControlRecursive(child) + Next + End If + Catch ex As Exception + ' Fehler bei einzelnem Control ignorieren + If LOG_HOTSPOTS Then + MyValidationLogger.Warn($"[RESET] Fehler bei Control [{parent.Name}]: {ex.Message}") + End If + End Try + End Sub Private Sub bbtniDelete_ItemClick(sender As Object, e As ItemClickEventArgs) Handles bbtniDelete.ItemClick If ForceGridValidation() = True Then delete_active_File()