From de4f348be5ee731ea0123a59066b3ef6fc3f771e Mon Sep 17 00:00:00 2001 From: Developer01 Date: Tue, 11 Aug 2026 14:53:26 +0200 Subject: [PATCH] Verbesserung von Validierungen und State-Management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Änderungen umfassen: - Hinzufügen der Methode `Reset_Current` in `frmMain` zur zentralisierten Rücksetzung von Zuständen. - Erweiterung von `Item_Scope` mit Validierungen für ungültige Klicks und Fallback-Logik bei DevExpress-Bugs. - Verbesserte Fehlerbehandlung und Validierungen im `DoubleClick`- und `MouseDown`-Handler. - Einführung der Methode `ParseColorString` zur sicheren Verarbeitung von Farbwerten. - Optimierung von `TreeList_Cockpit_DoubleClick` mit Debugging-Logs und State-Reset. - Hinzufügen von State-Reset-Logik in `frmValidator` (`previousLUSelectedValues`, `hadPreviousLUSelection`). - Verbesserte Sicherung und Wiederherstellung von Lookup-Werten in `FillIndexValues`. - SQL-Optimierung: Löschen von Einträgen in `TBTF_PROFILE_FILES_WORK`. - Erweiterte Debugging-Informationen und Fehlerbehandlung in mehreren Methoden. --- app/TaskFlow/frmMain.vb | 154 +++++++++++++++++++++++++++++++---- app/TaskFlow/frmValidator.vb | 68 ++++++++-------- 2 files changed, 174 insertions(+), 48 deletions(-) diff --git a/app/TaskFlow/frmMain.vb b/app/TaskFlow/frmMain.vb index e5fea63..6957164 100644 --- a/app/TaskFlow/frmMain.vb +++ b/app/TaskFlow/frmMain.vb @@ -2492,6 +2492,14 @@ Public Class frmMain End If End Try End Sub + Private Sub Reset_Current() + 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) ========== If Application.OpenForms().OfType(Of frmValidator).Any Then @@ -2514,16 +2522,33 @@ Public Class frmMain Try LOGGER.Info("Starting Profile Loading") + Reset_Current() ' ========== UI-VORBEREITUNG ========== Me.UseWaitCursor = True useWaitCursorApplied = True bsiMessage.Caption = "Processing selection..." messageApplied = True - ' ========== HITINFO NUR EINMAL BERECHNEN ========== Dim hitInfo As GridHitInfo = GridViewWorkflows.CalcHitInfo(GridCursorLocation) + ' ===== FRÜHE VALIDIERUNG: UNGÜLTIGE ROWHANDLES ABFANGEN ===== + If hitInfo.RowHandle = DevExpress.XtraGrid.GridControl.InvalidRowHandle Then + LOGGER.Warn($"⚠️ Item_Scope: InvalidRowHandle detected (click on empty grid area?) - exiting") + Exit Function + End If + + ' ===== ZUSÄTZLICH: Prüfen ob überhaupt eine Zeile getroffen wurde ===== + If Not hitInfo.InRow Then + LOGGER.Warn($"⚠️ Item_Scope: Click not in any row (HitTest:[{hitInfo.HitTest}]) - exiting") + Exit Function + End If + + ' ===== STARTEDROM NORMALISIEREN ===== + If startedFrom = "DOUBLECLICK" Then + startedFrom = If(hitInfo.InGroupRow, "CMGROUP", "CMROW") + LOGGER.Debug($"User clicked {If(hitInfo.InGroupRow, "group", "normal")} row.") + End If ' ========== STARTEDROM NORMALISIEREN ========== If startedFrom = "DOUBLECLICK" Then startedFrom = If(hitInfo.InGroupRow, "CMGROUP", "CMROW") @@ -2531,21 +2556,56 @@ Public Class frmMain End If ' ========== PROFIL-ID ERMITTELN (OPTIMIERT) ========== + ' ========== PROFIL-ID ERMITTELN (MIT FALLBACK-LOGIK) ========== Dim oHitProfilID As Object = Nothing + + ' ===== SCHRITT 1: Direkte Erkennung versuchen ===== If hitInfo.InGroupRow Then + ' ✅ Gruppenkopf: Profil-ID aus erster Datenzeile der Gruppe oHitProfilID = GridViewWorkflows.GetRowCellValue( GridViewWorkflows.GetDataRowHandleByGroupRowHandle(hitInfo.RowHandle), GridViewWorkflows.Columns("PROFILE_ID")) + LOGGER.Debug("Clicked on Group Row") + ElseIf hitInfo.InDataRow Then + ' ✅ Normale Datenzeile: Profil-ID direkt aus dieser Zeile oHitProfilID = GridViewWorkflows.GetRowCellValue( - GridViewWorkflows.GetDataRowHandleByGroupRowHandle( - GridViewWorkflows.GetParentRowHandle(hitInfo.RowHandle)), + hitInfo.RowHandle, GridViewWorkflows.Columns("PROFILE_ID")) + LOGGER.Debug("Clicked on Data Row") + + Else + ' ===== SCHRITT 2: FALLBACK für "unklare" Klicks ===== + ' Wenn hitInfo weder InGroupRow noch InDataRow ist, RowHandle direkt prüfen + LOGGER.Warn($"⚠️ hitInfo ist WEDER InGroupRow noch InDataRow - RowHandle:[{hitInfo.RowHandle}]") + + If GridViewWorkflows.IsGroupRow(hitInfo.RowHandle) Then + ' Es ist doch eine Gruppe (DevExpress Bug-Workaround) + LOGGER.Debug("Fallback: IsGroupRow(RowHandle) = True") + oHitProfilID = GridViewWorkflows.GetRowCellValue( + GridViewWorkflows.GetDataRowHandleByGroupRowHandle(hitInfo.RowHandle), + GridViewWorkflows.Columns("PROFILE_ID")) + + ElseIf GridViewWorkflows.IsDataRow(hitInfo.RowHandle) Then + ' Es ist doch eine Datenzeile (DevExpress Bug-Workaround) + LOGGER.Debug("Fallback: IsDataRow(RowHandle) = True") + oHitProfilID = GridViewWorkflows.GetRowCellValue( + hitInfo.RowHandle, + GridViewWorkflows.Columns("PROFILE_ID")) + + Else + LOGGER.Error($"⚠️ RowHandle [{hitInfo.RowHandle}] ist weder Group noch DataRow!") + End If End If LOGGER.Debug("Clicked ProfileId: [{0}], Started From: [{1}]", oHitProfilID, startedFrom) - - ' ========== PROFIL-ID VALIDIERUNG UND UPDATE ========== + ' ========== PROFIL-ID VALIDIERUNG ========== + If oHitProfilID Is Nothing OrElse Not IsNumeric(oHitProfilID) OrElse CInt(oHitProfilID) = 0 Then + LOGGER.Warn("⚠️ Item_Scope: Could not determine valid PROFILE_ID from clicked row!") + FormHelper.ShowInfoMessage("Konnte keine gültige Profil-ID ermitteln!", omsgTitleWarning) + Exit Function + End If + ' ========== PROFIL-ID UPDATE ========== If oHitProfilID IsNot Nothing AndAlso IsNumeric(oHitProfilID) AndAlso CInt(oHitProfilID) > 0 Then If oHitProfilID <> CURRENT_CLICKED_PROFILE_ID Then LOGGER.Debug($"Item_Scope: oHitProfilID {oHitProfilID} <> CURRENT_CLICKED_PROFILE_ID {CURRENT_CLICKED_PROFILE_ID}") @@ -2748,9 +2808,7 @@ Public Class frmMain If hitInfo.InGroupRow OrElse (startedFrom = "CMGROUP" AndAlso hitInfo.InDataRow) Then ' GRUPPE: Workflow ohne spezifisches Dokument - CURRENT_JUMP_DOC_GUID = 0 - CURRENT_DOC_GUID = 0 - CURRENT_DOC_ID = 0 + Reset_Current() CURRENT_ProfilGUID = CURRENT_CLICKED_PROFILE_ID LOGGER.Debug($"Item_Scope: hitInfo.InGroupRow...CURRENT_CLICKED_PROFILE_ID [{CURRENT_CLICKED_PROFILE_ID}]") Load_Profil_from_Grid(CURRENT_CLICKED_PROFILE_ID) @@ -3315,9 +3373,38 @@ Public Class frmMain End Function 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 + Try + ' ===== KRITISCH: HitInfo MIT AKTUELLEM Mauszeiger-Position berechnen ===== + Dim oCurrentMousePosition As System.Drawing.Point = GridControlWorkflows.PointToClient(Cursor.Position) + Dim hitInfo As GridHitInfo = GridViewWorkflows.CalcHitInfo(oCurrentMousePosition) + + ' ===== FRÜHE VALIDIERUNG ===== + If hitInfo.RowHandle = DevExpress.XtraGrid.GridControl.InvalidRowHandle Then + LOGGER.Warn("⚠️ DoubleClick: InvalidRowHandle - ignoring") + Exit Sub + End If + + If Not hitInfo.InRow Then + LOGGER.Warn("⚠️ DoubleClick: Not in row - ignoring") + Exit Sub + End If + + ' ===== AKTUALISIERTE GridCursorLocation SETZEN ===== + GridCursorLocation = oCurrentMousePosition + + LOGGER.Debug($"DoubleClick: RowHandle=[{hitInfo.RowHandle}], InGroupRow=[{hitInfo.InGroupRow}], InDataRow=[{hitInfo.InDataRow}]") + + Me.Cursor = Cursors.WaitCursor + Try + Await Item_Scope("DOUBLECLICK") + Finally + Me.Cursor = Cursors.Default + End Try + + Catch ex As Exception + LOGGER.Error(ex) + Me.Cursor = Cursors.Default + End Try End Sub 'Private Sub GridViewWorkflows_CustomDrawGroupRow(sender As Object, e As Views.Base.RowObjectCustomDrawEventArgs) Handles GridViewWorkflows.CustomDrawGroupRow @@ -3372,7 +3459,6 @@ Public Class frmMain Private Sub GridViewWorkflows_CustomDrawGroupRow(sender As Object, e As Views.Base.RowObjectCustomDrawEventArgs) Handles GridViewWorkflows.CustomDrawGroupRow Try - If FormOpenClose = True And GridIsLoaded = False Then Exit Sub End If @@ -3387,11 +3473,27 @@ Public Class frmMain If oInfo.Column.FieldName = "GROUP_TEXT" Then oInfo.GroupText = oInfo.GroupValueText + ' ===== PRÜFUNG AUF KINDERZEILEN HINZUFÜGEN ===== + Dim oChildCount As Integer = oView.GetChildRowCount(oInfo.RowHandle) + + ' Wenn keine Kinder vorhanden sind, Standard-Farben verwenden + If oChildCount = 0 Then + LOGGER.Debug($"CustomDrawGroupRow: Group [{oInfo.GroupValueText}] has no children - using default colors") + oInfo.Appearance.BackColor = Color.LightGray + oInfo.Appearance.ForeColor = Color.Black + Exit Sub + End If + + ' ===== NUR BEI VORHANDENEN KINDERN FARBE AUSLESEN ===== Dim oColorString As String = "LightGray" Dim oFontColorString As String = "Black" Dim oChildRowHandle As Integer = oView.GetChildRowHandle(oInfo.RowHandle, 0) - oColorString = oView.GetRowCellValue(oChildRowHandle, "GROUP_COLOR") + ' GetRowCellValue kann Nothing zurückgeben, daher absichern + Dim oCellValue As Object = oView.GetRowCellValue(oChildRowHandle, "GROUP_COLOR") + If oCellValue IsNot Nothing AndAlso Not IsDBNull(oCellValue) Then + oColorString = oCellValue.ToString() + End If Dim oColor As Color = ParseColorString(oColorString, Color.LightGray, "Background Color") Dim oFontColor As Color = ParseColorString(oFontColorString, Color.Black, "Font Color") @@ -3405,6 +3507,11 @@ Public Class frmMain End Sub Private Function ParseColorString(ColorString As String, DefaultColor As Color, ColorDescription As String) As Color + ' ===== NULL-CHECK HINZUFÜGEN ===== + If String.IsNullOrWhiteSpace(ColorString) Then + LOGGER.Debug($"ParseColorString: ColorString is null/empty for {ColorDescription} - using default color") + Return DefaultColor + End If Dim oResultColor As Color If ColorString.Contains(";") Or ColorString.Contains(".") Then @@ -3439,6 +3546,17 @@ Public Class frmMain Dim view As GridView = sender Dim hi As GridHitInfo = view.CalcHitInfo(e.Location) Dim groupRowButtonClicked = (hi.HitTest = GridHitTest.RowGroupButton) + ' ===== UNGÜLTIGE CLICKS ABFANGEN ===== + If hi.RowHandle = DevExpress.XtraGrid.GridControl.InvalidRowHandle Then + LOGGER.Debug("MouseDown: InvalidRowHandle - ignoring click") + Exit Sub + End If + + If Not hi.InRow Then + LOGGER.Debug($"MouseDown: Click not in row (HitTest:[{hi.HitTest}]) - ignoring") + Exit Sub + End If + GridCursorLocation = e.Location 'If e.Button = MouseButtons.Left Then @@ -3449,18 +3567,21 @@ Public Class frmMain GridViewItem_Clicked = "GROUP" If Not Application.OpenForms().OfType(Of frmValidator).Any Then CURRENT_CLICKED_PROFILE_ID = GridViewWorkflows.GetRowCellValue(GridViewWorkflows.GetDataRowHandleByGroupRowHandle(hi.RowHandle), GridViewWorkflows.Columns("PROFILE_ID")) + LOGGER.Debug($"MouseDown: PROFILE_ID for GroupRow [{hi.RowHandle}] is [{CURRENT_CLICKED_PROFILE_ID}]") End If ElseIf hi.InDataRow Then GridViewItem_Clicked = "ROW" If Not Application.OpenForms().OfType(Of frmValidator).Any Then CURRENT_CLICKED_PROFILE_ID = GridViewWorkflows.GetRowCellValue(GridViewWorkflows.GetDataRowHandleByGroupRowHandle(hi.RowHandle), GridViewWorkflows.Columns("PROFILE_ID")) + LOGGER.Debug($"MouseDown: PROFILE_ID for DataRow [{hi.RowHandle}] is [{CURRENT_CLICKED_PROFILE_ID}]") End If Else GridViewItem_Clicked = Nothing If hi.HitTest = GridHitTest.FilterPanelCloseButton Then Ev_Filter_Panel_Closed = True + LOGGER.Debug("MouseDown: FilterPanelCloseButton clicked - Ev_Filter_Panel_Closed set to True") Grid_Reset_Filter() Ev_Filter_Panel_Closed = False End If @@ -3471,6 +3592,7 @@ Public Class frmMain For Each orow As DataRow In CURRENT_DT_PROFILES.Rows If orow.Item("GUID") = CURRENT_CLICKED_PROFILE_ID Then If Not Application.OpenForms().OfType(Of frmValidator).Any Then + LOGGER.Debug($"MouseDown: PROFILE_TITLE for PROFILE_ID [{CURRENT_CLICKED_PROFILE_ID}] is [{orow.Item("TITLE")}]") CURRENT_CLICKED_PROFILE_TITLE = orow.Item("TITLE") End If @@ -4972,10 +5094,10 @@ FROM VWPM_PROFILE_ACTIVE T WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_G Dim oProfileId As Integer = CInt(oFkProfileId) LOGGER.Debug($"TreeList_Cockpit_DoubleClick: Opening validator for profile ID [{oProfileId}]") - + Reset_Current() ' ===== PROFIL-DATEN INS GRID LADEN (FALLS NOCH NICHT GELADEN) ===== ' Wenn das Grid aktuell leer ist oder ein anderes Profil zeigt, müssen wir erst laden - If GRID_LOAD_TYPE <> $"PROFILE#{oProfileId}" OrElse DT_CURR_WF_ITEMS Is Nothing OrElse DT_CURR_WF_ITEMS.Rows.Count = 0 Then + If DT_CURR_WF_ITEMS Is Nothing OrElse DT_CURR_WF_ITEMS.Rows.Count = 0 Then LOGGER.Debug($"TreeList_Cockpit_DoubleClick: Grid does not show profile [{oProfileId}] - loading it first") CURRENT_CLICKED_PROFILE_ID = oProfileId @@ -5001,6 +5123,8 @@ FROM VWPM_PROFILE_ACTIVE T WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_G FormHelper.ShowInfoMessage(omsg, omsgTitleAttention) Exit Sub End If + Else + LOGGER.Debug($"TreeList_Cockpit_DoubleClick: Grid already shows profile [{CURRENT_CLICKED_PROFILE_ID}] with [{DT_CURR_WF_ITEMS.Rows.Count}] items") End If ' ===== DOCIDS AUS DT_CURR_WF_ITEMS SAMMELN ===== diff --git a/app/TaskFlow/frmValidator.vb b/app/TaskFlow/frmValidator.vb index 03f896a..7b0a6e4 100644 --- a/app/TaskFlow/frmValidator.vb +++ b/app/TaskFlow/frmValidator.vb @@ -142,11 +142,12 @@ Public Class frmValidator Private _overlayLock As New Object() ' ← NEU: Thread-Safe Lock Private _documentPathHandler As DocumentPathHandler Private _isLoadingAdditionalSearches As Boolean = False - Private _separateGridDataCache As New Dictionary(Of String, DataTable) ' Bei den anderen Private-Deklarationen: Private _separateGridControlCache As New Dictionary(Of String, GridControl) - + ' ========== BUGFIX START: Alte SelectedValues SICHERN bevor DataSource überschrieben wird ========== + Private previousLUSelectedValues As List(Of String) = Nothing + Private hadPreviousLUSelection As Boolean = False Private Class Translation_Strings Inherits My.Resources.frmValidator_Strings @@ -816,9 +817,9 @@ Public Class frmValidator End If Try - Dim oSQL As String - oSQL = $"DELETE FROM TBPM_DOCWALKOVER WHERE UserID = {USER_ID};" & vbCrLf & - $"DELETE FROM TBPM_VALIDATION_PROFILE_GROUP_USER WHERE UserID = {USER_ID};" + Dim oSQL = $"DELETE FROM TBPM_DOCWALKOVER WHERE UserID = {USER_ID};" & vbCrLf & + $"DELETE FROM TBPM_VALIDATION_PROFILE_GROUP_USER WHERE UserID = {USER_ID};" & vbCrLf & + $"DELETE FROM TBTF_PROFILE_FILES_WORK WHERE Action_UserID = {USER_ID};" DatabaseFallback.ExecuteNonQueryECM(oSQL) Catch ex As Exception MyValidationLogger.Error(ex) @@ -903,6 +904,9 @@ Public Class frmValidator If Not IsNothing(DT_AdditionalSearches_Resultset_Docs) Then DT_AdditionalSearches_Resultset_Docs.Clear() End If + ' Lookup-State zurücksetzen + previousLUSelectedValues = Nothing + hadPreviousLUSelection = False End Sub Private Sub CleanupTempFolder() @@ -1788,7 +1792,9 @@ Public Class frmValidator End If End Select Next - + ' Lookup-State zurücksetzen + previousLUSelectedValues = Nothing + hadPreviousLUSelection = False Focus_FirstControl() End Sub @@ -3799,7 +3805,7 @@ Public Class frmValidator oBIT = 1 End If Dim oSQL = $"EXEC PRPM_GET_NEXT_DOC_INFO {CURRENT_ProfilGUID},{CURRENT_DOC_ID},{USER_ID}" - + MyValidationLogger.Debug($"Get_Next_GUID: SQL [{oSQL}]...") Dim oDT As DataTable = DatabaseFallback.GetDatatableECM(oSQL) CURRENT_DOC_ID = 0 CURRENT_DOC_GUID = 0 @@ -3808,7 +3814,7 @@ Public Class frmValidator oNewGUID = oDT.Rows(0).Item(0) MyValidationLogger.Info($"Get_Next_GUID: oNewGUID [{oNewGUID}]...") Catch ex As Exception - MyValidationLogger.Warn($"⚠️ >> Attention: in GetNextGUID - Could not get the next GUID - SQL [{oSQL}]") + MyValidationLogger.Warn($"⚠️ Attention: in GetNextGUID - Could not get the next GUID - SQL [{oSQL}]") MyValidationLogger.Warn($"⚠️ ERRORMESSAGE [{ex.Message}]") End Try @@ -4053,7 +4059,9 @@ Public Class frmValidator MyValidationLogger.Info($"LOG_HOTSPOTS - CURRENT_DOC_GUID: {CURRENT_DOC_GUID}") ' ========== ENDE DIAGNOSE ========== End If - + ' State-Variablen zurücksetzen beim Laden eines neuen Dokuments + previousLUSelectedValues = Nothing + hadPreviousLUSelection = False Dim oMilliseconts As Double clsPatterns.ClearControlCache() ' Cache-Invalidierung Dim perfStart As DateTime = DateTime.MinValue @@ -5649,16 +5657,14 @@ Public Class frmValidator Dim oLookup As LookupControl3 = oControl Dim oLookupMeta As ClassControlCreator.ControlMetadata = DirectCast(oLookup.Tag, ClassControlCreator.ControlMetadata) - ' ========== BUGFIX START: Alte SelectedValues SICHERN bevor DataSource überschrieben wird ========== - Dim previousSelectedValues As List(Of String) = Nothing - Dim hadPreviousSelection As Boolean = False - - If oLookup.Properties.SelectedValues IsNot Nothing AndAlso oLookup.Properties.SelectedValues.Count > 0 Then - previousSelectedValues = New List(Of String)(oLookup.Properties.SelectedValues) - hadPreviousSelection = True - MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: Alte SelectedValues gesichert = [{String.Join(",", previousSelectedValues)}]") + ' Nur sichern wenn NICHT bereits von einem vorherigen Dokument vorhanden + If Not hadPreviousLUSelection Then + If oLookup.Properties.SelectedValues IsNot Nothing AndAlso oLookup.Properties.SelectedValues.Count > 0 Then + previousLUSelectedValues = New List(Of String)(oLookup.Properties.SelectedValues) + hadPreviousLUSelection = True + MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: Alte SelectedValues gesichert = [{String.Join(",", previousLUSelectedValues)}]") + End If End If - ' ========== BUGFIX END: Sicherung ========== oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride) @@ -5691,20 +5697,20 @@ Public Class frmValidator End If Else ' ========== BUGFIX START: Wenn KEIN neuer Wert, alte Werte behalten ========== - If hadPreviousSelection AndAlso previousSelectedValues IsNot Nothing AndAlso previousSelectedValues.Count > 0 Then + 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 = previousSelectedValues + oNewValues = previousLUSelectedValues ElseIf oDefaultValue <> String.Empty Then - MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: Keine alten Werte, verwende DefaultValue = [{oDefaultValue}]") + MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: Verwende DefaultValue = [{oDefaultValue}]") oNewValues = oDefaultValue.Split(",").ToList() Else - MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: KEINE Werte (oValueFromSource=Nothing, oDefaultValue leer, keine vorherigen Werte)") + MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: KEINE Werte!") End If - ' ========== BUGFIX END: Wert-Beibehaltung ========== - End If + ' ========== BUGFIX END: Wert-Beibehaltung ========== + End If - ' ========== KRITISCH: DataSource-Backup erstellen BEVOR SelectedValues gelöscht wird ========== - Dim savedDataSource = oLookup.Properties.DataSource + ' ========== KRITISCH: DataSource-Backup erstellen BEVOR SelectedValues gelöscht wird ========== + Dim savedDataSource = oLookup.Properties.DataSource MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: DataSource-Backup erstellt") ' ========== KRITISCH: DataSource ZUERST wiederherstellen, DANN SelectedValues leeren ========== @@ -8508,8 +8514,9 @@ Public Class frmValidator Cursor = Cursors.WaitCursor Dim perfStart As DateTime = If(LOG_HOTSPOTS, DateTime.Now, Nothing) Dim perfLastCheck As DateTime = perfStart - - + ' ========== WICHTIG: State-Variablen zurücksetzen vor neuem Dokument ========== + previousLUSelectedValues = Nothing + hadPreviousLUSelection = False If LOG_HOTSPOTS Then ' ========== DIAGNOSE START ========== @@ -8531,12 +8538,7 @@ Public Class frmValidator ' ========== ENDE DIAGNOSE ========== End If - - Reset_CurrentReferences() - - - If LOG_HOTSPOTS Then MyValidationLogger.Info($"[PERF] Nach Reset_CurrentReferences: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now