Vor Controls2B_EnDisabled Change

This commit is contained in:
Developer01
2026-03-11 16:43:34 +01:00
parent 7629d54fe1
commit 969e07eb17
2 changed files with 119 additions and 39 deletions

View File

@@ -39,46 +39,85 @@ Public Class ClassFormat
Dim normalized As String = pValue.Trim()
LOGGER.Debug($"[NormalizeNumericString] Input: [{pValue}]")
' Entferne Währungssymbole und Leerzeichen
normalized = System.Text.RegularExpressions.Regex.Replace(normalized, "[€$£¥\s]", "")
' Prüfe, ob der String sowohl Punkt als auch Komma enthält
Dim hasDot As Boolean = normalized.Contains(".")
Dim hasComma As Boolean = normalized.Contains(",")
LOGGER.Debug($"[NormalizeNumericString] After cleanup: [{normalized}], HasDot={hasDot}, HasComma={hasComma}")
If hasDot AndAlso hasComma Then
' Beide vorhanden: Das letzte ist der Dezimaltrenner
Dim lastDotPos As Integer = normalized.LastIndexOf(".")
Dim lastCommaPos As Integer = normalized.LastIndexOf(",")
LOGGER.Debug($"[NormalizeNumericString] Both separators found: LastDotPos={lastDotPos}, LastCommaPos={lastCommaPos}")
If lastDotPos > lastCommaPos Then
' Punkt ist Dezimaltrenner, Komma ist Tausendertrenner
normalized = normalized.Replace(",", "")
Else
' Komma ist Dezimaltrenner, Punkt ist Tausendertrenner
normalized = normalized.Replace(".", "").Replace(",", ".")
End If
ElseIf hasComma Then
' Nur Komma: Könnte Dezimal- oder Tausendertrenner sein
' Wenn mehr als ein Komma → Tausendertrenner
' Wenn nur ein Komma und <= 3 Stellen danach → Dezimaltrenner
Dim commaCount As Integer = normalized.Count(Function(c) c = ","c)
LOGGER.Debug($"[NormalizeNumericString] Only comma found: CommaCount={commaCount}")
If commaCount = 1 Then
Dim lastCommaPos As Integer = normalized.LastIndexOf(",")
Dim digitsAfterComma As Integer = normalized.Length - lastCommaPos - 1
LOGGER.Debug($"[NormalizeNumericString] Single comma: DigitsAfterComma={digitsAfterComma}")
If digitsAfterComma <= 3 Then
' Wahrscheinlich Dezimaltrenner
normalized = normalized.Replace(",", ".")
Else
' Wahrscheinlich Tausendertrenner
normalized = normalized.Replace(",", "")
End If
Else
' Mehrere Kommas → Tausendertrenner
normalized = normalized.Replace(",", "")
End If
ElseIf hasDot Then
Dim dotCount As Integer = normalized.Count(Function(c) c = "."c)
LOGGER.Debug($"[NormalizeNumericString] Only dot found: DotCount={dotCount}")
If dotCount = 1 Then
Dim lastDotPos As Integer = normalized.LastIndexOf(".")
Dim digitsAfterDot As Integer = normalized.Length - lastDotPos - 1
LOGGER.Debug($"[NormalizeNumericString] Single dot: DigitsAfterDot={digitsAfterDot}")
' ✅ KRITISCHE ÄNDERUNG: Prüfe auch Stellen VOR dem Punkt
Dim digitsBeforeDot As Integer = lastDotPos
' Heuristik: Wenn <= 3 Stellen nach Punkt UND >= 1 Stelle davor → Dezimaltrenner
' Wenn > 3 Stellen davor UND <= 3 Stellen nach Punkt → unklar, vermutlich Dezimal
' Wenn > 3 Stellen nach Punkt → definitiv KEIN Dezimaltrenner
If digitsAfterDot > 3 Then
LOGGER.Warn($"⚠️ [NormalizeNumericString] Dot with {digitsAfterDot} digits after → treating as THOUSAND separator!")
normalized = normalized.Replace(".", "")
ElseIf digitsAfterDot >= 1 AndAlso digitsAfterDot <= 3 Then
' Wahrscheinlich Dezimaltrenner (z.B. 5464.17 oder 120.5)
LOGGER.Debug($"[NormalizeNumericString] Dot treated as decimal separator ({digitsBeforeDot} digits before, {digitsAfterDot} after)")
Else
' digitsAfterDot = 0 → Punkt am Ende, vermutlich Fehler
LOGGER.Warn($"⚠️ [NormalizeNumericString] Dot at end of string → removing")
normalized = normalized.Replace(".", "")
End If
Else
' Mehrere Punkte → Tausendertrenner
LOGGER.Debug($"[NormalizeNumericString] Multiple dots → removing all")
normalized = normalized.Replace(".", "")
End If
Else
LOGGER.Debug($"[NormalizeNumericString] No separators found → integer or already normalized")
End If
' Wenn nur Punkt vorhanden: bereits im richtigen Format
LOGGER.Debug($"[NormalizeNumericString] Output: [{normalized}]")
Return normalized
End Function
@@ -96,6 +135,7 @@ Public Class ClassFormat
Select Case pType
Case ClassControlCreator.CONTROL_TYPE_DOUBLE
Try
' ✅ IMMER normalisieren auch für DB-Werte!
Dim normalizedValue As String = NormalizeNumericString(pValue?.ToString())
If Double.TryParse(normalizedValue, NumberStyles.Float, CultureInfo.InvariantCulture, oConvertedValue) Then
Return oConvertedValue
@@ -106,12 +146,15 @@ Public Class ClassFormat
Case ClassControlCreator.CONTROL_TYPE_CURRENCY
Try
' ✅ KRITISCH: Normalisierung VOR Konvertierung
Dim normalizedValue As String = NormalizeNumericString(pValue?.ToString())
LOGGER.Debug($"GetConvertedValue: Converting {pValue.ToString} (normalized: {normalizedValue}) to Currency ")
LOGGER.Debug($"GetConvertedValue CURRENCY: Original=[{pValue}], Normalized=[{normalizedValue}]")
If Double.TryParse(normalizedValue, NumberStyles.Float, CultureInfo.InvariantCulture, oConvertedValue) Then
Return oConvertedValue
End If
Catch ex As Exception
LOGGER.Error($"Currency conversion failed for [{pValue}]: {ex.Message}")
LOGGER.Error(ex)
End Try
@@ -124,6 +167,7 @@ Public Class ClassFormat
Catch ex As Exception
LOGGER.Error(ex)
End Try
Case Else
LOGGER.Debug($"GetConvertedValue - Case ELSE - pType is {pType}")
Try
@@ -132,7 +176,6 @@ Public Class ClassFormat
LOGGER.Warn($"Error in GetConvertedValue: pType is {pType} - converting value to String")
oConvertedValue = ""
End Try
End Select
Return oConvertedValue
@@ -140,26 +183,32 @@ Public Class ClassFormat
''' <summary>
''' Converts values to their respective data type and then back to string
''' according to the current culture
''' using INVARIANT culture for consistency across systems.
''' </summary>
''' <param name="pValue"></param>
''' <returns></returns>
Public Shared Function GetStringValue(pValue As Object) As String
' ✅ FIX: Immer InvariantCulture verwenden für DB-Speicherung
Select Case pValue.GetType
Case GetType(Single)
Return DirectCast(pValue, Single).ToString(CultureInfo.CurrentCulture)
' ✅ NEU: InvariantCulture statt CurrentCulture
Return DirectCast(pValue, Single).ToString(CultureInfo.InvariantCulture)
Case GetType(Double)
Return DirectCast(pValue, Double).ToString(CultureInfo.CurrentCulture)
' ✅ NEU: InvariantCulture statt CurrentCulture
Return DirectCast(pValue, Double).ToString(CultureInfo.InvariantCulture)
Case GetType(Decimal)
Return DirectCast(pValue, Decimal).ToString(CultureInfo.CurrentCulture)
' ✅ NEU: InvariantCulture statt CurrentCulture
Return DirectCast(pValue, Decimal).ToString(CultureInfo.InvariantCulture)
Case GetType(Date)
Return DirectCast(pValue, Date).ToString(CultureInfo.CurrentCulture)
' Datum: ISO 8601 Format für Culture-Unabhängigkeit
Return DirectCast(pValue, Date).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)
Case GetType(DateTime)
Return DirectCast(pValue, DateTime).ToString(CultureInfo.CurrentCulture)
' DateTime: ISO 8601 Format
Return DirectCast(pValue, DateTime).ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)
Case Else
Return pValue.ToString

View File

@@ -3779,12 +3779,15 @@ Public Class frmValidator
MyValidationLogger.Error(ex)
errormessage = "unexpected error in Load_Next_Document:" & ex.Message
My.Settings.Save()
MyValidationLogger.Info("unexpected error in Load_Next_Document: " & ex.Message)
frmError.ShowDialog()
Finally
If layoutSuspended Then
PanelValidatorControl.ResumeLayout()
End If
CloseOverlaySafe()
If LOG_HOTSPOTS Then
' ========== DIAGNOSE ENDE ==========
MyValidationLogger.Info($"[INFO] Load_Next_Document ENDE")
@@ -4533,33 +4536,61 @@ Public Class frmValidator
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
oNewRow.Item(index) = 0
' 1. Basis-Checks
Dim rawValue As String = If(index < oColValuesfromSource.Length, oColValuesfromSource(index), String.Empty)
Dim targetColumn As DataColumn = oDataSource.Columns(index)
Dim colType As Type = targetColumn.DataType
' 2. NULL-Handling
If String.IsNullOrWhiteSpace(rawValue) Then
If colType.IsValueType AndAlso Nullable.GetUnderlyingType(colType) Is Nothing Then
' Nicht-Nullable Value-Type → Default-Wert setzen
oNewRow.Item(index) = Activator.CreateInstance(colType)
MyValidationLogger.Debug($"Grid row default: ColIdx={index}, ColType={colType.Name}")
Else
oNewRow.Item(index) = String.Empty
' Nullable/Reference-Type → DBNull
oNewRow.Item(index) = DBNull.Value
End If
Continue For
End If
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)
' 3. Typ-spezifische Konvertierung
Try
MyValidationLogger.Debug("Column.AllowDBNull={0}, Column.MaxLength={1}", targetColumn.AllowDBNull, targetColumn.MaxLength)
Catch
Select Case Type.GetTypeCode(colType)
Case TypeCode.Int32
oNewRow.Item(index) = Integer.Parse(rawValue.Trim(), CultureInfo.InvariantCulture)
Case TypeCode.Int64
oNewRow.Item(index) = Long.Parse(rawValue.Trim(), CultureInfo.InvariantCulture)
Case TypeCode.Double
oNewRow.Item(index) = Double.Parse(rawValue.Trim().Replace(",", "."), CultureInfo.InvariantCulture)
Case TypeCode.Decimal
oNewRow.Item(index) = Decimal.Parse(rawValue.Trim().Replace(",", "."), CultureInfo.InvariantCulture)
Case TypeCode.Boolean
oNewRow.Item(index) = Boolean.Parse(rawValue.Trim())
Case TypeCode.DateTime
oNewRow.Item(index) = DateTime.Parse(rawValue.Trim(), CultureInfo.CurrentCulture)
Case Else
' String oder Custom-Type → direkt übernehmen
oNewRow.Item(index) = rawValue
End Select
Catch convEx As FormatException
MyValidationLogger.Warn($"⚠️ Grid conversion FAILED: ColIdx={index}, ColType={colType.Name}, RawValue=[{rawValue}] → using default")
' Fallback: Default-Wert statt Crash
If colType.IsValueType Then
oNewRow.Item(index) = Activator.CreateInstance(colType)
Else
oNewRow.Item(index) = DBNull.Value
End If
End Try
Throw
Catch logEx As Exception
' Fallback: Minimales Logging ohne Fehler
MyValidationLogger.Debug($"Grid row assign CRITICAL: ColIdx={index} [error: {logEx.Message}]")
' Leere Zelle → DBNull
oNewRow.Item(index) = DBNull.Value
End Try
Next
MyValidationLogger.Debug("Adding row To grid..")