Unterstützung für dynamische SQL-Templates hinzugefügt

Die Änderungen umfassen:
- Hinzufügen von Platzhalter-Checks für SQL-Templates (`ContainsTableColumnPlaceholder`) und deren Verarbeitung.
- Implementierung zeilenspezifischer Editoren (`CreateRowSpecificEditor`) basierend auf aufgelösten SQL-Templates.
- Erweiterung der Editor-Logik in `GridControl.vb`, um dynamische Editoren zu unterstützen.
- Modularisierung und Verbesserung der SQL-Formel-Verarbeitung (`TriggerSqlFormulasAfterExpressionUpdate`, `ExecuteSqlFormulas`).
- Erweiterung der Validierung in `frmValidator.vb`, um Platzhalter in SQL-Befehlen zu prüfen.
- Optimierung der Logging-Ausgaben für bessere Nachvollziehbarkeit.
- Refactoring zur Verbesserung der Lesbarkeit und Konsistenz.
- Erweiterung der Komponenten in `Product.wxs` (z. B. Hinzufügen von `DLLLicenseManager.dll`).
- Zusätzliche Validierungen für Spaltenformeln und neue Zeilen.

Diese Änderungen verbessern die Flexibilität, Stabilität und Nachvollziehbarkeit der Anwendung.
This commit is contained in:
Developer01
2026-06-09 08:55:48 +02:00
parent e49713246b
commit 6260c215f2
4 changed files with 1915 additions and 214 deletions

View File

@@ -126,6 +126,7 @@
<File Id="DDPatterns" Name="DigitalData.Modules.Patterns.dll" Source="DigitalData.Modules.Patterns.dll"/> <File Id="DDPatterns" Name="DigitalData.Modules.Patterns.dll" Source="DigitalData.Modules.Patterns.dll"/>
<File Id="DDEDMIAPI" Name="DigitalData.Modules.EDMI.API.dll" Source="DigitalData.Modules.EDMI.API.dll"/> <File Id="DDEDMIAPI" Name="DigitalData.Modules.EDMI.API.dll" Source="DigitalData.Modules.EDMI.API.dll"/>
<File Id="DDDocumentViewer" Name="DigitalData.Controls.DocumentViewer.dll" Source="DigitalData.Controls.DocumentViewer.dll"/> <File Id="DDDocumentViewer" Name="DigitalData.Controls.DocumentViewer.dll" Source="DigitalData.Controls.DocumentViewer.dll"/>
<File Id="DDLicenseManager" Name="DLLLicenseManager.dll" Source="DLLLicenseManager.dll" KeyPath="no" />
<File Id="Messaging" Name="DigitalData.Modules.Messaging.dll" Source="DigitalData.Modules.Messaging.dll" KeyPath="no" /> <File Id="Messaging" Name="DigitalData.Modules.Messaging.dll" Source="DigitalData.Modules.Messaging.dll" KeyPath="no" />
<File Id="Messaging.License" Name="MailLicense.xml" Source="MailLicense.xml" KeyPath="no" /> <File Id="Messaging.License" Name="MailLicense.xml" Source="MailLicense.xml" KeyPath="no" />
<File Id="Limilabs.Mail" Name="Mail.dll" Source="Mail.dll" KeyPath="no" /> <File Id="Limilabs.Mail" Name="Mail.dll" Source="Mail.dll" KeyPath="no" />

View File

