From 743ef3fe229d6bc8264e741f9072b56132572b9c Mon Sep 17 00:00:00 2001 From: Developer01 Date: Wed, 25 Feb 2026 13:16:12 +0100 Subject: [PATCH] MS 2.8.2 Fehlerhandling und Column-Formel Test bei Henning --- app/TaskFlow/ClassInit.vb | 20 +- app/TaskFlow/ClassParamRefresh.vb | 6 +- app/TaskFlow/ControlCreator/GridControl.vb | 60 +- app/TaskFlow/My Project/AssemblyInfo.vb | 2 +- app/TaskFlow/TaskFlow.vbproj | 9 + app/TaskFlow/frmColumn_Detail.Designer.vb | 58 +- app/TaskFlow/frmColumn_Detail.resx | 81 +- app/TaskFlow/frmColumn_Detail.vb | 18 + .../frmExpression_Designer.Designer.vb | 465 ++++ app/TaskFlow/frmExpression_Designer.resx | 120 + app/TaskFlow/frmExpression_Designer.vb | 284 +++ app/TaskFlow/frmFormDesigner.vb | 21 +- app/TaskFlow/frmGhostMode.vb | 4 +- app/TaskFlow/frmMain.resx | 2 +- app/TaskFlow/frmMain.vb | 240 +- app/TaskFlow/frmValidator.vb | 2130 +++++++++-------- 16 files changed, 2376 insertions(+), 1144 deletions(-) create mode 100644 app/TaskFlow/frmExpression_Designer.Designer.vb create mode 100644 app/TaskFlow/frmExpression_Designer.resx create mode 100644 app/TaskFlow/frmExpression_Designer.vb diff --git a/app/TaskFlow/ClassInit.vb b/app/TaskFlow/ClassInit.vb index 95d5228..85e591f 100644 --- a/app/TaskFlow/ClassInit.vb +++ b/app/TaskFlow/ClassInit.vb @@ -397,7 +397,7 @@ Public Class ClassInit USER_DATE_FORMAT = DT_CHECKUSER_MODULE.Rows(0).Item("USER_DATE_FORMAT") - ClassParamRefresh.Refresh_Params(DT_CHECKUSER_MODULE) + ClassParamRefresh.Refresh_Params(DT_CHECKUSER_MODULE, "Load") FINALINDICES = New ClassFinalIndex() @@ -468,7 +468,7 @@ Public Class ClassInit ' DataASorDB = New ClassDataASorDB 'End If Dim oStopWatch As New RefreshHelper.SW("InitBasics") - Dim oSql = String.Format("select * from TBPM_KONFIGURATION WHERE GUID = 1") + Dim oSql = String.Format("select * from TBPM_KONFIGURATION WITH (NOLOCK) WHERE GUID = 1") oStep = "TBPM_KONFIGURATION" BASEDATA_DT_CONFIG = DatabaseFallback.GetDatatable("TBPM_KONFIGURATION", New GetDatatableOptions(oSql, DatabaseType.ECM) With { @@ -498,23 +498,23 @@ Public Class ClassInit LOGGER.Warn($"Keine GDPICTURE-Lizenz gefunden. Version Konfiguration: {My.Settings.GDPICTURE_VERSION} - Prüfe TBDD_3RD_PARTY_MODULES") End If oStep = "TBDD_SQL_COMMANDS" - oSql = "Select * FROM TBDD_SQL_COMMANDS" + oSql = "Select * FROM TBDD_SQL_COMMANDS WITH (NOLOCK)" BASEDATA_DT_TBDD_SQL_COMMANDS = DatabaseFallback.GetDatatable("TBDD_SQL_COMMANDS", New GetDatatableOptions(oSql, DatabaseType.ECM)) oStep = "TBDD_GUI_LANGUAGE_PHRASE" - oSql = $"SELECT * FROM TBDD_GUI_LANGUAGE_PHRASE WHERE MODULE IN ('PM','All Modules')" + oSql = $"SELECT * FROM TBDD_GUI_LANGUAGE_PHRASE WITH (NOLOCK) WHERE MODULE IN ('PM','All Modules')" 'BASEDATA_DT_GUI_LANGUAGE_PHRASES = DataASorDB.GetDatatable("DD_ECM", oSql, "TBDD_GUI_LANGUAGE_PHRASE", "") BASEDATA_DT_GUI_LANGUAGE_PHRASES = DatabaseFallback.GetDatatable("TBDD_GUI_LANGUAGE_PHRASE", New GetDatatableOptions(oSql, DatabaseType.ECM)) oStep = "TBPM_PROFILE_SEARCH" - oSql = "select * from TBPM_PROFILE_SEARCH where TYPE = 'DOC' AND ACTIVE = 1 ORDER BY PROFILE_ID,TAB_INDEX" + oSql = "select * from TBPM_PROFILE_SEARCH WITH (NOLOCK) where TYPE = 'DOC' AND ACTIVE = 1 ORDER BY PROFILE_ID,TAB_INDEX" BASEDATA_DT_PROFILES_SEARCHES_DOC = DatabaseFallback.GetDatatable("TBPM_PROFILE_SEARCH", New GetDatatableOptions(oSql, DatabaseType.ECM) With { .SortByColumn = "PROFILE_ID,TAB_INDEX" }) DT_FILTERED_PROFILE_SEARCHES_DOC = BASEDATA_DT_PROFILES_SEARCHES_DOC.Clone() oStep = "TBPM_MAIN_VIEW_GROUPS" - oSql = "SELECT * FROM TBPM_MAIN_VIEW_GROUPS WHERE ACTIVE = 1" + oSql = "SELECT * FROM TBPM_MAIN_VIEW_GROUPS WITH (NOLOCK) WHERE ACTIVE = 1" BASEDATA_DTGRID_GROUPS = DatabaseFallback.GetDatatable("TBPM_MAIN_VIEW_GROUPS", New GetDatatableOptions(oSql, DatabaseType.ECM)) @@ -524,11 +524,11 @@ Public Class ClassInit BASEDATA_DT_CHARTS = DatabaseFallback.GetDatatable("TBPM_CHART", New GetDatatableOptions(oSql, DatabaseType.ECM)) oStep = "TBDD_GUI_LANGUAGE" - oSql = "SELECT LANG_CODE FROM TBDD_GUI_LANGUAGE WHERE ACTIVE = 1 ORDER BY LANG_CODE" + oSql = "SELECT LANG_CODE FROM TBDD_GUI_LANGUAGE WITH (NOLOCK) WHERE ACTIVE = 1 ORDER BY LANG_CODE" BASEDATA_DT_LANGUAGE = DatabaseFallback.GetDatatable("TBDD_GUI_LANGUAGE", New GetDatatableOptions(oSql, DatabaseType.ECM)) - oSql = "SELECT * FROM TBDD_COLUMNS_FORMAT WHERE MODULE = 'taskFLOW' AND GRIDVIEW = 'GridViewWorkflows'" + oSql = "SELECT * FROM TBDD_COLUMNS_FORMAT WITH (NOLOCK) WHERE MODULE = 'taskFLOW' AND GRIDVIEW = 'GridViewWorkflows'" BASEDATA_TBDD_COLUMNS_FORMAT = DatabaseFallback.GetDatatable("TBDD_COLUMNS_FORMAT", New GetDatatableOptions(oSql, DatabaseType.ECM)) @@ -556,7 +556,7 @@ Public Class ClassInit End If oSql = "SELECT KEY_NAME, VALUE_TEXT1 - FROM TBDD_USER_KEY_VALUE_PAIR + FROM TBDD_USER_KEY_VALUE_PAIR WITH (NOLOCK) 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)) @@ -608,7 +608,7 @@ Public Class ClassInit Private Function Settings_LoadBasicConfig() Try - Dim oSql As String = "select * from tbdd_Modules where SHORT_NAME = 'PM'" + Dim oSql As String = "select * from tbdd_Modules WITH (NOLOCK) where SHORT_NAME = 'PM'" Dim oDTtbdd_Modules As DataTable 'oDTtbdd_Modules = DataASorDB.GetDatatable("DD_ECM", oSql, "tbdd_Modules", $" SHORT_NAME = 'PM'") oDTtbdd_Modules = DatabaseFallback.GetDatatable("TBDD_MODULES", New GetDatatableOptions(oSql, DatabaseType.ECM) With { diff --git a/app/TaskFlow/ClassParamRefresh.vb b/app/TaskFlow/ClassParamRefresh.vb index 31b9f2e..bb4e5da 100644 --- a/app/TaskFlow/ClassParamRefresh.vb +++ b/app/TaskFlow/ClassParamRefresh.vb @@ -1,7 +1,7 @@ Imports DigitalData.Modules.Database Public Class ClassParamRefresh - Public Shared Sub Refresh_Params(DT_CHECKUSER As DataTable) + Public Shared Sub Refresh_Params(DT_CHECKUSER As DataTable, pMode As String) LOGGER.Debug("Refresh_Params starting ...") Dim oStopwatch As New RefreshHelper.SW("Refresh_Params") FORCE_LAYOUT_OVERVIEW = False @@ -221,14 +221,14 @@ Public Class ClassParamRefresh Catch ex As Exception TITLE_NOTIFICATIONS = "" End Try - ElseIf oMode.StartsWith("TF.InheritanceMsgAmount") Then + ElseIf oMode.StartsWith("TF.InheritanceMsgAmount") And pMode = "Load" Then Dim oParam = oMode.Replace("TF.InheritanceMsgAmount=", "") Try InheritanceMsgAmount = oParam Catch ex As Exception End Try - ElseIf oMode.StartsWith("TF.InheritanceCalcReset") Then + ElseIf oMode.StartsWith("TF.InheritanceCalcReset") And pMode = "Load" Then Dim oParam = oMode.Replace("TF.InheritanceCalcReset=", "") Try If CBool(oParam) = True Then diff --git a/app/TaskFlow/ControlCreator/GridControl.vb b/app/TaskFlow/ControlCreator/GridControl.vb index 184f4a8..87ae10e 100644 --- a/app/TaskFlow/ControlCreator/GridControl.vb +++ b/app/TaskFlow/ControlCreator/GridControl.vb @@ -34,6 +34,7 @@ Namespace ControlCreator Public Function CreateGridColumns(pColumnTable As DataTable) As DataTable Dim oDataTable As New DataTable + Dim columnsWithExpressions As New List(Of Tuple(Of DataColumn, String)) For Each oRow As DataRow In pColumnTable.Rows ' Create Columns in Datatable @@ -57,22 +58,65 @@ Namespace ControlCreator Case Else oColumn.DataType = GetType(String) End Select + Dim oFormulaExpression = ObjectEx.NotNull(oRow.Item("FORMULA_EXPRESSION"), String.Empty) If oFormulaExpression <> String.Empty Then - Try - oColumn.Expression = oFormulaExpression - oColumn.ReadOnly = True - Catch ex As Exception - _Logger.Warn("⚠️ Invalid FORMULA_EXPRESSION for column {0}: {1}", oColumn.ColumnName, oFormulaExpression) - _Logger.Error(ex) - End Try + ' Expression merken, aber erst später setzen + columnsWithExpressions.Add(New Tuple(Of DataColumn, String)(oColumn, oFormulaExpression)) End If - oDataTable.Columns.Add(oColumn) + + Try + oDataTable.Columns.Add(oColumn) + Catch ex As Exception + _Logger.Warn("⚠️ Could not add column {0} to DataTable", oColumn.ColumnName) + _Logger.Error(ex) + End Try + Next + + ' Jetzt alle Expressions setzen, nachdem alle Spalten existieren + For Each columnExpressionPair In columnsWithExpressions + Dim oColumn = columnExpressionPair.Item1 + Dim oExpression = columnExpressionPair.Item2 + + Try + _Logger.Debug("Setting expression for column [{0}]: {1}", oColumn.ColumnName, oExpression) + + ' Prüfe, ob alle referenzierten Spalten existieren + Dim referencedColumns = GetReferencedColumnNames(oExpression) + For Each refCol In referencedColumns + If Not oDataTable.Columns.Contains(refCol) Then + _Logger.Warn("⚠️ Referenced column [{0}] does not exist in DataTable!", refCol) + MsgBox(String.Format("Referenced column [{0}] does not exist in DataTable!", refCol), MsgBoxStyle.Exclamation) + + Else + _Logger.Debug("Referenced column [{0}] exists with DataType: {1}", refCol, oDataTable.Columns(refCol).DataType.Name) + End If + Next + + oColumn.Expression = oExpression + oColumn.ReadOnly = True + _Logger.Info("✓ Expression successfully set for column [{0}]: {1}", oColumn.ColumnName, oColumn.Expression) + Catch ex As Exception + _Logger.Warn("⚠️ Invalid FORMULA_EXPRESSION for column {0}: {1}", oColumn.ColumnName, oExpression) + _Logger.Error(ex) + MsgBox(String.Format("The column '{0}' inlcudes an invalid formula: {1}. Please check the FORMULA_EXPRESSION in the table designer." & vbCrLf & + "Error: {2}", oColumn.ColumnName, oExpression, ex.Message), MsgBoxStyle.Exclamation, "Ungültige Formel") + End Try Next Return oDataTable End Function + Private Function GetReferencedColumnNames(expression As String) As List(Of String) + Dim columnNames As New List(Of String) + Dim pattern As String = "\[([^\]]+)\]" + Dim matches = Regex.Matches(expression, pattern) + + For Each match As Match In matches + columnNames.Add(match.Groups(1).Value) + Next + Return columnNames + End Function Public Function FillGridTables(pColumnTable As DataTable, pControlId As Integer, pControlName As String) As Dictionary(Of Integer, Dictionary(Of String, RepositoryItem)) For Each oRow As DataRow In pColumnTable.Rows ' Fetch and cache Combobox results diff --git a/app/TaskFlow/My Project/AssemblyInfo.vb b/app/TaskFlow/My Project/AssemblyInfo.vb index 9ab75bb..defb2f9 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/TaskFlow.vbproj b/app/TaskFlow/TaskFlow.vbproj index a2d23ac..b686d29 100644 --- a/app/TaskFlow/TaskFlow.vbproj +++ b/app/TaskFlow/TaskFlow.vbproj @@ -624,6 +624,12 @@ Form + + frmExpression_Designer.vb + + + Form + frmFileInfo.vb @@ -868,6 +874,9 @@ frmError.vb Designer + + frmExpression_Designer.vb + frmFileInfo.vb Designer diff --git a/app/TaskFlow/frmColumn_Detail.Designer.vb b/app/TaskFlow/frmColumn_Detail.Designer.vb index 620af69..beadbbf 100644 --- a/app/TaskFlow/frmColumn_Detail.Designer.vb +++ b/app/TaskFlow/frmColumn_Detail.Designer.vb @@ -37,7 +37,7 @@ Partial Class frmColumn_Detail Me.RibbonStatusBar1 = New DevExpress.XtraBars.Ribbon.RibbonStatusBar() Me.RibbonPage2 = New DevExpress.XtraBars.Ribbon.RibbonPage() Me.LayoutControl1 = New DevExpress.XtraLayout.LayoutControl() - Me.LabelControl1 = New DevExpress.XtraEditors.LabelControl() + Me.SimpleButton3 = New DevExpress.XtraEditors.SimpleButton() Me.FORMULA_EXPRESSIONTextBox = New System.Windows.Forms.TextBox() Me.LU_CAPTIONTextBox = New System.Windows.Forms.TextBox() Me.GUIDTextBox = New DevExpress.XtraEditors.TextEdit() @@ -88,7 +88,7 @@ Partial Class frmColumn_Detail Me.LayoutControlItem23 = New DevExpress.XtraLayout.LayoutControlItem() Me.LayoutControlItem21 = New DevExpress.XtraLayout.LayoutControlItem() Me.LayoutControlItem24 = New DevExpress.XtraLayout.LayoutControlItem() - Me.LayoutControlItem15 = New DevExpress.XtraLayout.LayoutControlItem() + Me.LayoutControlItem26 = New DevExpress.XtraLayout.LayoutControlItem() CType(Me.TBPM_CONTROL_TABLEBindingSource, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.DD_DMSLiteDataSet, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.RibbonControl1, System.ComponentModel.ISupportInitialize).BeginInit() @@ -140,7 +140,7 @@ Partial Class frmColumn_Detail CType(Me.LayoutControlItem23, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.LayoutControlItem21, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.LayoutControlItem24, System.ComponentModel.ISupportInitialize).BeginInit() - CType(Me.LayoutControlItem15, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.LayoutControlItem26, System.ComponentModel.ISupportInitialize).BeginInit() Me.SuspendLayout() ' 'TBPM_CONTROL_TABLEBindingSource @@ -237,7 +237,7 @@ Partial Class frmColumn_Detail ' 'LayoutControl1 ' - Me.LayoutControl1.Controls.Add(Me.LabelControl1) + Me.LayoutControl1.Controls.Add(Me.SimpleButton3) Me.LayoutControl1.Controls.Add(Me.FORMULA_EXPRESSIONTextBox) Me.LayoutControl1.Controls.Add(Me.LU_CAPTIONTextBox) Me.LayoutControl1.Controls.Add(Me.GUIDTextBox) @@ -266,15 +266,11 @@ Partial Class frmColumn_Detail Me.LayoutControl1.Name = "LayoutControl1" Me.LayoutControl1.Root = Me.Root ' - 'LabelControl1 + 'SimpleButton3 ' - Me.LabelControl1.Appearance.Font = CType(resources.GetObject("LabelControl1.Appearance.Font"), System.Drawing.Font) - Me.LabelControl1.Appearance.Options.UseFont = True - Me.LabelControl1.Appearance.Options.UseTextOptions = True - Me.LabelControl1.Appearance.TextOptions.WordWrap = DevExpress.Utils.WordWrap.Wrap - resources.ApplyResources(Me.LabelControl1, "LabelControl1") - Me.LabelControl1.Name = "LabelControl1" - Me.LabelControl1.StyleController = Me.LayoutControl1 + resources.ApplyResources(Me.SimpleButton3, "SimpleButton3") + Me.SimpleButton3.Name = "SimpleButton3" + Me.SimpleButton3.StyleController = Me.LayoutControl1 ' 'FORMULA_EXPRESSIONTextBox ' @@ -482,7 +478,7 @@ Partial Class frmColumn_Detail ' Me.Root.EnableIndentsWithoutBorders = DevExpress.Utils.DefaultBoolean.[True] Me.Root.GroupBordersVisible = False - Me.Root.Items.AddRange(New DevExpress.XtraLayout.BaseLayoutItem() {Me.LayoutControlItem1, Me.LayoutControlItem2, Me.LayoutControlItem3, Me.LayoutControlItem4, Me.LayoutControlItem5, Me.LayoutControlItem6, Me.LayoutControlItem8, Me.LayoutControlItem7, Me.LayoutControlItem9, Me.LayoutControlItem10, Me.LayoutControlItem12, Me.LayoutControlItem11, Me.LayoutControlItem13, Me.LayoutControlGroup1, Me.LayoutControlItem18, Me.LayoutControlItem19, Me.LayoutControlItem23, Me.LayoutControlItem21, Me.LayoutControlItem24, Me.LayoutControlItem15}) + Me.Root.Items.AddRange(New DevExpress.XtraLayout.BaseLayoutItem() {Me.LayoutControlItem1, Me.LayoutControlItem2, Me.LayoutControlItem3, Me.LayoutControlItem4, Me.LayoutControlItem5, Me.LayoutControlItem6, Me.LayoutControlItem8, Me.LayoutControlItem7, Me.LayoutControlItem9, Me.LayoutControlItem10, Me.LayoutControlItem12, Me.LayoutControlItem11, Me.LayoutControlItem13, Me.LayoutControlGroup1, Me.LayoutControlItem18, Me.LayoutControlItem19, Me.LayoutControlItem23, Me.LayoutControlItem21, Me.LayoutControlItem24, Me.LayoutControlItem26}) Me.Root.Name = "Root" Me.Root.Size = New System.Drawing.Size(593, 816) Me.Root.TextVisible = False @@ -578,7 +574,7 @@ Partial Class frmColumn_Detail 'LayoutControlItem10 ' Me.LayoutControlItem10.Control = Me.TextEdit7 - Me.LayoutControlItem10.Location = New System.Drawing.Point(0, 547) + Me.LayoutControlItem10.Location = New System.Drawing.Point(0, 458) Me.LayoutControlItem10.Name = "LayoutControlItem10" Me.LayoutControlItem10.Padding = New DevExpress.XtraLayout.Utils.Padding(10, 10, 10, 10) Me.LayoutControlItem10.Size = New System.Drawing.Size(286, 40) @@ -588,7 +584,7 @@ Partial Class frmColumn_Detail 'LayoutControlItem12 ' Me.LayoutControlItem12.Control = Me.CHANGED_WHOTextBox - Me.LayoutControlItem12.Location = New System.Drawing.Point(0, 587) + Me.LayoutControlItem12.Location = New System.Drawing.Point(0, 498) Me.LayoutControlItem12.Name = "LayoutControlItem12" Me.LayoutControlItem12.Padding = New DevExpress.XtraLayout.Utils.Padding(10, 10, 10, 10) Me.LayoutControlItem12.Size = New System.Drawing.Size(286, 40) @@ -598,7 +594,7 @@ Partial Class frmColumn_Detail 'LayoutControlItem11 ' Me.LayoutControlItem11.Control = Me.TextEdit8 - Me.LayoutControlItem11.Location = New System.Drawing.Point(286, 547) + Me.LayoutControlItem11.Location = New System.Drawing.Point(286, 458) Me.LayoutControlItem11.Name = "LayoutControlItem11" Me.LayoutControlItem11.Padding = New DevExpress.XtraLayout.Utils.Padding(10, 10, 10, 10) Me.LayoutControlItem11.Size = New System.Drawing.Size(287, 40) @@ -608,7 +604,7 @@ Partial Class frmColumn_Detail 'LayoutControlItem13 ' Me.LayoutControlItem13.Control = Me.TextEdit10 - Me.LayoutControlItem13.Location = New System.Drawing.Point(286, 587) + Me.LayoutControlItem13.Location = New System.Drawing.Point(286, 498) Me.LayoutControlItem13.Name = "LayoutControlItem13" Me.LayoutControlItem13.Padding = New DevExpress.XtraLayout.Utils.Padding(10, 10, 10, 10) Me.LayoutControlItem13.Size = New System.Drawing.Size(287, 40) @@ -618,9 +614,9 @@ Partial Class frmColumn_Detail 'LayoutControlGroup1 ' Me.LayoutControlGroup1.Items.AddRange(New DevExpress.XtraLayout.BaseLayoutItem() {Me.LayoutControlItem16, Me.LayoutControlItem14, Me.LayoutControlItem17, Me.LayoutControlItem25, Me.LayoutControlItem20, Me.LayoutControlItem22}) - Me.LayoutControlGroup1.Location = New System.Drawing.Point(0, 627) + Me.LayoutControlGroup1.Location = New System.Drawing.Point(0, 538) Me.LayoutControlGroup1.Name = "LayoutControlGroup1" - Me.LayoutControlGroup1.Size = New System.Drawing.Size(573, 169) + Me.LayoutControlGroup1.Size = New System.Drawing.Size(573, 258) resources.ApplyResources(Me.LayoutControlGroup1, "LayoutControlGroup1") ' 'LayoutControlItem16 @@ -674,7 +670,7 @@ Partial Class frmColumn_Detail Me.LayoutControlItem22.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.TBPM_CONTROL_TABLEBindingSource, "INHERIT_VALUE", True)) Me.LayoutControlItem22.Location = New System.Drawing.Point(0, 90) Me.LayoutControlItem22.Name = "LayoutControlItem22" - Me.LayoutControlItem22.Size = New System.Drawing.Size(549, 34) + Me.LayoutControlItem22.Size = New System.Drawing.Size(549, 123) Me.LayoutControlItem22.TextSize = New System.Drawing.Size(0, 0) Me.LayoutControlItem22.TextVisible = False ' @@ -724,18 +720,18 @@ Partial Class frmColumn_Detail Me.LayoutControlItem24.Location = New System.Drawing.Point(0, 412) Me.LayoutControlItem24.Name = "LayoutControlItem24" Me.LayoutControlItem24.Padding = New DevExpress.XtraLayout.Utils.Padding(10, 10, 10, 10) - Me.LayoutControlItem24.Size = New System.Drawing.Size(573, 40) + Me.LayoutControlItem24.Size = New System.Drawing.Size(488, 46) resources.ApplyResources(Me.LayoutControlItem24, "LayoutControlItem24") Me.LayoutControlItem24.TextSize = New System.Drawing.Size(110, 13) ' - 'LayoutControlItem15 + 'LayoutControlItem26 ' - Me.LayoutControlItem15.Control = Me.LabelControl1 - Me.LayoutControlItem15.Location = New System.Drawing.Point(0, 452) - Me.LayoutControlItem15.Name = "LayoutControlItem15" - Me.LayoutControlItem15.Size = New System.Drawing.Size(573, 95) - Me.LayoutControlItem15.TextSize = New System.Drawing.Size(0, 0) - Me.LayoutControlItem15.TextVisible = False + Me.LayoutControlItem26.Control = Me.SimpleButton3 + Me.LayoutControlItem26.Location = New System.Drawing.Point(488, 412) + Me.LayoutControlItem26.Name = "LayoutControlItem26" + Me.LayoutControlItem26.Size = New System.Drawing.Size(85, 46) + Me.LayoutControlItem26.TextSize = New System.Drawing.Size(0, 0) + Me.LayoutControlItem26.TextVisible = False ' 'frmColumn_Detail ' @@ -802,7 +798,7 @@ Partial Class frmColumn_Detail CType(Me.LayoutControlItem23, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.LayoutControlItem21, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.LayoutControlItem24, System.ComponentModel.ISupportInitialize).EndInit() - CType(Me.LayoutControlItem15, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.LayoutControlItem26, System.ComponentModel.ISupportInitialize).EndInit() Me.ResumeLayout(False) Me.PerformLayout @@ -870,6 +866,6 @@ End Sub Friend WithEvents FORMULA_EXPRESSIONTextBox As TextBox Friend WithEvents LayoutControlItem24 As DevExpress.XtraLayout.LayoutControlItem Friend WithEvents LayoutControlItem25 As DevExpress.XtraLayout.LayoutControlItem - Friend WithEvents LabelControl1 As DevExpress.XtraEditors.LabelControl - Friend WithEvents LayoutControlItem15 As DevExpress.XtraLayout.LayoutControlItem + Friend WithEvents SimpleButton3 As DevExpress.XtraEditors.SimpleButton + Friend WithEvents LayoutControlItem26 As DevExpress.XtraLayout.LayoutControlItem End Class diff --git a/app/TaskFlow/frmColumn_Detail.resx b/app/TaskFlow/frmColumn_Detail.resx index 9d3fce5..f1fc629 100644 --- a/app/TaskFlow/frmColumn_Detail.resx +++ b/app/TaskFlow/frmColumn_Detail.resx @@ -184,50 +184,40 @@ RibbonPage2 - - Segoe UI, 8.25pt - - - - None + + 500, 424 - - 12, 464 + + + 10, 10, 10, 10 - - 569, 91 + + 81, 42 - - 30 - - - In der Formel nutzen wir die DataColumn.Expression‑Ausdruckssprache von ADO.NET -Kurz: ADO.NET DataColumn Expression Language. -Die Spaltennamen sind hier relevant. -Beispiele: -Multiplikation: [colMENGE] * [colPREIS] -Verkettung: [colVORNAME] + ' - ' [colNACHNAME] -IIF([colSTATUS] = 'X', 'OK', 'NOK') - - - - LabelControl1 - - - DevExpress.XtraEditors.LabelControl, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a - - + + 31 + + + ... + + + SimpleButton3 + + + DevExpress.XtraEditors.SimpleButton, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + + LayoutControl1 - + 4 142, 432 - 431, 20 + 346, 20 29 @@ -380,7 +370,6 @@ IIF([colSTATUS] = 'X', 'OK', 'NOK') 500, 212 - 10, 10, 10, 10 @@ -478,7 +467,7 @@ IIF([colSTATUS] = 'X', 'OK', 'NOK') 15 - 142, 567 + 142, 478 144, 20 @@ -499,7 +488,7 @@ IIF([colSTATUS] = 'X', 'OK', 'NOK') 16 - 428, 567 + 428, 478 145, 20 @@ -520,7 +509,7 @@ IIF([colSTATUS] = 'X', 'OK', 'NOK') 17 - 142, 607 + 142, 518 144, 20 @@ -541,7 +530,7 @@ IIF([colSTATUS] = 'X', 'OK', 'NOK') 18 - 428, 607 + 428, 518 145, 20 @@ -562,7 +551,7 @@ IIF([colSTATUS] = 'X', 'OK', 'NOK') 19 - 24, 696 + 24, 607 Read Only @@ -586,7 +575,7 @@ IIF([colSTATUS] = 'X', 'OK', 'NOK') 20 - 24, 740 + 24, 651 Lade Indexdaten @@ -610,7 +599,7 @@ IIF([colSTATUS] = 'X', 'OK', 'NOK') 21 - 24, 672 + 24, 583 Muss ausgefüllt werden @@ -634,7 +623,7 @@ IIF([colSTATUS] = 'X', 'OK', 'NOK') 22 - 24, 718 + 24, 629 Erweitertes Auswahl Control (für lange Listen) @@ -706,7 +695,7 @@ IIF([colSTATUS] = 'X', 'OK', 'NOK') 25 - 420, 672 + 420, 583 Combo @@ -760,7 +749,7 @@ IIF([colSTATUS] = 'X', 'OK', 'NOK') 27 - 24, 762 + 24, 673 Inherit Value (Vererbt den Wert der aktuellen Zelle auf alle nachfolgenden) @@ -1098,10 +1087,10 @@ IIF([colSTATUS] = 'X', 'OK', 'NOK') DevExpress.XtraLayout.LayoutControlItem, DevExpress.XtraLayout.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a - - LayoutControlItem15 + + LayoutControlItem26 - + DevExpress.XtraLayout.LayoutControlItem, DevExpress.XtraLayout.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a diff --git a/app/TaskFlow/frmColumn_Detail.vb b/app/TaskFlow/frmColumn_Detail.vb index a2773d1..27e683c 100644 --- a/app/TaskFlow/frmColumn_Detail.vb +++ b/app/TaskFlow/frmColumn_Detail.vb @@ -206,4 +206,22 @@ Public Class frmColumn_Detail Private Sub RibbonControl1_Click(sender As Object, e As EventArgs) Handles RibbonControl1.Click End Sub + + Private Sub SimpleButton3_Click(sender As Object, e As EventArgs) Handles SimpleButton3.Click + ' Alle verfügbaren Spalten für dieses Control laden + Dim availableColumns As DataTable = GetAvailableColumnsForControl() + + ' Expression Designer öffnen + Using designer As New frmExpression_Designer(availableColumns, FORMULA_EXPRESSIONTextBox.Text) + If designer.ShowDialog() = DialogResult.OK Then + FORMULA_EXPRESSIONTextBox.Text = designer.Expression + End If + End Using + End Sub + Private Function GetAvailableColumnsForControl() As DataTable + ' Spalten aus der aktuellen Control-Definition laden + Dim oSQL = "SELECT * FROM TBPM_CONTROL_TABLE WHERE CONTROL_ID = " & CURRENT_CONTROL_ID & " ORDER BY SEQUENCE" + Dim dt As DataTable = DatabaseFallback.GetDatatableECM(oSQL) + Return dt + End Function End Class \ No newline at end of file diff --git a/app/TaskFlow/frmExpression_Designer.Designer.vb b/app/TaskFlow/frmExpression_Designer.Designer.vb new file mode 100644 index 0000000..3932047 --- /dev/null +++ b/app/TaskFlow/frmExpression_Designer.Designer.vb @@ -0,0 +1,465 @@ +Imports DevExpress.XtraEditors + + +Partial Class frmExpression_Designer + Inherits DevExpress.XtraEditors.XtraForm + + 'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen. + + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + + 'Wird vom Windows Form-Designer benötigt. + Private components As System.ComponentModel.IContainer + + 'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich. + 'Das Bearbeiten ist mit dem Windows Form-Designer möglich. + 'Das Bearbeiten mit dem Code-Editor ist nicht möglich. + + Private Sub InitializeComponent() + Me.layoutControl1 = New DevExpress.XtraLayout.LayoutControl() + Me.btnClear = New DevExpress.XtraEditors.SimpleButton() + Me.btnCancel = New DevExpress.XtraEditors.SimpleButton() + Me.btnOK = New DevExpress.XtraEditors.SimpleButton() + Me.lblColumnCount = New System.Windows.Forms.Label() + Me.lblValidation = New System.Windows.Forms.Label() + Me.btnValidate = New DevExpress.XtraEditors.SimpleButton() + Me.panelOperators = New System.Windows.Forms.Panel() + Me.lstFunctions = New System.Windows.Forms.ListBox() + Me.lstColumns = New System.Windows.Forms.ListBox() + Me.txtExpression = New DevExpress.XtraEditors.MemoEdit() + Me.Root = New DevExpress.XtraLayout.LayoutControlGroup() + Me.layoutControlItem1 = New DevExpress.XtraLayout.LayoutControlItem() + Me.layoutControlItem2 = New DevExpress.XtraLayout.LayoutControlItem() + Me.layoutControlItem3 = New DevExpress.XtraLayout.LayoutControlItem() + Me.layoutControlItem4 = New DevExpress.XtraLayout.LayoutControlItem() + Me.layoutControlItem5 = New DevExpress.XtraLayout.LayoutControlItem() + Me.layoutControlItem6 = New DevExpress.XtraLayout.LayoutControlItem() + Me.layoutControlItem7 = New DevExpress.XtraLayout.LayoutControlItem() + Me.emptySpaceItem1 = New DevExpress.XtraLayout.EmptySpaceItem() + Me.layoutControlItem8 = New DevExpress.XtraLayout.LayoutControlItem() + Me.layoutControlItem9 = New DevExpress.XtraLayout.LayoutControlItem() + Me.layoutControlItem10 = New DevExpress.XtraLayout.LayoutControlItem() + Me.btnAdd = New DevExpress.XtraEditors.SimpleButton() + Me.btnSubtract = New DevExpress.XtraEditors.SimpleButton() + Me.btnMultiply = New DevExpress.XtraEditors.SimpleButton() + Me.btnDivide = New DevExpress.XtraEditors.SimpleButton() + Me.btnEquals = New DevExpress.XtraEditors.SimpleButton() + Me.btnNotEquals = New DevExpress.XtraEditors.SimpleButton() + Me.btnGreater = New DevExpress.XtraEditors.SimpleButton() + Me.btnLess = New DevExpress.XtraEditors.SimpleButton() + Me.btnAnd = New DevExpress.XtraEditors.SimpleButton() + Me.btnOr = New DevExpress.XtraEditors.SimpleButton() + Me.btnNot = New DevExpress.XtraEditors.SimpleButton() + Me.btnOpenBracket = New DevExpress.XtraEditors.SimpleButton() + Me.btnCloseBracket = New DevExpress.XtraEditors.SimpleButton() + CType(Me.layoutControl1, System.ComponentModel.ISupportInitialize).BeginInit() + Me.layoutControl1.SuspendLayout() + CType(Me.txtExpression.Properties, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.Root, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.layoutControlItem1, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.layoutControlItem2, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.layoutControlItem3, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.layoutControlItem4, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.layoutControlItem5, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.layoutControlItem6, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.layoutControlItem7, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.emptySpaceItem1, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.layoutControlItem8, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.layoutControlItem9, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.layoutControlItem10, System.ComponentModel.ISupportInitialize).BeginInit() + Me.SuspendLayout() + ' + 'layoutControl1 + ' + Me.layoutControl1.Controls.Add(Me.btnClear) + Me.layoutControl1.Controls.Add(Me.btnCancel) + Me.layoutControl1.Controls.Add(Me.btnOK) + Me.layoutControl1.Controls.Add(Me.lblColumnCount) + Me.layoutControl1.Controls.Add(Me.lblValidation) + Me.layoutControl1.Controls.Add(Me.btnValidate) + Me.layoutControl1.Controls.Add(Me.panelOperators) + Me.layoutControl1.Controls.Add(Me.lstFunctions) + Me.layoutControl1.Controls.Add(Me.lstColumns) + Me.layoutControl1.Controls.Add(Me.txtExpression) + Me.layoutControl1.Dock = System.Windows.Forms.DockStyle.Fill + Me.layoutControl1.Location = New System.Drawing.Point(0, 0) + Me.layoutControl1.Name = "layoutControl1" + Me.layoutControl1.Root = Me.Root + Me.layoutControl1.Size = New System.Drawing.Size(900, 600) + Me.layoutControl1.TabIndex = 0 + Me.layoutControl1.Text = "LayoutControl1" + ' + 'btnClear + ' + Me.btnClear.Location = New System.Drawing.Point(809, 558) + Me.btnClear.Name = "btnClear" + Me.btnClear.Size = New System.Drawing.Size(79, 30) + Me.btnClear.StyleController = Me.layoutControl1 + Me.btnClear.TabIndex = 13 + Me.btnClear.Text = "Löschen" + ' + 'btnCancel + ' + Me.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel + Me.btnCancel.Location = New System.Drawing.Point(724, 558) + Me.btnCancel.Name = "btnCancel" + Me.btnCancel.Size = New System.Drawing.Size(81, 30) + Me.btnCancel.StyleController = Me.layoutControl1 + Me.btnCancel.TabIndex = 12 + Me.btnCancel.Text = "Abbrechen" + ' + 'btnOK + ' + Me.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK + Me.btnOK.Location = New System.Drawing.Point(644, 558) + Me.btnOK.Name = "btnOK" + Me.btnOK.Size = New System.Drawing.Size(76, 30) + Me.btnOK.StyleController = Me.layoutControl1 + Me.btnOK.TabIndex = 11 + Me.btnOK.Text = "OK" + ' + 'lblColumnCount + ' + Me.lblColumnCount.Location = New System.Drawing.Point(12, 472) + Me.lblColumnCount.Name = "lblColumnCount" + Me.lblColumnCount.Size = New System.Drawing.Size(876, 20) + Me.lblColumnCount.TabIndex = 10 + Me.lblColumnCount.Text = "Referenzierte Spalten: 0" + ' + 'lblValidation + ' + Me.lblValidation.Location = New System.Drawing.Point(116, 438) + Me.lblValidation.Name = "lblValidation" + Me.lblValidation.Size = New System.Drawing.Size(772, 30) + Me.lblValidation.TabIndex = 9 + ' + 'btnValidate + ' + Me.btnValidate.Location = New System.Drawing.Point(12, 438) + Me.btnValidate.Name = "btnValidate" + Me.btnValidate.Size = New System.Drawing.Size(100, 30) + Me.btnValidate.StyleController = Me.layoutControl1 + Me.btnValidate.TabIndex = 8 + Me.btnValidate.Text = "Validieren" + ' + 'panelOperators + ' + Me.panelOperators.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle + Me.panelOperators.Location = New System.Drawing.Point(602, 161) + Me.panelOperators.Name = "panelOperators" + Me.panelOperators.Size = New System.Drawing.Size(286, 273) + Me.panelOperators.TabIndex = 7 + ' + 'lstFunctions + ' + Me.lstFunctions.FormattingEnabled = True + Me.lstFunctions.Location = New System.Drawing.Point(307, 161) + Me.lstFunctions.Name = "lstFunctions" + Me.lstFunctions.Size = New System.Drawing.Size(291, 273) + Me.lstFunctions.TabIndex = 6 + ' + 'lstColumns + ' + Me.lstColumns.FormattingEnabled = True + Me.lstColumns.Location = New System.Drawing.Point(12, 161) + Me.lstColumns.Name = "lstColumns" + Me.lstColumns.Size = New System.Drawing.Size(291, 273) + Me.lstColumns.TabIndex = 5 + ' + 'txtExpression + ' + Me.txtExpression.Location = New System.Drawing.Point(12, 28) + Me.txtExpression.Name = "txtExpression" + Me.txtExpression.Properties.ScrollBars = System.Windows.Forms.ScrollBars.Both + Me.txtExpression.Properties.WordWrap = False + Me.txtExpression.Size = New System.Drawing.Size(876, 113) + Me.txtExpression.StyleController = Me.layoutControl1 + Me.txtExpression.TabIndex = 4 + ' + 'Root + ' + Me.Root.EnableIndentsWithoutBorders = DevExpress.Utils.DefaultBoolean.[True] + Me.Root.GroupBordersVisible = False + Me.Root.Items.AddRange(New DevExpress.XtraLayout.BaseLayoutItem() {Me.layoutControlItem1, Me.layoutControlItem2, Me.layoutControlItem3, Me.layoutControlItem4, Me.layoutControlItem5, Me.layoutControlItem6, Me.layoutControlItem7, Me.emptySpaceItem1, Me.layoutControlItem8, Me.layoutControlItem9, Me.layoutControlItem10}) + Me.Root.Name = "Root" + Me.Root.Size = New System.Drawing.Size(900, 600) + Me.Root.TextVisible = False + ' + 'layoutControlItem1 + ' + Me.layoutControlItem1.Control = Me.txtExpression + Me.layoutControlItem1.Location = New System.Drawing.Point(0, 0) + Me.layoutControlItem1.Name = "layoutControlItem1" + Me.layoutControlItem1.Size = New System.Drawing.Size(880, 133) + Me.layoutControlItem1.Text = "Expression:" + Me.layoutControlItem1.TextLocation = DevExpress.Utils.Locations.Top + Me.layoutControlItem1.TextSize = New System.Drawing.Size(61, 13) + ' + 'layoutControlItem2 + ' + Me.layoutControlItem2.Control = Me.lstColumns + Me.layoutControlItem2.Location = New System.Drawing.Point(0, 133) + Me.layoutControlItem2.Name = "layoutControlItem2" + Me.layoutControlItem2.Size = New System.Drawing.Size(295, 293) + Me.layoutControlItem2.Text = "Verfügbare Spalten:" + Me.layoutControlItem2.TextLocation = DevExpress.Utils.Locations.Top + Me.layoutControlItem2.TextSize = New System.Drawing.Size(61, 13) + ' + 'layoutControlItem3 + ' + Me.layoutControlItem3.Control = Me.lstFunctions + Me.layoutControlItem3.Location = New System.Drawing.Point(295, 133) + Me.layoutControlItem3.Name = "layoutControlItem3" + Me.layoutControlItem3.Size = New System.Drawing.Size(295, 293) + Me.layoutControlItem3.Text = "Funktionen:" + Me.layoutControlItem3.TextLocation = DevExpress.Utils.Locations.Top + Me.layoutControlItem3.TextSize = New System.Drawing.Size(61, 13) + ' + 'layoutControlItem4 + ' + Me.layoutControlItem4.Control = Me.panelOperators + Me.layoutControlItem4.Location = New System.Drawing.Point(590, 133) + Me.layoutControlItem4.Name = "layoutControlItem4" + Me.layoutControlItem4.Size = New System.Drawing.Size(290, 293) + Me.layoutControlItem4.Text = "Operatoren:" + Me.layoutControlItem4.TextLocation = DevExpress.Utils.Locations.Top + Me.layoutControlItem4.TextSize = New System.Drawing.Size(61, 13) + ' + 'layoutControlItem5 + ' + Me.layoutControlItem5.Control = Me.btnValidate + Me.layoutControlItem5.Location = New System.Drawing.Point(0, 426) + Me.layoutControlItem5.MaxSize = New System.Drawing.Size(104, 34) + Me.layoutControlItem5.MinSize = New System.Drawing.Size(104, 34) + Me.layoutControlItem5.Name = "layoutControlItem5" + Me.layoutControlItem5.Size = New System.Drawing.Size(104, 34) + Me.layoutControlItem5.SizeConstraintsType = DevExpress.XtraLayout.SizeConstraintsType.Custom + Me.layoutControlItem5.TextSize = New System.Drawing.Size(0, 0) + Me.layoutControlItem5.TextVisible = False + ' + 'layoutControlItem6 + ' + Me.layoutControlItem6.Control = Me.lblValidation + Me.layoutControlItem6.Location = New System.Drawing.Point(104, 426) + Me.layoutControlItem6.Name = "layoutControlItem6" + Me.layoutControlItem6.Size = New System.Drawing.Size(776, 34) + Me.layoutControlItem6.TextSize = New System.Drawing.Size(0, 0) + Me.layoutControlItem6.TextVisible = False + ' + 'layoutControlItem7 + ' + Me.layoutControlItem7.Control = Me.lblColumnCount + Me.layoutControlItem7.Location = New System.Drawing.Point(0, 460) + Me.layoutControlItem7.Name = "layoutControlItem7" + Me.layoutControlItem7.Size = New System.Drawing.Size(880, 24) + Me.layoutControlItem7.TextSize = New System.Drawing.Size(0, 0) + Me.layoutControlItem7.TextVisible = False + ' + 'emptySpaceItem1 + ' + Me.emptySpaceItem1.AllowHotTrack = False + Me.emptySpaceItem1.Location = New System.Drawing.Point(0, 484) + Me.emptySpaceItem1.Name = "emptySpaceItem1" + Me.emptySpaceItem1.Size = New System.Drawing.Size(632, 62) + Me.emptySpaceItem1.TextSize = New System.Drawing.Size(0, 0) + ' + 'layoutControlItem8 + ' + Me.layoutControlItem8.Control = Me.btnOK + Me.layoutControlItem8.Location = New System.Drawing.Point(632, 546) + Me.layoutControlItem8.MaxSize = New System.Drawing.Size(80, 34) + Me.layoutControlItem8.MinSize = New System.Drawing.Size(80, 34) + Me.layoutControlItem8.Name = "layoutControlItem8" + Me.layoutControlItem8.Size = New System.Drawing.Size(80, 34) + Me.layoutControlItem8.SizeConstraintsType = DevExpress.XtraLayout.SizeConstraintsType.Custom + Me.layoutControlItem8.TextSize = New System.Drawing.Size(0, 0) + Me.layoutControlItem8.TextVisible = False + ' + 'layoutControlItem9 + ' + Me.layoutControlItem9.Control = Me.btnCancel + Me.layoutControlItem9.Location = New System.Drawing.Point(712, 546) + Me.layoutControlItem9.MaxSize = New System.Drawing.Size(85, 34) + Me.layoutControlItem9.MinSize = New System.Drawing.Size(85, 34) + Me.layoutControlItem9.Name = "layoutControlItem9" + Me.layoutControlItem9.Size = New System.Drawing.Size(85, 34) + Me.layoutControlItem9.SizeConstraintsType = DevExpress.XtraLayout.SizeConstraintsType.Custom + Me.layoutControlItem9.TextSize = New System.Drawing.Size(0, 0) + Me.layoutControlItem9.TextVisible = False + ' + 'layoutControlItem10 + ' + Me.layoutControlItem10.Control = Me.btnClear + Me.layoutControlItem10.Location = New System.Drawing.Point(797, 546) + Me.layoutControlItem10.MaxSize = New System.Drawing.Size(83, 34) + Me.layoutControlItem10.MinSize = New System.Drawing.Size(83, 34) + Me.layoutControlItem10.Name = "layoutControlItem10" + Me.layoutControlItem10.Size = New System.Drawing.Size(83, 34) + Me.layoutControlItem10.SizeConstraintsType = DevExpress.XtraLayout.SizeConstraintsType.Custom + Me.layoutControlItem10.TextSize = New System.Drawing.Size(0, 0) + Me.layoutControlItem10.TextVisible = False + ' + 'btnAdd + ' + Me.btnAdd.Name = "btnAdd" + Me.btnAdd.Size = New System.Drawing.Size(50, 30) + Me.btnAdd.TabIndex = 0 + Me.btnAdd.Text = "+" + ' + 'btnSubtract + ' + Me.btnSubtract.Name = "btnSubtract" + Me.btnSubtract.Size = New System.Drawing.Size(50, 30) + Me.btnSubtract.TabIndex = 1 + Me.btnSubtract.Text = "-" + ' + 'btnMultiply + ' + Me.btnMultiply.Name = "btnMultiply" + Me.btnMultiply.Size = New System.Drawing.Size(50, 30) + Me.btnMultiply.TabIndex = 2 + Me.btnMultiply.Text = "*" + ' + 'btnDivide + ' + Me.btnDivide.Name = "btnDivide" + Me.btnDivide.Size = New System.Drawing.Size(50, 30) + Me.btnDivide.TabIndex = 3 + Me.btnDivide.Text = "/" + ' + 'btnEquals + ' + Me.btnEquals.Name = "btnEquals" + Me.btnEquals.Size = New System.Drawing.Size(50, 30) + Me.btnEquals.TabIndex = 4 + Me.btnEquals.Text = "=" + ' + 'btnNotEquals + ' + Me.btnNotEquals.Name = "btnNotEquals" + Me.btnNotEquals.Size = New System.Drawing.Size(50, 30) + Me.btnNotEquals.TabIndex = 5 + Me.btnNotEquals.Text = "<>" + ' + 'btnGreater + ' + Me.btnGreater.Name = "btnGreater" + Me.btnGreater.Size = New System.Drawing.Size(50, 30) + Me.btnGreater.TabIndex = 6 + Me.btnGreater.Text = ">" + ' + 'btnLess + ' + Me.btnLess.Name = "btnLess" + Me.btnLess.Size = New System.Drawing.Size(50, 30) + Me.btnLess.TabIndex = 7 + Me.btnLess.Text = "<" + ' + 'btnAnd + ' + Me.btnAnd.Name = "btnAnd" + Me.btnAnd.Size = New System.Drawing.Size(50, 30) + Me.btnAnd.TabIndex = 8 + Me.btnAnd.Text = "AND" + ' + 'btnOr + ' + Me.btnOr.Name = "btnOr" + Me.btnOr.Size = New System.Drawing.Size(50, 30) + Me.btnOr.TabIndex = 9 + Me.btnOr.Text = "OR" + ' + 'btnNot + ' + Me.btnNot.Name = "btnNot" + Me.btnNot.Size = New System.Drawing.Size(50, 30) + Me.btnNot.TabIndex = 10 + Me.btnNot.Text = "NOT" + ' + 'btnOpenBracket + ' + Me.btnOpenBracket.Name = "btnOpenBracket" + Me.btnOpenBracket.Size = New System.Drawing.Size(50, 30) + Me.btnOpenBracket.TabIndex = 11 + Me.btnOpenBracket.Text = "(" + ' + 'btnCloseBracket + ' + Me.btnCloseBracket.Name = "btnCloseBracket" + Me.btnCloseBracket.Size = New System.Drawing.Size(50, 30) + Me.btnCloseBracket.TabIndex = 12 + Me.btnCloseBracket.Text = ")" + ' + 'frmExpression_Designer + ' + Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) + Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font + Me.ClientSize = New System.Drawing.Size(900, 600) + Me.Controls.Add(Me.layoutControl1) + Me.Name = "frmExpression_Designer" + Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent + Me.Text = "Expression Designer" + CType(Me.layoutControl1, System.ComponentModel.ISupportInitialize).EndInit() + Me.layoutControl1.ResumeLayout(False) + CType(Me.txtExpression.Properties, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.Root, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.layoutControlItem1, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.layoutControlItem2, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.layoutControlItem3, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.layoutControlItem4, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.layoutControlItem5, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.layoutControlItem6, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.layoutControlItem7, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.emptySpaceItem1, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.layoutControlItem8, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.layoutControlItem9, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.layoutControlItem10, System.ComponentModel.ISupportInitialize).EndInit() + Me.ResumeLayout(False) + + End Sub + + Friend WithEvents layoutControl1 As DevExpress.XtraLayout.LayoutControl + Friend WithEvents btnClear As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnCancel As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnOK As DevExpress.XtraEditors.SimpleButton + Friend WithEvents lblColumnCount As Label + Friend WithEvents lblValidation As Label + Friend WithEvents btnValidate As DevExpress.XtraEditors.SimpleButton + Friend WithEvents panelOperators As Panel + Friend WithEvents lstFunctions As ListBox + Friend WithEvents lstColumns As ListBox + Friend WithEvents txtExpression As DevExpress.XtraEditors.MemoEdit + Friend WithEvents Root As DevExpress.XtraLayout.LayoutControlGroup + Friend WithEvents layoutControlItem1 As DevExpress.XtraLayout.LayoutControlItem + Friend WithEvents layoutControlItem2 As DevExpress.XtraLayout.LayoutControlItem + Friend WithEvents layoutControlItem3 As DevExpress.XtraLayout.LayoutControlItem + Friend WithEvents layoutControlItem4 As DevExpress.XtraLayout.LayoutControlItem + Friend WithEvents layoutControlItem5 As DevExpress.XtraLayout.LayoutControlItem + Friend WithEvents layoutControlItem6 As DevExpress.XtraLayout.LayoutControlItem + Friend WithEvents layoutControlItem7 As DevExpress.XtraLayout.LayoutControlItem + Friend WithEvents emptySpaceItem1 As DevExpress.XtraLayout.EmptySpaceItem + Friend WithEvents layoutControlItem8 As DevExpress.XtraLayout.LayoutControlItem + Friend WithEvents layoutControlItem9 As DevExpress.XtraLayout.LayoutControlItem + Friend WithEvents layoutControlItem10 As DevExpress.XtraLayout.LayoutControlItem + Friend WithEvents btnAdd As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnSubtract As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnMultiply As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnDivide As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnEquals As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnNotEquals As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnGreater As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnLess As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnAnd As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnOr As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnNot As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnOpenBracket As DevExpress.XtraEditors.SimpleButton + Friend WithEvents btnCloseBracket As DevExpress.XtraEditors.SimpleButton +End Class \ No newline at end of file diff --git a/app/TaskFlow/frmExpression_Designer.resx b/app/TaskFlow/frmExpression_Designer.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/app/TaskFlow/frmExpression_Designer.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/app/TaskFlow/frmExpression_Designer.vb b/app/TaskFlow/frmExpression_Designer.vb new file mode 100644 index 0000000..6af4280 --- /dev/null +++ b/app/TaskFlow/frmExpression_Designer.vb @@ -0,0 +1,284 @@ +Imports System.Text.RegularExpressions +Imports DevExpress.XtraEditors + +Public Class frmExpression_Designer + Private _availableColumns As DataTable + Private _currentExpression As String = "" + + Public Property Expression As String + Get + Return _currentExpression + End Get + Set(value As String) + _currentExpression = value + txtExpression.Text = value + End Set + End Property + + Public Sub New(pAvailableColumns As DataTable, pCurrentExpression As String) + InitializeComponent() + + _availableColumns = pAvailableColumns + _currentExpression = pCurrentExpression + End Sub + Private Sub ConfigureOperatorButtons() + Dim yPos As Integer = 10 + + ' Arithmetische Operatoren + AddOperatorButton(btnAdd, "+", 10, yPos, "Addition") + AddOperatorButton(btnSubtract, "-", 70, yPos, "Subtraktion") + AddOperatorButton(btnMultiply, "*", 130, yPos, "Multiplikation") + AddOperatorButton(btnDivide, "/", 190, yPos, "Division") + + yPos += 40 + + ' Vergleichsoperatoren + AddOperatorButton(btnEquals, "=", 10, yPos, "Gleich") + AddOperatorButton(btnNotEquals, "<>", 70, yPos, "Ungleich") + AddOperatorButton(btnGreater, ">", 130, yPos, "Größer") + AddOperatorButton(btnLess, "<", 190, yPos, "Kleiner") + + yPos += 40 + + ' Logische Operatoren + AddOperatorButton(btnAnd, "AND", 10, yPos, "Und") + AddOperatorButton(btnOr, "OR", 70, yPos, "Oder") + AddOperatorButton(btnNot, "NOT", 130, yPos, "Nicht") + + yPos += 40 + + ' Klammern + AddOperatorButton(btnOpenBracket, "(", 10, yPos, "Öffnende Klammer") + AddOperatorButton(btnCloseBracket, ")", 70, yPos, "Schließende Klammer") + End Sub + + Private Sub AddOperatorButton(btn As SimpleButton, text As String, x As Integer, y As Integer, tooltip As String) + btn.Text = text + btn.Location = New Point(x, y) + btn.Size = New Size(50, 30) + btn.ToolTip = tooltip + Me.panelOperators.Controls.Add(btn) + End Sub + Private Sub frmExpressionDesigner_Load(sender As Object, e As EventArgs) Handles MyBase.Load + ' ZUERST Operatoren-Buttons erstellen + ConfigureOperatorButtons() + + ' Spalten laden + LoadAvailableColumns() + + ' Funktionen laden + LoadFunctions() + + ' Operatoren laden + LoadOperators() + + ' Aktuelle Expression anzeigen + txtExpression.Text = _currentExpression + + ' Syntax-Highlighting aktivieren (optional) + UpdateSyntaxHighlighting() + ' Event-Handler für Text-Änderungen hinzufügen + AddHandler txtExpression.EditValueChanged, AddressOf txtExpression_EditValueChanged + End Sub + + Private Sub txtExpression_EditValueChanged(sender As Object, e As EventArgs) + ' Validierungsmeldung zurücksetzen + lblValidation.Text = String.Empty + lblValidation.ForeColor = Color.Black + + ' Syntax-Highlighting aktualisieren + UpdateSyntaxHighlighting() + + ' Aktuellen Wert speichern + _currentExpression = txtExpression.Text + End Sub + Private Sub LoadAvailableColumns() + lstColumns.Items.Clear() + + For Each row As DataRow In _availableColumns.Rows + Dim columnName As String = row.Item("SPALTENNAME").ToString() + Dim columnType As String = row.Item("TYPE_COLUMN").ToString() + Dim displayText As String = $"{columnName} ({columnType})" + + lstColumns.Items.Add(New ListBoxItem With { + .DisplayText = displayText, + .ColumnName = columnName, + .DataType = columnType + }) + Next + End Sub + + Private Sub LoadFunctions() + lstFunctions.Items.Clear() + + ' Mathematische Funktionen + lstFunctions.Items.Add(New FunctionItem("IIF", "IIF([Bedingung], Wahr, Falsch)", "Bedingte Verzweigung")) + lstFunctions.Items.Add(New FunctionItem("IsNull", "IsNull([Spalte], Ersatzwert)", "Null-Behandlung")) + lstFunctions.Items.Add(New FunctionItem("Convert", "Convert([Spalte], 'System.Double')", "Typkonvertierung")) + + ' String-Funktionen + lstFunctions.Items.Add(New FunctionItem("Len", "Len([Text])", "Länge eines Textes")) + lstFunctions.Items.Add(New FunctionItem("Trim", "Trim([Text])", "Leerzeichen entfernen")) + lstFunctions.Items.Add(New FunctionItem("Substring", "Substring([Text], Start, Länge)", "Teilstring extrahieren")) + End Sub + + Private Sub LoadOperators() + ' Arithmetische Operatoren + btnAdd.Tag = " + " + btnSubtract.Tag = " - " + btnMultiply.Tag = " * " + btnDivide.Tag = " / " + + ' Vergleichsoperatoren + btnEquals.Tag = " = " + btnNotEquals.Tag = " <> " + btnGreater.Tag = " > " + btnLess.Tag = " < " + + ' Logische Operatoren + btnAnd.Tag = " AND " + btnOr.Tag = " OR " + btnNot.Tag = " NOT " + + ' Klammern + btnOpenBracket.Tag = "(" + btnCloseBracket.Tag = ")" + End Sub + + Private Sub lstColumns_DoubleClick(sender As Object, e As EventArgs) Handles lstColumns.DoubleClick + If lstColumns.SelectedItem IsNot Nothing Then + Dim item As ListBoxItem = CType(lstColumns.SelectedItem, ListBoxItem) + InsertText($"[{item.ColumnName}]") + End If + End Sub + + Private Sub lstFunctions_DoubleClick(sender As Object, e As EventArgs) Handles lstFunctions.DoubleClick + If lstFunctions.SelectedItem IsNot Nothing Then + Dim item As FunctionItem = CType(lstFunctions.SelectedItem, FunctionItem) + InsertText(item.Template) + End If + End Sub + + Private Sub Operator_Click(sender As Object, e As EventArgs) Handles btnAdd.Click, btnSubtract.Click, btnMultiply.Click, btnDivide.Click, + btnEquals.Click, btnNotEquals.Click, btnGreater.Click, btnLess.Click, + btnAnd.Click, btnOr.Click, btnNot.Click, + btnOpenBracket.Click, btnCloseBracket.Click + Dim btn As SimpleButton = CType(sender, SimpleButton) + InsertText(btn.Tag.ToString()) + End Sub + + + Private Sub InsertText(text As String) + Dim selectionStart As Integer = txtExpression.SelectionStart + + txtExpression.Text = txtExpression.Text.Insert(selectionStart, text) + txtExpression.SelectionStart = selectionStart + text.Length + txtExpression.Focus() + + _currentExpression = txtExpression.Text + ' UpdateSyntaxHighlighting() wird jetzt im Event-Handler aufgerufen + End Sub + + Private Sub btnValidate_Click(sender As Object, e As EventArgs) Handles btnValidate.Click + ValidateExpression() + End Sub + + Private Sub ValidateExpression() + Try + ' Testdatatable erstellen + Dim testTable As New DataTable() + + ' Spalten hinzufügen + For Each row As DataRow In _availableColumns.Rows + Dim colName As String = row.Item("SPALTENNAME").ToString() + Dim colType As String = row.Item("TYPE_COLUMN").ToString() + + Dim dataType As Type = GetType(String) + Select Case colType + Case "INTEGER" + dataType = GetType(Integer) + Case "DOUBLE", "CURRENCY" + dataType = GetType(Double) + Case "BOOLEAN" + dataType = GetType(Boolean) + End Select + + testTable.Columns.Add(colName, dataType) + Next + + ' Test-Spalte mit Expression erstellen + Dim testColumn As New DataColumn("TEST_EXPRESSION") With { + .Expression = txtExpression.Text + } + testTable.Columns.Add(testColumn) + + ' Erfolg! + lblValidation.Text = "✓ Expression ist gültig!" + lblValidation.ForeColor = Color.Green + + Catch ex As Exception + lblValidation.Text = $"⚠️ Fehler: {ex.Message}" + lblValidation.ForeColor = Color.Red + End Try + End Sub + + Private Sub UpdateSyntaxHighlighting() + ' Optional: Einfaches Syntax-Highlighting + ' Spalten-Referenzen markieren + Dim pattern As String = "\[([^\]]+)\]" + Dim matches = Regex.Matches(txtExpression.Text, pattern) + + ' Anzahl der referenzierten Spalten anzeigen + lblColumnCount.Text = $"Referenzierte Spalten: {matches.Count}" + End Sub + + Private Sub btnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click + ' Finale Validierung + ValidateExpression() + + If lblValidation.ForeColor = Color.Green Then + _currentExpression = txtExpression.Text + Me.DialogResult = DialogResult.OK + Me.Close() + Else + MessageBox.Show("Bitte korrigieren Sie die Expression zuerst!", "Validierung fehlgeschlagen", MessageBoxButtons.OK, MessageBoxIcon.Warning) + End If + End Sub + + Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click + Me.DialogResult = DialogResult.Cancel + Me.Close() + End Sub + + Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click + txtExpression.EditValue = String.Empty + _currentExpression = "" + End Sub + + ' Hilfeklassen + Private Class ListBoxItem + Public Property DisplayText As String + Public Property ColumnName As String + Public Property DataType As String + + Public Overrides Function ToString() As String + Return DisplayText + End Function + End Class + + Private Class FunctionItem + Public Property Name As String + Public Property Template As String + Public Property Description As String + + Public Sub New(name As String, template As String, description As String) + Me.Name = name + Me.Template = template + Me.Description = description + End Sub + + Public Overrides Function ToString() As String + Return $"{Name} - {Description}" + End Function + End Class +End Class \ No newline at end of file diff --git a/app/TaskFlow/frmFormDesigner.vb b/app/TaskFlow/frmFormDesigner.vb index a5a1b1c..24aa955 100644 --- a/app/TaskFlow/frmFormDesigner.vb +++ b/app/TaskFlow/frmFormDesigner.vb @@ -291,20 +291,25 @@ Public Class frmFormDesigner SetMovementHandlers(dgv) Case "TABLE" - - Dim oSQL = $"Select IIF(LANG.CAPTION Is NULL,T.SPALTEN_HEADER,LANG.CAPTION) SPALTEN_HEADER_LANG, T.* FROM TBPM_CONTROL_TABLE T + Try + Dim oSQL = $"Select IIF(LANG.CAPTION Is NULL,T.SPALTEN_HEADER,LANG.CAPTION) SPALTEN_HEADER_LANG, T.* FROM TBPM_CONTROL_TABLE T INNER JOIN TBPM_PROFILE_CONTROLS T1 ON T.CONTROL_ID = T1.GUID LEFT JOIN (SELECT * FROM TBPM_CONTOL_TABLE_LANG WHERE LANG_CODE = '{USER_LANGUAGE}') LANG ON T.GUID = LANG.COL_ID WHERE T1.CONTROL_ACTIVE = 1 AND T.CONTROL_ID = T1.GUID AND T.CONTROL_ID = {guid} ORDER BY T.SEQUENCE" - Dim oDTColumnsPerDevExGrid As DataTable = DatabaseFallback.GetDatatableECM(oSQL) ', "FDesignLaodControls") + Dim oDTColumnsPerDevExGrid As DataTable = DatabaseFallback.GetDatatableECM(oSQL) ', "FDesignLaodControls") + + Dim table = ControlCreator.CreateExistingGridControl(row, oDTColumnsPerDevExGrid, True, "EUR") - Dim table = ControlCreator.CreateExistingGridControl(row, oDTColumnsPerDevExGrid, True, "EUR") + AddHandler table.MouseClick, AddressOf gridControl_MouseClick + ' AddHandler table.ColumnHeaderMouseClick, AddressOf table_ColumnHeaderMouseClick - AddHandler table.MouseClick, AddressOf gridControl_MouseClick - ' AddHandler table.ColumnHeaderMouseClick, AddressOf table_ColumnHeaderMouseClick + pnldesigner.Controls.Add(table) + SetMovementHandlers(table) + Catch ex As Exception + _Logger.Error(ex) + MsgBox("Error while loading Table Control with Id " & guid & vbNewLine & ex.Message, MsgBoxStyle.Critical, "Achtung:") + End Try - pnldesigner.Controls.Add(table) - SetMovementHandlers(table) Case "LOOKUP" Dim lookup = ControlCreator.CreateExistingLookupControl(row, True) diff --git a/app/TaskFlow/frmGhostMode.vb b/app/TaskFlow/frmGhostMode.vb index 611b99e..f602af0 100644 --- a/app/TaskFlow/frmGhostMode.vb +++ b/app/TaskFlow/frmGhostMode.vb @@ -1,11 +1,11 @@ Public Class frmGhostMode Private Sub frmGhostMode_Load(sender As Object, e As EventArgs) Handles Me.Load - Dim oSQL = "SELECT [SQL_COMMAND] FROM TBDD_SQL_COMMANDS where TITLE = 'GHOST_SELECT'" + Dim oSQL = "SELECT [SQL_COMMAND] FROM TBDD_SQL_COMMANDS WITH (NOLOCK) where TITLE = 'GHOST_SELECT'" Dim DT_USER = DatabaseFallback.GetDatatableECM(oSQL) ' If IsNothing(DT_USER) Then LOGGER.Info("GHOST Select 1 was nothing, now trying 2nd..") - oSQL = "SELECT CONFIG_VALUE FROM TBIDB_BASE WHERE CONFIG_NAME = 'GHOST_SELECT'" + oSQL = "SELECT CONFIG_VALUE FROM TBIDB_BASE WITH (NOLOCK) WHERE CONFIG_NAME = 'GHOST_SELECT'" If Not IsNothing(oSQL) Then oSQL = DatabaseFallback.GetScalarValueIDB(oSQL) DT_USER = DatabaseFallback.GetDatatableIDB(oSQL) diff --git a/app/TaskFlow/frmMain.resx b/app/TaskFlow/frmMain.resx index 3b2bf0b..b8c8a43 100644 --- a/app/TaskFlow/frmMain.resx +++ b/app/TaskFlow/frmMain.resx @@ -125,7 +125,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADw - CAAAAk1TRnQBSQFMAgEBAgEAAbgBCwG4AQsBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + CAAAAk1TRnQBSQFMAgEBAgEAAcABCwHAAQsBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA diff --git a/app/TaskFlow/frmMain.vb b/app/TaskFlow/frmMain.vb index 5da7bde..ef6311a 100644 --- a/app/TaskFlow/frmMain.vb +++ b/app/TaskFlow/frmMain.vb @@ -21,6 +21,7 @@ Imports DigitalData.Modules.EDMI.API.Constants Imports DigitalData.Modules.EDMI.API.DatabaseWithFallback Imports DigitalData.Modules.Windream Imports DigitalData.Modules.ZooFlow +Imports GdPicture.Internal.CAD.DWG.Entities Public Class frmMain Private Property FormHelper As FormHelper @@ -36,7 +37,7 @@ Public Class frmMain Private YellowDocuments As Integer = 0 Private GreenDocuments As Integer = 0 Private GridViewItem_Clicked = Nothing - Private GridCursorLocation As Point + Private GridCursorLocation As System.Drawing.Point Private GRID_LOAD_TYPE As String = "OVERVIEW" Private GRID_INV_COL_REMOVED As Boolean = False Private NO_WORKFLOWITEMS As Boolean = False @@ -454,7 +455,7 @@ Public Class frmMain Timer_Inactivity_Reset_Disable("FormLoad") 'Restore_Form_Position() - Dim oSavedPosition As Point = My.Settings.frmMainPosition + Dim oSavedPosition As System.Drawing.Point = My.Settings.frmMainPosition ' Prüfen, ob die Position sichtbar ist If IsPositionVisible(oSavedPosition) Then @@ -539,10 +540,10 @@ Public Class frmMain FormOpenClose = False End Sub - Private Function IsPositionVisible(position As Point) As Boolean + Private Function IsPositionVisible(position As System.Drawing.Point) As Boolean For Each scr As Screen In Screen.AllScreens If scr.WorkingArea.Contains(position) Then - Return True ' Punkt ist sichtbar + Return True ' Punkt ist auf diesem Bildschirm sichtbar End If Next Return False ' Punkt ist außerhalb aller sichtbaren Bereiche @@ -1430,7 +1431,6 @@ Public Class frmMain ' ========== UI VORBEREITEN (NUR BEI OVERVIEW) ========== Dim loadSuccess As Boolean = False - If GRID_LOAD_TYPE = "OVERVIEW" Then If LOG_HOTSPOTS Then LOGGER.Info("[PERF Decide_Load] ruft LoadOverviewData auf...") @@ -1441,6 +1441,8 @@ Public Class frmMain Exit Function End If + Await Task.Yield() + ' Daten laden loadSuccess = Await LoadOverviewData(pIsFormLoad, ForceReload) @@ -1454,6 +1456,8 @@ Public Class frmMain Exit Function End If + Await Task.Yield() + ' Daten laden loadSuccess = Await LoadProfileData(ForceReload) End If @@ -1518,9 +1522,17 @@ Public Class frmMain ' OVERVIEW DATEN LADEN - Spezialisiert auf Overview ' ======================================== Private Async Function LoadOverviewData(pFormLoad As Boolean, pForceReload As Boolean) As Task(Of Boolean) + Dim perfStart As DateTime = DateTime.MinValue + Dim perfStep As DateTime = DateTime.MinValue Dim gridUpdateStarted As Boolean = False Dim viewUpdateStarted As Boolean = False + If LOG_HOTSPOTS Then + perfStart = DateTime.Now + perfStep = perfStart + LOGGER.Info($"[PERF LoadOverviewData] START - pFormLoad:[{pFormLoad}] pForceReload:[{pForceReload}]") + End If + Try ' ========== GRID UPDATES VORBEREITEN ========== If GridControlWorkflows.Visible Then @@ -1541,8 +1553,22 @@ Public Class frmMain Return False End If + If LOG_HOTSPOTS Then + LOGGER.Info($"[PERF LoadOverviewData] Load_Profiles_for_User wird aufgerufen...") + End If + Load_Profiles_for_User() + If LOG_HOTSPOTS Then + Dim elapsed = (DateTime.Now - perfStep).TotalMilliseconds + If elapsed > 4000 Then + LOGGER.Warn($"[PERF LoadOverviewData] ⚠️ Load_Profiles_for_User LANGSAM: {elapsed}ms (Schwellwert: 4000ms)") + Else + LOGGER.Info($"[PERF LoadOverviewData] Load_Profiles_for_User: {elapsed}ms") + End If + perfStep = DateTime.Now + End If + ' ========== SQL VORBEREITEN ========== Dim oSQLOverview = BASEDATA_DT_CONFIG.Rows(0).Item("SQL_PROFILE_MAIN_VIEW") @@ -1557,9 +1583,25 @@ Public Class frmMain ' SQL-Platzhalter ersetzen oSQLOverview = PrepareSQLWithReplacements(oSQLOverview) + If LOG_HOTSPOTS Then + Dim rowCount = If(DT_CURR_WF_ITEMS IsNot Nothing, DT_CURR_WF_ITEMS.Rows.Count, 0) + LOGGER.Info($"[PERF LoadOverviewData] SQL-Abfrage für Workflows startet (aktuelle Rows: {rowCount})...") + End If + ' ========== DATEN ABRUFEN ========== DT_CURR_WF_ITEMS = Await DatabaseFallback.GetDatatableECMAsync(oSQLOverview) + 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 LoadOverviewData] ⚠️ Datenbank-Abfrage für Workflows LANGSAM: {elapsed}ms ({rowCount} Zeilen) (Schwellwert: 4000ms) - SQL prüfen!") + Else + LOGGER.Info($"[PERF LoadOverviewData] Datenbank-Abfrage für Workflows: {elapsed}ms ({rowCount} Zeilen)") + End If + perfStep = DateTime.Now + End If + If IsNothing(DT_CURR_WF_ITEMS) Then NO_WORKFLOWITEMS = True GridControlWorkflows.Visible = False @@ -1580,7 +1622,21 @@ Public Class frmMain End If ' ========== ICON-SPALTE VORBEREITEN ========== - PrepareIconColumn() + If LOG_HOTSPOTS Then + LOGGER.Info($"[PERF LoadOverviewData] Icon-Verarbeitung startet ({DT_CURR_WF_ITEMS.Rows.Count} Zeilen)...") + End If + + Await Task.Run(Sub() PrepareIconColumn()) + + If LOG_HOTSPOTS Then + Dim elapsed = (DateTime.Now - perfStep).TotalMilliseconds + If elapsed > 4000 Then + LOGGER.Warn($"[PERF LoadOverviewData] ⚠️ Icon-Verarbeitung LANGSAM: {elapsed}ms ({DT_CURR_WF_ITEMS.Rows.Count} Zeilen) (Schwellwert: 4000ms)") + Else + LOGGER.Info($"[PERF LoadOverviewData] Icon-Verarbeitung: {elapsed}ms") + End If + perfStep = DateTime.Now + End If ' ========== GRID MIT DATEN FÜLLEN ========== bindsourcegrid.DataSource = DT_CURR_WF_ITEMS @@ -1589,9 +1645,32 @@ Public Class frmMain Create_View_Caption() + If LOG_HOTSPOTS Then + Dim elapsed = (DateTime.Now - perfStep).TotalMilliseconds + If elapsed > 4000 Then + LOGGER.Warn($"[PERF LoadOverviewData] ⚠️ Grid-DataSource-Zuweisung LANGSAM: {elapsed}ms (Schwellwert: 4000ms)") + Else + LOGGER.Info($"[PERF LoadOverviewData] Grid-DataSource-Zuweisung: {elapsed}ms") + End If + perfStep = DateTime.Now + End If + ' ========== LAYOUT ANWENDEN ========== + If LOG_HOTSPOTS Then + LOGGER.Info($"[PERF LoadOverviewData] Layout-Anwendung startet...") + End If + Await ApplyGridLayout(pForceReload) + If LOG_HOTSPOTS Then + Dim elapsed = (DateTime.Now - perfStep).TotalMilliseconds + If elapsed > 4000 Then + LOGGER.Warn($"[PERF LoadOverviewData] ⚠️ Layout-Wiederherstellung LANGSAM: {elapsed}ms (Schwellwert: 4000ms)") + Else + LOGGER.Info($"[PERF LoadOverviewData] Layout-Wiederherstellung: {elapsed}ms") + End If + End If + Return True Catch ex As Exception @@ -1609,9 +1688,17 @@ Public Class frmMain ' LoadingPanel verstecken (NUR HIER!) GridViewWorkflows.HideLoadingPanel() + + If LOG_HOTSPOTS Then + Dim totalElapsed = (DateTime.Now - perfStart).TotalMilliseconds + If totalElapsed > 4000 Then + LOGGER.Warn($"[PERF LoadOverviewData] ⚠️ GESAMT LANGSAM: {totalElapsed}ms (Schwellwert: 4000ms)") + Else + LOGGER.Info($"[PERF LoadOverviewData] GESAMT: {totalElapsed}ms") + End If + End If End Try End Function - ' ======================================== ' PROFILE DATEN LADEN - Spezialisiert auf einzelnes Profil ' ======================================== @@ -1657,7 +1744,7 @@ Public Class frmMain End If ' ========== BASIC VIEW ERSTELLEN ========== - CreateBasicViewForProfile() + Await CreateBasicViewForProfile() Return True @@ -1793,7 +1880,7 @@ Public Class frmMain End Try End Sub - Private Sub CreateBasicViewForProfile() + Private Async Function CreateBasicViewForProfile() As Task GridControlWorkflows.DataSource = Nothing Try GridViewWorkflows.Columns.Clear() @@ -1802,7 +1889,7 @@ Public Class frmMain LOGGER.Warn("⚠️ Could not clear GridViewWorkflows.Columns") End Try - PrepareIconColumn() + Await Task.Run(Sub() PrepareIconColumn()) bindsourcegrid.DataSource = DT_CURR_WF_ITEMS GridControlWorkflows.DataSource = bindsourcegrid @@ -1820,7 +1907,7 @@ Public Class frmMain Catch ex As Exception End Try End If - End Sub + End Function Private Sub ApplyPostLoadSettings() If SHOW_MASS_VALIDATOR = False Then @@ -2099,45 +2186,100 @@ Public Class frmMain CURRENT_CLICKED_PROFILE_ID = oHitProfilID End If End If - - ' ========== GRUPPE VERARBEITEN (OPTIMIERT) ========== + ' ========== GRUPPE VERARBEITEN (MIT KORREKTER GRUPPEN-ERMITTLUNG) ========== If startedFrom = "CMGROUP" Then - LOGGER.Debug("Loading Child DocIds..") + LOGGER.Debug("Loading Child DocIds from focused expanded group..") Dim oIds As New List(Of Integer) - Dim oGroupRowHandle = hitInfo.RowHandle - Dim oChildRowCount = GridViewWorkflows.GetChildRowCount(oGroupRowHandle) + Dim oGroupRowHandle As Integer - ' OPTIMIERUNG: Kapazität vorbelegen - oIds.Capacity = oChildRowCount - - ' OPTIMIERUNG: Direkte Schleife statt verschachtelter Logik - If oChildRowCount > 0 Then - For index = 0 To oChildRowCount - 1 - Dim oChildRowHandle = GridViewWorkflows.GetChildRowHandle(oGroupRowHandle, index) - Dim oRow = GridViewWorkflows.GetRow(oChildRowHandle) - If oRow IsNot Nothing Then - Dim oDocId = oRow.Item("DocId") - If oDocId IsNot Nothing Then - oIds.Add(oDocId) - End If - End If - Next + ' KRITISCH: Den RICHTIGEN Gruppen-Handle ermitteln + If GridViewWorkflows.IsGroupRow(hitInfo.RowHandle) Then + ' User hat direkt auf die Gruppen-Zeile geklickt + oGroupRowHandle = hitInfo.RowHandle + LOGGER.Debug($"User clicked directly on group row, handle: {oGroupRowHandle}") Else - ' Fallback nur bei Bedarf - For index = 0 To GridViewWorkflows.RowCount - 1 - Dim oRow = GridViewWorkflows.GetRow(index) - If oRow Is Nothing Then Continue For + ' User hat auf eine Daten-Zeile INNERHALB einer Gruppe geklickt + ' → Parent-Gruppe ermitteln + oGroupRowHandle = GridViewWorkflows.GetParentRowHandle(hitInfo.RowHandle) + LOGGER.Debug($"User clicked on data row {hitInfo.RowHandle}, parent group handle: {oGroupRowHandle}") + + If Not GridViewWorkflows.IsGroupRow(oGroupRowHandle) Then + LOGGER.Warn($"⚠️ Parent handle {oGroupRowHandle} is not a group row!") + FormHelper.ShowWarningMessage("Bitte klicken Sie direkt auf die Gruppenzeile!", omsgTitleAttention) + Exit Function + End If + End If - Dim oProfileId = oRow.row.item("PROFILE_ID") - If oProfileId Is Nothing Then Continue For + ' Spalten-Objekt VOR der Schleife holen + Dim docIdColumn As GridColumn = GridViewWorkflows.Columns.ColumnByFieldName("DocID") + If docIdColumn Is Nothing Then + docIdColumn = GridViewWorkflows.Columns.ColumnByFieldName("DOCID") + End If + If docIdColumn Is Nothing Then + LOGGER.Error("⚠️ Column 'DocID' not found in GridView!") - If CInt(oProfileId) = CURRENT_CLICKED_PROFILE_ID Then - oIds.Add(oRow.item("DocId")) - End If + ' DEBUG: Alle verfügbaren Spalten ausgeben + LOGGER.Debug("=== Available Columns ===") + For Each col As GridColumn In GridViewWorkflows.Columns + LOGGER.Debug($" {col.FieldName} (Caption: {col.Caption})") Next + LOGGER.Debug("=== END Available Columns ===") + + FormHelper.ShowInfoMessage("Column 'DocID' not found!", omsgTitleWarning) + Exit Function + End If + + ' JETZT GetChildRowCount auf der RICHTIGEN Gruppe + Dim oChildRowCount = GridViewWorkflows.GetChildRowCount(oGroupRowHandle) + LOGGER.Debug($"Group handle {oGroupRowHandle} has {oChildRowCount} total child rows") + + ' WICHTIG: Wenn 0 Kinder → Gruppe ist zugeklappt oder leer + If oChildRowCount = 0 Then + ' Versuche die Gruppe aufzuklappen + LOGGER.Debug($"Expanding group at handle {oGroupRowHandle}...") + GridViewWorkflows.ExpandGroupRow(oGroupRowHandle) + + ' UI-Thread Zeit geben + Application.DoEvents() + + ' Erneut prüfen + oChildRowCount = GridViewWorkflows.GetChildRowCount(oGroupRowHandle) + LOGGER.Debug($"After expanding: {oChildRowCount} child rows") + + If oChildRowCount = 0 Then + LOGGER.Warn($"⚠️ Group has 0 children even after expanding") + Dim omsg = "Die Gruppe ist leer!" + FormHelper.ShowWarningMessage(omsg, omsgTitleAttention) + Exit Function + End If End If - LOGGER.Debug("[{0}] DocIds loaded", oIds.Count) + ' JETZT sollten Kinder vorhanden sein + For childIndex = 0 To oChildRowCount - 1 + Dim oChildRowHandle = GridViewWorkflows.GetChildRowHandle(oGroupRowHandle, childIndex) + + ' WICHTIG: Nur Daten-Rows verarbeiten, KEINE Gruppen + If Not GridViewWorkflows.IsDataRow(oChildRowHandle) Then + LOGGER.Debug($"Skipping non-data row at child index {childIndex} (Handle: {oChildRowHandle})") + Continue For + End If + + ' DocId auslesen - MIT COLUMN-OBJEKT + Try + Dim oDocId = GridViewWorkflows.GetRowCellValue(oChildRowHandle, docIdColumn) + + If oDocId IsNot Nothing AndAlso IsNumeric(oDocId) Then + oIds.Add(CInt(oDocId)) + LOGGER.Debug($"Added DocId: {oDocId} from child index {childIndex} (Handle: {oChildRowHandle})") + Else + LOGGER.Warn($"⚠️ DocId is Nothing/Invalid at child index {childIndex}, Handle: {oChildRowHandle}") + End If + Catch ex As Exception + LOGGER.Error($"Error reading DocId at child index {childIndex}: {ex.Message}") + End Try + Next + + LOGGER.Debug($"[{oIds.Count}] DocIds collected from focused group") If oIds.Count = 0 Then Dim omsg = String.Format(S.System_konnte_die_Profilworkflows_nicht_auswerten_, vbNewLine) @@ -2145,14 +2287,13 @@ Public Class frmMain Exit Function End If - ' ========== DB-OPERATIONEN OPTIMIERT ========== + ' ========== 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) + LOGGER.Debug("Adding {0} queued DocIds..", oIds.Count) - ' OPTIMIERUNG: Batch-Insert statt einzelner Inserts Dim oInsertBatch As New System.Text.StringBuilder() oInsertBatch.AppendLine("INSERT INTO TBPM_VALIDATION_PROFILE_GROUP_USER ([PROFIL_ID],[DocID],[UserID],[ADDED_WHO]) VALUES") @@ -2161,6 +2302,9 @@ Public Class frmMain 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()) End If End If @@ -2999,7 +3143,7 @@ Public Class frmMain }) End Sub Sub LoadVWPM_CONTROL_INDEX() - Dim oSQL = $"SELECT * FROM VWPM_CONTROL_INDEX WITH (NOLOCK) ORDER BY PROFIL_ID,Y_LOC, X_LOC" + Dim oSQL = $"SELECT * FROM VWPM_CONTROL_INDEX ORDER BY PROFIL_ID,Y_LOC, X_LOC" 'DTVWCONTROLS_INDEX = DataASorDB.GetDatatable("DD_ECM", oSQL, "VWPM_CONTROL_INDEX", "") DTVWCONTROLS_INDEX = DatabaseFallback.GetDatatable("VWPM_CONTROL_INDEX", New GetDatatableOptions(oSQL, DatabaseType.ECM)) End Sub @@ -3014,7 +3158,7 @@ Public Class frmMain If pMode = "bwBasicData" Then bwBasicData.ReportProgress(10) If pMode <> "Load" Then - ClassParamRefresh.Refresh_Params(DT_CHECKUSER_MODULE) + ClassParamRefresh.Refresh_Params(DT_CHECKUSER_MODULE, pMode) End If If pMode = "bwBasicData" Then bwBasicData.ReportProgress(20) @@ -3023,7 +3167,7 @@ Public Class frmMain LOGGER.Debug($"VWPM_PROFILE_ACTIVE-SELECT used from DD-SQL-Config..") Else oSQL = $"SELECT [dbo].[FNDD_LANGUAGE_PHRASE] ('PROFILE_TITLE' + CONVERT(VARCHAR(4),T.GUID),'{USER_LANGUAGE}','PM') as GROUP_TEXT_LANG, T.* -FROM VWPM_PROFILE_ACTIVE T WITH (NOLOCK) WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_GET_ACTIVE_PROFILES_USER] ({USER_ID}))" +FROM VWPM_PROFILE_ACTIVE T WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_GET_ACTIVE_PROFILES_USER] ({USER_ID}))" End If @@ -3350,7 +3494,7 @@ FROM VWPM_PROFILE_ACTIVE T WITH (NOLOCK) WHERE T.GUID IN (SELECT PROFILE_ID FROM End Sub Private Sub OutOfRangePMFixierenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OutOfRangePMFixierenToolStripMenuItem.Click - Dim myPoint As Point = New Point(50, 50) + Dim myPoint As System.Drawing.Point = New System.Drawing.Point(50, 50) Me.Location = Screen.AllScreens(UBound(Screen.AllScreens)).Bounds.Location + myPoint BringMonitor2Front() End Sub diff --git a/app/TaskFlow/frmValidator.vb b/app/TaskFlow/frmValidator.vb index 3f321ee..ccd6a1c 100644 --- a/app/TaskFlow/frmValidator.vb +++ b/app/TaskFlow/frmValidator.vb @@ -124,11 +124,13 @@ Public Class frmValidator Private listofControls As New List(Of String) Private frmMessages As frmValidator_Messages - Private ReadOnly _SqlDataCache As New Dictionary(Of String, DataTable)(StringComparer.OrdinalIgnoreCase) - Private ReadOnly _SqlScalarCache As New Dictionary(Of String, Object)(StringComparer.OrdinalIgnoreCase) - Private _SqlControlsByGuid As Dictionary(Of Integer, List(Of DataRow)) - Private _LookupControlsByRepository As Dictionary(Of RepositoryItemLookupControl3, LookupControl3) + Private ReadOnly _CachedSqlDataCache As New Dictionary(Of String, DataTable)(StringComparer.OrdinalIgnoreCase) + Private ReadOnly _CachedSqlScalarCache As New Dictionary(Of String, Object)(StringComparer.OrdinalIgnoreCase) + Private _CachedSqlControlsByGuid As Dictionary(Of Integer, List(Of DataRow)) + Private _CachedLookupControlsByRepository As Dictionary(Of RepositoryItemLookupControl3, LookupControl3) + Private _CachedControlsBySetControlData As Dictionary(Of Integer, DataRow) Private _CachedFinalIndexing As DataTable = Nothing + Private _CachedControlsByGuid As Dictionary(Of Integer, Control) Private _isUpdatingLookup As Boolean = False Private _suppressLookupEvents As Boolean = False Private Class Translation_Strings @@ -582,6 +584,23 @@ Public Class frmValidator End Sub Private Sub frmValidation_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing + If LOG_HOTSPOTS Then + ' ========== DIAGNOSE: Wer schließt die Form? ========== + MyValidationLogger.Warn($" frmValidator_FormClosing aufgerufen!") + MyValidationLogger.Warn($" CloseReason: {e.CloseReason}") + MyValidationLogger.Warn($" Cancel: {e.Cancel}") + + ' *** KORREKTUR: StackTrace richtig erstellen *** + Dim st As New StackTrace(True) + MyValidationLogger.Warn($" StackTrace: {st.ToString()}") + + ' Zusätzliche Diagnostik + MyValidationLogger.Warn($" _FormClosing-Flag: {_FormClosing}") + MyValidationLogger.Warn($" CURRENT_DOC_GUID: {CURRENT_DOC_GUID}") + MyValidationLogger.Warn($" CURRENT_ProfilGUID: {CURRENT_ProfilGUID}") + ' ========== ENDE DIAGNOSE ========== + End If + Dim perfStart As DateTime = DateTime.MinValue Dim perfLastCheck As DateTime = DateTime.MinValue If LOG_HOTSPOTS Then @@ -819,11 +838,11 @@ Public Class frmValidator End Sub Private Sub EnsureSqlControlLookup() - If _SqlControlsByGuid IsNot Nothing Then + If _CachedSqlControlsByGuid IsNot Nothing Then Return End If - _SqlControlsByGuid = New Dictionary(Of Integer, List(Of DataRow))() + _CachedSqlControlsByGuid = New Dictionary(Of Integer, List(Of DataRow))() If DTCONTROLS_WITH_SQL Is Nothing OrElse DTCONTROLS_WITH_SQL.Rows.Count = 0 Then Return @@ -840,9 +859,9 @@ Public Class frmValidator End If Dim list As List(Of DataRow) = Nothing - If Not _SqlControlsByGuid.TryGetValue(controlId, list) Then + If Not _CachedSqlControlsByGuid.TryGetValue(controlId, list) Then list = New List(Of DataRow)() - _SqlControlsByGuid(controlId) = list + _CachedSqlControlsByGuid(controlId) = list End If list.Add(row) Next @@ -858,7 +877,7 @@ Public Class frmValidator EnsureSqlControlLookup() Dim rows As List(Of DataRow) = Nothing - If _SqlControlsByGuid Is Nothing OrElse Not _SqlControlsByGuid.TryGetValue(pControlId, rows) Then + If _CachedSqlControlsByGuid Is Nothing OrElse Not _CachedSqlControlsByGuid.TryGetValue(pControlId, rows) Then Exit Sub End If @@ -1000,18 +1019,23 @@ Public Class frmValidator Dim oControlInfo As String Try - + _CachedControlsByGuid = Nothing ' Cache invalidieren PanelValidatorControl.Controls.Clear() - _LookupControlsByRepository = New Dictionary(Of RepositoryItemLookupControl3, LookupControl3)() + _CachedLookupControlsByRepository = New Dictionary(Of RepositoryItemLookupControl3, LookupControl3)() Dim oSQL As String Dim oFilter As String = $"LANGUAGE = '{USER_LANGUAGE}' AND PROFIL_ID = {CURRENT_ProfilGUID}" DT_CONTROLS = GetControlMetaBySql(oFilter, "Y_LOC, X_LOC") - 'Dim oSQL = $"SELECT [dbo].[FNPM_LANGUAGE_CONTROL_TEXT] (NAME,'{USER_LANGUAGE}',CTRL_TYPE,CTRL_TEXT) CTRL_CAPTION_LANG, * FROM TBPM_PROFILE_CONTROLS WHERE CONTROL_ACTIVE = 1 AND PROFIL_ID = {CURRENT_ProfilGUID} ORDER BY Y_LOC, X_LOC" - 'DT_CONTROLS = DatabaseFallback.GetDatatable("TBPM_PROFILE_CONTROLS_LANGUAGE", New GetDatatableOptions(oSQL, DatabaseType.ECM) With { - ' .FilterExpression = $"LANGUAGE = '{USER_LANGUAGE}' AND PROFIL_ID = {CURRENT_ProfilGUID}", - ' .SortByColumn = "Y_LOC, X_LOC" - '}) + ' ========== NEU: Einmalige Gruppierung für SetControlValues_FromControl ========== + If DT_CONTROLS IsNot Nothing AndAlso DT_CONTROLS.Rows.Count > 0 Then + _CachedControlsBySetControlData = New Dictionary(Of Integer, DataRow)() + + For Each row As DataRow In DT_CONTROLS.AsEnumerable().Where(Function(r) Not String.IsNullOrWhiteSpace(r.ItemEx("SET_CONTROL_DATA", String.Empty))) + Dim controlId As Integer = row.Item("GUID") + _CachedControlsBySetControlData(controlId) = row + Next + End If + ' ========== ENDE ========== oSQL = $"SELECT IIF(LANG.CAPTION IS NULL,T.SPALTEN_HEADER,LANG.CAPTION) SPALTEN_HEADER_LANG, T.* from TBPM_CONTROL_TABLE T INNER JOIN TBPM_PROFILE_CONTROLS T1 ON T.CONTROL_ID = T1.GUID LEFT JOIN (SELECT * FROM TBPM_CONTOL_TABLE_LANG WHERE LANG_CODE = '{USER_LANGUAGE}') LANG ON T.GUID = LANG.COL_ID WHERE T1.CONTROL_ACTIVE = 1 AND T.CONTROL_ID = T1.GUID AND T1.PROFIL_ID = {CURRENT_ProfilGUID} ORDER BY T.SEQUENCE" @@ -1236,7 +1260,7 @@ Public Class frmValidator Catch ex As Exception MyValidationLogger.Warn($"Unexpected error in LOOKUP GetValues SQL - Error: {ex.Message}") End Try - End If + End If If ObjectEx.NotNull(oControlRow.Item("DEFAULT_VALUE"), "") <> "" Then @@ -1244,7 +1268,7 @@ Public Class frmValidator End If oMyControl = MyLookupControl - _LookupControlsByRepository(MyLookupControl.Properties) = MyLookupControl + _CachedLookupControlsByRepository(MyLookupControl.Properties) = MyLookupControl AddHandler MyLookupControl.Properties.SelectedValuesChanged, AddressOf LookupListChanged Dim oFilteredData As DataTable = DT_CONTROLS.Clone() @@ -1399,26 +1423,51 @@ Public Class frmValidator Public Sub OnTextBoxLostFocus(sender As System.Object, e As System.EventArgs) CountAction += 1 - Dim oTextbox As BaseEdit = sender + Dim oTextbox As BaseEdit = TryCast(sender, BaseEdit) + + ' ========== 1. NULL-Guards ========== + If oTextbox Is Nothing Then + Exit Sub + End If + + Dim oMeta As ClassControlCreator.ControlMetadata = TryCast(oTextbox.Tag, ClassControlCreator.ControlMetadata) + If oMeta Is Nothing Then + Exit Sub + End If + + ' ========== 2. Form-Closing Guard ========== + If _FormClosing OrElse Me.IsDisposed Then + Exit Sub + End If + + ' ========== 3. Name-Guard für Cache ========== + If String.IsNullOrEmpty(oMeta.Name) Then + MyValidationLogger.Warn($"[{CountAction}] oMeta.Name ist leer!") + Exit Sub + End If + ' ========== ENDE Guards ========== + Dim oeditvalue = oTextbox.EditValue Dim odisplayvalue = oTextbox.Text - Dim oMeta As ClassControlCreator.ControlMetadata = oTextbox.Tag + Console.WriteLine($"[{CountAction}] LostFocus - {oMeta.Name}") + If oMeta.ReadOnly = False Then oTextbox.BackColor = oMeta.BackColor oTextbox.ForeColor = GraphicsEx.GetContrastedColor(oMeta.BackColor) End If - ' NEU: Dirty-Flag setzen - OHNE .Modified Property - ' Stattdessen prüfen wir, ob das Control bereits als dirty markiert wurde - ' oder setzen es bei jedem LostFocus (einfachste Lösung) If Not oMeta.IsDirty Then oMeta.IsDirty = True MyValidationLogger.Debug($"Control [{oMeta.Name}] marked as dirty") End If - ' *** NEU: Cache aktualisieren *** - clsPatterns.UpdateControlInCache(oTextbox.Name, oTextbox.EditValue) + ' *** Cache aktualisieren (mit Try-Catch) *** + Try + clsPatterns.UpdateControlInCache(oMeta.Name, oTextbox.EditValue) + Catch ex As Exception + MyValidationLogger.Error($"Cache-Update failed: {ex.Message}") + End Try SetControlValues_FromControl(oTextbox) Controls2beEnabled(oTextbox.Name) @@ -1731,8 +1780,8 @@ Public Class frmValidator Dim oRepositoryItem As RepositoryItemLookupControl3 = sender Dim oLookup As LookupControl3 = Nothing - If _LookupControlsByRepository IsNot Nothing Then - _LookupControlsByRepository.TryGetValue(oRepositoryItem, oLookup) + If _CachedLookupControlsByRepository IsNot Nothing Then + _CachedLookupControlsByRepository.TryGetValue(oRepositoryItem, oLookup) End If If oLookup Is Nothing Then @@ -1783,8 +1832,8 @@ Public Class frmValidator Dim oLookup As RepositoryItemLookupControl3 = sender Dim oLookupControl As LookupControl3 = Nothing - If _LookupControlsByRepository IsNot Nothing Then - _LookupControlsByRepository.TryGetValue(oLookup, oLookupControl) + If _CachedLookupControlsByRepository IsNot Nothing Then + _CachedLookupControlsByRepository.TryGetValue(oLookup, oLookupControl) End If If oLookupControl Is Nothing Then @@ -1883,43 +1932,40 @@ Public Class frmValidator Dim oControlMeta = DirectCast(pControl.Tag, ClassControlCreator.ControlMetadata) Dim oControlID = oControlMeta.Guid - If _SetControlValue_In_Action = True Then + If _SetControlValue_In_Action Then MyValidationLogger.Debug("SetControlValue in action. Exiting.") Exit Sub End If - Dim oFilteredDatatable As DataTable = DT_CONTROLS.Clone() - DT_CONTROLS. - Select($"GUID = {oControlID} and LEN(SET_CONTROL_DATA) > 0"). - CopyToDataTable(oFilteredDatatable, LoadOption.PreserveChanges) - - If oFilteredDatatable.Rows.Count < 1 Then + ' ========== OPTIMIERUNG: Dictionary-Lookup statt Select() ========== + Dim oRow As DataRow = Nothing + If _CachedControlsBySetControlData Is Nothing OrElse Not _CachedControlsBySetControlData.TryGetValue(oControlID, oRow) Then MyValidationLogger.Debug("SET_CONTROL_DATA is empty for control [{0}]. Exiting.", oControlName) Exit Sub End If + ' ========== ENDE OPTIMIERUNG ========== - Dim oRow As DataRow = oFilteredDatatable.Rows.Item(0) - Dim oControlGUID2Set = oControlID Dim oControlname2Set = oRow.Item("NAME") - MyValidationLogger.Debug($"Workin on SetControLValue for {oControlname2Set} ...") + MyValidationLogger.Debug($"Working on SetControlValue for {oControlname2Set} ...") Dim oConnectionId = oRow.ItemEx("CONNECTION_ID", 0) Dim oControlDataSql = oRow.ItemEx("SET_CONTROL_DATA", String.Empty) If oConnectionId = -1 Or oControlDataSql = String.Empty Then - MyValidationLogger.Debug($"Error: Check CoNN ID and SQL on NULL VALUES!") + MyValidationLogger.Debug("Error: Check CONN ID and SQL on NULL VALUES!") Exit Sub End If oControlDataSql = clsPatterns.ReplaceAllValues(oControlDataSql, PanelValidatorControl, True) - Dim oControlDataResult As DataTable = GetCachedDatatable(oControlDataSql, oConnectionId) If oControlDataResult Is Nothing Then Exit Sub End If + Dim oButtonFinishSet As Boolean = False + For Each oResultRow As DataRow In oControlDataResult.Rows Try _SetControlValue_In_Action = True @@ -1939,184 +1985,184 @@ Public Class frmValidator Continue For End If - Dim oFound As Boolean = False - Dim oControlId2Set As Integer - - 'If Not Integer.TryParse(oControl2Set, oControlId2Set) Then - ' LOGGER.Warn("⚠️ Careful: the oControl2Set contains no CONTROL_GUID") - ' Exit Sub - 'End If - + ' ========== OPTIMIERUNG: FirstOrDefault statt Loop ========== Dim oControlObject2Set = PanelValidatorControl.Controls.Cast(Of Control). - Where(Function(c) - Dim oMeta = DirectCast(c.Tag, ClassControlCreator.ControlMetadata) - Return oControl2Set = oMeta.Guid OrElse oControl2Set = oMeta.Name - End Function).FirstOrDefault() + Where(Function(c) + Dim meta = DirectCast(c.Tag, ClassControlCreator.ControlMetadata) + Return oControl2Set = meta.Guid OrElse oControl2Set = meta.Name + End Function).FirstOrDefault() - If oControlObject2Set IsNot Nothing Then - - Dim oControl As Control = oControlObject2Set - Dim oMeta As ClassControlCreator.ControlMetadata = DirectCast(oControl.Tag, ClassControlCreator.ControlMetadata) - - MyValidationLogger.Debug(String.Format("Got the Control2Set: {0}..Setting the values..", {oControl.Name})) + If oControlObject2Set Is Nothing Then + MyValidationLogger.Debug($"Could not find the Control2Set with ID {oControl2Set} on panel!!!") + Continue For + End If + ' ========== ENDE OPTIMIERUNG ========== + Dim oControl As Control = oControlObject2Set + ' *** WICHTIG: Verwende LOKALE Variable statt erneuter Deklaration *** + Dim oMeta As ClassControlCreator.ControlMetadata = DirectCast(oControl.Tag, ClassControlCreator.ControlMetadata) - Select Case True - Case oControl.GetType() = GetType(DevExpress.XtraEditors.TextEdit) Or oControl.GetType() = GetType(MemoEdit) - Try - If oControlTextOption = "Replace" Then - oControl.Text = oControlCaption - Else - oControl.Text &= oControlCaption - End If + MyValidationLogger.Debug(String.Format("Got the Control2Set: {0}..Setting the values..", {oControl.Name})) - oControl.BackColor = oControlBackColor - oControl.ForeColor = oControlFontColor - Catch ex As Exception - MyValidationLogger.Warn($"Error while Control2Set (TextEdit): {ex.Message}") - End Try + Select Case True + Case oControl.GetType() = GetType(DevExpress.XtraEditors.TextEdit) Or oControl.GetType() = GetType(MemoEdit) + Try + If oControlTextOption = "Replace" Then + oControl.Text = oControlCaption + Else + oControl.Text &= oControlCaption + End If + oControl.BackColor = oControlBackColor + oControl.ForeColor = oControlFontColor + Catch ex As Exception + MyValidationLogger.Warn($"Error while Control2Set (TextEdit): {ex.Message}") + End Try - Case oControl.GetType() = GetType(LookupControl3) - Try - Dim oDependingLookup As LookupControl3 = oControl - If oDependingLookup.Properties.MultiSelect = True Then - If oControlTextOption = "Replace" Then - oDependingLookup.Properties.SelectedValues = New List(Of String) From {oControlCaption} - Else - oDependingLookup.Properties.SelectedValues.Add(oControlCaption) - End If - Else + Case oControl.GetType() = GetType(LookupControl3) + Try + Dim oDependingLookup As LookupControl3 = oControl + If oDependingLookup.Properties.MultiSelect = True Then + If oControlTextOption = "Replace" Then oDependingLookup.Properties.SelectedValues = New List(Of String) From {oControlCaption} - End If - Catch ex As Exception - MyValidationLogger.Warn($"Error while Control2Set (LookupControl3): {ex.Message}") - End Try - - Case oControl.GetType() = GetType(Windows.Forms.ComboBox) - Try - Dim oDependingCombobox As Windows.Forms.ComboBox = oControl - ' Versuche, den Index des Eintrags zu finden, der genau dem String entspricht - Dim oIndex As Integer = oDependingCombobox.FindStringExact(oControlCaption) - - If oIndex <> -1 Then - ' Wenn ein gültiger Index gefunden wurde, setze ihn als ausgewählten Index - oDependingCombobox.SelectedIndex = oIndex - Try - oDependingCombobox.BackColor = oControlBackColor - Catch ex As Exception - - End Try - Try - oDependingCombobox.ForeColor = oControlFontColor - Catch ex As Exception - - End Try - - Else - ' Optional: Handle den Fall, dass der String nicht gefunden wurde - - End If - Catch ex As Exception - MyValidationLogger.Warn($"Error while Control2Set (Combobox): {ex.Message}") - End Try - Case oControl.GetType() = GetType(DevExpress.XtraEditors.DateEdit) - Try - Dim oDateEdit As DevExpress.XtraEditors.DateEdit = DirectCast(oControl, DevExpress.XtraEditors.DateEdit) - Dim parsed As DateTime - If String.IsNullOrWhiteSpace(oControlCaption) Then - oDateEdit.EditValue = Nothing - ElseIf DateTime.TryParse(oControlCaption, parsed) Then - oDateEdit.EditValue = parsed - ElseIf DateTime.TryParse(oControlCaption, CultureInfo.CurrentCulture, DateTimeStyles.None, parsed) Then - oDateEdit.EditValue = parsed - ElseIf DateTime.TryParse(oControlCaption, CultureInfo.InvariantCulture, DateTimeStyles.None, parsed) Then - oDateEdit.EditValue = parsed - Else - oDateEdit.EditValue = Nothing - End If - - Catch ex As Exception - MyValidationLogger.Warn($"Error While Control2Set (DateEdit): {ex.Message}") - End Try - Case oControl.GetType() = GetType(System.Windows.Forms.DateTimePicker) - Try - Dim dtp As System.Windows.Forms.DateTimePicker = DirectCast(oControl, System.Windows.Forms.DateTimePicker) - Dim parsed As DateTime - If String.IsNullOrWhiteSpace(oControlCaption) Then - dtp.Value = DateTimePicker.MinimumDateTime - ElseIf DateTime.TryParse(oControlCaption, parsed) _ - OrElse DateTime.TryParse(oControlCaption, CultureInfo.CurrentCulture, DateTimeStyles.None, parsed) _ - OrElse DateTime.TryParse(oControlCaption, CultureInfo.InvariantCulture, DateTimeStyles.None, parsed) Then - dtp.Value = parsed Else - dtp.Value = DateTimePicker.MinimumDateTime + oDependingLookup.Properties.SelectedValues.Add(oControlCaption) End If + Else + oDependingLookup.Properties.SelectedValues = New List(Of String) From {oControlCaption} + End If + Catch ex As Exception + MyValidationLogger.Warn($"Error while Control2Set (LookupControl3): {ex.Message}") + End Try - Catch ex As Exception - MyValidationLogger.Warn($"Error While Control2Set (DateTimePicker): {ex.Message}") - End Try + Case oControl.GetType() = GetType(Windows.Forms.ComboBox) + Try + Dim oDependingCombobox As Windows.Forms.ComboBox = oControl + Dim oIndex As Integer = oDependingCombobox.FindStringExact(oControlCaption) - Case oControl.GetType() = GetType(Windows.Forms.CheckBox) - Dim oBitValue As Boolean - Try - oBitValue = CBool(oControlCaption) - Dim oDependingCheckbox As Windows.Forms.CheckBox = oControl - oDependingCheckbox.Checked = oBitValue + If oIndex <> -1 Then + oDependingCombobox.SelectedIndex = oIndex Try - oDependingCheckbox.BackColor = oControlBackColor + oDependingCombobox.BackColor = oControlBackColor Catch ex As Exception - End Try Try - oDependingCheckbox.ForeColor = oControlFontColor + oDependingCombobox.ForeColor = oControlFontColor Catch ex As Exception - End Try - Catch ex As Exception - MyValidationLogger.Warn($"Error while Control2Set (Checkbox) {ex.Message}") - End Try + End If + Catch ex As Exception + MyValidationLogger.Warn($"Error while Control2Set (Combobox): {ex.Message}") + End Try + Case oControl.GetType() = GetType(DevExpress.XtraEditors.DateEdit) + Try + Dim oDateEdit As DevExpress.XtraEditors.DateEdit = DirectCast(oControl, DevExpress.XtraEditors.DateEdit) + Dim parsed As DateTime + If String.IsNullOrWhiteSpace(oControlCaption) Then + oDateEdit.EditValue = Nothing + ElseIf DateTime.TryParse(oControlCaption, parsed) Then + oDateEdit.EditValue = parsed + ElseIf DateTime.TryParse(oControlCaption, CultureInfo.CurrentCulture, DateTimeStyles.None, parsed) Then + oDateEdit.EditValue = parsed + ElseIf DateTime.TryParse(oControlCaption, CultureInfo.InvariantCulture, DateTimeStyles.None, parsed) Then + oDateEdit.EditValue = parsed + Else + oDateEdit.EditValue = Nothing + End If + Catch ex As Exception + MyValidationLogger.Warn($"Error While Control2Set (DateEdit): {ex.Message}") + End Try - Case Else - MyValidationLogger.Warn("⚠️ SetControlData used on unsupported control") + Case oControl.GetType() = GetType(System.Windows.Forms.DateTimePicker) + Try + Dim dtp As System.Windows.Forms.DateTimePicker = DirectCast(oControl, System.Windows.Forms.DateTimePicker) + Dim parsed As DateTime + If String.IsNullOrWhiteSpace(oControlCaption) Then + dtp.Value = DateTimePicker.MinimumDateTime + ElseIf DateTime.TryParse(oControlCaption, parsed) _ + OrElse DateTime.TryParse(oControlCaption, CultureInfo.CurrentCulture, DateTimeStyles.None, parsed) _ + OrElse DateTime.TryParse(oControlCaption, CultureInfo.InvariantCulture, DateTimeStyles.None, parsed) Then + dtp.Value = parsed + Else + dtp.Value = DateTimePicker.MinimumDateTime + End If + Catch ex As Exception + MyValidationLogger.Warn($"Error While Control2Set (DateTimePicker): {ex.Message}") + End Try - End Select + Case oControl.GetType() = GetType(Windows.Forms.CheckBox) + Try + Dim oBitValue As Boolean = CBool(oControlCaption) + Dim oDependingCheckbox As Windows.Forms.CheckBox = oControl + oDependingCheckbox.Checked = oBitValue + Try + oDependingCheckbox.BackColor = oControlBackColor + Catch ex As Exception + End Try + Try + oDependingCheckbox.ForeColor = oControlFontColor + Catch ex As Exception + End Try + Catch ex As Exception + MyValidationLogger.Warn($"Error while Control2Set (Checkbox) {ex.Message}") + End Try - oFound = True - 'Exit For - End If + Case Else + MyValidationLogger.Warn("⚠️ SetControlData used on unsupported control") + End Select - If oFound = False Then - MyValidationLogger.Debug($"Could Not find the Control2Set with ID {oControlGUID2Set} on panel!!!") - End If Catch ex As Exception MyValidationLogger.Error(ex) - MyValidationLogger.Warn($"Error while Control2Set for [{oControlname2Set}]: " & ex.Message) + MyValidationLogger.Warn($"Error while Control2Set for [{oControlname2Set}]: " & ex.Message) Finally _SetControlValue_In_Action = False End Try Next End Sub Private Sub LookupControl_DependingControls(LookupControl As LookupControl3, SelectedValues As List(Of String)) + If SelectedValues Is Nothing OrElse SelectedValues.Count = 0 Then + MyValidationLogger.Debug("LookupControl_DependingControls: No values selected") + Exit Sub + End If + 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!!") + ' ========== OPTIMIERUNG 1: Dictionary für Controls erstellen (einmalig) ========== + If _CachedControlsByGuid Is Nothing Then + _CachedControlsByGuid = New Dictionary(Of Integer, Control)() + For Each ctrl As Control In PanelValidatorControl.Controls + Try + Dim meta = DirectCast(ctrl.Tag, ClassControlCreator.ControlMetadata) + _CachedControlsByGuid(meta.Guid) = ctrl + Catch + Continue For + End Try + Next End If + ' ========== ENDE OPTIMIERUNG 1 ========== - For Each oRowDependingControl As DataRow In oFilteredDatatable.Rows - Dim oDEPENDING_GUID = oRowDependingControl.Item("GUID") - Dim oDEPENDING_CtrlName = oRowDependingControl.Item("NAME") + ' ========== OPTIMIERUNG 2: Gefilterte Rows mit LINQ (statt .Select()) ========== + Dim dependingRows = DT_CONTROLS.AsEnumerable(). + Where(Function(r) Not IsDBNull(r("SQL_UEBERPRUEFUNG")) AndAlso + r("SQL_UEBERPRUEFUNG").ToString().Contains($"#CTRL#{oLOOKUPName}")). + ToList() + + If dependingRows.Count = 0 Then + MyValidationLogger.Debug($"Sorry NO depending controls for [{oLOOKUPName}]!") + Exit Sub + End If + + MyValidationLogger.Debug($"We got {dependingRows.Count} depending controls!!") + ' ========== ENDE OPTIMIERUNG 2 ========== + + For Each oRowDependingControl As DataRow In dependingRows + Dim oDEPENDING_GUID = CInt(oRowDependingControl.Item("GUID")) + Dim oDEPENDING_CtrlName = oRowDependingControl.Item("NAME").ToString() MyValidationLogger.Debug($"Control {oDEPENDING_CtrlName} is depending on lookUp {oLOOKUPName}..") If _DependingControl_In_Action = True Then @@ -2124,108 +2170,101 @@ Public Class frmValidator 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 + If IsDBNull(oRowDependingControl.Item("CONNECTION_ID")) OrElse IsDBNull(oRowDependingControl.Item("SQL_UEBERPRUEFUNG")) Then + MyValidationLogger.Debug($"Error: Check CoNN ID and SQL on NULL VALUES!") + Continue For + End If - Dim oDTDEPENDING_RESULT As DataTable = GetCachedDatatable(oSqlCommand, oRowDependingControl.Item("CONNECTION_ID")) + Dim oSqlCommand = oRowDependingControl.Item("SQL_UEBERPRUEFUNG").ToString() + oSqlCommand = clsPatterns.ReplaceAllValues(oSqlCommand, PanelValidatorControl, True) + _DependingControl_In_Action = True - If Not IsNothing(oDTDEPENDING_RESULT) Then - Try - Dim oFound As Boolean = False + Dim oDTDEPENDING_RESULT As DataTable = GetCachedDatatable(oSqlCommand, oRowDependingControl.Item("CONNECTION_ID")) - For Each oControl As Control In PanelValidatorControl.Controls - If DirectCast(oControl.Tag, ClassControlCreator.ControlMetadata).Guid = oDEPENDING_GUID Then - oFound = True - MyValidationLogger.Debug($"Got the depending control ID:{oDEPENDING_GUID}..Setting the values..") + If oDTDEPENDING_RESULT Is Nothing Then + MyValidationLogger.Warn($"Datatable for Depending Controls was nothing! Check the SQL [{oSqlCommand}]") + _DependingControl_In_Action = False + Continue For + End If - ' *** WICHTIG: Während Suppress-Modus Updates durchführen *** - Dim wasSuppressed = _suppressLookupEvents - _suppressLookupEvents = True + ' ========== OPTIMIERUNG 3: Dictionary-Lookup statt Loop ========== + Dim oControl As Control = Nothing + If Not _CachedControlsByGuid.TryGetValue(oDEPENDING_GUID, oControl) Then + MyValidationLogger.Debug($"Could not find the depending Control with ID {oDEPENDING_GUID} on panel!!!") + _DependingControl_In_Action = False + Continue For + End If + ' ========== ENDE OPTIMIERUNG 3 ========== - Try - 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) - 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 Dim oTEXT = oDTDEPENDING_RESULT.Rows(0).Item(0): {ex.Message}") - End Try + MyValidationLogger.Debug($"Got the depending control ID:{oDEPENDING_GUID}..Setting the values..") - 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 + ' *** 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 + 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) + DirectCast(oControl, DevExpress.XtraEditors.TextEdit).EditValue = oValue + Catch ex As Exception + MyValidationLogger.Warn($"Unexpected error in Checking oTEXT: {ex.Message}") + End Try + + Try + Dim oColor = System.Drawing.Color.FromName(oDTDEPENDING_RESULT.Rows(0).Item("BackgroundColor")) + oControl.BackColor = oColor + Catch + oControl.BackColor = Color.White + 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 + Try + Dim btntext = oDTDEPENDING_RESULT.Rows(0).Item("btnFinishCaption") + btnSave.Text = btntext & " (F2)" + Catch + End Try - Case oControl.GetType() = GetType(GridControl) - ' GridControl-Handling + Try + Dim oColor = System.Drawing.Color.FromName(oDTDEPENDING_RESULT.Rows(0).Item("btnFinishColor")) + btnSave.BackColor = oColor + Catch + btnSave.BackColor = Color.Transparent + End Try - 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 + 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 - _DependingControl_In_Action = False - Exit For - End If - Next + Case oControl.GetType() = GetType(GridControl) + ' GridControl-Handling (unverändert) - If oFound = False Then - MyValidationLogger.Debug($"Could not find the depending Control with ID {oDEPENDING_GUID} on panel!!!") - End If - Catch ex As Exception - MyValidationLogger.Warn($"Error while setting depending control-value for [{oDEPENDING_CtrlName}]: " & ex.Message) - _DependingControl_In_Action = False - End Try - Else - MyValidationLogger.Warn($"Datatable for Depending Controls was nothing! Check the SQL [{oSqlCommand}]") - End If - Else - MyValidationLogger.Debug($"Error: Check CoNN ID and SQL on NULL VALUES!") - End If + Case oControl.GetType() = GetType(CheckBox) + Try + Dim oCheckState = CBool(oDTDEPENDING_RESULT.Rows(0).Item(0)) + Dim oDependingChk As CheckBox = oControl + oDependingChk.CheckState = If(oCheckState, CheckState.Checked, CheckState.Unchecked) + + Try + Dim oColor = System.Drawing.Color.FromName(oDTDEPENDING_RESULT.Rows(0).Item("BackgroundColor")) + oControl.BackColor = oColor + Catch + End Try + Catch ex As Exception + MyValidationLogger.Warn($"Unexpected error in Checking oCheckBoxDependingControlLOOKUP: {ex.Message}") + End Try + End Select + + Catch ex As Exception + MyValidationLogger.Warn($"Error while setting depending control-value for [{oDEPENDING_CtrlName}]: {ex.Message}") + Finally + _suppressLookupEvents = wasSuppressed + _DependingControl_In_Action = False + End Try Next End Sub Private Sub CheckBox_DependingControls(pCheckbox As CheckBox) @@ -2709,7 +2748,7 @@ Public Class frmValidator Dim dt As DataTable = Nothing Dim cacheKey = $"META|{filter}|{SortBy}" - If _SqlDataCache.TryGetValue(cacheKey, dt) Then + If _CachedSqlDataCache.TryGetValue(cacheKey, dt) Then Return dt End If @@ -2728,7 +2767,7 @@ Public Class frmValidator dt = rows.CopyToDataTable() End If - _SqlDataCache(cacheKey) = dt + _CachedSqlDataCache(cacheKey) = dt Return dt Catch ex As Exception MyValidationLogger.Warn($"GetControlMetaBySql cache filter failed, fallback to DB: {ex.Message}") @@ -2749,7 +2788,7 @@ Public Class frmValidator dt = DatabaseFallback.GetDatatable("TBPM_PROFILE_CONTROLS", New GetDatatableOptions(query, DatabaseType.ECM)) If dt IsNot Nothing Then - _SqlDataCache(cacheKey) = dt + _CachedSqlDataCache(cacheKey) = dt End If Return dt @@ -2758,12 +2797,12 @@ Public Class frmValidator Dim dt As DataTable = Nothing Dim cacheKey = $"{connectionId}|{sql}" - If Not _SqlDataCache.TryGetValue(cacheKey, dt) Then + If Not _CachedSqlDataCache.TryGetValue(cacheKey, dt) Then dt = DatabaseFallback.GetDatatable(New GetDatatableOptions(sql, DatabaseType.ECM) With { .ConnectionId = connectionId }) If dt IsNot Nothing Then - _SqlDataCache(cacheKey) = dt + _CachedSqlDataCache(cacheKey) = dt End If End If @@ -2774,9 +2813,9 @@ Public Class frmValidator Dim result As Object = Nothing Dim cacheKey = $"SCALAR|{connectionId}|{sql}" - If Not _SqlScalarCache.TryGetValue(cacheKey, result) Then + If Not _CachedSqlScalarCache.TryGetValue(cacheKey, result) Then result = DatabaseFallback.GetScalarValueWithConnection(sql, connectionId) - _SqlScalarCache(cacheKey) = result + _CachedSqlScalarCache(cacheKey) = result End If Return result @@ -2863,6 +2902,12 @@ Public Class frmValidator End Try Else MyValidationLogger.Info($">> Attention: GetNextGUID - Could not get the next GUID - SQL [{oSQL}]") + If User.IsAdmin And LOGCONFIG.Debug = True Then + My.Computer.Clipboard.SetText(oSQL) + MsgBox($">> Attention: in GetNextGUID - Could not get a GUID(1)" & vbCrLf & + $"SQL kopiert: {oSQL.Substring(0, Math.Min(100, oSQL.Length))}...", + MsgBoxStyle.Exclamation) + End If oNewGUID = 0 Return oNewGUID End If @@ -2995,6 +3040,16 @@ Public Class frmValidator Sub Load_Next_Document(first As Boolean) + If LOG_HOTSPOTS Then + ' ========== DIAGNOSE START ========== + MyValidationLogger.Info($"[INFO] Load_Next_Document START - first: {first}") + MyValidationLogger.Info($" frmValidator.IsDisposed: {Me.IsDisposed}") + MyValidationLogger.Info($" frmValidator.Visible: {Me.Visible}") + MyValidationLogger.Info($" _FormClosing: {_FormClosing}") + MyValidationLogger.Info($" CURRENT_DOC_GUID: {CURRENT_DOC_GUID}") + ' ========== ENDE DIAGNOSE ========== + End If + Dim oMilliseconts As Double clsPatterns.ClearControlCache() ' Cache-Invalidierung @@ -3006,9 +3061,9 @@ Public Class frmValidator MyValidationLogger.Info("[PERF LND] Load_Next_Document START") End If - _SqlDataCache.Clear() - _SqlScalarCache.Clear() - _SqlControlsByGuid = Nothing + _CachedSqlDataCache.Clear() + _CachedSqlScalarCache.Clear() + _CachedSqlControlsByGuid = Nothing CURRENT_WMFILE = Nothing activate_controls(False) oErrMsgMissingInput = "" @@ -3306,7 +3361,13 @@ Public Class frmValidator If layoutSuspended Then PanelValidatorControl.ResumeLayout() End If + If LOG_HOTSPOTS Then + ' ========== DIAGNOSE ENDE ========== + MyValidationLogger.Info($"[INFO] Load_Next_Document ENDE") + MyValidationLogger.Info($" frmValidator.IsDisposed: {Me.IsDisposed}") + MyValidationLogger.Info($" frmValidator.Visible: {Me.Visible}") + ' ========== ENDE DIAGNOSE ========== MyValidationLogger.Info($"[PERF LND] Load_Next_Document GESAMT: {(DateTime.Now - perfStart).TotalMilliseconds}ms") End If End Try @@ -3715,6 +3776,15 @@ Public Class frmValidator End Function Sub FillIndexValues(first As Boolean, Optional SingleAttribute As String = "") + ' ========== PERFORMANCE-LOGGING ========== + Dim perfStart As DateTime = DateTime.MinValue + Dim perfLastCheck As DateTime = DateTime.MinValue + If LOG_HOTSPOTS Then + perfStart = DateTime.Now + perfLastCheck = perfStart + MyValidationLogger.Info($"[PERF FillIndexValues] START - Controls: {PanelValidatorControl.Controls.Count}") + End If + If LOG_PERF Then PerformanceLogger.Info("FillIndexValues") Dim oControlType As String @@ -3722,834 +3792,849 @@ Public Class frmValidator 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 + ' ========== OPTIMIERUNG 1: Einmalige Gruppierung von Grid-Spalten ========== + ' VORHER: Für jedes Grid wurde DT_COLUMNS_GRID.Select() aufgerufen → O(n * m) + ' NACHHER: Einmalig gruppieren, dann Dictionary-Lookup → O(n + m) + 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 + + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF FillIndexValues] Nach columnsByControl-Gruppierung: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If + End If + ' ========== ENDE OPTIMIERUNG 1 ========== + + ' ========== OPTIMIERUNG 2: Control-Dictionary für schnellere Suche ========== + ' VORHER: Verschachtelte Loops für Control-Suche → O(n²) + ' NACHHER: Dictionary-Lookup → O(1) + If _CachedControlsByGuid Is Nothing Then + _CachedControlsByGuid = New Dictionary(Of Integer, Control)() + For Each ctrl As Control In PanelValidatorControl.Controls + Try + Dim meta = DirectCast(ctrl.Tag, ClassControlCreator.ControlMetadata) + _CachedControlsByGuid(meta.Guid) = ctrl + Catch + Continue For + End Try Next + + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF FillIndexValues] Nach _CachedControlsByGuid-Erstellung: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If 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 - Dim oValueFromSource - Dim oFormattedValue As String = "" - Dim oControlId = DirectCast(oControl.Tag, ClassControlCreator.ControlMetadata).Guid - Dim oControlRow = (From form In DTVWCONTROL_INDEX.AsEnumerable() - Select form - Where form.Item("GUID") = oControlId).Single() - - Dim oTyp As String = oControlRow.Item("CTRL_TYPE") - Dim oIDBTyp As String - If IDB_ACTIVE Then - oIDBTyp = oControlRow.Item("IDB_TYP") - End If - - Dim oSourceIndexName As String = oControlRow.Item("INDEX_NAME") - ' Wenn kein defaultValue existiert, leeren String setzen - Dim oDefaultValue As String = ObjectEx.NotNull(oControlRow.Item("DEFAULT_VALUE"), String.Empty) - oIndexName = oSourceIndexName - oControName = oControl.Name - Dim oLoadIndex As Boolean = oControlRow.Item("LOAD_IDX_VALUE") - If oIndexName = "@@DISPLAY_ONLY" Then - oLoadIndex = False - End If - MyValidationLogger.Debug("INDEX: " & oSourceIndexName & " - CONTROLNAME: " & oControl.Name & " - LOAD IDXVALUES: " & oLoadIndex.ToString) + ' ========== ENDE OPTIMIERUNG 2 ========== + ' ========== OPTIMIERUNG 3: UI-Updates pausieren (kritisch für Performance!) ========== + ' VORHER: Jede Zuweisung triggerte Repaint → tausende UI-Updates + ' NACHHER: Alle Updates gebündelt → nur ein Repaint am Ende + PanelValidatorControl.SuspendLayout() + Try + ' ========== ENDE OPTIMIERUNG 3 ========== + + If DTVWCONTROL_INDEX.Rows.Count > 0 Then + Dim oCount As Integer = 0 + For Each oControl As Control In Me.PanelValidatorControl.Controls + Dim oValueFromSource + Dim oFormattedValue As String = "" + + ' ========== OPTIMIERUNG 4: LINQ statt Loop für Control-Row-Suche ========== + ' VORHER: Implizite Loop über DTVWCONTROL_INDEX + ' NACHHER: Optimierter LINQ-Query mit SingleOrDefault + Dim oControlId = DirectCast(oControl.Tag, ClassControlCreator.ControlMetadata).Guid + Dim oControlRow = (From form In DTVWCONTROL_INDEX.AsEnumerable() + Where form.Item("GUID") = oControlId).SingleOrDefault() + + If oControlRow Is Nothing Then Continue For + ' ========== ENDE OPTIMIERUNG 4 ========== + + Dim oTyp As String = oControlRow.Item("CTRL_TYPE") + Dim oIDBTyp As String + If IDB_ACTIVE Then + oIDBTyp = oControlRow.Item("IDB_TYP") + End If - Select Case True - Case oControl.GetType = GetType(DevExpress.XtraEditors.TextEdit) Or oControl.GetType = GetType(MemoEdit) - If LOG_PERF Then PerformanceLogger.Info("FillIndexValues/TextEdit") + Dim oSourceIndexName As String = oControlRow.Item("INDEX_NAME") + Dim oDefaultValue As String = ObjectEx.NotNull(oControlRow.Item("DEFAULT_VALUE"), String.Empty) + oIndexName = oSourceIndexName + oControName = oControl.Name + Dim oLoadIndex As Boolean = oControlRow.Item("LOAD_IDX_VALUE") + If oIndexName = "@@DISPLAY_ONLY" Then + oLoadIndex = False + End If + MyValidationLogger.Debug("INDEX: " & oSourceIndexName & " - CONTROLNAME: " & oControl.Name & " - LOAD IDXVALUES: " & oLoadIndex.ToString) - Try - oControlType = "Textbox" - Dim oTextBox As DevExpress.XtraEditors.TextEdit = oControl - Dim oMeta As ClassControlCreator.ControlMetadata = oTextBox.Tag + Select Case True + Case oControl.GetType = GetType(DevExpress.XtraEditors.TextEdit) Or oControl.GetType = GetType(MemoEdit) + If LOG_PERF Then PerformanceLogger.Info("FillIndexValues/TextEdit") - If oSourceIndexName = "" Then - MsgBox("Attention wrong configuration:" & vbNewLine & "for control " & oControl.Name & " no INDEX configured!" & vbNewLine & "Bitte prüfen Sie den Formulardesigner!", MsgBoxStyle.Critical) - Exit For - End If - If oSourceIndexName Is Nothing = False Then - If oLoadIndex = False Then - MyValidationLogger.Debug($" oControl {oControl.Name}: Indexwert soll nicht geladen werden.") - If Not {"@@DISPLAY_ONLY", "DD PM-ONLY FOR DISPLAY"}.Contains(oSourceIndexName) Then - ' Wenn kein Index exisitiert, defaultValue laden - oTextBox.EditValue = oDefaultValue - End If + Try + oControlType = "Textbox" + Dim oTextBox As DevExpress.XtraEditors.TextEdit = oControl + Dim oMeta As ClassControlCreator.ControlMetadata = oTextBox.Tag - Exit Select + If oSourceIndexName = "" Then + MsgBox("Attention wrong configuration:" & vbNewLine & "for control " & oControl.Name & " no INDEX configured!" & vbNewLine & "Bitte prüfen Sie den Formulardesigner!", MsgBoxStyle.Critical) + Exit For End If + If oSourceIndexName Is Nothing = False Then + If oLoadIndex = False Then + MyValidationLogger.Debug($" oControl {oControl.Name}: Indexwert soll nicht geladen werden.") + If Not {"@@DISPLAY_ONLY", "DD PM-ONLY FOR DISPLAY"}.Contains(oSourceIndexName) Then + oTextBox.EditValue = oDefaultValue + End If + Exit Select + End If - - If oSourceIndexName.StartsWith("[%VKT") And PROFIL_VEKTORINDEX <> "" Then - oValueFromSource = ReturnVektor_IndexValue(oSourceIndexName) - Else - - oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride) - - If oValueFromSource Is Nothing Then - oValueFromSource = "" + If oSourceIndexName.StartsWith("[%VKT") And PROFIL_VEKTORINDEX <> "" Then + oValueFromSource = ReturnVektor_IndexValue(oSourceIndexName) Else - If oValueFromSource.ToString = "System.Object[]" Then - MyValidationLogger.Debug("TextBox with VektorField: " & oSourceIndexName) - Try - MyValidationLogger.Debug($"Length of Vektorarray: {oValueFromSource.length}") - Catch ex As Exception - MyValidationLogger.Info($"Error in gettin the lenth of vektorfield {oSourceIndexName} - {ex.Message}") - End Try - If oValueFromSource.length = 1 Then - oValueFromSource = oValueFromSource(0) - Else ' - MyValidationLogger.Info(" >> Vectorfield " & oSourceIndexName & "' contains more then one value - First value will be used") - oValueFromSource = oValueFromSource(0) - End If - MyValidationLogger.Debug($"wertWD has been saved...") + oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride) + If oValueFromSource Is Nothing Then + oValueFromSource = "" + Else + If oValueFromSource.ToString = "System.Object[]" Then + MyValidationLogger.Debug("TextBox with VektorField: " & oSourceIndexName) + Try + MyValidationLogger.Debug($"Length of Vektorarray: {oValueFromSource.length}") + Catch ex As Exception + MyValidationLogger.Info($"Error in gettin the lenth of vektorfield {oSourceIndexName} - {ex.Message}") + End Try + If oValueFromSource.length = 1 Then + oValueFromSource = oValueFromSource(0) + Else + MyValidationLogger.Info(" >> Vectorfield " & oSourceIndexName & "' contains more then one value - First value will be used") + oValueFromSource = oValueFromSource(0) + End If + MyValidationLogger.Debug($"wertWD has been saved...") + End If End If End If - End If - MyValidationLogger.Debug("Value from Source: [{0}]", oValueFromSource) + MyValidationLogger.Debug("Value from Source: [{0}]", oValueFromSource) - Try - Dim oFormatString As String = oControlRow.ItemEx("CTRL_FORMAT_STRING", "") - 'oFormattedValue = ClassFormat.GetFormattedValue(oControl.Name, oValueFromSource, oFormatString) + Try + Dim oFormatString As String = oControlRow.ItemEx("CTRL_FORMAT_STRING", "") + oTextBox.EditValue = ObjectEx.NotNull(oValueFromSource, oDefaultValue) - 'If Not IsNothing(oFormattedValue) And oFormattedValue <> String.Empty Then - ' oTextBox.EditValue = ObjectEx.NotNull(oFormattedValue, oDefaultValue) - 'Else - ' oTextBox.EditValue = ObjectEx.NotNull(oValueFromSource, oDefaultValue) - 'End If + If oControl.GetType = GetType(DevExpress.XtraEditors.TextEdit) And oFormatString = "CURRENCY" Then + ApplyCurrencyMask(oTextBox) + End If - oTextBox.EditValue = ObjectEx.NotNull(oValueFromSource, oDefaultValue) + ' BackColor-Logik + Try + Dim oBackColor As String = oControlRow.Item("CTRL_BACKCOLOR_IF") + If oBackColor <> String.Empty Then + Dim oSPlit = Split(oBackColor, ";") + If oSPlit.Length = 3 Then + Dim oValueConverted + If IsNumeric(oValueFromSource) Then + oValueConverted = oValueFromSource.ToString.Replace(",", ".") + Else + oValueConverted = oValueFromSource + End If + Dim oExpression = $"{oValueConverted} {oSPlit(0)}" - If oControl.GetType = GetType(DevExpress.XtraEditors.TextEdit) And oFormatString = "CURRENCY" Then - ApplyCurrencyMask(oTextBox) - End If - Try - Dim oBackColor As String = oControlRow.Item("CTRL_BACKCOLOR_IF") - If oBackColor <> String.Empty Then - Dim oSPlit = Split(oBackColor, ";") - If oSPlit.Length = 3 Then - Dim oValueConverted - If IsNumeric(oValueFromSource) Then - oValueConverted = oValueFromSource.ToString.Replace(",", ".") - Else - oValueConverted = oValueFromSource - End If - Dim oExpression = $"{oValueConverted} {oSPlit(0)}" + Dim oSQl = $"SELECT CASE WHEN {oExpression} THEN CONVERT(BIT,1) ELSE CONVERT(BIT,0) END " + Dim oColorName = IIf(DatabaseECM.GetScalarValue(oSQl), oSPlit(1), oSPlit(2)) - Dim oSQl = $"SELECT CASE WHEN {oExpression} THEN CONVERT(BIT,1) ELSE CONVERT(BIT,0) END " - Dim oColorName = IIf(DatabaseECM.GetScalarValue(oSQl), oSPlit(1), oSPlit(2)) + oControl.BackColor = Color.FromName(oColorName) + oMeta.BackColor = oControl.BackColor + oControl.ForeColor = GraphicsEx.GetContrastedColor(oControl.BackColor) + End If + End If + Catch ex As Exception + MyValidationLogger.Warn($"Unexpected error in Set Backcolor [{oControl.Name}]: {ex.Message}") + MyValidationLogger.Error(ex) + End Try - oControl.BackColor = Color.FromName(oColorName) - oMeta.BackColor = oControl.BackColor + ' ========== OPTIMIERUNG 5: GridTables erst NACH allen TextBox-Updates ========== + ' NACHHER wird dies EINMAL am Ende aufgerufen (siehe unten) + ' ========== ENDE OPTIMIERUNG 5 ========== - oControl.ForeColor = GraphicsEx.GetContrastedColor(oControl.BackColor) - End If - End If Catch ex As Exception - MyValidationLogger.Warn($"Unexpected error in Set Backcolor [{oControl.Name}]: {ex.Message}") - MyValidationLogger.Error(ex) + MyValidationLogger.Info("Error While converting defaultValue [" & oDefaultValue & "]: " & ex.Message) + oTextBox.EditValue = "" End Try - ControlCreator.GridTables_HandleControlValueChange(PanelValidatorControl, DT_COLUMNS_GRID_WITH_SQL_WITH_CTRL_PLACEHOLDER) - - Catch ex As Exception - MyValidationLogger.Info("Error While converting defaultValue [" & oDefaultValue & "]: " & ex.Message) - oTextBox.EditValue = "" - End Try + End If + Catch ex As Exception + MyValidationLogger.Error(ex) + errormessage = $"Unvorhergesehener Fehler bei FillIndexValues TextBox [{oControl.Name}]:" & vbNewLine & ex.Message & vbNewLine & "Check Logfile" + My.Settings.Save() + frmError.ShowDialog() + MyValidationLogger.Info("Unexpected error in FillIndexValuesTextBox: " & ex.Message, True) + MyValidationLogger.Info(">> Controltype: " & oControlType) + MyValidationLogger.Info(">> Indexname windream: " & oIndexName) + Exit Sub + End Try + Case oControl.GetType = GetType(Windows.Forms.ComboBox) + If LOG_PERF Then PerformanceLogger.Info("FillIndexValues/ComboBox") - End If - Catch ex As Exception - MyValidationLogger.Error(ex) - errormessage = $"Unvorhergesehener Fehler bei FillIndexValues TextBox [{oControl.Name}]:" & vbNewLine & ex.Message & vbNewLine & "Check Logfile" - My.Settings.Save() - frmError.ShowDialog() - MyValidationLogger.Info("Unexpected error in FillIndexValuesTextBox: " & ex.Message, True) - MyValidationLogger.Info(">> Controltype: " & oControlType) - MyValidationLogger.Info(">> Indexname windream: " & oIndexName) - Exit Sub - End Try + oControlType = "ComboBox" + Dim oMyCombobox As Windows.Forms.ComboBox = oControl + Try + If oSourceIndexName = "" Then + MsgBox("Attention wrong configuration:" & vbNewLine & "for control " & oControl.Name & " no INDEX configured!" & vbNewLine & "Bitte prüfen Sie den Formulardesigner!", MsgBoxStyle.Critical) + Exit For + End If + If oSourceIndexName Is Nothing = False Then + If oLoadIndex = False Then + MyValidationLogger.Debug($" oMyComboBox {oMyCombobox.Name}: Indexwert soll nicht geladen werden.") + If Not {"@@DISPLAY_ONLY", "DD PM-ONLY FOR DISPLAY"}.Contains(oSourceIndexName) Then + If oDefaultValue = String.Empty Then + oMyCombobox.SelectedIndex = -1 + Else + oMyCombobox.Text = oDefaultValue + End If + End If + Exit Select + End If - Case oControl.GetType = GetType(Windows.Forms.ComboBox) - If LOG_PERF Then PerformanceLogger.Info("FillIndexValues/ComboBox") + If oSourceIndexName.StartsWith("[%VKT") And PROFIL_VEKTORINDEX <> "" Then + oValueFromSource = ReturnVektor_IndexValue(oSourceIndexName) + Else + oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride) + End If - oControlType = "ComboBox" - Dim oMyCombobox As Windows.Forms.ComboBox = oControl - Try - If oSourceIndexName = "" Then - MsgBox("Attention wrong configuration:" & vbNewLine & "for control " & oControl.Name & " no INDEX configured!" & vbNewLine & "Bitte prüfen Sie den Formulardesigner!", MsgBoxStyle.Critical) - Exit For - End If - If oSourceIndexName Is Nothing = False Then - If oLoadIndex = False Then - MyValidationLogger.Debug($" oMyComboBox {oMyCombobox.Name}: Indexwert soll nicht geladen werden.") - If Not {"@@DISPLAY_ONLY", "DD PM-ONLY FOR DISPLAY"}.Contains(oSourceIndexName) Then + If oValueFromSource Is Nothing Then + MyValidationLogger.Debug($"oMyComboBox {oMyCombobox.Name} - Indexvalue from index {oSourceIndexName}: Nothing") If oDefaultValue = String.Empty Then + MyValidationLogger.Debug($"oMyComboBox {oMyCombobox.Name}-defaultValue wurde nicht gefunden") oMyCombobox.SelectedIndex = -1 Else + MyValidationLogger.Debug($"oMyComboBox {oMyCombobox.Name}-defaultValue wird geladen") oMyCombobox.Text = oDefaultValue End If - End If - - Exit Select - End If - - If oSourceIndexName.StartsWith("[%VKT") And PROFIL_VEKTORINDEX <> "" Then - oValueFromSource = ReturnVektor_IndexValue(oSourceIndexName) - Else - oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride) - End If - - If oValueFromSource Is Nothing Then - - MyValidationLogger.Debug($"oMyComboBox {oMyCombobox.Name} - Indexvalue from index {oSourceIndexName}: Nothing") - If oDefaultValue = String.Empty Then - MyValidationLogger.Debug($"oMyComboBox {oMyCombobox.Name}-defaultValue wurde nicht gefunden") - oMyCombobox.SelectedIndex = -1 Else - MyValidationLogger.Debug($"oMyComboBox {oMyCombobox.Name}-defaultValue wird geladen") - oMyCombobox.Text = oDefaultValue - 'cmb.SelectedIndex = cmb.FindStringExact(defaultValue) - End If - Else - If oValueFromSource.ToString = "System.Object[]" Then - MyValidationLogger.Debug($"oMyComboBox {oMyCombobox.Name} - Combobox with VektorField: " & oSourceIndexName) - Try - MyValidationLogger.Debug($"Length of Vektorarray: {oValueFromSource.length}") - Catch ex As Exception - MyValidationLogger.Info($"Error in gettin the length of vektorfield {oSourceIndexName} - {ex.Message}") - End Try - If oValueFromSource.length = 1 Then - oValueFromSource = oValueFromSource(0) - Else ' - MyValidationLogger.Info(" >> Vectorfield " & oSourceIndexName & "' contains more then one value - First value will be used") - oValueFromSource = oValueFromSource(0) + If oValueFromSource.ToString = "System.Object[]" Then + MyValidationLogger.Debug($"oMyComboBox {oMyCombobox.Name} - Combobox with VektorField: " & oSourceIndexName) + Try + MyValidationLogger.Debug($"Length of Vektorarray: {oValueFromSource.length}") + Catch ex As Exception + MyValidationLogger.Info($"Error in gettin the length of vektorfield {oSourceIndexName} - {ex.Message}") + End Try + If oValueFromSource.length = 1 Then + oValueFromSource = oValueFromSource(0) + Else + MyValidationLogger.Info(" >> Vectorfield " & oSourceIndexName & "' contains more then one value - First value will be used") + oValueFromSource = oValueFromSource(0) + End If + MyValidationLogger.Debug($"wertWD has been saved...") End If - MyValidationLogger.Debug($"wertWD has been saved...") - Else - - End If - MyValidationLogger.Debug($"Indexwert from Index {oSourceIndexName}: {oValueFromSource}") - MyValidationLogger.Debug($"Items in Combobox: {oMyCombobox.Items.Count}") - - If oMyCombobox.Items.Count = 0 Then - ' If LogErrorsOnly = False Then Logger.Info($"Index Wert wurde gesetzt") - oMyCombobox.Text = oValueFromSource - Else - MyValidationLogger.Debug($"Index Wert [{oValueFromSource}] wurde ausgewählt") - oMyCombobox.SelectedIndex = oMyCombobox.FindStringExact(oValueFromSource) - MyValidationLogger.Debug($"oMyComboBox {oMyCombobox.Name} .SelectedIndex: {oMyCombobox.SelectedIndex}") + MyValidationLogger.Debug($"Indexwert from Index {oSourceIndexName}: {oValueFromSource}") + MyValidationLogger.Debug($"Items in Combobox: {oMyCombobox.Items.Count}") + If oMyCombobox.Items.Count = 0 Then + oMyCombobox.Text = oValueFromSource + Else + MyValidationLogger.Debug($"Index Wert [{oValueFromSource}] wurde ausgewählt") + oMyCombobox.SelectedIndex = oMyCombobox.FindStringExact(oValueFromSource) + MyValidationLogger.Debug($"oMyComboBox {oMyCombobox.Name} .SelectedIndex: {oMyCombobox.SelectedIndex}") + End If End If End If - End If - MyValidationLogger.Debug("") - Catch ex As Exception - MyValidationLogger.Error(ex) - MyValidationLogger.Info(">> Unexpected error in FillIndexValues(Combobox: " & oMyCombobox.Name & "): " & ex.Message, True) - MyValidationLogger.Info(">> Controltype: " & oControlType) - MyValidationLogger.Info(">> Indexname windream: " & oIndexName) - errormessage = "Unexpected error in FillIndexValues(Combobox: " & oMyCombobox.Name & "): " & vbNewLine & ex.Message & vbNewLine & "Check Logfile" - My.Settings.Save() - frmError.ShowDialog() - - End Try + MyValidationLogger.Debug("") + Catch ex As Exception + MyValidationLogger.Error(ex) + MyValidationLogger.Info(">> Unexpected error in FillIndexValues(Combobox: " & oMyCombobox.Name & "): " & ex.Message, True) + MyValidationLogger.Info(">> Controltype: " & oControlType) + MyValidationLogger.Info(">> Indexname windream: " & oIndexName) + errormessage = "Unexpected error in FillIndexValues(Combobox: " & oMyCombobox.Name & "): " & vbNewLine & ex.Message & vbNewLine & "Check Logfile" + My.Settings.Save() + frmError.ShowDialog() + End Try + Case oControl.GetType = GetType(GridControl) + If LOG_PERF Then PerformanceLogger.Info("FillIndexValues/GridControl") - Case oControl.GetType = GetType(GridControl) - If LOG_PERF Then PerformanceLogger.Info("FillIndexValues/GridControl") + oControlType = "DevExpress.XtraGrid.GridControl" + Dim oMyGridControl As GridControl = oControl - oControlType = "DevExpress.XtraGrid.GridControl" - 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 - MsgBox("Attention wrong configuration:" & vbNewLine & "for control " & oControl.Name & " no INDEX configured!" & vbNewLine & "Bitte prüfen Sie den Formulardesigner!", MsgBoxStyle.Critical, ADDITIONAL_TITLE) - Exit For + ' ========== OPTIMIERUNG 6: Dictionary-Lookup statt Select() ========== + ' VORHER: DT_COLUMNS_GRID.Select($"CONTROL_ID = {oControlId}") → O(n) pro Grid + ' NACHHER: Dictionary.TryGetValue() → O(1) + 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 + oDTColumnsPerDevExGrid = DT_COLUMNS_GRID.Clone() + MyValidationLogger.Warn($"Grid [{oControl.Name}]: Keine Spalten-Definition gefunden!") End If - If oSourceIndexName Is Nothing = False Then - If oLoadIndex = False Then - MyValidationLogger.Debug($" oControl {oControl.Name}: Indexwert soll nicht geladen werden.") - MyValidationLogger.Debug("Indexwert soll nicht geladen werden.") - Exit Select - End If - MyValidationLogger.Debug($"getting Value for Attribute [{oSourceIndexName}] - oIDBTyp [{oIDBTyp}] - oIDBOverride [{oIDBOverride}]...") - ' Dim wertWD = CURRENT_WMFILE.GetVariableValue(oSourceIndexName) - oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride) - - If oValueFromSource Is Nothing = False Then - Dim oValueType = oValueFromSource.GetType.ToString - MyValidationLogger.Debug($"oValueType is [{oValueType}]!") - 'Es wird gegen ein Vektorfeld nachindexiert - If oValueType.Contains("System.Object") Or oValueType = "System.Data.DataTable" Or oValueType = "System.String" Then - Select Case oTyp - 'Tabellendarstellung - Case "TABLE" - '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}.") - - If oDTColumnsPerDevExGrid.Rows.Count >= 1 Then - Dim oDataSource As DataTable = oMyGridControl.DataSource - oDataSource.Rows.Clear() - If IDB_ACTIVE = False Then - MyValidationLogger.Debug("ValueFromSource contains {0} items", oValueFromSource) - - For Each Zeile As Object In oValueFromSource - MyValidationLogger.Debug($"vektorrow Value {Zeile.ToString}...") - oColValuesfromSource = Split(Zeile, PMDelimiter) - Dim oNewRow = oDataSource.NewRow() - MyValidationLogger.Debug("Creating new row..") - + ' ========== ENDE OPTIMIERUNG 6 ========== - For index = 0 To oDTColumnsPerDevExGrid.Rows.Count - 1 - Dim rawValue As String = If(index < oColValuesfromSource.Length, oColValuesfromSource(index), String.Empty) - Dim targetColumn As DataColumn = oDataSource.Columns(index) - Dim colName As String = targetColumn.ColumnName - Dim colType As String = targetColumn.DataType.FullName + Try + If oSourceIndexName = "" Then + MsgBox("Attention wrong configuration:" & vbNewLine & "for control " & oControl.Name & " no INDEX configured!" & vbNewLine & "Bitte prüfen Sie den Formulardesigner!", MsgBoxStyle.Critical, ADDITIONAL_TITLE) + Exit For + End If + If oSourceIndexName Is Nothing = False Then + If oLoadIndex = False Then + MyValidationLogger.Debug($" oControl {oControl.Name}: Indexwert soll nicht geladen werden.") + Exit Select + End If + MyValidationLogger.Debug($"getting Value for Attribute [{oSourceIndexName}] - oIDBTyp [{oIDBTyp}] - oIDBOverride [{oIDBOverride}]...") + oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride) - ' Detailliertes Debug vor der Zuweisung - MyValidationLogger.Debug("Grid row assign: RowIdx={0}, ColIdx={1}, ColName={2}, ColType={3}, RawValue=[{4}], IsEmpty={5}", - oDataSource.Rows.Count, index, colName, colType, rawValue, String.IsNullOrWhiteSpace(rawValue)) + If oValueFromSource Is Nothing = False Then + Dim oValueType = oValueFromSource.GetType.ToString + MyValidationLogger.Debug($"oValueType is [{oValueType}]!") + + If oValueType.Contains("System.Object") Or oValueType = "System.Data.DataTable" Or oValueType = "System.String" Then + Select Case oTyp + Case "TABLE" + Dim oColValuesfromSource As String() + MyValidationLogger.Debug($"DevExpressGrid: {oDTColumnsPerDevExGrid.Rows.Count} Columns configured for control {oControlId}.") + + If oDTColumnsPerDevExGrid.Rows.Count >= 1 Then + Dim oDataSource As DataTable = oMyGridControl.DataSource + oDataSource.Rows.Clear() + If IDB_ACTIVE = False Then + MyValidationLogger.Debug("ValueFromSource contains {0} items", oValueFromSource) + + For Each Zeile As Object In oValueFromSource + MyValidationLogger.Debug($"vektorrow Value {Zeile.ToString}...") + oColValuesfromSource = Split(Zeile, PMDelimiter) + Dim oNewRow = oDataSource.NewRow() + MyValidationLogger.Debug("Creating new row..") + + For index = 0 To oDTColumnsPerDevExGrid.Rows.Count - 1 + Dim rawValue As String = If(index < oColValuesfromSource.Length, oColValuesfromSource(index), String.Empty) + Dim targetColumn As DataColumn = oDataSource.Columns(index) + Dim colName As String = targetColumn.ColumnName + Dim colType As String = targetColumn.DataType.FullName + + MyValidationLogger.Debug("Grid row assign: RowIdx={0}, ColIdx={1}, ColName={2}, ColType={3}, RawValue=[{4}], IsEmpty={5}", + oDataSource.Rows.Count, index, colName, colType, rawValue, String.IsNullOrWhiteSpace(rawValue)) - Try - If oColValuesfromSource.Length > index Then - oNewRow.Item(index) = oColValuesfromSource(index) - Else - If colType = "System.Double" Or colType = "System.Int32" Or colType = "System.Int64" Then - ' Numerische Spalten können nicht mit Empty befüllt werden - oNewRow.Item(index) = 0 + Try + If oColValuesfromSource.Length > index Then + oNewRow.Item(index) = oColValuesfromSource(index) Else - oNewRow.Item(index) = String.Empty + If colType = "System.Double" Or colType = "System.Int32" Or colType = "System.Int64" Then + oNewRow.Item(index) = 0 + Else + oNewRow.Item(index) = String.Empty + End If End If - 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}]", - oDataSource.Rows.Count, index, colName, colType, rawValue) - MyValidationLogger.Error(ex) - ' Optional: weitere Kontexthilfe – z.B. ob Spalte DBNull erlaubt - Try - MyValidationLogger.Debug("Column.AllowDBNull={0}, Column.MaxLength={1}", targetColumn.AllowDBNull, targetColumn.MaxLength) - Catch + Catch ex As Exception + 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) + Try + MyValidationLogger.Debug("Column.AllowDBNull={0}, Column.MaxLength={1}", targetColumn.AllowDBNull, targetColumn.MaxLength) + Catch + End Try + Throw End Try - ' Fehler weiterwerfen, damit ursprüngliches Verhalten erhalten bleibt - Throw - End Try - Next - MyValidationLogger.Debug("Adding row To grid..") - oDataSource.Rows.Add(oNewRow) - - - Next - Else - If oValueType = "System.String" Then - MyValidationLogger.Debug($"IDB Fill Grid [{oControl.Name}] With String") - MyValidationLogger.Debug($"oValueFromSource [{oValueFromSource}] - PMDelimiter[{PMDelimiter}]") - - oColValuesfromSource = Split(oValueFromSource.ToString, PMDelimiter) - If oColValuesfromSource.Length > 8 Then - MyValidationLogger.Warn("⚠️ Fill Grid Error - Max 8 columns can be configured!") - End If - - Dim oRowData As New List(Of Object) - MyValidationLogger.Debug(String.Format("Now creating the rows For DevexpressGrid ...")) - Dim oMSG = "" - Try - For index = 1 To oColValuesfromSource.Length - oMSG = "" - Dim oValue = oColValuesfromSource(index - 1) - oMSG = String.Format("...Index [{0}] - Value [{1}]", index, oValue) - MyValidationLogger.Debug(oMSG) - If oDTColumnsPerDevExGrid.Rows.Count > (index - 1) Then - Dim oColumnType = oDTColumnsPerDevExGrid.Rows.Item(index - 1).Item("TYPE_COLUMN") - Dim oConvertedValue = ClassFormat.GetConvertedValue(oValue, oColumnType) - oRowData.Add(oConvertedValue) - Else - MyValidationLogger.Warn(String.Format("Mehr Values als Spaten in oDTColumnsPerDevExGrid {0}", oControl.Name)) - End If - Next - Catch ex As Exception - MyValidationLogger.Warn(String.Format("Unexpected Error While working On IDB Fill GridControl {0}", oControl.Name)) - If Not oMSG = String.Empty Then - MyValidationLogger.Warn(String.Format("oMSG {0}", oMSG)) + MyValidationLogger.Debug("Adding row To grid..") + oDataSource.Rows.Add(oNewRow) + Next + Else + ' IDB-Logik (bleibt gleich) + If oValueType = "System.String" Then + MyValidationLogger.Debug($"IDB Fill Grid [{oControl.Name}] With String") + MyValidationLogger.Debug($"oValueFromSource [{oValueFromSource}] - PMDelimiter[{PMDelimiter}]") + + oColValuesfromSource = Split(oValueFromSource.ToString, PMDelimiter) + If oColValuesfromSource.Length > 8 Then + MyValidationLogger.Warn("⚠️ Fill Grid Error - Max 8 columns can be configured!") End If - MyValidationLogger.Error(ex) - End Try - - oDataSource.Rows.Add(oRowData.ToArray()) - - - ElseIf oValueType = "System.Data.DataTable" Then - Dim oMyDatatable As DataTable = oValueFromSource - MyValidationLogger.Debug($"IDB Fill Grid [{oControl.Name}] With Datatable - Rows " & oMyDatatable.Rows.Count) - For Each oRow As DataRow In oMyDatatable.Rows + Dim oRowData As New List(Of Object) + MyValidationLogger.Debug(String.Format("Now creating the rows For DevexpressGrid ...")) + Dim oMSG = "" Try - MyValidationLogger.Debug($"IDB ROW Vector {oRow.Item(0).ToString}...") - 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!") - End If - MyValidationLogger.Debug($"oColValuesfromSource splitted - Length ({oColValuesfromSource.Length.ToString})") - Dim oRowData As New List(Of Object) - For index = 1 To oColValuesfromSource.Length - Try + oMSG = "" + Dim oValue = oColValuesfromSource(index - 1) + oMSG = String.Format("...Index [{0}] - Value [{1}]", index, oValue) + MyValidationLogger.Debug(oMSG) + If oDTColumnsPerDevExGrid.Rows.Count > (index - 1) Then Dim oColumnType = oDTColumnsPerDevExGrid.Rows.Item(index - 1).Item("TYPE_COLUMN") - MyValidationLogger.Debug($"oColumnType Of DGView-Column ({oColumnType.ToString})...") - Dim oConvertedValue = ClassFormat.GetConvertedValue(oColValuesfromSource(index - 1), oColumnType) + Dim oConvertedValue = ClassFormat.GetConvertedValue(oValue, oColumnType) oRowData.Add(oConvertedValue) - Catch ex As Exception - MyValidationLogger.Warn($"Error While converting/adding Value To oRowData " & ex.Message) - End Try + Else + MyValidationLogger.Warn(String.Format("Mehr Values als Spaten in oDTColumnsPerDevExGrid {0}", oControl.Name)) + End If Next - oDataSource.Rows.Add(oRowData.ToArray()) Catch ex As Exception - MyValidationLogger.Warn($"Error While adding datarow [{oRow.Item(0).ToString}] To Grid " & ex.Message) + MyValidationLogger.Warn(String.Format("Unexpected Error While working On IDB Fill GridControl {0}", oControl.Name)) + If Not oMSG = String.Empty Then + MyValidationLogger.Warn(String.Format("oMSG {0}", oMSG)) + End If + MyValidationLogger.Error(ex) End Try + oDataSource.Rows.Add(oRowData.ToArray()) - Next - End If - - End If - Else - MyValidationLogger.Info($"DevExpressGrid There are no columns configured/listed For control {oControlId}.") - End If - - Case Else - 'es handelt sich um ein einfaches Vektorfeld mit einem Wert - Dim oDataSource As DataTable = oMyGridControl.DataSource - For Each obj As Object In oValueFromSource - If obj Is Nothing = False Then - oDataSource.Rows.Add(New String() {obj.ToString}) - 'dgv.Rows.Add(New String() {obj.ToString}) + ElseIf oValueType = "System.Data.DataTable" Then + Dim oMyDatatable As DataTable = oValueFromSource + MyValidationLogger.Debug($"IDB Fill Grid [{oControl.Name}] With Datatable - Rows " & oMyDatatable.Rows.Count) + For Each oRow As DataRow In oMyDatatable.Rows + Try + MyValidationLogger.Debug($"IDB ROW Vector {oRow.Item(0).ToString}...") + 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!") + End If + MyValidationLogger.Debug($"oColValuesfromSource splitted - Length ({oColValuesfromSource.Length.ToString})") + Dim oRowData As New List(Of Object) + + For index = 1 To oColValuesfromSource.Length + Try + Dim oColumnType = oDTColumnsPerDevExGrid.Rows.Item(index - 1).Item("TYPE_COLUMN") + MyValidationLogger.Debug($"oColumnType Of DGView-Column ({oColumnType.ToString})...") + Dim oConvertedValue = ClassFormat.GetConvertedValue(oColValuesfromSource(index - 1), oColumnType) + oRowData.Add(oConvertedValue) + Catch ex As Exception + MyValidationLogger.Warn($"Error While converting/adding Value To oRowData " & ex.Message) + End Try + Next + oDataSource.Rows.Add(oRowData.ToArray()) + Catch ex As Exception + MyValidationLogger.Warn($"Error While adding datarow [{oRow.Item(0).ToString}] To Grid " & ex.Message) + End Try + Next + End If + End If + Else + MyValidationLogger.Info($"DevExpressGrid There are no columns configured/listed For control {oControlId}.") End If - Next - End Select - Else - MyValidationLogger.Warn($"Could Not load Devexpress.Grid [{oControl.Name }] As omytype Is [{oValueType}]!") - - End If - - Else - If first = False Then - Dim oDataSource As DataTable = oMyGridControl.DataSource - - If oDataSource.Rows.Count > 0 Then - oDataSource.Rows.Clear() + Case Else + Dim oDataSource As DataTable = oMyGridControl.DataSource + For Each obj As Object In oValueFromSource + If obj Is Nothing = False Then + oDataSource.Rows.Add(New String() {obj.ToString}) + End If + Next + End Select + Else + MyValidationLogger.Warn($"Could Not load Devexpress.Grid [{oControl.Name }] As omytype Is [{oValueType}]!") End If - - End If - End If - Try - Dim oMyGridView As DevExpress.XtraGrid.Views.Grid.GridView = oMyGridControl.MainView - oMyGridView.OptionsView.ColumnAutoWidth = False - - ' ========== 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") + Else + If first = False Then + Dim oDataSource As DataTable = oMyGridControl.DataSource + If oDataSource.Rows.Count > 0 Then + oDataSource.Rows.Clear() End If - Next + End If End If - ' ========== ENDE OPTIMIERUNG ========== - Dim i = 0 - ' RestoreDevExpressGridControl_Layout(CURRENT_CLICKED_PROFILE_ID, oControlId, oMyGridView) - Catch ex As Exception - MyValidationLogger.Error(ex) - End Try - End If - Catch ex As Exception - MyValidationLogger.Error(ex) - MyValidationLogger.Info(">> Unexpected Error In FillIndexValues(GridControl " & oMyGridControl.Name & ") " & ex.Message, True) - MyValidationLogger.Info(">> Controltype " & oControlType) - MyValidationLogger.Info(">> Attributname " & oIndexName) - errormessage = "Unexpected Error In FillIndexValues(Combobox " & oMyGridControl.Name & ") " & vbNewLine & ex.Message & vbNewLine & "Check Logfile" - My.Settings.Save() - frmError.ShowDialog() - End Try + ' ========== OPTIMIERUNG 7: GridView-Spaltenbreiten mit Dictionary ========== + ' VORHER: Verschachtelte Loop über Columns × oDTColumnsPerDevExGrid → O(n × m) + ' NACHHER: Dictionary-Lookup → O(n + m) + Try + Dim oMyGridView As DevExpress.XtraGrid.Views.Grid.GridView = oMyGridControl.MainView + oMyGridView.OptionsView.ColumnAutoWidth = False + If oDTColumnsPerDevExGrid IsNot Nothing AndAlso oDTColumnsPerDevExGrid.Rows.Count > 0 Then + Dim columnsByName = oMyGridView.Columns.Cast(Of GridColumn)(). + ToDictionary(Function(c) c.FieldName, StringComparer.OrdinalIgnoreCase) - Case oControl.GetType = GetType(CheckBox) - MyValidationLogger.Debug("Loading checkbox...") - oControlType = "CheckBox" - If oSourceIndexName = "" Then - MsgBox("Attention wrong configuration" & vbNewLine & "For control " & oControl.Name & " no INDEX configured!" & vbNewLine & "Bitte prüfen Sie den Formulardesigner!", MsgBoxStyle.Critical, ADDITIONAL_TITLE) - Exit For - End If - If oSourceIndexName Is Nothing = False Then + For Each oRow As DataRow In oDTColumnsPerDevExGrid.Rows + Dim columnName = oRow.Item("SPALTENNAME").ToString() + Dim column As GridColumn = Nothing - Dim myCheckBox As CheckBox = oControl + If columnsByName.TryGetValue(columnName, column) Then + column.Width = oRow.Item("SPALTENBREITE") + End If + Next + End If + Catch ex As Exception + MyValidationLogger.Error(ex) + End Try + ' ========== ENDE OPTIMIERUNG 7 ========== + End If + Catch ex As Exception + MyValidationLogger.Error(ex) + MyValidationLogger.Info(">> Unexpected Error In FillIndexValues(GridControl " & oMyGridControl.Name & ") " & ex.Message, True) + MyValidationLogger.Info(">> Controltype " & oControlType) + MyValidationLogger.Info(">> Attributname " & oIndexName) + errormessage = "Unexpected Error In FillIndexValues(Combobox " & oMyGridControl.Name & ") " & vbNewLine & ex.Message & vbNewLine & "Check Logfile" + My.Settings.Save() + frmError.ShowDialog() + End Try - If oLoadIndex = False Or {"@@DISPLAY_ONLY", "DD PM-ONLY For DISPLAY"}.Contains(oSourceIndexName) Then - MyValidationLogger.Debug($" oControl {oControl.Name} Indexwert soll nicht geladen werden.") - Exit Select + Case oControl.GetType = GetType(CheckBox) + MyValidationLogger.Debug("Loading checkbox...") + oControlType = "CheckBox" + If oSourceIndexName = "" Then + MsgBox("Attention wrong configuration" & vbNewLine & "For control " & oControl.Name & " no INDEX configured!" & vbNewLine & "Bitte prüfen Sie den Formulardesigner!", MsgBoxStyle.Critical, ADDITIONAL_TITLE) + Exit For End If + If oSourceIndexName Is Nothing = False Then + Dim myCheckBox As CheckBox = oControl + If oLoadIndex = False Or {"@@DISPLAY_ONLY", "DD PM-ONLY For DISPLAY"}.Contains(oSourceIndexName) Then + MyValidationLogger.Debug($" oControl {oControl.Name} Indexwert soll nicht geladen werden.") + Exit Select + End If - MyValidationLogger.Debug("Loading Bool-Value from Source...") - - If oSourceIndexName.StartsWith("[%VKT") And PROFIL_VEKTORINDEX <> "" Then - oValueFromSource = ReturnVektor_IndexValue(oSourceIndexName) - Else - Try - MyValidationLogger.Debug($"..Now GetVariableValue({oSourceIndexName})...") - oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride) - Catch ex As Exception - MyValidationLogger.Warn($"Could Not Get the windreamValue For CheckboxIndex {oSourceIndexName} [{ex.Message}]") - End Try - - End If - + MyValidationLogger.Debug("Loading Bool-Value from Source...") - If oValueFromSource Is Nothing Then - MyValidationLogger.Info(">> Zurückgegebener Wert des Wertes für Checkbox mit Indexname '" & oIndexName & "' ist nothing. Checking defaultvalue") - MyValidationLogger.Debug(">> Zurückgegebener Wert des Wertes für Checkbox mit Indexname '" & oIndexName & "' ist nothing. Checking defaultvalue") - If oDefaultValue <> String.Empty Then - MyValidationLogger.Info($"Using Default value [{oDefaultValue}]") - MyValidationLogger.Debug($"Using Default value [{oDefaultValue}]") - myCheckBox.Checked = CBool(oDefaultValue) - Exit Select + If oSourceIndexName.StartsWith("[%VKT") And PROFIL_VEKTORINDEX <> "" Then + oValueFromSource = ReturnVektor_IndexValue(oSourceIndexName) Else - MyValidationLogger.Debug("No Default Value for Checkbox - so using false!") - myCheckBox.CheckState = CheckState.Indeterminate + Try + MyValidationLogger.Debug($"..Now GetVariableValue({oSourceIndexName})...") + oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride) + Catch ex As Exception + MyValidationLogger.Warn($"Could Not Get the windreamValue For CheckboxIndex {oSourceIndexName} [{ex.Message}]") + End Try End If - - Else - MyValidationLogger.Debug("oValueFromSource: " & oValueFromSource.ToString) - If oValueFromSource.ToString = "" Then - MyValidationLogger.Info(">> Versuch, default Value zu laden") + If oValueFromSource Is Nothing Then + MyValidationLogger.Info(">> Zurückgegebener Wert des Wertes für Checkbox mit Indexname '" & oIndexName & "' ist nothing. Checking defaultvalue") + MyValidationLogger.Debug(">> Zurückgegebener Wert des Wertes für Checkbox mit Indexname '" & oIndexName & "' ist nothing. Checking defaultvalue") If oDefaultValue <> String.Empty Then - Dim result = False - If Boolean.TryParse(oDefaultValue, result) Then - MyValidationLogger.Info(">> defaultValue wurde geladen") - myCheckBox.Checked = result - If result = False Then - myCheckBox.CheckState = CheckState.Unchecked + MyValidationLogger.Info($"Using Default value [{oDefaultValue}]") + MyValidationLogger.Debug($"Using Default value [{oDefaultValue}]") + myCheckBox.Checked = CBool(oDefaultValue) + Exit Select + Else + MyValidationLogger.Debug("No Default Value for Checkbox - so using false!") + myCheckBox.CheckState = CheckState.Indeterminate + End If + Else + MyValidationLogger.Debug("oValueFromSource: " & oValueFromSource.ToString) + If oValueFromSource.ToString = "" Then + MyValidationLogger.Info(">> Versuch, default Value zu laden") + If oDefaultValue <> String.Empty Then + Dim result = False + If Boolean.TryParse(oDefaultValue, result) Then + MyValidationLogger.Info(">> defaultValue wurde geladen") + myCheckBox.Checked = result + myCheckBox.CheckState = If(result, CheckState.Checked, CheckState.Unchecked) Else - myCheckBox.CheckState = CheckState.Checked + myCheckBox.Checked = False + myCheckBox.CheckState = CheckState.Unchecked End If - Else + MyValidationLogger.Info(">> defaultValue war leer") myCheckBox.Checked = False myCheckBox.CheckState = CheckState.Unchecked End If Else - MyValidationLogger.Info(">> defaultValue war leer") - myCheckBox.Checked = False - myCheckBox.CheckState = CheckState.Unchecked - End If - Else - Dim _value - If oValueFromSource.ToString = "System.Object[]" Then - MyValidationLogger.Debug("CheckBoxValue with VectorField: " & oSourceIndexName) - If oValueFromSource.length = 1 Then - _value = oValueFromSource(0) - Else ' - MyValidationLogger.Info(" >> Vectorfield " & oSourceIndexName & "' contains more then one value - First value will be used") - _value = oValueFromSource(0) + Dim _value + If oValueFromSource.ToString = "System.Object[]" Then + MyValidationLogger.Debug("CheckBoxValue with VectorField: " & oSourceIndexName) + If oValueFromSource.length = 1 Then + _value = oValueFromSource(0) + Else + MyValidationLogger.Info(" >> Vectorfield " & oSourceIndexName & "' contains more then one value - First value will be used") + _value = oValueFromSource(0) + End If + Else + _value = oValueFromSource + MyValidationLogger.Debug($"Value is not nothing and also not System.Object: [{_value}]") End If - Else - _value = oValueFromSource - MyValidationLogger.Debug($"Value is not nothing and also not System.Object: [{_value}]") + Try + Select Case CBool(_value) + Case True + MyValidationLogger.Debug(">> CBool(_value) = True") + myCheckBox.Checked = True + myCheckBox.CheckState = CheckState.Checked + Case False + MyValidationLogger.Debug(">> CBool(_value) = False") + myCheckBox.Checked = False + myCheckBox.CheckState = CheckState.Unchecked + End Select + Catch ex As Exception + MyValidationLogger.Error(ex) + MyValidationLogger.Info("Unexpected error in CBool(wertWD) - CheckBox: " & ex.Message & vbNewLine & "Wert WD: " & oValueFromSource.ToString, True) + myCheckBox.Checked = False + myCheckBox.CheckState = CheckState.Unchecked + End Try End If - Try - Select Case CBool(_value) - Case True - MyValidationLogger.Debug(">> CBool(_value) = True") - myCheckBox.Checked = True - myCheckBox.CheckState = CheckState.Checked - Case False - MyValidationLogger.Debug(">> CBool(_value) = False") - myCheckBox.Checked = False - myCheckBox.CheckState = CheckState.Unchecked - End Select - Catch ex As Exception - MyValidationLogger.Error(ex) - MyValidationLogger.Info("Unexpected error in CBool(wertWD) - CheckBox: " & ex.Message & vbNewLine & "Wert WD: " & oValueFromSource.ToString, True) - myCheckBox.Checked = False - myCheckBox.CheckState = CheckState.Unchecked - End Try End If End If - End If - Case oControl.GetType = GetType(LookupControl3) - If LOG_PERF Then PerformanceLogger.Info("FillIndexValues/LookupControl") + Case oControl.GetType = GetType(LookupControl3) + If LOG_PERF Then PerformanceLogger.Info("FillIndexValues/LookupControl") - Try - Dim oLookup As LookupControl3 = oControl - oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride) - 'Dim oWindreamValue = CURRENT_WMFILE.GetVariableValue(oSourceIndexName) Try - oLookup.Properties.SelectedValues = Nothing - oLookup.Properties.SelectedValues = New List(Of String) - Catch ex As Exception + Dim oLookup As LookupControl3 = oControl + oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride) - End Try - If Not IsNothing(oValueFromSource) Then - Dim oMyType = oValueFromSource.GetType.ToString - If oMyType.Contains("System.Object") Or oMyType = "System.Data.DataTable" Then - Dim oArrlist As New List(Of String) - If IDB_ACTIVE = False Then - For Each oVectorRow As Object In oValueFromSource - Dim Ocontent = oVectorRow.ToString - oArrlist.Add(Ocontent) - Next + Try + oLookup.Properties.SelectedValues = Nothing + oLookup.Properties.SelectedValues = New List(Of String) + Catch ex As Exception + End Try + + If Not IsNothing(oValueFromSource) Then + Dim oMyType = oValueFromSource.GetType.ToString + If oMyType.Contains("System.Object") Or oMyType = "System.Data.DataTable" Then + Dim oArrlist As New List(Of String) + If IDB_ACTIVE = False Then + For Each oVectorRow As Object In oValueFromSource + Dim Ocontent = oVectorRow.ToString + oArrlist.Add(Ocontent) + Next + Else + Dim myDT As DataTable = oValueFromSource + For Each oVectorRow As DataRow In myDT.Rows + Dim Ocontent = oVectorRow.Item(0) + oArrlist.Add(Ocontent) + Next + End If + oLookup.Properties.SelectedValues = oArrlist Else - Dim myDT As DataTable = oValueFromSource - For Each oVectorRow As DataRow In myDT.Rows - Dim Ocontent = oVectorRow.Item(0) - oArrlist.Add(Ocontent) - Next + Dim oArrlist As New List(Of String) + oArrlist.Add(oValueFromSource.ToString) + oLookup.Properties.SelectedValues = oArrlist End If - - oLookup.Properties.SelectedValues = oArrlist Else - Dim oArrlist As New List(Of String) - oArrlist.Add(oValueFromSource.ToString) - oLookup.Properties.SelectedValues = oArrlist - End If - Else - If Not IsNothing(oLookup.Properties.SelectedValues) Then - If oLookup.Properties.SelectedValues.Count = 0 And oDefaultValue <> String.Empty Then - Dim oValues As List(Of String) = oDefaultValue.Split(",").ToList() - oLookup.Properties.SelectedValues = oValues + If Not IsNothing(oLookup.Properties.SelectedValues) Then + If oLookup.Properties.SelectedValues.Count = 0 And oDefaultValue <> String.Empty Then + Dim oValues As List(Of String) = oDefaultValue.Split(",").ToList() + oLookup.Properties.SelectedValues = oValues + End If End If End If + Catch ex As Exception + MyValidationLogger.Error(ex) + MyValidationLogger.Info(" - Unvorhergesehener Unexpected error in AddVorschlag_ComboBox - Indexname: " & oIndexName & " - Fehler: " & vbNewLine & ex.Message) + MsgBox(ex.Message, MsgBoxStyle.Critical, "Unvorhergesehener Unexpected error in Add LookupControl3:") + End Try + + Case oControl.GetType = GetType(DateTimePicker) + oControlType = "DateTimePicker" + Dim DTP As DateTimePicker = oControl + If oSourceIndexName = "" Then + MsgBox("Attention wrong configuration:" & vbNewLine & "for control " & oControl.Name & " no INDEX configured!" & vbNewLine & "Bitte prüfen Sie den Formulardesigner!", MsgBoxStyle.Critical, ADDITIONAL_TITLE) + Exit For End If + If oSourceIndexName Is Nothing = False Then + Try + If oSourceIndexName.StartsWith("[%VKT") And PROFIL_VEKTORINDEX <> "" Then + MyValidationLogger.Debug("DATE über PM-Vektor holen") + oValueFromSource = ReturnVektor_IndexValue(oSourceIndexName) + MyValidationLogger.Info(">> DTP is """) + Else + oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride) + End If - Catch ex As Exception - MyValidationLogger.Error(ex) - MyValidationLogger.Info(" - Unvorhergesehener Unexpected error in AddVorschlag_ComboBox - Indexname: " & oIndexName & " - Fehler: " & vbNewLine & ex.Message) - MsgBox(ex.Message, MsgBoxStyle.Critical, "Unvorhergesehener Unexpected error in Add LookupControl3:") - End Try + If oValueFromSource Is Nothing Then oValueFromSource = "" + Dim tempdate As Date = CDate("01.01.0001 00:00:00") + If oValueFromSource.ToString.Length > 0 Then + Try + tempdate = CDate(oValueFromSource) + MyValidationLogger.Debug("DATE konnte umgewandelt werden") + Catch ex As Exception + MyValidationLogger.Error(ex) + MyValidationLogger.Debug("DATE wurde auf heute gesetzt") + End Try + DTP.Text = tempdate + Else + MyValidationLogger.Debug("DATE ist leer") + DTP.Text = tempdate + End If + Catch ex As Exception + MyValidationLogger.Error(ex) + errormessage = "Unvorhergesehener Fehler bei DTP: " & vbNewLine & ex.Message + MyValidationLogger.Info("Unexpected error in FillIndex DTP: " & ex.Message & vbNewLine & "Wert WD: " & oValueFromSource.ToString & vbNewLine & "Indexname: " & oSourceIndexName, True) + frmError.ShowDialog() + MyValidationLogger.Info("Unexpected error in FillIndex DTP: " & ex.Message, True) + End Try + End If + End Select + oCount += 1 + Next - Case oControl.GetType = GetType(DateTimePicker) - oControlType = "DateTimePicker" - Dim DTP As DateTimePicker = oControl - If oSourceIndexName = "" Then - MsgBox("Attention wrong configuration:" & vbNewLine & "for control " & oControl.Name & " no INDEX configured!" & vbNewLine & "Bitte prüfen Sie den Formulardesigner!", MsgBoxStyle.Critical, ADDITIONAL_TITLE) - Exit For - End If - If oSourceIndexName Is Nothing = False Then + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF FillIndexValues] Nach Control-Schleife: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If - Try - If oSourceIndexName.StartsWith("[%VKT") And PROFIL_VEKTORINDEX <> "" Then - MyValidationLogger.Debug("DATE über PM-Vektor holen") + Focus_FirstControl() - oValueFromSource = ReturnVektor_IndexValue(oSourceIndexName) - MyValidationLogger.Info(">> DTP is """) - Else - oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride) + ' ========== OPTIMIERUNG 8: Grid-Dropdown-Columns nur EINMAL am Ende ========== + ' VORHER: Wurde potenziell mehrfach aufgerufen + ' NACHHER: Nur einmal nach allen Control-Updates + Try + Dim oDataTable As DataTable = DT_COLUMNS_GRID_WITH_SQL.Clone() + DT_COLUMNS_GRID_WITH_SQL.Select($"SQL_COMMAND not like '%#CTRL#%'").CopyToDataTable(oDataTable, LoadOption.PreserveChanges) + + ' ========== OPTIMIERUNG 9: Control-Suche mit Dictionary ========== + ' VORHER: Für jede Row wurde über alle Controls geloopt + ' NACHHER: Dictionary-Lookup + For Each oRow As DataRow In oDataTable.Rows + Dim oDEPENDING_CTRL_ID = CInt(oRow.Item("CONTROL_ID")) + Dim oDEPENDING_COLUMN = oRow.Item("SPALTENNAME") + Dim oSqlCommand = oRow.Item("SQL_COMMAND") + Dim oCONNID = oRow.Item("CONNECTION_ID") + Dim oAdvancedLookup = oRow.Item("ADVANCED_LOOKUP") + oSqlCommand = clsPatterns.ReplaceAllValues(oSqlCommand, PanelValidatorControl, True) - End If + Try + Dim oDTRESULT_FOR_COLUMN As DataTable = GetCachedDatatable(oSqlCommand, oCONNID) - If oValueFromSource Is Nothing Then oValueFromSource = "" - Dim tempdate As Date = CDate("01.01.0001 00:00:00") - If oValueFromSource.ToString.Length > 0 Then - Try - tempdate = CDate(oValueFromSource) - MyValidationLogger.Debug("DATE konnte umgewandelt werden") - Catch ex As Exception - MyValidationLogger.Error(ex) - MyValidationLogger.Debug("DATE wurde auf heute gesetzt") - End Try - DTP.Text = tempdate + If Not IsNothing(oDTRESULT_FOR_COLUMN) Then + MyValidationLogger.Debug($"Trying to create a DropDown(FIV) for CONTROL-ID [{oDEPENDING_CTRL_ID}] - RowCount: [{oDTRESULT_FOR_COLUMN.Rows.Count}] ") + + ' Dictionary-Lookup statt Loop + Dim oControl As Control = Nothing + If _CachedControlsByGuid.TryGetValue(oDEPENDING_CTRL_ID, oControl) Then + ControlCreator.GridTables_CacheDatatableForColumn(oDEPENDING_CTRL_ID, oDEPENDING_COLUMN, oSqlCommand, oCONNID, oAdvancedLookup) Else - MyValidationLogger.Debug("DATE ist leer") - DTP.Text = tempdate + MyValidationLogger.Warn($"Control mit ID {oDEPENDING_CTRL_ID} nicht gefunden!") End If - Catch ex As Exception - MyValidationLogger.Error(ex) - errormessage = "Unvorhergesehener Fehler bei DTP: " & vbNewLine & ex.Message - - MyValidationLogger.Info("Unexpected error in FillIndex DTP: " & ex.Message & vbNewLine & "Wert WD: " & oValueFromSource.ToString & vbNewLine & "Indexname: " & oSourceIndexName, True) - frmError.ShowDialog() - MyValidationLogger.Info("Unexpected error in FillIndex DTP: " & ex.Message, True) - End Try - End If - End Select - oCount += 1 - Next - - - Focus_FirstControl() - - Try - Dim oDataTable As DataTable = DT_COLUMNS_GRID_WITH_SQL.Clone() - DT_COLUMNS_GRID_WITH_SQL.Select($"SQL_COMMAND not like '%#CTRL#%'").CopyToDataTable(oDataTable, LoadOption.PreserveChanges) + Else + MyValidationLogger.Warn($"FillIndexValues - oDTRESULT_FOR_COLUMN is nothing!") + End If + Catch ex As Exception + MyValidationLogger.Warn($"FillIndexValues - Unexpected error in creating Grid-Dropdown-Column [{oDEPENDING_COLUMN}] for CONTROL-ID [{oDEPENDING_CTRL_ID}]: " & ex.Message) + End Try + Next + Catch ex As Exception + MyValidationLogger.Warn($"FillIndexValues - Unexpected error in creating dropdown for Grid: " & ex.Message) + End Try + ' ========== ENDE OPTIMIERUNG 8+9 ========== - For Each oRow As DataRow In oDataTable.Rows + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF FillIndexValues] Nach Grid-Dropdown-Loop: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If - Dim oDEPENDING_CTRL_ID = oRow.Item("CONTROL_ID") - Dim oDEPENDING_COLUMN = oRow.Item("SPALTENNAME") - Dim oSqlCommand = oRow.Item("SQL_COMMAND") - Dim oCONNID = oRow.Item("CONNECTION_ID") - Dim oAdvancedLookup = oRow.Item("ADVANCED_LOOKUP") - oSqlCommand = clsPatterns.ReplaceAllValues(oSqlCommand, PanelValidatorControl, True) + If LOG_PERF Then PerformanceLogger.Info("FillIndexValues/Postload") + ' IDB PM_Info Setup (bleibt gleich) + If IDB_ACTIVE = True Then Try - 'Dim oDTRESULT_FOR_COLUMN As DataTable = ClassDatabase.Return_Datatable_ConId(oSqlCommand, oCONNID, $"oDEPENDING_CTRL_ID: {oDEPENDING_CTRL_ID}") - Dim oDTRESULT_FOR_COLUMN As DataTable = DatabaseFallback.GetDatatable(New GetDatatableOptions(oSqlCommand, DatabaseType.ECM) With { - .ConnectionId = oCONNID - }) - - If Not IsNothing(oDTRESULT_FOR_COLUMN) Then - MyValidationLogger.Debug($"Trying to create a DropDown(FIV) for CONTROL-ID [{oDEPENDING_CTRL_ID}] - RowCount: [{oDTRESULT_FOR_COLUMN.Rows.Count}] ") - For Each oControl As Control In PanelValidatorControl.Controls - Dim oControlId = DirectCast(oControl.Tag, ClassControlCreator.ControlMetadata).Guid - If oControlId = oDEPENDING_CTRL_ID Then - ControlCreator.GridTables_CacheDatatableForColumn(oControlId, oDEPENDING_COLUMN, oSqlCommand, oCONNID, oAdvancedLookup) - Exit For + Dim oSQL = $"select Attribut, TERM_VALUE from VWIDB_VALUE_TEXT WHERE LANG_CODE IN ('{USER_LANGUAGE}','UNQID') AND IDB_OBJ_ID = {CURRENT_DOC_ID} AND Attribut in ('PM_Info1','PM_Info2') ORDER BY Attribut" + Dim oDTINFO As DataTable = DatabaseFallback.GetDatatableIDB(oSQL) + If Not IsNothing(oDTINFO) Then + Dim oColor As System.Drawing.Color + If oDTINFO.Rows.Count > 0 Then + Dim oColumns As String() + If oDTINFO.Rows.Count = 1 Then + oColumns = Split(oDTINFO.Rows(0).Item("TERM_VALUE"), "#") + If oColumns.Length = 1 Then + bsiInfo1.Caption = oDTINFO.Rows(0).Item("TERM_VALUE") + ElseIf oColumns.Length = 2 Then + bsiInfo1.Caption = oColumns(0) + Try + oColor = System.Drawing.Color.FromName(oColumns(1)) + bsiInfo1.ItemAppearance.Normal.ForeColor = oColor + Catch ex As Exception + End Try + End If + bsiInfo2.Visibility = BarItemVisibility.Never + ElseIf oDTINFO.Rows.Count = 2 Then + oColumns = Split(oDTINFO.Rows(0).Item("TERM_VALUE"), "#") + If oColumns.Length = 1 Then + bsiInfo1.Caption = oDTINFO.Rows(0).Item("TERM_VALUE") + ElseIf oColumns.Length = 2 Then + bsiInfo1.Caption = oColumns(0) + Try + oColor = System.Drawing.Color.FromName(oColumns(1)) + bsiInfo1.ItemAppearance.Normal.ForeColor = oColor + Catch ex As Exception + End Try + End If + + oColumns = Split(oDTINFO.Rows(1).Item("TERM_VALUE"), "#") + If oColumns.Length = 1 Then + bsiInfo2.Caption = oDTINFO.Rows(1).Item("TERM_VALUE") + ElseIf oColumns.Length = 2 Then + bsiInfo2.Caption = oColumns(0) + Try + oColor = System.Drawing.Color.FromName(oColumns(1)) + bsiInfo2.ItemAppearance.Normal.ForeColor = oColor + Catch ex As Exception + End Try + End If + bsiInfo2.Visibility = BarItemVisibility.Always End If - Next + RibbonPageGroup2.Visible = True + Else + MyValidationLogger.Debug($"No PM_Info-Configuration!!") + RibbonPageGroup2.Visible = False + End If Else - MyValidationLogger.Warn($"FillIndexValues - oDTRESULT_FOR_COLUMN is nothing!") + MyValidationLogger.Warn($"oDTINFO is nothing!!") + RibbonPageGroup2.Visible = False End If - Catch ex As Exception - MyValidationLogger.Warn($"FillIndexValues - Unexpected error in creating Grid-Dropdown-Column [{oDEPENDING_COLUMN}] for CONTROL-ID [{oDEPENDING_CTRL_ID}]: " & ex.Message) + MyValidationLogger.Warn($"Unexpected error in Setting PMINFO - ERROR: {ex.Message}") + RibbonPageGroup2.Visible = False End Try - Next - Catch ex As Exception - MyValidationLogger.Warn($"FillIndexValues - Unexpected error in creating dropdown for Grid: " & ex.Message) - End Try + Else + RibbonPageGroup2.Visible = False + End If - If LOG_PERF Then PerformanceLogger.Info("FillIndexValues/Postload") + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF FillIndexValues] Nach PM_Info-Setup: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If - If IDB_ACTIVE = True Then - Try - Dim oSQL = $"select Attribut, TERM_VALUE from VWIDB_VALUE_TEXT WHERE LANG_CODE IN ('{USER_LANGUAGE}','UNQID') AND IDB_OBJ_ID = {CURRENT_DOC_ID} AND Attribut in ('PM_Info1','PM_Info2') ORDER BY Attribut" - Dim oDTINFO As DataTable = DatabaseFallback.GetDatatableIDB(oSQL) - If Not IsNothing(oDTINFO) Then - Dim oColor As System.Drawing.Color - If oDTINFO.Rows.Count > 0 Then - Dim oColumns As String() - If oDTINFO.Rows.Count = 1 Then - oColumns = Split(oDTINFO.Rows(0).Item("TERM_VALUE"), "#") - If oColumns.Length = 1 Then - bsiInfo1.Caption = oDTINFO.Rows(0).Item("TERM_VALUE") - ElseIf oColumns.Length = 2 Then - bsiInfo1.Caption = oColumns(0) - Try - oColor = System.Drawing.Color.FromName(oColumns(1)) - bsiInfo1.ItemAppearance.Normal.ForeColor = oColor - Catch ex As Exception + _Indexe_Loaded = True - End Try - End If + Load_Additional_Searches(Not CONFIG.Config.ADDITIONAL_SEARCHES_LOAD_ONCLICK) - bsiInfo2.Visibility = BarItemVisibility.Never - ElseIf oDTINFO.Rows.Count = 2 Then - 'ITEM 1 - oColumns = Split(oDTINFO.Rows(0).Item("TERM_VALUE"), "#") - If oColumns.Length = 1 Then - bsiInfo1.Caption = oDTINFO.Rows(0).Item("TERM_VALUE") - ElseIf oColumns.Length = 2 Then - bsiInfo1.Caption = oColumns(0) - Try - oColor = System.Drawing.Color.FromName(oColumns(1)) - bsiInfo1.ItemAppearance.Normal.ForeColor = oColor - Catch ex As Exception + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF FillIndexValues] Nach Load_Additional_Searches: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If - End Try - End If - 'ITEM 1 - oColumns = Split(oDTINFO.Rows(1).Item("TERM_VALUE"), "#") - If oColumns.Length = 1 Then - bsiInfo2.Caption = oDTINFO.Rows(1).Item("TERM_VALUE") - ElseIf oColumns.Length = 2 Then - bsiInfo2.Caption = oColumns(0) - Try - oColor = System.Drawing.Color.FromName(oColumns(1)) - bsiInfo2.ItemAppearance.Normal.ForeColor = oColor - Catch ex As Exception + If CONFIG.Config.ADDITIONAL_SEARCHES_LOAD_ONCLICK = False And (AdditionalDocResultsExist = True Or AdditionalDataResultsExist = True) Then + TryOpen_Additional_Searches() + End If - End Try - End If - bsiInfo2.Visibility = BarItemVisibility.Always - End If - RibbonPageGroup2.Visible = True - Else - MyValidationLogger.Debug($"No PM_Info-Configuration!!") - RibbonPageGroup2.Visible = False - End If - Else - MyValidationLogger.Warn($"oDTINFO is nothing!!") - RibbonPageGroup2.Visible = False - End If - Catch ex As Exception - MyValidationLogger.Warn($"Unexpected error in Setting PMINFO - ERROR: {ex.Message}") - RibbonPageGroup2.Visible = False - End Try + If LOG_HOTSPOTS Then + MyValidationLogger.Info($"[PERF FillIndexValues] Nach TryOpen_Additional_Searches: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + perfLastCheck = DateTime.Now + End If Else - RibbonPageGroup2.Visible = False + MsgBox("No Form-Mask defined for this profile!" & vbNewLine & "Please inform Your admin!" & vbNewLine & "The validator will be closed!", MsgBoxStyle.Exclamation, "Attention:") + Me.Close() End If - 'Flag setzen das Indexe geladen sind - _Indexe_Loaded = True + Catch ex As Exception + MyValidationLogger.Warn($"Unexpected error in FillIndexValues: [{oControName} -TYPE: {oControlType}-INDEXNAME: {oIndexName}] ERROR: {ex.Message}") + errormessage = $"Unexpected error in FillIndexValues: [{oControName} -TYPE: {oControlType}-INDEXNAME: {oIndexName}] ERROR: {ex.Message}" & vbNewLine & "Check Logfile" + My.Settings.Save() + frmError.ShowDialog() + Finally + ' ========== OPTIMIERUNG 10: UI-Updates wieder aktivieren ========== + ' KRITISCH: Erst HIER wird das Panel neu gezeichnet → nur EINMAL statt tausende Male + PanelValidatorControl.ResumeLayout() + ' ========== ENDE OPTIMIERUNG 10 ========== - ' Should the custom Ribbon group be displayed at all? - ' Will be hidden later if not search results are found + ' ========== OPTIMIERUNG 11: GridTables nur EINMAL am Ende ========== + ' VORHER: War im TextBox-Case drin → wurde für jede TextBox aufgerufen + ' NACHHER: Nur noch EINMAL am Ende → massive Zeitersparnis + Try + ControlCreator.GridTables_HandleControlValueChange(PanelValidatorControl, DT_COLUMNS_GRID_WITH_SQL_WITH_CTRL_PLACEHOLDER) + Catch ex As Exception + MyValidationLogger.Warn($"GridTables_HandleControlValueChange Fehler: {ex.Message}") + End Try + ' ========== ENDE OPTIMIERUNG 11 ========== - Load_Additional_Searches(Not CONFIG.Config.ADDITIONAL_SEARCHES_LOAD_ONCLICK) - ' If Searches should be loaded automatically, not only on click - If CONFIG.Config.ADDITIONAL_SEARCHES_LOAD_ONCLICK = False And (AdditionalDocResultsExist = True Or AdditionalDataResultsExist = True) Then - ' _frmValidatorSearch?.Show() - TryOpen_Additional_Searches() + If LOG_HOTSPOTS Then + Dim totalMs = (DateTime.Now - perfStart).TotalMilliseconds + If totalMs > 6000 Then + MyValidationLogger.Warn($"[PERF FillIndexValues] ⚠️ GESAMT LANGSAM: {totalMs}ms (Schwellwert: 6000ms)") + Else + MyValidationLogger.Info($"[PERF FillIndexValues] GESAMT: {totalMs}ms") + End If End If - Else - MsgBox("No Form-Mask defined for this profile!" & vbNewLine & "Please inform Your admin!" & vbNewLine & "The validator will be closed!", MsgBoxStyle.Exclamation, "Attention:") - Me.Close() - End If - - Catch ex As Exception - MyValidationLogger.Warn($"Unexpected error in FillIndexValues: [{oControName} -TYPE: {oControlType}-INDEXNAME: {oIndexName}] ERROR: {ex.Message}") - errormessage = $"Unexpected error in FillIndexValues: [{oControName} -TYPE: {oControlType}-INDEXNAME: {oIndexName}] ERROR: {ex.Message}" & vbNewLine & "Check Logfile" - My.Settings.Save() - frmError.ShowDialog() - End Try - - + End Try End Sub Private Sub ApplyCurrencyMask(pTextEdit As TextEdit) @@ -6407,25 +6492,50 @@ Public Class frmValidator Sub Datei_ueberspringen() Dim perfStart As DateTime = If(LOG_HOTSPOTS, DateTime.Now, Nothing) Dim perfLastCheck As DateTime = perfStart + If LOG_HOTSPOTS Then + ' ========== DIAGNOSE START ========== + MyValidationLogger.Info($"[INFO] Datei_ueberspringen START") + MyValidationLogger.Info($" frmValidator.IsDisposed: {Me.IsDisposed}") + MyValidationLogger.Info($" CURRENT_DOC_GUID: {CURRENT_DOC_GUID}") + ' ========== ENDE DIAGNOSE ========== + End If If LOG_HOTSPOTS Then MyValidationLogger.Info("[PERF] Datei_ueberspringen START") Try MyValidationLogger.Debug("Skipping document....(Datei_ueberspringen)") 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};" - + $"EXECUTE PRPM_FILES_NOT_INDEXED '{USER_USERNAME}',{CURRENT_ProfilGUID},'{WMDocPathWindows}',{CURRENT_DOC_GUID};" + If LOG_HOTSPOTS Then + ' ========== DIAGNOSE: Vor DB-Execute ========== + MyValidationLogger.Info($"[INFO] Führe DB-UPDATE aus...") + MyValidationLogger.Info($" VOR DB: frmValidator.IsDisposed: {Me.IsDisposed}") + ' ========== ENDE DIAGNOSE ========== + End If DatabaseFallback.ExecuteNonQueryECM(oSQL) + If LOG_HOTSPOTS Then + MyValidationLogger.Info($" NACH DB: frmValidator.IsDisposed: {Me.IsDisposed}") MyValidationLogger.Info($"[PERF] Nach UPDATE+PRPM_FILES_NOT_INDEXED: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now End If MyValidationLogger.Debug($"Skipped DocGUID {CURRENT_DOC_GUID}") + If LOG_HOTSPOTS Then + ' ========== DIAGNOSE: Vor Load_Next_Document ========== + MyValidationLogger.Info($"[INFO] Rufe Load_Next_Document auf...") + MyValidationLogger.Info($" VOR: frmValidator.IsDisposed: {Me.IsDisposed}") + ' ========== ENDE DIAGNOSE ========== + End If + Load_Next_Document(False) If LOG_HOTSPOTS Then + ' ========== DIAGNOSE: Nach Load_Next_Document ========== + MyValidationLogger.Info($" NACH: frmValidator.IsDisposed: {Me.IsDisposed}") + MyValidationLogger.Info($" NACH: frmValidator.Visible: {Me.Visible}") + ' ========== ENDE DIAGNOSE ========== MyValidationLogger.Info($"[PERF] Nach Load_Next_Document: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") End If @@ -6435,7 +6545,13 @@ Public Class frmValidator Finally If LOG_HOTSPOTS Then MyValidationLogger.Info($"[PERF] Datei_ueberspringen GESAMT: {(DateTime.Now - perfStart).TotalMilliseconds}ms") + + ' ========== DIAGNOSE ENDE ========== + MyValidationLogger.Info($"[INFO] Datei_ueberspringen ENDE") + MyValidationLogger.Info($" frmValidator.IsDisposed: {Me.IsDisposed}") + ' ========== ENDE DIAGNOSE ========== End If + End Try End Sub Private Function PRTF_PROFILE_FILES_WORK(ByVal pMode As String) As Boolean @@ -6583,9 +6699,6 @@ Public Class frmValidator End Sub - Private Sub frmValidator_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing - - End Sub Private Sub frmValidator_Resize(sender As Object, e As EventArgs) Handles Me.Resize If _FormLoaded = False Then @@ -6677,33 +6790,78 @@ Public Class frmValidator End Sub Private Sub bbtniNext_ItemClick(sender As Object, e As ItemClickEventArgs) Handles bbtniNext.ItemClick + Cursor = Cursors.WaitCursor Dim perfStart As DateTime = If(LOG_HOTSPOTS, DateTime.Now, Nothing) Dim perfLastCheck As DateTime = perfStart - If LOG_HOTSPOTS Then MyValidationLogger.Info("[PERF] bbtniNext_ItemClick START") + + + + If LOG_HOTSPOTS Then + ' ========== DIAGNOSE START ========== + MyValidationLogger.Info($"[START] bbtniNext_ItemClick START") + MyValidationLogger.Info($" frmValidator.IsDisposed: {Me.IsDisposed}") + MyValidationLogger.Info($" frmValidator.Visible: {Me.Visible}") + MyValidationLogger.Info($" _FormClosing: {_FormClosing}") + ' ========== ENDE DIAGNOSE ========== + MyValidationLogger.Info("[PERF] bbtniNext_ItemClick START") + End If If ForceGridValidation() = True Then If LOG_HOTSPOTS Then MyValidationLogger.Info($"[PERF] Nach ForceGridValidation: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now + ' ========== DIAGNOSE: Vor Reset_CurrentReferences ========== + MyValidationLogger.Info($"[START] Rufe Reset_CurrentReferences auf...") + MyValidationLogger.Info($" VOR: frmValidator.IsDisposed: {Me.IsDisposed}") + ' ========== ENDE DIAGNOSE ========== + End If + Reset_CurrentReferences() + + If LOG_HOTSPOTS Then MyValidationLogger.Info($"[PERF] Nach Reset_CurrentReferences: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") perfLastCheck = DateTime.Now + ' ========== DIAGNOSE: Nach Reset_CurrentReferences ========== + MyValidationLogger.Info($" NACH: frmValidator.IsDisposed: {Me.IsDisposed}") + MyValidationLogger.Info($" NACH: frmValidator.Visible: {Me.Visible}") + ' ========== ENDE DIAGNOSE ========== + ' ========== DIAGNOSE: Vor Datei_ueberspringen ========== + MyValidationLogger.Info($"[START] Rufe Datei_ueberspringen auf...") + MyValidationLogger.Info($" VOR: frmValidator.IsDisposed: {Me.IsDisposed}") + ' ========== ENDE DIAGNOSE ========== End If + + Datei_ueberspringen() + If LOG_HOTSPOTS Then MyValidationLogger.Info($"[PERF] Nach Datei_ueberspringen: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") + ' ========== DIAGNOSE: Nach Datei_ueberspringen ========== + MyValidationLogger.Info($" NACH: frmValidator.IsDisposed: {Me.IsDisposed}") + MyValidationLogger.Info($" NACH: frmValidator.Visible: {Me.Visible}") + ' ========== ENDE DIAGNOSE ========== + End If End If If LOG_HOTSPOTS Then MyValidationLogger.Info($"[PERF] bbtniNext_ItemClick GESAMT: {(DateTime.Now - perfStart).TotalMilliseconds}ms") + ' ========== DIAGNOSE ENDE ========== + MyValidationLogger.Info($"[START] bbtniNext_ItemClick ENDE") + MyValidationLogger.Info($" frmValidator.IsDisposed: {Me.IsDisposed}") + MyValidationLogger.Info($" frmValidator.Visible: {Me.Visible}") + ' ========== ENDE DIAGNOSE ========== End If + + + + Cursor = Cursors.Default End Sub Private Sub bbtniDelete_ItemClick(sender As Object, e As ItemClickEventArgs) Handles bbtniDelete.ItemClick