Optimierung von dynamischen Editoren und Debugging-Logs
Neue Funktionalität für dynamische Editoren: - Einführung eines Shared-Caches (`_DynamicEditorCacheShared`) zur Wiederverwendung von Editoren in `GridControl`. - Dynamische Editoren werden nun pro Zeile behandelt und bei Bedarf aus dem Cache geladen oder neu erstellt. - Neue Methode `ClearDynamicEditorCache`, um den Cache bei Dokumentwechsel zu leeren. Optimierung der Ereignisbehandlung: - Überarbeitung des `CustomRowCellEdit`-Events für effizientere Zuweisung dynamischer Editoren. - Vereinfachung der Logik für `ShowingEditor` und Entfernung veralteter Logik für `HiddenEditor`. Erweiterte Debugging-Optionen: - Einführung des Flags `LOG_HOTSPOTS`, um gezielt Debugging-Informationen zu aktivieren. - Verbesserte Logs für SQL-Abfragen, Cache-Zugriffe und Editor-Erstellungen. Code-Bereinigung und Stabilität: - Entfernung redundanter Logik und Vereinfachung der Behandlung von Währungsformaten. - Verbesserte Speicherverwaltung durch explizites Entfernen und Disposen von Editoren. - Zusätzliche Sicherheitsprüfungen und Fehlerbehandlungen. Ziel der Änderungen: Verbesserung der Performance durch Caching, Erhöhung der Stabilität durch erweiterte Fehlerbehandlung und Optimierung der Wartbarkeit durch klarere Logs und vereinfachte Logik.
This commit is contained in:
@@ -901,7 +901,15 @@ Public Class ClassControlCreator
|
|||||||
Dim oColumnName = oRow.Item("SPALTENNAME")
|
Dim oColumnName = oRow.Item("SPALTENNAME")
|
||||||
Dim oAdvancedLookup = oRow.Item("ADVANCED_LOOKUP")
|
Dim oAdvancedLookup = oRow.Item("ADVANCED_LOOKUP")
|
||||||
|
|
||||||
|
' *** NEU: Prüfe ob Spalte #TBCOL# verwendet (dynamisch pro Zeile) ***
|
||||||
If oSqlStatement <> String.Empty AndAlso oConnectionId > -1 Then
|
If oSqlStatement <> String.Empty AndAlso oConnectionId > -1 Then
|
||||||
|
' *** NEU: Skip Spalten mit #TBCOL# (werden in ShowingEditor behandelt) ***
|
||||||
|
If oSqlStatement.Contains("{#TBCOL#") Then
|
||||||
|
Logger.Debug($"GridTables_HandleControlValueChange -> Skipping column [{oColumnName}] (has #TBCOL# placeholders, will be resolved per row)")
|
||||||
|
Continue For
|
||||||
|
End If
|
||||||
|
|
||||||
|
' *** BESTEHENDER CODE: Nur für statische Spalten ({#CTRL#} only) ***
|
||||||
oSqlStatement = clsPatterns.ReplaceAllValues(oSqlStatement, pControlPanel, True)
|
oSqlStatement = clsPatterns.ReplaceAllValues(oSqlStatement, pControlPanel, True)
|
||||||
GridTables_CacheDatatableForColumn(oControlId, oColumnName, oSqlStatement, oConnectionId, oAdvancedLookup)
|
GridTables_CacheDatatableForColumn(oControlId, oColumnName, oSqlStatement, oConnectionId, oAdvancedLookup)
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ Namespace ControlCreator
|
|||||||
Private _FormulaColumnNames As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
|
Private _FormulaColumnNames As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
|
||||||
Private _FormulaSqlColumns As New Dictionary(Of String, FormulaSqlDefinition)(StringComparer.OrdinalIgnoreCase)
|
Private _FormulaSqlColumns As New Dictionary(Of String, FormulaSqlDefinition)(StringComparer.OrdinalIgnoreCase)
|
||||||
Private _DynamicEditorColumns As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
|
Private _DynamicEditorColumns As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
|
||||||
|
Private Shared _DynamicEditorCacheShared As New Dictionary(Of String, RepositoryItem)
|
||||||
|
|
||||||
Private _isRefreshingFormula As Boolean = False ' *** NEU: Flag für Formel-Refresh ***
|
Private _isRefreshingFormula As Boolean = False ' *** NEU: Flag für Formel-Refresh ***
|
||||||
Private _currencySymbol As String = "€"
|
Private _currencySymbol As String = "€"
|
||||||
@@ -41,6 +42,14 @@ Namespace ControlCreator
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Private Shared _CurrencySymbolByGridName As New Dictionary(Of String, String)(StringComparer.OrdinalIgnoreCase)
|
Private Shared _CurrencySymbolByGridName As New Dictionary(Of String, String)(StringComparer.OrdinalIgnoreCase)
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Leert den Cache für dynamische Editoren. Muss bei jedem Dokumentwechsel aufgerufen werden.
|
||||||
|
''' </summary>
|
||||||
|
Public Shared Sub ClearDynamicEditorCache()
|
||||||
|
SyncLock _DynamicEditorCacheShared
|
||||||
|
_DynamicEditorCacheShared.Clear()
|
||||||
|
End SyncLock
|
||||||
|
End Sub
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' Definiert eine SQL-basierte Formelspalte mit allen nötigen Metadaten.
|
''' Definiert eine SQL-basierte Formelspalte mit allen nötigen Metadaten.
|
||||||
''' </summary>
|
''' </summary>
|
||||||
@@ -583,7 +592,6 @@ Namespace ControlCreator
|
|||||||
Dim oFormulaExpression = ObjectEx.NotNull(oColumnData.Item("FORMULA_EXPRESSION"), String.Empty)
|
Dim oFormulaExpression = ObjectEx.NotNull(oColumnData.Item("FORMULA_EXPRESSION"), String.Empty)
|
||||||
Dim oFormulaSql = ObjectEx.NotNull(oColumnData.Item("FORMULA_SQL"), String.Empty)
|
Dim oFormulaSql = ObjectEx.NotNull(oColumnData.Item("FORMULA_SQL"), String.Empty)
|
||||||
|
|
||||||
' Entweder/Oder: Beide gleichzeitig → Expression gewinnt, SQL ignoriert
|
|
||||||
If oFormulaExpression <> String.Empty AndAlso oFormulaSql <> String.Empty Then
|
If oFormulaExpression <> String.Empty AndAlso oFormulaSql <> String.Empty Then
|
||||||
_Logger.Warn("[ConfigureViewColumnsCurrency] Column [{0}] has BOTH FORMULA_EXPRESSION and FORMULA_SQL – treating as EXPRESSION only.", oCol.FieldName)
|
_Logger.Warn("[ConfigureViewColumnsCurrency] Column [{0}] has BOTH FORMULA_EXPRESSION and FORMULA_SQL – treating as EXPRESSION only.", oCol.FieldName)
|
||||||
oFormulaSql = String.Empty
|
oFormulaSql = String.Empty
|
||||||
@@ -591,19 +599,13 @@ Namespace ControlCreator
|
|||||||
_Logger.Debug("[ConfigureViewColumnsCurrency] Column [{0}] is a SQL formula column: {1}", oCol.FieldName, oFormulaSql)
|
_Logger.Debug("[ConfigureViewColumnsCurrency] Column [{0}] is a SQL formula column: {1}", oCol.FieldName, oFormulaSql)
|
||||||
End If
|
End If
|
||||||
|
|
||||||
' Spalte ist eine Formel-Spalte (Expression ODER SQL) → nur DisplayFormat, kein ColumnEdit
|
|
||||||
Dim oIsAnyFormula As Boolean = oFormulaExpression <> String.Empty OrElse oFormulaSql <> String.Empty
|
Dim oIsAnyFormula As Boolean = oFormulaExpression <> String.Empty OrElse oFormulaSql <> String.Empty
|
||||||
|
|
||||||
If oIsAnyFormula Then
|
If oIsAnyFormula Then
|
||||||
' Formel-Spalten (Expression oder SQL): nur DisplayFormat setzen
|
|
||||||
oCol.DisplayFormat.FormatType = FormatType.Custom
|
oCol.DisplayFormat.FormatType = FormatType.Custom
|
||||||
oCol.DisplayFormat.FormatString = $"#,##0.00 {_currencySymbol}"
|
oCol.DisplayFormat.FormatString = $"#,##0.00 {_currencySymbol}"
|
||||||
_Logger.Debug("[ConfigureViewColumnsCurrency] Formel-Spalte [{0}] (IsExpression=[{1}], IsSql=[{2}]): DisplayFormat=[{3}], RepositoryItems.Count=[{4}]",
|
_Logger.Debug("[ConfigureViewColumnsCurrency] Formel-Spalte [{0}]: DisplayFormat=[{1}]",
|
||||||
oCol.FieldName,
|
oCol.FieldName, oCol.DisplayFormat.FormatString)
|
||||||
oFormulaExpression <> String.Empty,
|
|
||||||
oFormulaSql <> String.Empty,
|
|
||||||
oCol.DisplayFormat.FormatString,
|
|
||||||
pGrid.RepositoryItems.Count)
|
|
||||||
|
|
||||||
ElseIf oCol.OptionsColumn.AllowEdit Then
|
ElseIf oCol.OptionsColumn.AllowEdit Then
|
||||||
_Logger.Debug("[ConfigureViewColumnsCurrency] [{0}] VOR ColumnEdit: RepositoryItems.Count=[{1}]",
|
_Logger.Debug("[ConfigureViewColumnsCurrency] [{0}] VOR ColumnEdit: RepositoryItems.Count=[{1}]",
|
||||||
@@ -613,79 +615,8 @@ Namespace ControlCreator
|
|||||||
|
|
||||||
_Logger.Debug("[ConfigureViewColumnsCurrency] [{0}] NACH ColumnEdit: RepositoryItems.Count=[{1}]",
|
_Logger.Debug("[ConfigureViewColumnsCurrency] [{0}] NACH ColumnEdit: RepositoryItems.Count=[{1}]",
|
||||||
oCol.FieldName, pGrid.RepositoryItems.Count)
|
oCol.FieldName, pGrid.RepositoryItems.Count)
|
||||||
|
|
||||||
Dim assignedEdit = TryCast(oCol.ColumnEdit, RepositoryItemTextEdit)
|
|
||||||
_Logger.Debug("[ConfigureViewColumnsCurrency] [{0}]: IsSameObject=[{1}], ColumnEdit.DisplayFormat=[{2}], ColumnEdit.HashCode=[{3}]",
|
|
||||||
oCol.FieldName,
|
|
||||||
Object.ReferenceEquals(assignedEdit, riTextEdit),
|
|
||||||
If(assignedEdit IsNot Nothing, assignedEdit.DisplayFormat.FormatString, "N/A"),
|
|
||||||
If(assignedEdit IsNot Nothing, assignedEdit.GetHashCode(), -1))
|
|
||||||
|
|
||||||
For i As Integer = 0 To pGrid.RepositoryItems.Count - 1
|
|
||||||
_Logger.Debug("[ConfigureViewColumnsCurrency] RepositoryItems[{0}]: Type=[{1}], HashCode=[{2}]",
|
|
||||||
i, pGrid.RepositoryItems(i).GetType().Name, pGrid.RepositoryItems(i).GetHashCode())
|
|
||||||
Next
|
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
|
|
||||||
Dim oTestFired As Boolean = False
|
|
||||||
AddHandler pGridView.CustomColumnDisplayText,
|
|
||||||
Sub(sender As Object, e As CustomColumnDisplayTextEventArgs)
|
|
||||||
If e.Column Is Nothing OrElse e.Value Is Nothing OrElse IsDBNull(e.Value) Then
|
|
||||||
Return
|
|
||||||
End If
|
|
||||||
|
|
||||||
Dim oColumnData As DataRow = pColumnTable.
|
|
||||||
Select($"SPALTENNAME = '{e.Column.FieldName}'").
|
|
||||||
FirstOrDefault()
|
|
||||||
|
|
||||||
If oColumnData IsNot Nothing AndAlso
|
|
||||||
oColumnData.Item("TYPE_COLUMN").ToString() = "CURRENCY" Then
|
|
||||||
|
|
||||||
Try
|
|
||||||
Dim currentSymbol As String = _currencySymbol
|
|
||||||
Dim gridName As String = pGrid.Name
|
|
||||||
SyncLock _CurrencySymbolByGridName
|
|
||||||
If _CurrencySymbolByGridName.ContainsKey(gridName) Then
|
|
||||||
currentSymbol = _CurrencySymbolByGridName(gridName)
|
|
||||||
End If
|
|
||||||
End SyncLock
|
|
||||||
|
|
||||||
Dim oValue As Double
|
|
||||||
If TypeOf e.Value Is Double OrElse TypeOf e.Value Is Decimal Then
|
|
||||||
oValue = Convert.ToDouble(e.Value)
|
|
||||||
ElseIf TypeOf e.Value Is String Then
|
|
||||||
Dim oStringValue As String = e.Value.ToString().Trim()
|
|
||||||
|
|
||||||
Dim oDeCulture As CultureInfo = New CultureInfo("de-DE")
|
|
||||||
If Double.TryParse(oStringValue, NumberStyles.Currency Or NumberStyles.Number, oDeCulture, oValue) Then
|
|
||||||
ElseIf Double.TryParse(oStringValue, NumberStyles.Currency Or NumberStyles.Number, CultureInfo.InvariantCulture, oValue) Then
|
|
||||||
Else
|
|
||||||
oValue = Convert.ToDouble(oStringValue, CultureInfo.CurrentCulture)
|
|
||||||
End If
|
|
||||||
Else
|
|
||||||
oValue = Convert.ToDouble(e.Value)
|
|
||||||
End If
|
|
||||||
|
|
||||||
Dim oDeCultureInfo As CultureInfo = New CultureInfo("de-DE")
|
|
||||||
e.DisplayText = oValue.ToString("N2", oDeCultureInfo) & " " & currentSymbol
|
|
||||||
|
|
||||||
_Logger.Debug("[CustomColumnDisplayText] CURRENCY [{0}]: DisplayText=[{1}], Symbol=[{2}] (from Shared Dict in ConfigureViewColumnsCurrency)",
|
|
||||||
e.Column.FieldName, e.DisplayText, currentSymbol)
|
|
||||||
|
|
||||||
Catch ex As Exception
|
|
||||||
_Logger.Warn("⚠️ Could not format currency value [{0}] for column [{1}]: {2}",
|
|
||||||
e.Value, e.Column.FieldName, ex.Message)
|
|
||||||
Dim fallbackSymbol As String = _currencySymbol
|
|
||||||
SyncLock _CurrencySymbolByGridName
|
|
||||||
If _CurrencySymbolByGridName.ContainsKey(pGrid.Name) Then
|
|
||||||
fallbackSymbol = _CurrencySymbolByGridName(pGrid.Name)
|
|
||||||
End If
|
|
||||||
End SyncLock
|
|
||||||
e.DisplayText = e.Value.ToString() & " " & fallbackSymbol
|
|
||||||
End Try
|
|
||||||
End If
|
|
||||||
End Sub
|
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Public Sub ConfigureViewEvents(pColumnTable As DataTable, pGridView As GridView, pControl As Windows.Forms.Control, pControlId As Integer)
|
Public Sub ConfigureViewEvents(pColumnTable As DataTable, pGridView As GridView, pControl As Windows.Forms.Control, pControlId As Integer)
|
||||||
@@ -828,44 +759,61 @@ Namespace ControlCreator
|
|||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
AddHandler pGridView.CustomRowCellEdit, Sub(sender As Object, e As CustomRowCellEditEventArgs)
|
AddHandler pGridView.CustomRowCellEdit,
|
||||||
|
Sub(sender As Object, e As CustomRowCellEditEventArgs)
|
||||||
Try
|
Try
|
||||||
For Each oRow As DataRow In pColumnTable.Rows
|
' *** NEU: Dynamische Editoren aus Cache oder neu erstellen ***
|
||||||
Dim oColumnName As String = oRow.Item("SPALTENNAME").ToString()
|
If _DynamicEditorColumns.Contains(e.Column.FieldName) Then
|
||||||
If oColumnName <> e.Column.FieldName Then Continue For
|
Dim oColumnData As DataRow = pColumnTable.
|
||||||
Dim oSqlCommand As String = oRow.ItemEx("SQL_COMMAND", "")
|
Select($"SPALTENNAME = '{e.Column.FieldName}'").
|
||||||
Dim oConnectionId As Integer = oRow.ItemEx("CONNECTION_ID", 1)
|
FirstOrDefault()
|
||||||
' *** KRITISCH: Prüfe ZUERST, ob diese Spalte #TBCOL# Platzhalter hat ***
|
|
||||||
If oSqlCommand <> "" AndAlso (ContainsTableColumnPlaceholder(oSqlCommand) Or
|
If oColumnData IsNot Nothing Then
|
||||||
clsPatterns.HasComplexPatterns(oSqlCommand)) Then
|
Dim oSqlCommand As String = oColumnData.ItemEx("SQL_COMMAND", "")
|
||||||
_Logger.Debug("[CustomRowCellEdit] Column [{0}] has placeholders – SKIPPING, editor set by ShowingEditor", oColumnName)
|
Dim oConnectionId As Integer = oColumnData.ItemEx("CONNECTION_ID", 1)
|
||||||
' *** NICHTS TUN – ShowingEditor verwaltet den Editor ***
|
Dim oIsAdvancedLookup As Boolean = oColumnData.ItemEx("ADVANCED_LOOKUP", False)
|
||||||
Exit For
|
|
||||||
|
' *** SQL auflösen (für Cache-Key) ***
|
||||||
|
Dim resolvedSql = ResolveSqlTemplate(oSqlCommand, TryCast(sender, GridView), e.RowHandle)
|
||||||
|
|
||||||
|
' *** CACHE-KEY: Spaltenname + aufgelöstes SQL (HashCode) ***
|
||||||
|
Dim cacheKey As String = $"{e.Column.FieldName}|{resolvedSql.GetHashCode()}"
|
||||||
|
|
||||||
|
' *** CACHE-CHECK ***
|
||||||
|
SyncLock _DynamicEditorCacheShared
|
||||||
|
If _DynamicEditorCacheShared.ContainsKey(cacheKey) Then
|
||||||
|
' ✅ CACHE HIT: Editor wiederverwenden
|
||||||
|
e.RepositoryItem = _DynamicEditorCacheShared(cacheKey)
|
||||||
|
_Logger.Debug("[CustomRowCellEdit] Using CACHED editor for [{0}] (CacheKey=[{1}])", e.Column.FieldName, cacheKey)
|
||||||
|
Else
|
||||||
|
' ❌ CACHE MISS: Neuen Editor erstellen
|
||||||
|
_Logger.Debug("[CustomRowCellEdit] Creating NEW row-specific editor for [{0}]", e.Column.FieldName)
|
||||||
|
|
||||||
|
Dim realEditor = CreateRowSpecificEditor(e.Column.FieldName, resolvedSql, oConnectionId, oIsAdvancedLookup)
|
||||||
|
|
||||||
|
If realEditor IsNot Nothing Then
|
||||||
|
' *** IN CACHE SPEICHERN ***
|
||||||
|
_DynamicEditorCacheShared(cacheKey) = realEditor
|
||||||
|
e.RepositoryItem = realEditor
|
||||||
|
_Logger.Debug("[CustomRowCellEdit] CACHED new editor (Type=[{0}], CacheKey=[{1}])", realEditor.GetType().Name, cacheKey)
|
||||||
|
Else
|
||||||
|
_Logger.Warn("[CustomRowCellEdit] CreateRowSpecificEditor returned Nothing for [{0}]", e.Column.FieldName)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End SyncLock
|
||||||
|
End If
|
||||||
|
Return
|
||||||
End If
|
End If
|
||||||
|
|
||||||
Dim oEditorExists = GridTables_TestEditorExistsByControlAndColumn(pControlId, oColumnName)
|
' Standard-Editor aus Cache
|
||||||
|
Dim oEditorExists = GridTables_TestEditorExistsByControlAndColumn(pControlId, e.Column.FieldName)
|
||||||
If oEditorExists Then
|
If oEditorExists Then
|
||||||
' Combobox/Lookup-Editor aus GridTables: immer zuweisen
|
_Logger.Debug("[CustomRowCellEdit] Assigning RepositoryItem for column [{0}] from GridTables cache.", e.Column.FieldName)
|
||||||
Dim oEditor = _GridTables.Item(pControlId).Item(oColumnName)
|
e.RepositoryItem = _GridTables.Item(pControlId).Item(e.Column.FieldName)
|
||||||
_Logger.Debug("Assigning Editor to Column [{0}]", oColumnName)
|
|
||||||
e.RepositoryItem = oEditor
|
|
||||||
Else
|
|
||||||
Dim oColumnType As String = ObjectEx.NotNull(oRow.Item("TYPE_COLUMN"), String.Empty).ToString()
|
|
||||||
If oColumnType = "CURRENCY" Then
|
|
||||||
If _FormulaColumnNames.Contains(oColumnName) Then
|
|
||||||
_Logger.Debug("CURRENCY column [{0}] is formula/readonly – CustomColumnDisplayText handles display", oColumnName)
|
|
||||||
Else
|
|
||||||
_Logger.Debug("CURRENCY column [{0}] – NO e.RepositoryItem set. Display via CustomColumnDisplayText, Edit via GridColumn.ColumnEdit", oColumnName)
|
|
||||||
End If
|
End If
|
||||||
Else
|
|
||||||
_Logger.Debug("Editor for Column [{0}] does not exist", oColumnName)
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
Exit For
|
|
||||||
Next
|
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
_Logger.Warn("⚠️ Error in CustomRowCellEdit for [{0}]", e.CellValue)
|
_Logger.Warn("⚠️ Error in CustomRowCellEdit for column [{0}]", e.Column.FieldName)
|
||||||
_Logger.Error(ex)
|
_Logger.Error(ex)
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
@@ -1010,113 +958,17 @@ Namespace ControlCreator
|
|||||||
|
|
||||||
_Logger.Debug("Showing editor.")
|
_Logger.Debug("Showing editor.")
|
||||||
|
|
||||||
' Formel-Spalten dürfen keinen Editor öffnen
|
' Formel-Spalten blockieren
|
||||||
If oView.FocusedColumn IsNot Nothing Then
|
If oView.FocusedColumn IsNot Nothing Then
|
||||||
Dim oFieldName As String = oView.FocusedColumn.FieldName
|
Dim oFieldName As String = oView.FocusedColumn.FieldName
|
||||||
If _FormulaColumnNames.Contains(oFieldName) Then
|
If _FormulaColumnNames.Contains(oFieldName) Then
|
||||||
_Logger.Debug("Cancelling editor – column [{0}] is a formula column (Expression or SQL).", oFieldName)
|
_Logger.Debug("Cancelling editor – column [{0}] is a formula column.", oFieldName)
|
||||||
e.Cancel = True
|
e.Cancel = True
|
||||||
Return
|
Return
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|
||||||
' *** NEU: Row-specific Editor für #TBCOL# Platzhalter ***
|
CheckNewItemRow:
|
||||||
If oView.FocusedColumn IsNot Nothing Then
|
|
||||||
Dim oFocusedColumnName As String = oView.FocusedColumn.FieldName
|
|
||||||
Dim oRowHandle As Integer = oView.FocusedRowHandle
|
|
||||||
|
|
||||||
' Spalten-Metadata aus pColumnTable holen
|
|
||||||
Dim oColumnData As DataRow = pColumnTable.
|
|
||||||
Select($"SPALTENNAME = '{oFocusedColumnName}'").
|
|
||||||
FirstOrDefault()
|
|
||||||
|
|
||||||
If oColumnData IsNot Nothing Then
|
|
||||||
Dim oSqlCommand As String = oColumnData.ItemEx("SQL_COMMAND", "")
|
|
||||||
Dim oConnectionId As Integer = oColumnData.ItemEx("CONNECTION_ID", 1)
|
|
||||||
|
|
||||||
' Prüfen ob SQL Platzhalter enthält
|
|
||||||
If oSqlCommand <> "" AndAlso ContainsTableColumnPlaceholder(oSqlCommand) Then
|
|
||||||
_Logger.Debug("[ShowingEditor] Column [{0}] has SQL with #TBCOL# placeholders – creating row-specific editor", oFocusedColumnName)
|
|
||||||
|
|
||||||
' *** KRITISCH: Alten Editor VORHER entfernen ***
|
|
||||||
Dim oldEditor = oView.FocusedColumn.ColumnEdit
|
|
||||||
If oldEditor IsNot Nothing Then
|
|
||||||
_Logger.Debug("[ShowingEditor] Removing old ColumnEdit (Type=[{0}], HashCode=[{1}])",
|
|
||||||
oldEditor.GetType().Name, oldEditor.GetHashCode())
|
|
||||||
|
|
||||||
' Editor von Spalte entfernen
|
|
||||||
oView.FocusedColumn.ColumnEdit = Nothing
|
|
||||||
|
|
||||||
' *** NEU: Editor aus RepositoryItems entfernen, falls vorhanden ***
|
|
||||||
If oView.GridControl.RepositoryItems.Contains(oldEditor) Then
|
|
||||||
oView.GridControl.RepositoryItems.Remove(oldEditor)
|
|
||||||
_Logger.Debug("[ShowingEditor] Removed old editor from RepositoryItems")
|
|
||||||
End If
|
|
||||||
|
|
||||||
' *** KRITISCH: Dispose() aufrufen um Memory Leaks zu vermeiden ***
|
|
||||||
Try
|
|
||||||
oldEditor.Dispose()
|
|
||||||
_Logger.Debug("[ShowingEditor] Disposed old editor")
|
|
||||||
Catch disposeEx As Exception
|
|
||||||
_Logger.Warn("[ShowingEditor] Could not dispose old editor: {0}", disposeEx.Message)
|
|
||||||
End Try
|
|
||||||
End If
|
|
||||||
|
|
||||||
' Platzhalter ersetzen mit aktuellen Zeilenwerten
|
|
||||||
Dim resolvedSql As String = ResolveSqlTemplate(oSqlCommand, oView, oRowHandle)
|
|
||||||
|
|
||||||
' Editor mit aufgelöstem SQL laden
|
|
||||||
Dim oRowSpecificEditor = CreateRowSpecificEditor(
|
|
||||||
oFocusedColumnName,
|
|
||||||
resolvedSql,
|
|
||||||
oConnectionId,
|
|
||||||
oColumnData.ItemEx("ADVANCED_LOOKUP", False))
|
|
||||||
|
|
||||||
If oRowSpecificEditor IsNot Nothing Then
|
|
||||||
_Logger.Debug("[ShowingEditor] Created new editor (Type=[{0}], HashCode=[{1}])",
|
|
||||||
oRowSpecificEditor.GetType().Name,
|
|
||||||
oRowSpecificEditor.GetHashCode())
|
|
||||||
|
|
||||||
' *** KRITISCH: DataSource-Größe loggen für Debugging ***
|
|
||||||
If TypeOf oRowSpecificEditor Is RepositoryItemLookupControl3 Then
|
|
||||||
Dim lookupEditor = DirectCast(oRowSpecificEditor, RepositoryItemLookupControl3)
|
|
||||||
If lookupEditor.DataSource IsNot Nothing AndAlso TypeOf lookupEditor.DataSource Is DataTable Then
|
|
||||||
Dim dt = DirectCast(lookupEditor.DataSource, DataTable)
|
|
||||||
_Logger.Debug("[ShowingEditor] LookupEditor DataSource: [{0}] rows", dt.Rows.Count)
|
|
||||||
' Log first 3 values for verification
|
|
||||||
For i As Integer = 0 To Math.Min(2, dt.Rows.Count - 1)
|
|
||||||
_Logger.Debug("[ShowingEditor] Row[{0}]: [{1}]", i, dt.Rows(i)(0))
|
|
||||||
Next
|
|
||||||
End If
|
|
||||||
ElseIf TypeOf oRowSpecificEditor Is RepositoryItemComboBox Then
|
|
||||||
Dim comboEditor = DirectCast(oRowSpecificEditor, RepositoryItemComboBox)
|
|
||||||
_Logger.Debug("[ShowingEditor] ComboBoxEditor Items: [{0}] items", comboEditor.Items.Count)
|
|
||||||
' Log first 3 items
|
|
||||||
For i As Integer = 0 To Math.Min(2, comboEditor.Items.Count - 1)
|
|
||||||
_Logger.Debug("[ShowingEditor] Item[{0}]: [{1}]", i, comboEditor.Items(i))
|
|
||||||
Next
|
|
||||||
End If
|
|
||||||
|
|
||||||
' *** KRITISCH: Editor zur GridControl.RepositoryItems hinzufügen ***
|
|
||||||
' Dies stellt sicher, dass DevExpress den Editor korrekt verwaltet
|
|
||||||
oView.GridControl.RepositoryItems.Add(oRowSpecificEditor)
|
|
||||||
_Logger.Debug("[ShowingEditor] Added editor to RepositoryItems (Total count: {0})",
|
|
||||||
oView.GridControl.RepositoryItems.Count)
|
|
||||||
|
|
||||||
' Editor zur Spalte zuweisen
|
|
||||||
oView.FocusedColumn.ColumnEdit = oRowSpecificEditor
|
|
||||||
|
|
||||||
_Logger.Debug("[ShowingEditor] Row-specific editor assigned and refreshed for [{0}]", oFocusedColumnName)
|
|
||||||
Else
|
|
||||||
_Logger.Warn("[ShowingEditor] Failed to create row-specific editor for [{0}] – cancelling edit", oFocusedColumnName)
|
|
||||||
e.Cancel = True
|
|
||||||
Return
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
|
|
||||||
' BESTEHENDER CODE: NewItemRow-Handling
|
|
||||||
If oView.IsNewItemRow(oView.FocusedRowHandle) AndAlso Not newRowModified Then
|
If oView.IsNewItemRow(oView.FocusedRowHandle) AndAlso Not newRowModified Then
|
||||||
_Logger.Debug("Adding new row.")
|
_Logger.Debug("Adding new row.")
|
||||||
oView.AddNewRow()
|
oView.AddNewRow()
|
||||||
@@ -1127,58 +979,6 @@ Namespace ControlCreator
|
|||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
' *** NEU: HiddenEditor-Event für Cleanup ***
|
|
||||||
AddHandler pGridView.HiddenEditor,
|
|
||||||
Sub(sender As Object, e As EventArgs)
|
|
||||||
Try
|
|
||||||
Dim oView As GridView = TryCast(sender, GridView)
|
|
||||||
If oView Is Nothing OrElse oView.FocusedColumn Is Nothing Then Return
|
|
||||||
|
|
||||||
Dim oFocusedColumnName As String = oView.FocusedColumn.FieldName
|
|
||||||
|
|
||||||
' Prüfen ob diese Spalte dynamische Editoren verwendet
|
|
||||||
Dim oColumnData As DataRow = pColumnTable.
|
|
||||||
Select($"SPALTENNAME = '{oFocusedColumnName}'").
|
|
||||||
FirstOrDefault()
|
|
||||||
|
|
||||||
If oColumnData IsNot Nothing Then
|
|
||||||
Dim oSqlCommand As String = oColumnData.ItemEx("SQL_COMMAND", "")
|
|
||||||
|
|
||||||
' Wenn Spalte #TBCOL# verwendet → Editor nach Schließen entfernen
|
|
||||||
If oSqlCommand <> "" AndAlso ContainsTableColumnPlaceholder(oSqlCommand) Then
|
|
||||||
Dim currentEditor = oView.FocusedColumn.ColumnEdit
|
|
||||||
|
|
||||||
If currentEditor IsNot Nothing Then
|
|
||||||
_Logger.Debug("[HiddenEditor] Cleaning up row-specific editor for [{0}] (HashCode=[{1}])",
|
|
||||||
oFocusedColumnName, currentEditor.GetHashCode())
|
|
||||||
|
|
||||||
' Editor von Spalte entfernen
|
|
||||||
oView.FocusedColumn.ColumnEdit = Nothing
|
|
||||||
|
|
||||||
' Editor aus RepositoryItems entfernen
|
|
||||||
If oView.GridControl.RepositoryItems.Contains(currentEditor) Then
|
|
||||||
oView.GridControl.RepositoryItems.Remove(currentEditor)
|
|
||||||
_Logger.Debug("[HiddenEditor] Removed editor from RepositoryItems (Remaining: {0})",
|
|
||||||
oView.GridControl.RepositoryItems.Count)
|
|
||||||
End If
|
|
||||||
|
|
||||||
' *** KRITISCH: Dispose aufrufen ***
|
|
||||||
Try
|
|
||||||
currentEditor.Dispose()
|
|
||||||
_Logger.Debug("[HiddenEditor] Disposed editor successfully")
|
|
||||||
Catch disposeEx As Exception
|
|
||||||
_Logger.Warn("[HiddenEditor] Could not dispose editor: {0}", disposeEx.Message)
|
|
||||||
End Try
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
|
|
||||||
Catch ex As Exception
|
|
||||||
_Logger.Error("[HiddenEditor] Error: {0}", ex.Message)
|
|
||||||
_Logger.Error(ex)
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
AddHandler pGridView.FocusedColumnChanged,
|
AddHandler pGridView.FocusedColumnChanged,
|
||||||
Sub(sender As Object, e As FocusedColumnChangedEventArgs)
|
Sub(sender As Object, e As FocusedColumnChangedEventArgs)
|
||||||
Try
|
Try
|
||||||
@@ -1361,7 +1161,8 @@ Namespace ControlCreator
|
|||||||
isAdvancedLookup As Boolean) As RepositoryItem
|
isAdvancedLookup As Boolean) As RepositoryItem
|
||||||
|
|
||||||
Try
|
Try
|
||||||
_Logger.Debug("[CreateRowSpecificEditor] Executing SQL for column [{0}]: {1}", columnName, resolvedSql)
|
If LOG_HOTSPOTS Then _Logger.Debug("[CreateRowSpecificEditor] Executing SQL for column [{0}]: {1}", columnName, resolvedSql)
|
||||||
|
|
||||||
|
|
||||||
' SQL ausführen
|
' SQL ausführen
|
||||||
Dim oDataTable As DataTable = DatabaseFallback.GetDatatable(
|
Dim oDataTable As DataTable = DatabaseFallback.GetDatatable(
|
||||||
@@ -1374,11 +1175,11 @@ Namespace ControlCreator
|
|||||||
Return Nothing
|
Return Nothing
|
||||||
End If
|
End If
|
||||||
|
|
||||||
_Logger.Debug("[CreateRowSpecificEditor] Retrieved {0} rows for column [{1}]", oDataTable.Rows.Count, columnName)
|
If LOG_HOTSPOTS Then _Logger.Debug("[CreateRowSpecificEditor] Retrieved {0} rows for column [{1}]", oDataTable.Rows.Count, columnName)
|
||||||
|
|
||||||
' *** NEU: Log erste 5 Rows für Debugging ***
|
' *** NEU: Log erste 5 Rows für Debugging ***
|
||||||
For i As Integer = 0 To Math.Min(4, oDataTable.Rows.Count - 1)
|
For i As Integer = 0 To Math.Min(4, oDataTable.Rows.Count - 1)
|
||||||
_Logger.Debug("[CreateRowSpecificEditor] DataTable Row[{0}]: [{1}]", i, oDataTable.Rows(i)(0))
|
If LOG_HOTSPOTS Then _Logger.Debug("[CreateRowSpecificEditor] DataTable Row[{0}]: [{1}]", i, oDataTable.Rows(i)(0))
|
||||||
Next
|
Next
|
||||||
|
|
||||||
' Editor erstellen (analog zu GridTables_GetRepositoryItemForColumn)
|
' Editor erstellen (analog zu GridTables_GetRepositoryItemForColumn)
|
||||||
@@ -1415,7 +1216,7 @@ Namespace ControlCreator
|
|||||||
|
|
||||||
oEditor.Items.Add(oValue)
|
oEditor.Items.Add(oValue)
|
||||||
oItems.Add(oValue)
|
oItems.Add(oValue)
|
||||||
_Logger.Debug("[CreateRowSpecificEditor] Added ComboBox item: [{0}]", oValue)
|
If LOG_HOTSPOTS Then _Logger.Debug("[CreateRowSpecificEditor] Added ComboBox item: [{0}]", oValue)
|
||||||
Next
|
Next
|
||||||
|
|
||||||
_Logger.Debug("[CreateRowSpecificEditor] Created ComboBox with {0} items", oEditor.Items.Count)
|
_Logger.Debug("[CreateRowSpecificEditor] Created ComboBox with {0} items", oEditor.Items.Count)
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ Public Class clsPatterns
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public Shared Sub ClearControlCache()
|
Public Shared Sub ClearControlCache()
|
||||||
_ControlLookupCache = Nothing
|
_ControlLookupCache = Nothing
|
||||||
LOGGER.Debug("Control cache cleared")
|
If LOG_HOTSPOTS Then LOGGER.Debug("Control cache cleared")
|
||||||
End Sub
|
End Sub
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' Aktualisiert den Wert eines Controls im Cache
|
''' Aktualisiert den Wert eines Controls im Cache
|
||||||
@@ -122,7 +122,7 @@ Public Class clsPatterns
|
|||||||
LOGGER.Warn($"Unsupported control type for cache update: {ctrl.GetType.Name}")
|
LOGGER.Warn($"Unsupported control type for cache update: {ctrl.GetType.Name}")
|
||||||
End Select
|
End Select
|
||||||
|
|
||||||
LOGGER.Debug($"Cache updated for control [{controlName}] with value type [{newValue?.GetType().Name}]")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"Cache updated for control [{controlName}] with value type [{newValue?.GetType().Name}]")
|
||||||
|
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
LOGGER.Error(ex)
|
LOGGER.Error(ex)
|
||||||
@@ -144,7 +144,7 @@ Public Class clsPatterns
|
|||||||
UpdateControlInCache(kvp.Key, kvp.Value)
|
UpdateControlInCache(kvp.Key, kvp.Value)
|
||||||
Next
|
Next
|
||||||
|
|
||||||
LOGGER.Debug($"Batch cache update completed for {updates.Count} controls")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"Batch cache update completed for {updates.Count} controls")
|
||||||
End Sub
|
End Sub
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' Wraps a pattern-type and -value in the common format: {#type#value}
|
''' Wraps a pattern-type and -value in the common format: {#type#value}
|
||||||
@@ -175,9 +175,9 @@ Public Class clsPatterns
|
|||||||
|
|
||||||
If Not IsNothing(oResult) Then
|
If Not IsNothing(oResult) Then
|
||||||
oResult = ReplaceUserValues(oResult)
|
oResult = ReplaceUserValues(oResult)
|
||||||
LOGGER.Debug($"input AFTER replacing: [{oResult}]")
|
|
||||||
End If
|
|
||||||
|
|
||||||
|
End If
|
||||||
|
LOGGER.Debug($"input AFTER replacing: [{oResult}]")
|
||||||
Return oResult
|
Return oResult
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
LOGGER.Error(ex)
|
LOGGER.Error(ex)
|
||||||
@@ -305,7 +305,7 @@ Public Class clsPatterns
|
|||||||
End SyncLock
|
End SyncLock
|
||||||
|
|
||||||
Try
|
Try
|
||||||
LOGGER.Debug($"Starting ReplaceControlValues with input: [{oResult}] for document ID: {CURRENT_DOC_ID}")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"Starting ReplaceControlValues with input: [{oResult}] for document ID: {CURRENT_DOC_ID}")
|
||||||
Dim oTryCounter = 0
|
Dim oTryCounter = 0
|
||||||
|
|
||||||
While ContainsPattern(oResult, PATTERN_CTRL)
|
While ContainsPattern(oResult, PATTERN_CTRL)
|
||||||
@@ -325,7 +325,7 @@ Public Class clsPatterns
|
|||||||
oColumnName = oSplitName.Last()
|
oColumnName = oSplitName.Last()
|
||||||
End If
|
End If
|
||||||
|
|
||||||
LOGGER.Debug("Found placeholder for control [{0}].", oControlName)
|
If LOG_HOTSPOTS Then LOGGER.Debug("Found placeholder for control [{0}].", oControlName)
|
||||||
' Beim Cache-Zugriff Lock verwenden
|
' Beim Cache-Zugriff Lock verwenden
|
||||||
Dim oControl As Control = Nothing
|
Dim oControl As Control = Nothing
|
||||||
SyncLock _ControlLookupCache
|
SyncLock _ControlLookupCache
|
||||||
@@ -349,11 +349,11 @@ Public Class clsPatterns
|
|||||||
|
|
||||||
If oControl IsNot Nothing Then
|
If oControl IsNot Nothing Then
|
||||||
Dim oReplaceValue As String
|
Dim oReplaceValue As String
|
||||||
LOGGER.Debug("oControl.GetType [{0}].", oControl.GetType.ToString)
|
If LOG_HOTSPOTS Then LOGGER.Debug("oControl.GetType [{0}].", oControl.GetType.ToString)
|
||||||
Select Case oControl.GetType
|
Select Case oControl.GetType
|
||||||
Case GetType(TextBox)
|
Case GetType(TextBox)
|
||||||
oReplaceValue = oControl.Text
|
oReplaceValue = oControl.Text
|
||||||
LOGGER.Debug("TextBox- oReplaceValue will be [{0}].", oReplaceValue)
|
If LOG_HOTSPOTS Then LOGGER.Debug("TextBox- oReplaceValue will be [{0}].", oReplaceValue)
|
||||||
Case GetType(TextEdit)
|
Case GetType(TextEdit)
|
||||||
Try
|
Try
|
||||||
oReplaceValue = ClassAllgemeineFunktionen.NotNullString(DirectCast(oControl, TextEdit).EditValue, String.Empty)
|
oReplaceValue = ClassAllgemeineFunktionen.NotNullString(DirectCast(oControl, TextEdit).EditValue, String.Empty)
|
||||||
@@ -361,7 +361,7 @@ Public Class clsPatterns
|
|||||||
LOGGER.Warn($"Error in ReplaceValue MemoEdit: {ex.Message}")
|
LOGGER.Warn($"Error in ReplaceValue MemoEdit: {ex.Message}")
|
||||||
oReplaceValue = ""
|
oReplaceValue = ""
|
||||||
End Try
|
End Try
|
||||||
LOGGER.Debug("TextEdit- oReplaceValue will be [{0}].", oReplaceValue)
|
If LOG_HOTSPOTS Then LOGGER.Debug("TextEdit- oReplaceValue will be [{0}].", oReplaceValue)
|
||||||
Case GetType(MemoEdit)
|
Case GetType(MemoEdit)
|
||||||
Try
|
Try
|
||||||
oReplaceValue = ClassAllgemeineFunktionen.NotNullString(DirectCast(oControl, MemoEdit).EditValue, String.Empty)
|
oReplaceValue = ClassAllgemeineFunktionen.NotNullString(DirectCast(oControl, MemoEdit).EditValue, String.Empty)
|
||||||
@@ -369,7 +369,7 @@ Public Class clsPatterns
|
|||||||
LOGGER.Warn($"Error in ReplaceValue MemoEdit: {ex.Message}")
|
LOGGER.Warn($"Error in ReplaceValue MemoEdit: {ex.Message}")
|
||||||
oReplaceValue = ""
|
oReplaceValue = ""
|
||||||
End Try
|
End Try
|
||||||
LOGGER.Debug("MemoEdit- oReplaceValue will be [{0}].", oReplaceValue)
|
If LOG_HOTSPOTS Then LOGGER.Debug("MemoEdit- oReplaceValue will be [{0}].", oReplaceValue)
|
||||||
Case GetType(LookupControl3)
|
Case GetType(LookupControl3)
|
||||||
Dim oLookupControl3 As LookupControl3 = oControl
|
Dim oLookupControl3 As LookupControl3 = oControl
|
||||||
|
|
||||||
@@ -391,7 +391,7 @@ Public Class clsPatterns
|
|||||||
oReplaceValue = ERROR_REPLACE_VALUE
|
oReplaceValue = ERROR_REPLACE_VALUE
|
||||||
' ========== FIX END ==========
|
' ========== FIX END ==========
|
||||||
ElseIf selectedValues.Count > 1 Then
|
ElseIf selectedValues.Count > 1 Then
|
||||||
LOGGER.Debug($"LookupControl3 [{oControlName}] mit mehr als 1 Value")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"LookupControl3 [{oControlName}] mit mehr als 1 Value")
|
||||||
Dim oIndex As Integer = 0
|
Dim oIndex As Integer = 0
|
||||||
For Each oString As String In selectedValues
|
For Each oString As String In selectedValues
|
||||||
If oIndex = 0 Then
|
If oIndex = 0 Then
|
||||||
@@ -403,12 +403,11 @@ Public Class clsPatterns
|
|||||||
Next
|
Next
|
||||||
oIsSQL = False
|
oIsSQL = False
|
||||||
Else ' Count = 1
|
Else ' Count = 1
|
||||||
LOGGER.Debug($"LookupControl3 [{oControlName}] mit genau einem Value")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"LookupControl3 [{oControlName}] mit genau einem Value")
|
||||||
oReplaceValue = selectedValues(0)
|
oReplaceValue = selectedValues(0)
|
||||||
End If
|
End If
|
||||||
|
|
||||||
LOGGER.Debug($"oReplaceValue nach Durchlaufen selectedValues: {oReplaceValue}")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"oReplaceValue nach Durchlaufen selectedValues: {oReplaceValue}")
|
||||||
LOGGER.Debug($"oReplaceValue nach Durchlaufen selectedValues: {oReplaceValue}")
|
|
||||||
|
|
||||||
Case GetType(Windows.Forms.ComboBox)
|
Case GetType(Windows.Forms.ComboBox)
|
||||||
oReplaceValue = oControl.Text
|
oReplaceValue = oControl.Text
|
||||||
@@ -440,7 +439,7 @@ Public Class clsPatterns
|
|||||||
Case Else
|
Case Else
|
||||||
oReplaceValue = ERROR_REPLACE_VALUE
|
oReplaceValue = ERROR_REPLACE_VALUE
|
||||||
End Select
|
End Select
|
||||||
LOGGER.Debug($"[SQL-ESCAPE CHECK] Control: [{oControlName}], oReplaceValue Type: [{If(oReplaceValue?.GetType()?.Name, "NULL")}], Value: [{oReplaceValue}], IsSQL: [{oIsSQL}]")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"[SQL-ESCAPE CHECK] Control: [{oControlName}], oReplaceValue Type: [{If(oReplaceValue?.GetType()?.Name, "NULL")}], Value: [{oReplaceValue}], IsSQL: [{oIsSQL}]")
|
||||||
If oReplaceValue Is Nothing Then
|
If oReplaceValue Is Nothing Then
|
||||||
LOGGER.Warn($"⚠️ oReplaceValue is Nothing for control [{oControlName}]! Setting to ERROR_REPLACE_VALUE")
|
LOGGER.Warn($"⚠️ oReplaceValue is Nothing for control [{oControlName}]! Setting to ERROR_REPLACE_VALUE")
|
||||||
oReplaceValue = ERROR_REPLACE_VALUE
|
oReplaceValue = ERROR_REPLACE_VALUE
|
||||||
@@ -468,7 +467,7 @@ Public Class clsPatterns
|
|||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
Private Shared Function SafeSqlEscape(value As Object) As String
|
Private Shared Function SafeSqlEscape(value As Object) As String
|
||||||
LOGGER.Debug($"[SafeSqlEscape] Input Type: [{If(value?.GetType()?.Name, "NULL")}], Value: [{value}]")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"[SafeSqlEscape] Input Type: [{If(value?.GetType()?.Name, "NULL")}], Value: [{value}]")
|
||||||
|
|
||||||
If value Is Nothing Then
|
If value Is Nothing Then
|
||||||
LOGGER.Warn("[SafeSqlEscape] Value is Nothing → returning ERROR_REPLACE_VALUE")
|
LOGGER.Warn("[SafeSqlEscape] Value is Nothing → returning ERROR_REPLACE_VALUE")
|
||||||
@@ -490,14 +489,14 @@ Public Class clsPatterns
|
|||||||
End If
|
End If
|
||||||
|
|
||||||
Dim escaped = strValue.Replace("'", "''")
|
Dim escaped = strValue.Replace("'", "''")
|
||||||
LOGGER.Debug($"[SafeSqlEscape] Output: [{escaped}]")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"[SafeSqlEscape] Output: [{escaped}]")
|
||||||
Return escaped
|
Return escaped
|
||||||
End Function
|
End Function
|
||||||
Public Shared Function ReplaceWindreamIndicies(pInput As String, pDocument As WMObject, pIsSQL As Boolean) As String
|
Public Shared Function ReplaceWindreamIndicies(pInput As String, pDocument As WMObject, pIsSQL As Boolean) As String
|
||||||
Try
|
Try
|
||||||
Dim oResult = pInput
|
Dim oResult = pInput
|
||||||
Dim oTryCounter As Integer = 0
|
Dim oTryCounter As Integer = 0
|
||||||
LOGGER.Debug($"Starting ReplaceWindreamIndicies with input: [{oResult}] for document ID: {CURRENT_DOC_ID}")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"Starting ReplaceWindreamIndicies with input: [{oResult}] for document ID: {CURRENT_DOC_ID}")
|
||||||
While ContainsPattern(oResult, PATTERN_WMI)
|
While ContainsPattern(oResult, PATTERN_WMI)
|
||||||
Dim oWMValue As String
|
Dim oWMValue As String
|
||||||
Dim oIndexName As String = GetNextPattern(oResult, PATTERN_WMI).Value
|
Dim oIndexName As String = GetNextPattern(oResult, PATTERN_WMI).Value
|
||||||
@@ -517,9 +516,9 @@ Public Class clsPatterns
|
|||||||
|
|
||||||
If oWMValue IsNot Nothing Then
|
If oWMValue IsNot Nothing Then
|
||||||
If pIsSQL = True Then
|
If pIsSQL = True Then
|
||||||
LOGGER.Debug($"IS_SQL = True - oReplaceValue = {oWMValue}")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"IS_SQL = True - oReplaceValue = {oWMValue}")
|
||||||
oWMValue = oWMValue.ToString().Replace("'", "''")
|
oWMValue = oWMValue.ToString().Replace("'", "''")
|
||||||
LOGGER.Debug($"oReplaceValue = {oWMValue}")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"oReplaceValue = {oWMValue}")
|
||||||
End If
|
End If
|
||||||
oResult = ReplacePattern(oResult, PATTERN_WMI, oWMValue)
|
oResult = ReplacePattern(oResult, PATTERN_WMI, oWMValue)
|
||||||
Else
|
Else
|
||||||
@@ -543,7 +542,7 @@ Public Class clsPatterns
|
|||||||
Try
|
Try
|
||||||
Dim result = input
|
Dim result = input
|
||||||
Dim oTryCounter As Integer = 0
|
Dim oTryCounter As Integer = 0
|
||||||
LOGGER.Debug($"Starting ReplaceIDBAttributes with input: [{result}] for document ID: {CURRENT_DOC_ID}")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"Starting ReplaceIDBAttributes with input: [{result}] for document ID: {CURRENT_DOC_ID}")
|
||||||
While ContainsPattern(result, PATTERN_IDBA)
|
While ContainsPattern(result, PATTERN_IDBA)
|
||||||
|
|
||||||
Dim indexName As String = GetNextPattern(result, PATTERN_IDBA).Value
|
Dim indexName As String = GetNextPattern(result, PATTERN_IDBA).Value
|
||||||
@@ -568,7 +567,7 @@ Public Class clsPatterns
|
|||||||
If oIDBValue IsNot Nothing Or Not IsDBNull(oIDBValue) Then
|
If oIDBValue IsNot Nothing Or Not IsDBNull(oIDBValue) Then
|
||||||
Dim oReplaceValue = "{" + $"#{PATTERN_IDBA}#{indexName}" + "}"
|
Dim oReplaceValue = "{" + $"#{PATTERN_IDBA}#{indexName}" + "}"
|
||||||
If IS_SQL = True Then
|
If IS_SQL = True Then
|
||||||
LOGGER.Debug($"IS_SQL = True - oReplaceValue = [{oReplaceValue}]")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"IS_SQL = True - oReplaceValue = [{oReplaceValue}]")
|
||||||
If indexName <> "ObjectID" And indexName <> "OBJID" And indexName <> "DocID" Then
|
If indexName <> "ObjectID" And indexName <> "OBJID" And indexName <> "DocID" Then
|
||||||
Try
|
Try
|
||||||
oIDBValue = oIDBValue.Replace("'", "''")
|
oIDBValue = oIDBValue.Replace("'", "''")
|
||||||
@@ -578,7 +577,7 @@ Public Class clsPatterns
|
|||||||
End Try
|
End Try
|
||||||
|
|
||||||
End If
|
End If
|
||||||
LOGGER.Debug($"oIDBValue = {oIDBValue}")
|
If LOG_HOTSPOTS Then LOGGER.Debug($"oIDBValue = {oIDBValue}")
|
||||||
End If
|
End If
|
||||||
result = result.Replace(oReplaceValue, oIDBValue)
|
result = result.Replace(oReplaceValue, oIDBValue)
|
||||||
Else
|
Else
|
||||||
@@ -590,7 +589,7 @@ Public Class clsPatterns
|
|||||||
' Increase counter by 10 to avoid DDOSing the Database/IDB Service
|
' Increase counter by 10 to avoid DDOSing the Database/IDB Service
|
||||||
oTryCounter += 10
|
oTryCounter += 10
|
||||||
End While
|
End While
|
||||||
LOGGER.Debug("sql after ReplaceIDBAttributes: " & input)
|
If LOG_HOTSPOTS Then LOGGER.Debug("sql after ReplaceIDBAttributes: " & input)
|
||||||
Return result
|
Return result
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
LOGGER.Error(ex)
|
LOGGER.Error(ex)
|
||||||
|
|||||||
@@ -4195,6 +4195,9 @@ Public Class frmValidator
|
|||||||
DocCurrency = oCurrency
|
DocCurrency = oCurrency
|
||||||
MyValidationLogger.Info($"[FINAL] DocCurrency = [{DocCurrency}]")
|
MyValidationLogger.Info($"[FINAL] DocCurrency = [{DocCurrency}]")
|
||||||
|
|
||||||
|
taskFLOW.ControlCreator.GridControl.ClearDynamicEditorCache()
|
||||||
|
taskFLOW.ControlCreator.GridControl.ResetCurrencySymbolCache()
|
||||||
|
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
MyValidationLogger.Error($"Währungsladung fehlgeschlagen: {ex.Message}")
|
MyValidationLogger.Error($"Währungsladung fehlgeschlagen: {ex.Message}")
|
||||||
DocCurrency = "EUR"
|
DocCurrency = "EUR"
|
||||||
@@ -8816,4 +8819,8 @@ Public Class frmValidator
|
|||||||
CONFIG.Config.NOTES_ONCLICK = bchkitmNotes.Checked
|
CONFIG.Config.NOTES_ONCLICK = bchkitmNotes.Checked
|
||||||
CONFIG.Save()
|
CONFIG.Save()
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
Private Sub frmValidator_SizeChanged(sender As Object, e As EventArgs) Handles Me.SizeChanged
|
||||||
|
|
||||||
|
End Sub
|
||||||
End Class
|
End Class
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user