@@ -45,7 +45,9 @@ Namespace ControlCreator
Private Class FormulaSqlDefinition Private Class FormulaSqlDefinition
Public Property SqlTemplate As String Public Property SqlTemplate As String
Public Property ReferencedColumns As List(Of String) Public Property ReferencedColumns As List(Of String)
Public Property ConnectionId As Integer
End Class End Class
''' <summary> ''' <summary>
''' Extrahiert alle {#TBCOL#ColumnName}-Platzhalter aus einem SQL-Template. ''' Extrahiert alle {#TBCOL#ColumnName}-Platzhalter aus einem SQL-Template.
''' </summary> ''' </summary>
@@ -218,6 +220,13 @@ Namespace ControlCreator
Dim oComboboxDataTable As DataTable = Nothing Dim oComboboxDataTable As DataTable = Nothing
Dim oColumnName As String = oRow.Item("SPALTENNAME") Dim oColumnName As String = oRow.Item("SPALTENNAME")
_Logger.Debug("Working on SQL for Column[{0}]...", oColumnName) _Logger.Debug("Working on SQL for Column[{0}]...", oColumnName)
' *** NEU: Platzhalter-Check ***
If ContainsTableColumnPlaceholder(oSqlCommand) Then
_Logger.Debug("...SQL contains #TBCOL# placeholders skipping static caching, will be resolved per row.")
Continue For ' Überspringen wird in CustomRowCellEdit behandelt
End If
If Not clsPatterns.HasComplexPatterns(oSqlCommand) Then If Not clsPatterns.HasComplexPatterns(oSqlCommand) Then
_Logger.Debug("SQL has no complex patterns!") _Logger.Debug("SQL has no complex patterns!")
'oComboboxDataTable = ClassDatabase.Return_Datatable_ConId(oSqlCommand, oConnectionId) 'oComboboxDataTable = ClassDatabase.Return_Datatable_ConId(oSqlCommand, oConnectionId)
@@ -562,6 +571,8 @@ Namespace ControlCreator
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
ElseIf oFormulaSql <> String.Empty Then
_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 ' Spalte ist eine Formel-Spalte (Expression ODER SQL) → nur DisplayFormat, kein ColumnEdit
@@ -669,10 +680,10 @@ Namespace ControlCreator
For Each r As DataRow In pColumnTable.Rows For Each r As DataRow In pColumnTable.Rows
Dim oColName = r.Item("SPALTENNAME").ToString() Dim oColName = r.Item("SPALTENNAME").ToString()
Dim oExpr = ObjectEx.NotNull(r.Item("FORMULA_EXPRESSION"), String.Empty).ToString() Dim oExpr = ObjectEx.NotNull(r.Item("FORMULA_EXPRESSION"), String.Empty).ToString()
Dim oSql = ObjectEx.NotNull(r.Item("FORMULA_SQL"), String.Empty).ToString() Dim oSql_FORMULA = ObjectEx.NotNull(r.Item("FORMULA_SQL"), String.Empty).ToString()
' *** VALIDIERUNG: Beides gleichzeitig ist nicht erlaubt *** ' *** VALIDIERUNG: Beides gleichzeitig ist nicht erlaubt ***
If oExpr <> String.Empty AndAlso oSql <> String.Empty Then If oExpr <> String.Empty AndAlso oSql_FORMULA <> String.Empty Then
_Logger.Warn("⚠️ Column [{0}] has BOTH FORMULA_EXPRESSION and FORMULA_SQL this is not allowed! FORMULA_SQL will be ignored.", oColName) _Logger.Warn("⚠️ Column [{0}] has BOTH FORMULA_EXPRESSION and FORMULA_SQL this is not allowed! FORMULA_SQL will be ignored.", oColName)
MsgBox(String.Format( MsgBox(String.Format(
"Die Spalte '{0}' enthält sowohl eine FORMULA_EXPRESSION als auch eine FORMULA_SQL." & vbCrLf & "Die Spalte '{0}' enthält sowohl eine FORMULA_EXPRESSION als auch eine FORMULA_SQL." & vbCrLf &
@@ -680,22 +691,23 @@ Namespace ControlCreator
"FORMULA_SQL wird ignoriert. Bitte korrigieren Sie die Konfiguration im Tabellen-Designer.", "FORMULA_SQL wird ignoriert. Bitte korrigieren Sie die Konfiguration im Tabellen-Designer.",
oColName), MsgBoxStyle.Exclamation, "Ungültige Spalten-Konfiguration") oColName), MsgBoxStyle.Exclamation, "Ungültige Spalten-Konfiguration")
' FORMULA_EXPRESSION hat Vorrang → SQL ignorieren ' FORMULA_EXPRESSION hat Vorrang → SQL ignorieren
oSql = String.Empty oSql_FORMULA = String.Empty
End If End If
If oExpr <> String.Empty Then If oExpr <> String.Empty Then
_FormulaColumnNames.Add(oColName) _FormulaColumnNames.Add(oColName)
_Logger.Debug("[ConfigureViewEvents] Column [{0}] registered as FORMULA_EXPRESSION column.", oColName) _Logger.Debug("[ConfigureViewEvents] Column [{0}] registered as FORMULA_EXPRESSION column.", oColName)
ElseIf oSql <> String.Empty Then ElseIf oSql_FORMULA <> String.Empty Then
Dim oConnectionId As Integer = r.ItemEx("CONNECTION_ID", 0) Dim oConnectionId As Integer = r.ItemEx("CONNECTION_ID", 0)
_FormulaSqlColumns(oColName) = New FormulaSqlDefinition() With { _FormulaSqlColumns(oColName) = New FormulaSqlDefinition() With {
.SqlTemplate = oSql, .SqlTemplate = oSql_FORMULA,
.ReferencedColumns = GetReferencedSqlColumnNames(oSql) .ReferencedColumns = GetReferencedSqlColumnNames(oSql_FORMULA),
.ConnectionId = oConnectionId ' *** Hier speichern ***
} }
' SQL-Spalten auch in _FormulaColumnNames aufnehmen → Editor-Blockade + ReadOnly ' SQL-Spalten auch in _FormulaColumnNames aufnehmen → Editor-Blockade + ReadOnly
_FormulaColumnNames.Add(oColName) _FormulaColumnNames.Add(oColName)
_Logger.Debug("[ConfigureViewEvents] Column [{0}] registered as FORMULA_SQL column. ReferencedColumns=[{1}]", _Logger.Debug("[ConfigureViewEvents] Column [{0}] registered as FORMULA_SQL column. ReferencedColumns=[{1}]",
oColName, String.Join(", ", GetReferencedSqlColumnNames(oSql))) oColName, String.Join(", ", GetReferencedSqlColumnNames(oSql_FORMULA)))
End If End If
Next Next
@@ -797,6 +809,8 @@ Namespace ControlCreator
For Each oRow As DataRow In pColumnTable.Rows For Each oRow As DataRow In pColumnTable.Rows
Dim oColumnName As String = oRow.Item("SPALTENNAME").ToString() Dim oColumnName As String = oRow.Item("SPALTENNAME").ToString()
If oColumnName <> e.Column.FieldName Then Continue For If oColumnName <> e.Column.FieldName Then Continue For
Dim oSqlCommand As String = oRow.ItemEx("SQL_COMMAND", "")
Dim oConnectionId As Integer = oRow.ItemEx("CONNECTION_ID", 1)
Dim oEditorExists = GridTables_TestEditorExistsByControlAndColumn(pControlId, oColumnName) Dim oEditorExists = GridTables_TestEditorExistsByControlAndColumn(pControlId, oColumnName)
@@ -965,7 +979,7 @@ Namespace ControlCreator
_Logger.Debug("Showing editor.") _Logger.Debug("Showing editor.")
' Formel-Spalten dürfen keinen Editor öffnen (gilt für EXPRESSION UND SQL) ' Formel-Spalten dürfen keinen Editor öffnen
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
@@ -975,6 +989,48 @@ Namespace ControlCreator
End If End If
End If End If
' *** NEU: Row-specific Editor für #TBCOL# Platzhalter ***
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)
' 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
' Editor temporär zur Spalte hinzufügen
oView.FocusedColumn.ColumnEdit = oRowSpecificEditor
_Logger.Debug("[ShowingEditor] Row-specific editor assigned 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()
@@ -1054,6 +1110,8 @@ Namespace ControlCreator
_Logger.Debug("[FormulaRefresh] FALLBACK DisplayText for [{0}]: [{1}]", _Logger.Debug("[FormulaRefresh] FALLBACK DisplayText for [{0}]: [{1}]",
oFormulaColumnName, oView.GetRowCellDisplayText(oRowHandle, oGridColumn)) oFormulaColumnName, oView.GetRowCellDisplayText(oRowHandle, oGridColumn))
Next Next
' Dies fängt den Fall ab, dass eine SQL-Spalte eine Expression-Spalte referenziert
TriggerSqlFormulasAfterExpressionUpdate(oView, oRowHandle, oFormulaColumnsToRefresh)
Catch ex As Exception Catch ex As Exception
_Logger.Error(ex) _Logger.Error(ex)
End Try End Try
@@ -1146,6 +1204,224 @@ Namespace ControlCreator
End Try End Try
End Sub End Sub
End Sub End Sub
''' <summary>
''' Prüft, ob ein SQL-Command Tabellen-Spalten-Platzhalter ({#TBCOL#...}) enthält.
''' </summary>
Private Function ContainsTableColumnPlaceholder(sqlCommand As String) As Boolean
If String.IsNullOrWhiteSpace(sqlCommand) Then Return False
Return sqlCommand.IndexOf("{#TBCOL#", StringComparison.OrdinalIgnoreCase) >= 0
End Function
''' <summary>
''' Erstellt einen zeilenspezifischen Editor (Combobox/Lookup) basierend auf aufgelöstem SQL.
''' Wird verwendet, wenn SQL_COMMAND Platzhalter wie {#TBCOL#...} enthält.
''' </summary>
Private Function CreateRowSpecificEditor(
columnName As String,
resolvedSql As String,
connectionId As Integer,
isAdvancedLookup As Boolean) As RepositoryItem
Try
_Logger.Debug("[CreateRowSpecificEditor] Executing SQL for column [{0}]: {1}", columnName, resolvedSql)
' SQL ausführen
Dim oDataTable As DataTable = DatabaseFallback.GetDatatable(
New GetDatatableOptions(resolvedSql, DatabaseType.ECM) With {
.ConnectionId = connectionId
})
If oDataTable Is Nothing OrElse oDataTable.Rows.Count = 0 Then
_Logger.Warn("[CreateRowSpecificEditor] No data returned for column [{0}]", columnName)
Return Nothing
End If
_Logger.Debug("[CreateRowSpecificEditor] Retrieved {0} rows for column [{1}]", oDataTable.Rows.Count, columnName)
' Editor erstellen (analog zu GridTables_GetRepositoryItemForColumn)
If isAdvancedLookup Then
Dim oEditor = New RepositoryItemLookupControl3 With {
.DisplayMember = oDataTable.Columns(0).ColumnName,
.ValueMember = oDataTable.Columns(0).ColumnName,
.DataSource = oDataTable
}
Return oEditor
Else
Dim oEditor = New RepositoryItemComboBox()
Dim oItems As New List(Of String)
AddHandler oEditor.Validating,
Sub(_sender As ComboBoxEdit, _e As CancelEventArgs)
If oItems.Contains(_sender.EditValue) Then
_e.Cancel = False
Else
_e.Cancel = True
End If
End Sub
For Each oRow2 As DataRow In oDataTable.Rows
Dim oValue = oRow2.Item(0).ToString()
Try
If oRow2.ItemArray.Length > 1 Then
oValue &= $" | {oRow2.Item(1)}"
End If
Catch ex As Exception
End Try
oEditor.Items.Add(oValue)
oItems.Add(oValue)
Next
Return oEditor
End If
Catch ex As Exception
_Logger.Error("[CreateRowSpecificEditor] Failed to create editor for column [{0}]: {1}", columnName, ex.Message)
_Logger.Error(ex)
Return Nothing
End Try
End Function
''' <summary>
''' Triggert SQL-Formeln, die Expression-Spalten referenzieren (z.B. Gesamt referenziert Brutto).
''' Wird aufgerufen NACHDEM Expression-Spalten aktualisiert wurden.
''' </summary>
Private Sub TriggerSqlFormulasAfterExpressionUpdate(
pView As GridView,
pColumnTable As DataTable,
pRowHandle As Integer,
pUpdatedExpressionColumns As List(Of String))
If pUpdatedExpressionColumns.Count = 0 Then Return
' Finde alle SQL-Formeln, die eine der aktualisierten Expression-Spalten referenzieren
Dim oSqlColumnsToRefresh As New List(Of String)
For Each kvp In _FormulaSqlColumns
For Each updatedExprCol In pUpdatedExpressionColumns
If kvp.Value.ReferencedColumns.Any(
Function(col) String.Equals(col, updatedExprCol, StringComparison.OrdinalIgnoreCase)) Then
If Not oSqlColumnsToRefresh.Contains(kvp.Key) Then
oSqlColumnsToRefresh.Add(kvp.Key)
End If
Exit For
End If
Next
Next
If oSqlColumnsToRefresh.Count > 0 Then
_Logger.Debug("[FormulaSql] Expression columns [{0}] trigger SQL refresh for: [{1}]",
String.Join(", ", pUpdatedExpressionColumns),
String.Join(", ", oSqlColumnsToRefresh))
ExecuteSqlFormulas(pView, pRowHandle, oSqlColumnsToRefresh)
End If
End Sub
''' <summary>
''' Führt SQL-Formeln aus und aktualisiert die Zellwerte.
''' Ausgelagert in separate Methode, um Code-Duplikation zu vermeiden.
''' </summary>
Private Sub ExecuteSqlFormulas(
pView As GridView,
pRowHandle As Integer,
pSqlColumnsToRefresh As List(Of String))
pView.GridControl.BeginInvoke(New Action(
Sub()
Try
If Not pView.IsValidRowHandle(pRowHandle) Then Return
For Each oSqlColumnName As String In pSqlColumnsToRefresh
Dim oDefinition = _FormulaSqlColumns(oSqlColumnName)
' Prüfen ob ALLE referenzierten Spalten einen Wert haben
Dim allValuesPresent As Boolean = True
For Each refCol In oDefinition.ReferencedColumns
Dim cellVal = pView.GetRowCellValue(pRowHandle, refCol)
If cellVal Is Nothing OrElse IsDBNull(cellVal) Then
_Logger.Debug("[FormulaSql] Column [{0}] has NULL value skipping SQL for [{1}]", refCol, oSqlColumnName)
allValuesPresent = False
Exit For
End If
Next
If Not allValuesPresent Then Continue For
' Pattern ersetzen und SQL ausführen
Dim resolvedSql = ResolveSqlTemplate(oDefinition.SqlTemplate, pView, pRowHandle)
_Logger.Debug("[FormulaSql] Executing SQL for [{0}]: [{1}]", oSqlColumnName, resolvedSql)
Try
' *** VEREINFACHT: ConnectionId direkt aus Definition ***
Dim oConnectionId As Integer = oDefinition.ConnectionId
_Logger.Debug("[FormulaSql] Using ConnectionId [{0}] for column [{1}]", oConnectionId, oSqlColumnName)
Dim oResultTable As DataTable = DatabaseFallback.GetDatatable(
New GetDatatableOptions(resolvedSql, DatabaseType.ECM) With {
.ConnectionId = oConnectionId
})
If oResultTable IsNot Nothing AndAlso oResultTable.Rows.Count > 0 Then
Dim oResult = oResultTable.Rows(0).Item(0)
_Logger.Debug("[FormulaSql] Result for [{0}]: [{1}]", oSqlColumnName, oResult)
_isRefreshingFormula = True
Try
pView.SetRowCellValue(pRowHandle, oSqlColumnName,
If(oResult Is Nothing OrElse IsDBNull(oResult), DBNull.Value, oResult))
pView.RefreshRowCell(pRowHandle, pView.Columns.ColumnByFieldName(oSqlColumnName))
Finally
_isRefreshingFormula = False
End Try
Else
_Logger.Warn("[FormulaSql] No result returned for [{0}]", oSqlColumnName)
End If
Catch sqlEx As Exception
_Logger.Warn("⚠️ [FormulaSql] SQL execution failed for [{0}]: {1}", oSqlColumnName, sqlEx.Message)
_Logger.Error(sqlEx)
End Try
Next
Catch ex As Exception
_Logger.Error(ex)
End Try
End Sub))
End Sub
''' <summary>
''' Triggert SQL-Formeln, die Expression-Spalten referenzieren (z.B. Gesamt referenziert Brutto).
''' Wird aufgerufen NACHDEM Expression-Spalten aktualisiert wurden.
''' </summary>
Private Sub TriggerSqlFormulasAfterExpressionUpdate(
pView As GridView,
pRowHandle As Integer,
pUpdatedExpressionColumns As List(Of String))
If pUpdatedExpressionColumns.Count = 0 Then Return
' Finde alle SQL-Formeln, die eine der aktualisierten Expression-Spalten referenzieren
Dim oSqlColumnsToRefresh As New List(Of String)
For Each kvp In _FormulaSqlColumns
For Each updatedExprCol In pUpdatedExpressionColumns
If kvp.Value.ReferencedColumns.Any(
Function(col) String.Equals(col, updatedExprCol, StringComparison.OrdinalIgnoreCase)) Then
If Not oSqlColumnsToRefresh.Contains(kvp.Key) Then
oSqlColumnsToRefresh.Add(kvp.Key)
End If
Exit For
End If
Next
Next
If oSqlColumnsToRefresh.Count > 0 Then
_Logger.Debug("[FormulaSql] Expression columns [{0}] trigger SQL refresh for: [{1}]",
String.Join(", ", pUpdatedExpressionColumns),
String.Join(", ", oSqlColumnsToRefresh))
' *** pColumnTable nicht mehr nötig ***
ExecuteSqlFormulas(pView, pRowHandle, oSqlColumnsToRefresh)
End If
End Sub
Private Sub HandleInheritedColumnValue(pView As GridView, pColumnDefinition As DataTable, pArgs As CellValueChangedEventArgs) Private Sub HandleInheritedColumnValue(pView As GridView, pColumnDefinition As DataTable, pArgs As CellValueChangedEventArgs)
If pView Is Nothing OrElse pArgs Is Nothing OrElse pArgs.Column Is Nothing Then If pView Is Nothing OrElse pArgs Is Nothing OrElse pArgs.Column Is Nothing Then
Return Return

View File

@@ -5778,7 +5778,8 @@ Public Class frmValidator
Dim oAdvancedLookup = oRow.Item("ADVANCED_LOOKUP") Dim oAdvancedLookup = oRow.Item("ADVANCED_LOOKUP")
oSqlCommand = clsPatterns.ReplaceAllValues(oSqlCommand, PanelValidatorControl, True) oSqlCommand = clsPatterns.ReplaceAllValues(oSqlCommand, PanelValidatorControl, True)
' Prüfen ob Platzhalter enthalten sind
If Not ContainsTableColumnPlaceholder(oSqlCommand?.ToString()) Then
Try Try
Dim oDTRESULT_FOR_COLUMN As DataTable = GetCachedDatatable(oSqlCommand, oCONNID) Dim oDTRESULT_FOR_COLUMN As DataTable = GetCachedDatatable(oSqlCommand, oCONNID)
@@ -5798,6 +5799,9 @@ Public Class frmValidator
Catch ex As Exception 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($"⚠️ FillIndexValues - Unexpected error in creating Grid-Dropdown-Column [{oDEPENDING_COLUMN}] for CONTROL-ID [{oDEPENDING_CTRL_ID}]: " & ex.Message)
End Try End Try
Else
MyValidationLogger.Debug($"⚠️ FillIndexValues - SQL-Command for Grid-Dropdown-Column contains #CTRL# placeholder, skipping dropdown creation for CONTROL-ID [{oDEPENDING_CTRL_ID}] - Column [{oDEPENDING_COLUMN}]")
End If
Next Next
Catch ex As Exception Catch ex As Exception
MyValidationLogger.Warn($"⚠️ FillIndexValues - Unexpected error in creating dropdown for Grid: " & ex.Message) MyValidationLogger.Warn($"⚠️ FillIndexValues - Unexpected error in creating dropdown for Grid: " & ex.Message)
@@ -5935,7 +5939,19 @@ Public Class frmValidator
End If End If
End Try End Try
End Sub End Sub
''' <summary>
''' Prüft, ob ein SQL-Command Grid-Spalten-Platzhalter enthält
''' </summary>
''' <param name="sqlCommand">Der zu prüfende SQL-Command</param>
''' <returns>True wenn Platzhalter enthalten sind, sonst False</returns>
Private Function ContainsTableColumnPlaceholder(sqlCommand As String) As Boolean
If String.IsNullOrWhiteSpace(sqlCommand) Then
Return False
End If
' Prüft auf #TBCOL# Platzhalter (case-insensitive)
Return sqlCommand.IndexOf("#TBCOL#", StringComparison.OrdinalIgnoreCase) >= 0
End Function
Private Sub ApplyCurrencyMask(pTextEdit As TextEdit) Private Sub ApplyCurrencyMask(pTextEdit As TextEdit)
If pTextEdit Is Nothing Then Return If pTextEdit Is Nothing Then Return
Try Try

File diff suppressed because it is too large Load Diff