From 3dd884096bba660361abfe55e32450aa2b7ccf84 Mon Sep 17 00:00:00 2001 From: Developer01 Date: Thu, 28 May 2026 16:48:32 +0200 Subject: [PATCH] Verbesserung der SQL-Logik und Debugging-Optimierung MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Sichtbarkeitslogik in `ClassRefreshHelper.vb` wurde verbessert, um ungültige Indizes zu vermeiden. In `frmMain.vb` wurde die Methode `PrepareSQLWithReplacements` erweitert, um einen zusätzlichen Parameter `oProfileID` zu unterstützen, was die Flexibilität bei der SQL-Verarbeitung erhöht. Zusätzliche Debug-Logs wurden hinzugefügt, um die Nachvollziehbarkeit zu verbessern, insbesondere bei SQL-Fehlern, Ladeprozessen und TreeList-Operationen. Die Fehlerbehandlung wurde optimiert, um spezifischere Warnungen und Validierungen zu ermöglichen. Weitere Verbesserungen umfassen die Behandlung von `CUSTOM_OVERVIEW_SQL`, die Validierung des Overlays in `Decide_Load` und die Optimierung der SQL-Verarbeitung in `LoadOverviewData`. Allgemeine Code-Qualitätsmaßnahmen wie Kommentare und Strukturverbesserungen wurden ebenfalls vorgenommen. --- app/TaskFlow/ClassRefreshHelper.vb | 22 +++++++++-- app/TaskFlow/frmMain.vb | 61 ++++++++++++++++++++++-------- 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/app/TaskFlow/ClassRefreshHelper.vb b/app/TaskFlow/ClassRefreshHelper.vb index ef596cc..20a3414 100644 --- a/app/TaskFlow/ClassRefreshHelper.vb +++ b/app/TaskFlow/ClassRefreshHelper.vb @@ -194,14 +194,30 @@ Public Class RefreshHelper End Sub Private Sub SaveVisibleIndex() - _VisibleRowIndex = _View.GetVisibleIndex(_View.FocusedRowHandle) - _View.TopRowIndex + If _View.FocusedRowHandle <> GridControl.InvalidRowHandle AndAlso _View.FocusedRowHandle >= 0 Then + _VisibleRowIndex = _View.GetVisibleIndex(_View.FocusedRowHandle) - _View.TopRowIndex + Else + _VisibleRowIndex = 0 + End If End Sub Private Sub LoadVisibleIndex() Try + If _View.FocusedRowHandle = GridControl.InvalidRowHandle OrElse _View.FocusedRowHandle < 0 Then + LOGGER.Debug("No valid focused row handle found. Skipping visible index restoration.") + Return + End If + _View.MakeRowVisible(_View.FocusedRowHandle, True) - If _View.FocusedRowHandle <> -1 Then - _View.TopRowIndex = _View.GetVisibleIndex(_View.FocusedRowHandle) - _VisibleRowIndex + + Dim currentVisibleIndex As Integer = _View.GetVisibleIndex(_View.FocusedRowHandle) + Dim newTopRowIndex As Integer = currentVisibleIndex - _VisibleRowIndex + + ' Verhindere negative oder ungültige TopRowIndex-Werte + If newTopRowIndex >= 0 AndAlso newTopRowIndex < _View.RowCount Then + _View.TopRowIndex = newTopRowIndex + Else + LOGGER.Debug($"Calculated TopRowIndex {newTopRowIndex} is out of bounds. Skipping setting TopRowIndex.") End If Catch ex As Exception diff --git a/app/TaskFlow/frmMain.vb b/app/TaskFlow/frmMain.vb index 40ee7ba..38cd312 100644 --- a/app/TaskFlow/frmMain.vb +++ b/app/TaskFlow/frmMain.vb @@ -646,6 +646,7 @@ Public Class frmMain Sub(oNode As DevExpress.XtraTreeList.Nodes.TreeListNode) ' ===== NUR KNOTEN MIT TYPE_ID = 0 ODER 1 VERARBEITEN ===== Dim oTypeId As Object = oNode.GetValue("TYPE_ID") + Dim oProfileID As Object = oNode.GetValue("FK_PROFILE_ID") If oTypeId Is Nothing OrElse IsDBNull(oTypeId) Then LOGGER.Debug($"AppendCountsToTreeAsync: Node [{oNode.GetValue("NAME")}] has no TYPE_ID - skipping.") Exit Sub @@ -657,7 +658,7 @@ Public Class frmMain Dim oSqlCount As Object = oNode.GetValue("SQL_QUERY_COUNT") If oSqlCount IsNot Nothing AndAlso Not IsDBNull(oSqlCount) AndAlso Not String.IsNullOrWhiteSpace(oSqlCount.ToString()) Then - Dim oPreparedSQL As String = PrepareSQLWithReplacements(oSqlCount.ToString()) + Dim oPreparedSQL As String = PrepareSQLWithReplacements(oSqlCount.ToString(), CInt(oProfileID)) Dim oName As String = oNode.GetValue("NAME")?.ToString() If Not String.IsNullOrWhiteSpace(oName) Then oWorkItems.Add((oNode, oPreparedSQL, oName)) @@ -1205,7 +1206,7 @@ Public Class frmMain LOGGER.Info($"ATTENTION: CURR_DT_VWPM_PROFILE_ACTIVE is nothing!") Return False End If - + LOGGER.Debug($"Load_Profiles_for_User: Current datatable has {CURR_DT_VWPM_PROFILE_ACTIVE.Rows.Count} rows") Return True Catch ex As Exception LOGGER.Error(ex) @@ -1522,7 +1523,7 @@ Public Class frmMain End If TimerRefresh_running = True - + LOGGER.Debug("TimerRefresh_Tick started") ' Cancel Refresh if a Validator Form or an Admin Form is opened If Application.OpenForms().OfType(Of frmMassValidator).Any() Or Application.OpenForms().OfType(Of frmValidator).Any() Or @@ -1577,10 +1578,14 @@ Public Class frmMain Private Async Function Decide_Load(pIsFormLoad As Boolean, Optional ForceReload As Boolean = False) As Tasks.Task Dim oHandle As Object = Nothing Dim overlayStartedHere As Boolean = False - If Not _overlayActive Then + ' Overlay nur anzeigen, wenn die Anwendung aktuell den Fokus hat + Dim appHasFocus As Boolean = Application.OpenForms().Cast(Of Form)().Any(Function(f) f.ContainsFocus) + If Not _overlayActive AndAlso appHasFocus Then oHandle = SplashScreenManager.ShowOverlayForm(Me) _overlayActive = True overlayStartedHere = True + Else + LOGGER.Debug("Overlay wird nicht angezeigt, da bereits aktiv oder Anwendung keinen Fokus hat.") End If Dim perfStart As DateTime = DateTime.MinValue Dim refreshWasEnabled As Boolean = False @@ -1637,10 +1642,13 @@ Public Class frmMain End If If Not loadSuccess Then - LOGGER.Warn($"LoadProfileData for Profile-ID [{CURRENT_CLICKED_PROFILE_ID}] - Title [{CURRENT_CLICKED_PROFILE_TITLE}] failed or has no Data - exiting Decide_Load") + If GRID_LOAD_TYPE <> "OVERVIEW" Then + LOGGER.Warn($"LoadProfileData for Profile-ID [{CURRENT_CLICKED_PROFILE_ID}] - Title [{CURRENT_CLICKED_PROFILE_TITLE}] failed or has no Data - exiting Decide_Load") + Else + LOGGER.Warn($"LoadOverviewData failed or has no Data - exiting Decide_Load") + End If Exit Function End If - ' ========== NACHBEARBEITUNG ========== ApplyPostLoadSettings() @@ -1710,7 +1718,7 @@ Public Class frmMain End If If LOG_HOTSPOTS Then - LOGGER.Info($"[PERF LoadOverviewData] Load_Profiles_for_User wird aufgerufen...") + LOGGER.Debug($"[PERF LoadOverviewData] Load_Profiles_for_User wird aufgerufen...") End If Load_Profiles_for_User() @@ -1730,13 +1738,22 @@ Public Class frmMain If Not String.IsNullOrWhiteSpace(CUSTOM_OVERVIEW_SQL) Then LOGGER.Debug($"[LoadOverviewData] Using CUSTOM_OVERVIEW_SQL from TreeList node") oSQLOverview = CUSTOM_OVERVIEW_SQL - CUSTOM_OVERVIEW_SQL = String.Empty Else oSQLOverview = BASEDATA_DT_CONFIG.Rows(0).Item("SQL_PROFILE_MAIN_VIEW") End If If IsDBNull(oSQLOverview) OrElse Not oSQLOverview.ToString.Contains("GROUP_TEXT") Then - LOGGER.Warn("Overview SQL is Null or not properly configured (missing or GROUP_TEXT column) - cannot load overview data") + If IsDBNull(oSQLOverview) Then + LOGGER.Warn("Overview SQL is Null - cannot load overview data") + ElseIf Not oSQLOverview.ToString.Contains("GROUP_TEXT") Then + LOGGER.Warn("Overview SQL is not properly configured - missing GROUP_TEXT column - cannot load overview data") + LOGGER.Warn($"Overview SQL so far: {oSQLOverview}") + Else + LOGGER.Warn("Overview SQL is not properly configured (missing, empty or GROUP_TEXT column not included) - cannot load overview data") + LOGGER.Warn($"Overview SQL so far: {oSQLOverview}") + End If + + NO_WORKFLOW_ITEMS = True GridControlWorkflows.Visible = False bindsourcegrid.DataSource = Nothing @@ -1745,7 +1762,7 @@ Public Class frmMain End If ' SQL-Platzhalter ersetzen - oSQLOverview = PrepareSQLWithReplacements(oSQLOverview) + oSQLOverview = PrepareSQLWithReplacements(oSQLOverview, 0) If LOG_HOTSPOTS Then Dim rowCount = If(DT_CURR_WF_ITEMS IsNot Nothing, DT_CURR_WF_ITEMS.Rows.Count, 0) @@ -1887,7 +1904,7 @@ Public Class frmMain ' ========== SQL VORBEREITEN UND AUSFÜHREN ========== Dim oSQL = foundRow.Item("SQL_VIEW") - oSQL = PrepareSQLWithReplacements(oSQL) + oSQL = PrepareSQLWithReplacements(oSQL, CURRENT_CLICKED_PROFILE_ID) DT_CURR_WF_ITEMS = Await DatabaseFallback.GetDatatableECMAsync(oSQL) @@ -1931,14 +1948,25 @@ Public Class frmMain ' HILFSMETHODEN - Extrahierte Logik für Wiederverwendung ' ======================================== - Private Function PrepareSQLWithReplacements(oSQL As String) As String + Private Function PrepareSQLWithReplacements(oSQL As String, oProfileID As Integer) As String oSQL = clsPatterns.ReplaceInternalValues(oSQL) oSQL = clsPatterns.ReplaceUserValues(oSQL) oSQL = oSQL.Replace("@USER_ID", USER_ID) oSQL = oSQL.Replace("@USERNAME", USER_USERNAME) oSQL = oSQL.Replace("@MACHINE_NAME", System.Environment.MachineName) oSQL = oSQL.Replace("@DATE", Now.ToShortDateString) - oSQL = oSQL.Replace("@PROFILE_ID", CURRENT_CLICKED_PROFILE_ID) + If oProfileID = 0 Then + If GRID_LOAD_TYPE = "OVERVIEW" Then + LOGGER.Debug("PrepareSQLWithReplacements called with oProfileID = 0 in OVERVIEW context") + Else + LOGGER.Warn("PrepareSQLWithReplacements called with oProfileID = 0, using CURRENT_CLICKED_PROFILE_ID instead") + End If + oProfileID = CURRENT_CLICKED_PROFILE_ID + Else + LOGGER.Debug($"PrepareSQLWithReplacements called with oProfileID = {oProfileID}") + End If + oSQL = oSQL.Replace("@PROFILE_ID", oProfileID) + oSQL = oSQL.Replace("@PROFIL_ID", oProfileID) Return oSQL End Function @@ -4451,7 +4479,9 @@ FROM VWPM_PROFILE_ACTIVE T WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_G Finally Me.Cursor = Cursors.Default End Try - + ' ✅ CUSTOM_OVERVIEW_SQL erst HIER leeren – nach dem kompletten Lade-Zyklus inkl. internem GridLayout_Reset + LOGGER.Debug("TreeList_Cockpit: Clearing CUSTOM_OVERVIEW_SQL after loading overview") + CUSTOM_OVERVIEW_SQL = String.Empty If GridControlWorkflows.Visible = True And FormOpenClose = False Then RefreshHelper.LoadViewInfo() End If @@ -4552,9 +4582,10 @@ FROM VWPM_PROFILE_ACTIVE T WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_G End If If FormShown = False Then + LOGGER.Debug("TreeList1_FocusedNodeChanged: Form not shown - skipping") Exit Sub End If - + LOGGER.Debug("TreeList1_FocusedNodeChanged: Node changed - processing") Await ProcessTreeListNodeAsync(e.Node) Catch ex As Exception