Zu testen bei ewa

This commit is contained in:
Developer01
2026-03-18 15:31:59 +01:00
parent a50e7e3c55
commit 1469063ad7
7 changed files with 591 additions and 266 deletions

View File

@@ -274,11 +274,20 @@ Public Class ClassDocGrid
End If End If
End If End If
End Sub End Sub
Public Shared Sub FillColumns(pDocGridView As GridView, Public Shared Sub FillColumns(pDocGridView As GridView,
DT_RESULT As DataTable, DT_WINDREAM_RESULTLIST As DataTable, DT_DOCRESULT_DROPDOWN_ITEMS As DataTable, DT_RESULT As DataTable, DT_WINDREAM_RESULTLIST As DataTable, DT_DOCRESULT_DROPDOWN_ITEMS As DataTable,
DropdownValueChangedHandler As EventHandler, DatepickerValueChangedHandler As EventHandler, TextValueChangedHandler As EventHandler, CheckValueChangedHandler As EventHandler, DropdownValueChangedHandler As EventHandler, DatepickerValueChangedHandler As EventHandler, TextValueChangedHandler As EventHandler, CheckValueChangedHandler As EventHandler,
SearchType As String, RECORD_ID As Integer) SearchType As String, RECORD_ID As Integer)
' ── 1. KRITISCH: Event-Handler ENTFERNEN vor Neuregistrierung ───────────
RemoveHandler pDocGridView.MasterRowExpanded, AddressOf gridView_MasterRowExpanded
RemoveHandler pDocGridView.CustomColumnDisplayText, AddressOf gridView_CustomColumnDisplayText
RemoveHandler pDocGridView.FocusedRowChanged, AddressOf GVDoc_Values_FocusedRowChanged
' ── 2. DATE_COLUMNS Listen leeren (verhindert Duplikate) ────────────────
DATE_COLUMNS.Clear()
DATE_COLUMNS_CONFIG.Clear()
' Handler speichern ' Handler speichern
_dropdownValueChangedHandler = DropdownValueChangedHandler _dropdownValueChangedHandler = DropdownValueChangedHandler
_datepickerValueChangedHandler = DatepickerValueChangedHandler _datepickerValueChangedHandler = DatepickerValueChangedHandler
@@ -299,7 +308,6 @@ Public Class ClassDocGrid
Dim columnTitle As String = row.Item("HEADER_CAPTION") Dim columnTitle As String = row.Item("HEADER_CAPTION")
Dim type As Integer = row.Item("TYPE_ID") Dim type As Integer = row.Item("TYPE_ID")
If type = 3 And isConfig = False Then If type = 3 And isConfig = False Then
DATE_COLUMNS.Add(columnTitle) DATE_COLUMNS.Add(columnTitle)
ElseIf type = 3 And isConfig = True Then ElseIf type = 3 And isConfig = True Then
@@ -329,13 +337,13 @@ Public Class ClassDocGrid
DT_DETAIL_VALUES = ClassDataCache.GetOrLoad(cacheKey, Function() DT_DETAIL_VALUES = ClassDataCache.GetOrLoad(cacheKey, Function()
Dim sql = String.Format( Dim sql = String.Format(
"SELECT T.[GUID],T.[DocID],T.[CONFIG_ID],T1.HEADER_CAPTION,T.[VALUE],T1.[LANGUAGE], " & "SELECT T.[GUID],T.[DocID],T.[CONFIG_ID],T1.HEADER_CAPTION,T.[VALUE],T1.[LANGUAGE], " &
"T1.COLUMN_VIEW,T1.EDITABLE,T1.TYPE_ID,T1.VISIBLE,T.CHANGED_WHEN,T.CHANGED_WHO " & "T1.COLUMN_VIEW,T1.EDITABLE,T1.TYPE_ID,T1.VISIBLE,T.CHANGED_WHEN,T.CHANGED_WHO " &
"FROM TBPMO_DOC_VALUES T " & "FROM TBPMO_DOC_VALUES T " &
"INNER JOIN TBPMO_STRUCTURE_NODES_USER_TEMP TTEMP ON T.RECORD_ID = TTEMP.RECORD_ID " & "INNER JOIN TBPMO_STRUCTURE_NODES_USER_TEMP TTEMP ON T.RECORD_ID = TTEMP.RECORD_ID " &
"RIGHT JOIN TBPMO_DOCSEARCH_RESULTLIST_CONFIG T1 ON T.CONFIG_ID = T1.GUID " & "RIGHT JOIN TBPMO_DOCSEARCH_RESULTLIST_CONFIG T1 ON T.CONFIG_ID = T1.GUID " &
"WHERE T1.ENTITY_ID = {0} AND LANGUAGE = '{1}' AND T1.CONFIG_COLUMNS = 1", "WHERE T1.ENTITY_ID = {0} AND LANGUAGE = '{1}' AND T1.CONFIG_COLUMNS = 1",
CURRENT_ENTITY_ID, USER_LANGUAGE) CURRENT_ENTITY_ID, USER_LANGUAGE)
Return MYDB_ECM.GetDatatable(sql) Return MYDB_ECM.GetDatatable(sql)
End Function, TimeSpan.FromMinutes(2)) End Function, TimeSpan.FromMinutes(2))
@@ -344,12 +352,12 @@ Public Class ClassDocGrid
DT_DETAIL_VALUES = ClassDataCache.GetOrLoad(cacheKey, Function() DT_DETAIL_VALUES = ClassDataCache.GetOrLoad(cacheKey, Function()
Dim sql = String.Format( Dim sql = String.Format(
"SELECT T.[GUID],T.[DocID],T.[CONFIG_ID],T1.HEADER_CAPTION,T.[VALUE],T1.[LANGUAGE], " & "SELECT T.[GUID],T.[DocID],T.[CONFIG_ID],T1.HEADER_CAPTION,T.[VALUE],T1.[LANGUAGE], " &
"T1.COLUMN_VIEW,T1.EDITABLE,T1.TYPE_ID,T1.VISIBLE,T.CHANGED_WHEN,T.CHANGED_WHO " & "T1.COLUMN_VIEW,T1.EDITABLE,T1.TYPE_ID,T1.VISIBLE,T.CHANGED_WHEN,T.CHANGED_WHO " &
"FROM TBPMO_DOC_VALUES T " & "FROM TBPMO_DOC_VALUES T " &
"RIGHT JOIN TBPMO_DOCSEARCH_RESULTLIST_CONFIG T1 ON T.CONFIG_ID = T1.GUID " & "RIGHT JOIN TBPMO_DOCSEARCH_RESULTLIST_CONFIG T1 ON T.CONFIG_ID = T1.GUID " &
"WHERE T1.ENTITY_ID = {0} AND LANGUAGE = '{1}' AND T1.CONFIG_COLUMNS = 1 AND T.RECORD_ID = {2}", "WHERE T1.ENTITY_ID = {0} AND LANGUAGE = '{1}' AND T1.CONFIG_COLUMNS = 1 AND T.RECORD_ID = {2}",
CURRENT_ENTITY_ID, USER_LANGUAGE, RECORD_ID) CURRENT_ENTITY_ID, USER_LANGUAGE, RECORD_ID)
Return MYDB_ECM.GetDatatable(sql) Return MYDB_ECM.GetDatatable(sql)
End Function, TimeSpan.FromMinutes(2)) End Function, TimeSpan.FromMinutes(2))
End Select End Select
@@ -374,9 +382,6 @@ Public Class ClassDocGrid
If oFlteredRows.Length > 0 Then If oFlteredRows.Length > 0 Then
value = oFlteredRows(0)("VALUE").ToString() value = oFlteredRows(0)("VALUE").ToString()
End If End If
'value = MYDB_ECM.GetScalarValue(String.Format("SELECT VALUE FROM TBPMO_DOC_VALUES WHERE CONFIG_ID = {0} AND DocID = {1} AND RECORD_ID = {2}", oConfigID, oDocID, RECORD_ID))
Catch ex As Exception Catch ex As Exception
LOGGER.Warn(String.Format("Attention: Could not get Value from TBPMO_DOC_VALUES for ConfigId[{0}], DocId[{1}]: ", oConfigID, oDocID) & ex.Message) LOGGER.Warn(String.Format("Attention: Could not get Value from TBPMO_DOC_VALUES for ConfigId[{0}], DocId[{1}]: ", oConfigID, oDocID) & ex.Message)
End Try End Try
@@ -389,6 +394,7 @@ Public Class ClassDocGrid
LOGGER.Warn($"Attention: Could not load values from TBPMO_DOC_VALUES: " & ex.Message & vbNewLine & $"SELECT VALUE FROM TBPMO_DOC_VALUES WHERE CONFIG_ID = {oConfigID} AND DocID = {oDocID} AND RECORD_ID = {RECORD_ID}") LOGGER.Warn($"Attention: Could not load values from TBPMO_DOC_VALUES: " & ex.Message & vbNewLine & $"SELECT VALUE FROM TBPMO_DOC_VALUES WHERE CONFIG_ID = {oConfigID} AND DocID = {oDocID} AND RECORD_ID = {RECORD_ID}")
End Try End Try
LOGGER.Debug("Values loaded...") LOGGER.Debug("Values loaded...")
Try Try
' Tabellen zum DataSet hinzufügen ' Tabellen zum DataSet hinzufügen
ds.Tables.Add(DT_RESULT) ds.Tables.Add(DT_RESULT)
@@ -422,24 +428,26 @@ Public Class ClassDocGrid
Dim gridControl As GridControl = pDocGridView.GridControl Dim gridControl As GridControl = pDocGridView.GridControl
' ── 3. KRITISCH: Performance-optimiertes DataSource-Setzen ───────────
' ── Performance-optimiertes DataSource-Setzen ─────────────────────────
_isGridRefreshing = True ' Flag setzen VOR DataSource-Änderung _isGridRefreshing = True ' Flag setzen VOR DataSource-Änderung
Try Try
pDocGridView.BeginDataUpdate() ' Events unterdrücken pDocGridView.BeginDataUpdate() ' Events unterdrücken
pDocGridView.BeginUpdate() ' UI-Updates unterdrücken
' Datasource auf Master-Tabelle setzen ' Datasource auf Master-Tabelle setzen
gridControl.DataSource = ds.Tables(0) gridControl.DataSource = ds.Tables(0)
gridControl.ForceInitialize() gridControl.ForceInitialize()
pDocGridView.EndDataUpdate() ' Events reaktivieren pDocGridView.EndUpdate() ' UI-Updates reaktivieren
pDocGridView.EndDataUpdate() ' Events reaktivieren
Catch ex As Exception
LOGGER.Error($"Error setting DataSource: {ex.Message}")
Finally Finally
_isGridRefreshing = False ' Flag zurücksetzen ' Flag NICHT hier zurücksetzen - erst NACH allen Grid-Operationen!
End Try End Try
' Detail View anlegen und der Relation `docIdDetails` zuweisen ' Detail View anlegen und der Relation `docIdDetails` zuweisen
Dim GVDoc_Values As New GridView(gridControl) Dim GVDoc_Values As New GridView(gridControl)
'grvwDetail.OptionsBehavior.Editable = False
GVDoc_Values.OptionsView.ShowGroupPanel = False GVDoc_Values.OptionsView.ShowGroupPanel = False
GVDoc_Values.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.Style3D GVDoc_Values.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.Style3D
GVDoc_Values.OptionsView.EnableAppearanceEvenRow = True GVDoc_Values.OptionsView.EnableAppearanceEvenRow = True
@@ -447,18 +455,17 @@ Public Class ClassDocGrid
GVDoc_Values.Appearance.HeaderPanel.BackColor = Color.Orange GVDoc_Values.Appearance.HeaderPanel.BackColor = Color.Orange
GVDoc_Values.Appearance.HeaderPanel.Options.UseBackColor = True GVDoc_Values.Appearance.HeaderPanel.Options.UseBackColor = True
gridControl.LevelTree.Nodes.Add("docIdDetails", GVDoc_Values) gridControl.LevelTree.Nodes.Add("docIdDetails", GVDoc_Values)
Catch ex As Exception Catch ex As Exception
MsgBox("Error in FillColumns: " & vbNewLine & ex.Message, MsgBoxStyle.Critical) MsgBox("Error in FillColumns: " & vbNewLine & ex.Message, MsgBoxStyle.Critical)
LOGGER.Warn("Attention: Could not load converted datatable DocSearch: " & ex.Message) LOGGER.Warn("Attention: Could not load converted datatable DocSearch: " & ex.Message)
End Try End Try
' ── 4. KRITISCH: Handler NACH DataSource-Setzen registrieren ─────────────
AddHandler pDocGridView.MasterRowExpanded, AddressOf gridView_MasterRowExpanded AddHandler pDocGridView.MasterRowExpanded, AddressOf gridView_MasterRowExpanded
AddHandler pDocGridView.CustomColumnDisplayText, AddressOf gridView_CustomColumnDisplayText AddHandler pDocGridView.CustomColumnDisplayText, AddressOf gridView_CustomColumnDisplayText
AddHandler pDocGridView.FocusedRowChanged, AddressOf GVDoc_Values_FocusedRowChanged AddHandler pDocGridView.FocusedRowChanged, AddressOf GVDoc_Values_FocusedRowChanged
For Each row As DataRow In DT_WINDREAM_RESULTLIST.Rows For Each row As DataRow In DT_WINDREAM_RESULTLIST.Rows
Dim col As GridColumn = pDocGridView.Columns(row.Item("HEADER_CAPTION")) Dim col As GridColumn = pDocGridView.Columns(row.Item("HEADER_CAPTION"))
Dim colCaption = row.Item("HEADER_CAPTION") Dim colCaption = row.Item("HEADER_CAPTION")
@@ -501,18 +508,22 @@ Public Class ClassDocGrid
oChangedColumn.DisplayFormat.FormatString = CURRENT_DATE_FORMAT & " HH:MM:ss" oChangedColumn.DisplayFormat.FormatString = CURRENT_DATE_FORMAT & " HH:MM:ss"
End If End If
' ── 5. BestFitColumns mit gesetztem Flag ──────────────────────────────────
If GridDocResult_BestFitColumns Then If GridDocResult_BestFitColumns Then
_isGridRefreshing = True ' Auch hier Events unterdrücken ' _isGridRefreshing ist bereits True
Try Try
pDocGridView.BeginUpdate() pDocGridView.BeginUpdate()
pDocGridView.OptionsView.BestFitMaxRowCount = -1 pDocGridView.OptionsView.BestFitMaxRowCount = -1
pDocGridView.BestFitColumns(True) pDocGridView.BestFitColumns(True)
pDocGridView.EndUpdate() pDocGridView.EndUpdate()
Finally Catch ex As Exception
_isGridRefreshing = False LOGGER.Error($"Error in BestFitColumns: {ex.Message}")
End Try End Try
End If End If
' ── 6. KRITISCH: Flag ERST JETZT zurücksetzen! ────────────────────────────
_isGridRefreshing = False
' Alle Spalten aus ReadOnly setzen, danach werden alle passenden auf nicht ReadOnly gesetzt ' Alle Spalten aus ReadOnly setzen, danach werden alle passenden auf nicht ReadOnly gesetzt
For Each column As GridColumn In pDocGridView.Columns For Each column As GridColumn In pDocGridView.Columns
column.OptionsColumn.AllowEdit = False column.OptionsColumn.AllowEdit = False
@@ -623,69 +634,54 @@ Public Class ClassDocGrid
End If End If
Dim fieldName As String = e.Column.FieldName Dim fieldName As String = e.Column.FieldName
Dim valueString As String = e.Value.ToString()
' ── WICHTIG: Verhindere rekursive Aufrufe ────────────────────────────
' Wenn DisplayText bereits korrekt ist, nichts ändern
If e.DisplayText = valueString Then Return
Dim parsedDate As DateTime Dim parsedDate As DateTime
' ── Datumskonvertierung für Standard-Datumsspalten ─────────────────── ' ── Datumskonvertierung für Standard-Datumsspalten ───────────────────
If DATE_COLUMNS IsNot Nothing AndAlso DATE_COLUMNS.Contains(fieldName) Then If DATE_COLUMNS IsNot Nothing AndAlso DATE_COLUMNS.Contains(fieldName) Then
' Nur bei Verbose-Logging loggen
If EnableVerboseGridLogging Then
LOGGER.Debug($"gridView_CustomColumnDisplayText [Standard] [{fieldName}]")
End If
Try Try
' Versuche direktes Parsen If DateTime.TryParse(valueString, parsedDate) Then
If DateTime.TryParse(e.Value.ToString(), parsedDate) Then Dim formattedDate As String = parsedDate.ToString(CURRENT_DATE_FORMAT & " HH:mm:ss")
e.DisplayText = parsedDate.ToString(CURRENT_DATE_FORMAT & " HH:mm:ss") ' Nur setzen wenn unterschiedlich
Else If e.DisplayText <> formattedDate Then
' Fallback: ParseExact e.DisplayText = formattedDate
parsedDate = DateTime.ParseExact(e.Value.ToString(), End If
CURRENT_DATE_FORMAT & " HH:mm:ss",
System.Globalization.DateTimeFormatInfo.InvariantInfo)
e.DisplayText = parsedDate.ToString(CURRENT_DATE_FORMAT & " HH:mm:ss")
End If End If
Catch ex As FormatException Catch ex As FormatException
' Bei Parsing-Fehler Original-Wert anzeigen ' Bei Fehler Original-Wert belassen (NICHT setzen!)
e.DisplayText = e.Value.ToString()
If EnableVerboseGridLogging Then If EnableVerboseGridLogging Then
LOGGER.Debug($"Date parsing failed for [{fieldName}]: {e.Value}") LOGGER.Debug($"Date parsing failed for [{fieldName}]: {valueString}")
End If End If
End Try End Try
Return
Return ' Früher Exit - keine weitere Prüfung nötig
End If End If
' ── Datumskonvertierung für Config-Datumsspalten ────────────────────── ' ── Datumskonvertierung für Config-Datumsspalten ──────────────────────
If DATE_COLUMNS_CONFIG IsNot Nothing AndAlso DATE_COLUMNS_CONFIG.Contains(fieldName) Then If DATE_COLUMNS_CONFIG IsNot Nothing AndAlso DATE_COLUMNS_CONFIG.Contains(fieldName) Then
' Nur bei Verbose-Logging loggen
If EnableVerboseGridLogging Then
LOGGER.Debug($"gridView_CustomColumnDisplayText [Config] [{fieldName}]")
End If
Try Try
' Versuche direktes Parsen If DateTime.TryParse(valueString, parsedDate) Then
If DateTime.TryParse(e.Value.ToString(), parsedDate) Then Dim formattedDate As String = parsedDate.ToString(CURRENT_DATE_FORMAT)
e.DisplayText = parsedDate.ToString(CURRENT_DATE_FORMAT) ' Nur setzen wenn unterschiedlich
Else If e.DisplayText <> formattedDate Then
' Fallback: ParseExact e.DisplayText = formattedDate
parsedDate = DateTime.ParseExact(e.Value.ToString(), End If
CURRENT_DATE_FORMAT,
System.Globalization.DateTimeFormatInfo.InvariantInfo)
e.DisplayText = parsedDate.ToString(CURRENT_DATE_FORMAT)
End If End If
Catch ex As FormatException Catch ex As FormatException
' Bei Parsing-Fehler Original-Wert anzeigen ' Bei Fehler Original-Wert belassen
e.DisplayText = e.Value.ToString()
If EnableVerboseGridLogging Then If EnableVerboseGridLogging Then
LOGGER.Debug($"Date parsing failed for [{fieldName}]: {e.Value}") LOGGER.Debug($"Date parsing failed for [{fieldName}]: {valueString}")
End If End If
End Try End Try
End If End If
Catch ex As Exception Catch ex As Exception
' Fehler IMMER loggen (aber nicht Debug)
LOGGER.Error($"gridView_CustomColumnDisplayText Error [{e.Column?.FieldName}]: {ex.Message}") LOGGER.Error($"gridView_CustomColumnDisplayText Error [{e.Column?.FieldName}]: {ex.Message}")
End Try End Try
End Sub End Sub
Public Shared Sub GVDoc_Values_FocusedRowChanged(sender As GridView, e As DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs) Public Shared Sub GVDoc_Values_FocusedRowChanged(sender As GridView, e As DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs)
Try Try

View File

@@ -301,68 +301,7 @@ Public Class ClassHelper
End Try End Try
End Try End Try
End Sub End Sub
'Private Shared Sub BWFileHandler_DoWork()
' Try
' Dim oOverrideRunPath As String = ""
' Dim oExtension = Path.GetExtension(BW_DocPath).ToLower
' For Each oROW As DataRow In CURRENT_TBFILE_EXTENSION_OVERRIDE.Rows
' If oExtension.Replace(".", "") = oROW.Item("FILE_EXTENSION") Then
' LOGGER.Debug($"Specific fileextension override for extension [{oExtension}] found! ")
' oOverrideRunPath = oROW.Item("PROCESS")
' End If
' Next
' Dim oMyProcess = New Process()
' Dim oSql
' Try
' '######
' Dim startInfo As New ProcessStartInfo()
' If oOverrideRunPath <> "" Then
' startInfo.FileName = oOverrideRunPath
' startInfo.Arguments = """" & BW_DocPath & """"
' startInfo.UseShellExecute = True
' startInfo.RedirectStandardOutput = False
' Else
' startInfo.FileName = BW_DocPath
' startInfo.UseShellExecute = True
' startInfo.RedirectStandardOutput = False
' End If
' '#####
' oMyProcess.Start(startInfo)
' Dim myViewerProcessID = oMyProcess.Id
' oMyProcess.WaitForExit()
' oExtension = Path.GetExtension(BW_DocPath).ToLower
' LOGGER.Debug($"Checking oExtension [{oExtension}]...")
' If FILE_FORMATS_CHANGE_DURING_EDIT.Contains(oExtension) Then
' oSql = $"SELECT * FROM VWOF_DOCID_HANDLE WHERE dwParentID = {BW_ParentID} and [Filename] = '{BW_Filename}'"
' Dim oDTNEWDoc As DataTable = MYDB_ECM.GetDatatable(oSql)
' If Not IsNothing(oDTNEWDoc) Then
' If oDTNEWDoc.Rows.Count = 1 Then
' Dim oInsert = $"INSERT INTO TBPMO_DOC_ID_CHANGED (USER_ID,PROCESS_ID,VERSION_ID,OLD_DOC_ID,NEW_DOC_ID, DOC_PATH) VALUES (
' {USER_GUID},'{myViewerProcessID.ToString}',{oDTNEWDoc.Rows(0).Item("dwVersionID")},{BW_DocID},{oDTNEWDoc.Rows(0).Item("NewDocID")}, '{BW_DocPath}')"
' MYDB_ECM.ExecuteNonQuery(oInsert)
' End If
' End If
' End If
' Catch ex As Exception
' LOGGER.Warn("Error in Process1.Start(): " & ex.Message & vBCrlf & " - Path: " & BW_DocPath & " - DocID: " & BW_DocID)
' MsgBox("Error in OpenFile: " & ex.Message & vBCrlf & " - Path: " & BW_DocPath & " - DocID: " & BW_DocID, MsgBoxStyle.Exclamation)
' Exit Sub
' End Try
' Catch ex As Exception
' LOGGER.Warn("Error in Process.Start(): " & ex.Message & vBCrlf & " - Path: " & BW_DocPath & " - DocID: " & BW_DocID)
' Try
' Process.Start(BW_DocPath)
' Catch ex1 As Exception
' LOGGER.Warn("Error in Process.Start(1): " & ex1.Message & vBCrlf & " - Path: " & BW_DocPath & " - DocID: " & BW_DocID)
' End Try
' End Try
'End Sub
Private Shared Sub FOLDER_OPEN(PATH As Object, DocID As String) Private Shared Sub FOLDER_OPEN(PATH As Object, DocID As String)
Try Try
If PATH <> Nothing Then If PATH <> Nothing Then
@@ -461,12 +400,35 @@ Public Class ClassHelper
End Function End Function
Public Shared Sub REMOVE_OLD_DROP_FILES() Public Shared Sub REMOVE_OLD_DROP_FILES()
Try Try
' ✅ NEU: Pre-Check - welche Dateien sind betroffen?
Dim preCheckSQL = $"SELECT GUID, FILENAME_ONLY, ADDED_WHEN, DATEDIFF(MINUTE, ADDED_WHEN, GETDATE()) AS AGE_MINUTES " &
$"FROM TBPMO_FILES_USER " &
$"WHERE ADDED_WHEN < DATEADD(MINUTE, -15, GETDATE()) " &
$"AND WORKED = 0 AND USER_WORK = '{USER_USERNAME}'"
Dim preCheckDT = MYDB_ECM.GetDatatable(preCheckSQL)
If preCheckDT IsNot Nothing AndAlso preCheckDT.Rows.Count > 0 Then
LOGGER.Warn($"REMOVE_OLD_DROP_FILES: {preCheckDT.Rows.Count} Dateien werden als TIMEOUT markiert:")
For Each row As DataRow In preCheckDT.Rows
LOGGER.Warn($" - GUID={row("GUID")}, Datei={row("FILENAME_ONLY")}, Alter={row("AGE_MINUTES")} Minuten")
Next
Else
LOGGER.Debug($"REMOVE_OLD_DROP_FILES: Keine Dateien älter als 15 Minuten (User: {USER_USERNAME})")
End If
' ✅ Dann UPDATE
Dim oDEL = String.Format("UPDATE [DD_ECM].[dbo].[TBPMO_FILES_USER] Dim oDEL = String.Format("UPDATE [DD_ECM].[dbo].[TBPMO_FILES_USER]
SET [USER_WORK] = [USER_WORK] + '_TIMEOUT', SET [USER_WORK] = [USER_WORK] + '_TIMEOUT',
WORKED = 1 WORKED = 1
WHERE ADDED_WHEN < DATEADD(MINUTE, -5, GETDATE()) WHERE ADDED_WHEN < DATEADD(MINUTE, -15, GETDATE())
AND WORKED = 0 AND USER_WORK = '{0}' ;", USER_USERNAME) AND WORKED = 0 AND USER_WORK = '{0}' ;", USER_USERNAME)
MYDB_ECM.ExecuteNonQuery(oDEL)
Dim rowsAffected = MYDB_ECM.ExecuteNonQuery(oDEL)
If rowsAffected > 0 Then
LOGGER.Warn($"REMOVE_OLD_DROP_FILES: {rowsAffected} Dateien wurden als TIMEOUT markiert")
End If
Catch ex As Exception Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical, "Unexpected error while REMOVE_OLD_DROP_FILES") MsgBox(ex.Message, MsgBoxStyle.Critical, "Unexpected error while REMOVE_OLD_DROP_FILES")
End Try End Try
@@ -475,7 +437,19 @@ Public Class ClassHelper
Try Try
Dim sql = String.Format("SELECT *, CONVERT(BIT,0) AS DELETE_FILE FROM TBPMO_FILES_USER WHERE (USER_WORK = '{0}') AND WORKED = 0", USER_USERNAME) Dim sql = String.Format("SELECT *, CONVERT(BIT,0) AS DELETE_FILE FROM TBPMO_FILES_USER WHERE (USER_WORK = '{0}') AND WORKED = 0", USER_USERNAME)
CURRENT_TBPMO_FILES_USER = MYDB_ECM.GetDatatable(sql) CURRENT_TBPMO_FILES_USER = MYDB_ECM.GetDatatable(sql)
' ✅ NEU: Logging
If CURRENT_TBPMO_FILES_USER Is Nothing Then
LOGGER.Warn($"Create_USER_FILE_TABLE: GetDatatable gab Nothing zurück (User: {USER_USERNAME})")
Else
LOGGER.Debug($"Create_USER_FILE_TABLE: {CURRENT_TBPMO_FILES_USER.Rows.Count} Dateien geladen (User: {USER_USERNAME})")
' ✅ DEBUG: Zeige GUIDs der geladenen Dateien
For Each row As DataRow In CURRENT_TBPMO_FILES_USER.Rows
LOGGER.Debug($" - GUID={row("GUID")}, WORKED={row("WORKED")}, Datei={row("FILENAME2WORK")}")
Next
End If
Catch ex As Exception Catch ex As Exception
LOGGER.Error($"Create_USER_FILE_TABLE Exception: {ex.Message}")
MsgBox(ex.Message, MsgBoxStyle.Critical, "Unexpected error while creating User_File_Table") MsgBox(ex.Message, MsgBoxStyle.Critical, "Unexpected error while creating User_File_Table")
End Try End Try
End Sub End Sub
@@ -551,9 +525,11 @@ Public Class ClassHelper
Else Else
LOGGER.Warn($"File does not exist: [{pFilename}] - Cannot compute hash.") LOGGER.Warn($"File does not exist: [{pFilename}] - Cannot compute hash.")
End If End If
Dim oSQL = $"SELECT Filename, ADDED_WHO, FORMAT(ADDED_WHEN, 'dd-MM-yyyy HH:mm') AS ADDED_WHEN_STRING FROM TBPMO_DOCRESULT_LIST WHERE FILE_HASH = '{CURRENT_FILE_HASH}' ORDER BY ADDED_WHEN DESC" Dim oSQL = $"SELECT Filename, ADDED_WHO, FORMAT(ADDED_WHEN, 'dd-MM-yyyy HH:mm') AS ADDED_WHEN_STRING FROM TBPMO_DOCRESULT_LIST WHERE FILE_HASH = '{CURRENT_FILE_HASH}' ORDER BY ADDED_WHEN DESC"
LOGGER.Debug($"Inserting File - hash is [{CURRENT_FILE_HASH}]") LOGGER.Debug($"Inserting File - hash is [{CURRENT_FILE_HASH}]")
Dim oDTCHECK As DataTable = MYDB_ECM.GetDatatable(oSQL) Dim oDTCHECK As DataTable = MYDB_ECM.GetDatatable(oSQL)
If Not IsNothing(oDTCHECK) Then If Not IsNothing(oDTCHECK) Then
If oDTCHECK.Rows.Count >= 1 Then If oDTCHECK.Rows.Count >= 1 Then
LOGGER.Info($"We got a file with the same hash [{CURRENT_FILE_HASH}]") LOGGER.Info($"We got a file with the same hash [{CURRENT_FILE_HASH}]")
@@ -561,34 +537,74 @@ Public Class ClassHelper
Dim oUSER = oDTCHECK.Rows(0).Item(1) Dim oUSER = oDTCHECK.Rows(0).Item(1)
Dim oADDED_WHEN = oDTCHECK.Rows(0).Item(2) Dim oADDED_WHEN = oDTCHECK.Rows(0).Item(2)
Dim oMSG As String Dim oMSG As String
If USER_LANGUAGE <> "de-DE" Then If USER_LANGUAGE <> "de-DE" Then
oMSG = $"This file has already been imported into orgFLOW!" & vbCrLf & oMSG = $"This file has already been imported into orgFLOW!" & vbCrLf &
$"File: [{oFilename}]" & vbCrLf & $"File: [{oFilename}]" & vbCrLf &
$"Imported on: {oADDED_WHEN}" & vbCrLf & $"Imported on: {oADDED_WHEN}" & vbCrLf &
$"Imported by: {oUSER}" & vbCrLf & $"Imported by: {oUSER}" & vbCrLf &
$"Total imports with identical content: {oDTCHECK.Rows.Count}" & vbCrLf & vbCrLf & $"Total imports with identical content: {oDTCHECK.Rows.Count}" & vbCrLf & vbCrLf &
"Do you want to import this file again?" & vbCrLf & "Do you want to import this file again?" & vbCrLf &
"NO → Teh complete Import will be cancelled." "NO → Teh complete Import will be cancelled."
Else Else
oMSG = $"Diese Datei wurde bereits in orgFLOW importiert!" & vbCrLf & oMSG = $"Diese Datei wurde bereits in orgFLOW importiert!" & vbCrLf &
$"Datei: [{oFilename}]" & vbCrLf & $"Datei: [{oFilename}]" & vbCrLf &
$"Importiert am: {oADDED_WHEN}" & vbCrLf & $"Importiert am: {oADDED_WHEN}" & vbCrLf &
$"Importiert von: {oUSER}" & vbCrLf & $"Importiert von: {oUSER}" & vbCrLf &
$"Anzahl Importe mit identischem Inhalt: {oDTCHECK.Rows.Count}" & vbCrLf & vbCrLf & $"Anzahl Importe mit identischem Inhalt: {oDTCHECK.Rows.Count}" & vbCrLf & vbCrLf &
"Möchten Sie die Datei dennoch erneut importieren?" & vbCrLf & "Möchten Sie die Datei dennoch erneut importieren?" & vbCrLf &
"NEIN → Der gesamte Import (alle folgenden) wird abgebrochen." "NEIN → Der gesamte Import (alle folgenden) wird abgebrochen."
End If End If
Dim result As MsgBoxResult Dim result As MsgBoxResult
result = MessageBox.Show(oMSG, CAPTION_CONFIRMATION, MessageBoxButtons.YesNo, MessageBoxIcon.Question) result = MessageBox.Show(oMSG, CAPTION_CONFIRMATION, MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If result = MsgBoxResult.No Then If result = MsgBoxResult.No Then
LOGGER.Info($"User wählte NEIN bei Hash-Duplikat-Check für [{filename_only}] - Import abgebrochen")
Return False Return False
Else
LOGGER.Info($"User wählte JA bei Hash-Duplikat-Check für [{filename_only}] - fahre fort")
End If End If
End If End If
End If End If
Dim ins As String = String.Format("INSERT INTO TBPMO_FILES_USER (FILENAME2WORK, USER_WORK,HANDLE_TYPE,FILENAME_ONLY,FILE_HASH) VALUES ('{0}','{1}','{2}','{3}','{4}')", pFilename, USER_USERNAME, handleType, filename_only, CURRENT_FILE_HASH) ' ✅ NEU: Pre-Check - gibt es bereits einen Eintrag mit diesem Hash?
Return MYDB_ECM.ExecuteNonQuery(ins) Dim preCheckSQL = $"SELECT GUID, USER_WORK, WORKED FROM TBPMO_FILES_USER WHERE FILE_HASH = '{CURRENT_FILE_HASH}' AND USER_WORK = '{USER_USERNAME}'"
Dim preCheckDT = MYDB_ECM.GetDatatable(preCheckSQL)
If preCheckDT IsNot Nothing AndAlso preCheckDT.Rows.Count > 0 Then
LOGGER.Warn($"WARNUNG: Datei mit Hash [{CURRENT_FILE_HASH}] bereits in TBPMO_FILES_USER vorhanden:")
For Each row As DataRow In preCheckDT.Rows
LOGGER.Warn($" - GUID={row("GUID")}, USER_WORK={row("USER_WORK")}, WORKED={row("WORKED")}")
Next
End If
' ✅ INSERT mit explizitem Logging
Dim ins As String = String.Format("INSERT INTO TBPMO_FILES_USER (FILENAME2WORK, USER_WORK, HANDLE_TYPE, FILENAME_ONLY, FILE_HASH) VALUES ('{0}','{1}','{2}','{3}','{4}')", pFilename, USER_USERNAME, handleType, filename_only, CURRENT_FILE_HASH)
LOGGER.Debug($"Führe INSERT aus: [{ins}]")
Dim insertResult = MYDB_ECM.ExecuteNonQuery(ins)
If insertResult Then
' ✅ VERIFY - wurde wirklich eingefügt?
Dim verifySQL = $"SELECT TOP 1 GUID, ADDED_WHEN FROM TBPMO_FILES_USER WHERE FILE_HASH = '{CURRENT_FILE_HASH}' AND USER_WORK = '{USER_USERNAME}' ORDER BY GUID DESC"
Dim verifyDT = MYDB_ECM.GetDatatable(verifySQL)
If verifyDT IsNot Nothing AndAlso verifyDT.Rows.Count > 0 Then
Dim insertedGUID = verifyDT.Rows(0)("GUID")
Dim insertedADDED_WHEN = verifyDT.Rows(0)("ADDED_WHEN")
LOGGER.Info($"INSERT ERFOLGREICH: GUID={insertedGUID}, ADDED_WHEN={insertedADDED_WHEN}, Datei=[{filename_only}]")
Else
LOGGER.Error($"INSERT fehlgeschlagen (VERIFY)! Datei=[{filename_only}], Hash=[{CURRENT_FILE_HASH}]")
End If
Else
LOGGER.Error($"INSERT fehlgeschlagen (ExecuteNonQuery)! Datei=[{filename_only}]")
End If
Return insertResult
Catch ex As Exception Catch ex As Exception
LOGGER.Error($"Insert_USER_File Exception: {ex.Message}")
MsgBox("Unexpected Error in Insert file for user (TBPMO_FILES_USER): " & ex.Message, MsgBoxStyle.Critical) MsgBox("Unexpected Error in Insert file for user (TBPMO_FILES_USER): " & ex.Message, MsgBoxStyle.Critical)
Return False Return False
End Try End Try

Binary file not shown.

View File

@@ -1717,6 +1717,7 @@
<None Include="MailLicense.xml"> <None Include="MailLicense.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<Content Include="Log_ewa.txt" />
<Content Include="ORGFLOW_Icon_16x16.ico" /> <Content Include="ORGFLOW_Icon_16x16.ico" />
<Content Include="ORGFLOW_Icon_256x256.ico" /> <Content Include="ORGFLOW_Icon_256x256.ico" />
<Content Include="Resources\cube.ico" /> <Content Include="Resources\cube.ico" />

View File

@@ -2307,7 +2307,7 @@ Public Class frmNodeNavigation
End If End If
End If End If
If CURRENT_RECORD_ID = 0 Then If CURRENT_RECORD_ID = 0 Then
ClassHelper.MSGBOX_Handler("INFO", "Attention", "Input missing: ", "Please choose a record.") ClassHelper.MSGBOX_Handler("INFO", "Achtung", "Fokus unklar: ", "Bitte wählen Sie erneut einen Knoten aus!")
Exit Sub Exit Sub
End If End If
If DROPPED_CHECKED = False Then If DROPPED_CHECKED = False Then
@@ -2349,30 +2349,44 @@ Public Class frmNodeNavigation
End If End If
ClassHelper.REMOVE_OLD_DROP_FILES() ClassHelper.REMOVE_OLD_DROP_FILES()
ClassHelper.Create_USER_FILE_TABLE() ClassHelper.Create_USER_FILE_TABLE()
If Not IsNothing(CURRENT_TBPMO_FILES_USER) Then
If CURRENT_TBPMO_FILES_USER.Rows.Count > 0 Then
For Each Filerow As DataRow In CURRENT_TBPMO_FILES_USER.Rows
If CBool(Filerow.Item("WORKED")) = False Then
'Dim datei = Str.ToString.Replace("@DROPFROMFSYSTEM@", "")
CURRENT_FILEID = Filerow.Item("GUID")
' CURRENT_PARENT_ENTITY_ID = PARENT_ENTITYID
'CURRENT_RECORD_ID = RECORD_ID
'CURRENT_ENTITY_ID = ENTITY_ID
CURRENT_FORMVIEW_ID = FORMVIEW_ID
frmWM_IndexFile.ShowDialog()
Else ' ✅ ENDLOS-SCHLEIFE: Solange Dateien vorhanden sind, Formular öffnen
Do While True
End If ' ✅ Prüfe, ob noch Dateien vorhanden sind
Next If CURRENT_TBPMO_FILES_USER Is Nothing OrElse CURRENT_TBPMO_FILES_USER.Rows.Count = 0 Then
NNLogger.Info("Keine weiteren Dateien zu verarbeiten - beende Check_Dropped_Files")
Exit Do
End If End If
End If
' ✅ Hole die ERSTE unverarbeitete Datei
Dim firstFile = CURRENT_TBPMO_FILES_USER.Rows.Cast(Of DataRow)() _
.Where(Function(r) CBool(r("WORKED")) = False) _
.FirstOrDefault()
If firstFile Is Nothing Then
NNLogger.Info("Alle Dateien wurden verarbeitet - beende Check_Dropped_Files")
Exit Do
End If
' ✅ Setze globale Variablen
CURRENT_FILEID = CInt(firstFile("GUID"))
CURRENT_FORMVIEW_ID = FORMVIEW_ID
NNLogger.Debug($"Öffne frmWM_IndexFile für FileId={CURRENT_FILEID}")
' ✅ Öffne Formular (kann Multi-Indexing ausführen!)
frmWM_IndexFile.ShowDialog()
' ✅ WICHTIG: Lade Dateiliste NEU aus Datenbank!
ClassHelper.Create_USER_FILE_TABLE()
' ✅ Schleife läuft weiter, prüft erneut ob Dateien vorhanden sind
Loop
Catch ex As Exception Catch ex As Exception
NNLogger.Error(ex) NNLogger.Error(ex)
ClassHelper.MSGBOX_Handler("ERROR", "Unexpected Error", "Error in Check_Dropped_Files: ", ex.Message) ClassHelper.MSGBOX_Handler("ERROR", "Unexpected Error", "Error in Check_Dropped_Files: ", ex.Message)
End Try End Try
End Sub End Sub
Private Async Sub GridControlDocSearch_DragDrop(sender As Object, e As DragEventArgs) Handles GridControlDocSearch.DragDrop Private Async Sub GridControlDocSearch_DragDrop(sender As Object, e As DragEventArgs) Handles GridControlDocSearch.DragDrop
Await Drag_Drop(e) Await Drag_Drop(e)

View File

@@ -126,10 +126,10 @@
</data> </data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="OBJECT_TYPELabel.Location" type="System.Drawing.Point, System.Drawing"> <data name="OBJECT_TYPELabel.Location" type="System.Drawing.Point, System.Drawing">
<value>6, 25</value> <value>7, 33</value>
</data> </data>
<data name="OBJECT_TYPELabel.Size" type="System.Drawing.Size, System.Drawing"> <data name="OBJECT_TYPELabel.Size" type="System.Drawing.Size, System.Drawing">
<value>62, 15</value> <value>74, 20</value>
</data> </data>
<data name="OBJECT_TYPELabel.TabIndex" type="System.Int32, mscorlib"> <data name="OBJECT_TYPELabel.TabIndex" type="System.Int32, mscorlib">
<value>5</value> <value>5</value>
@@ -160,10 +160,10 @@
<value>True</value> <value>True</value>
</data> </data>
<data name="FW_DOCTYPE_IDLabel.Location" type="System.Drawing.Point, System.Drawing"> <data name="FW_DOCTYPE_IDLabel.Location" type="System.Drawing.Point, System.Drawing">
<value>428, 25</value> <value>489, 33</value>
</data> </data>
<data name="FW_DOCTYPE_IDLabel.Size" type="System.Drawing.Size, System.Drawing"> <data name="FW_DOCTYPE_IDLabel.Size" type="System.Drawing.Size, System.Drawing">
<value>70, 15</value> <value>86, 20</value>
</data> </data>
<data name="FW_DOCTYPE_IDLabel.TabIndex" type="System.Int32, mscorlib"> <data name="FW_DOCTYPE_IDLabel.TabIndex" type="System.Int32, mscorlib">
<value>6</value> <value>6</value>
@@ -190,10 +190,10 @@
<value>True</value> <value>True</value>
</data> </data>
<data name="PATHLabel.Location" type="System.Drawing.Point, System.Drawing"> <data name="PATHLabel.Location" type="System.Drawing.Point, System.Drawing">
<value>6, 54</value> <value>7, 72</value>
</data> </data>
<data name="PATHLabel.Size" type="System.Drawing.Size, System.Drawing"> <data name="PATHLabel.Size" type="System.Drawing.Size, System.Drawing">
<value>73, 15</value> <value>84, 20</value>
</data> </data>
<data name="PATHLabel.TabIndex" type="System.Int32, mscorlib"> <data name="PATHLabel.TabIndex" type="System.Int32, mscorlib">
<value>8</value> <value>8</value>
@@ -217,10 +217,10 @@
<value>True</value> <value>True</value>
</data> </data>
<data name="Label1.Location" type="System.Drawing.Point, System.Drawing"> <data name="Label1.Location" type="System.Drawing.Point, System.Drawing">
<value>12, 9</value> <value>14, 12</value>
</data> </data>
<data name="Label1.Size" type="System.Drawing.Size, System.Drawing"> <data name="Label1.Size" type="System.Drawing.Size, System.Drawing">
<value>61, 15</value> <value>79, 20</value>
</data> </data>
<data name="Label1.TabIndex" type="System.Int32, mscorlib"> <data name="Label1.TabIndex" type="System.Int32, mscorlib">
<value>0</value> <value>0</value>
@@ -244,10 +244,13 @@
<value>Top, Left, Right</value> <value>Top, Left, Right</value>
</data> </data>
<data name="txtFilepath.Location" type="System.Drawing.Point, System.Drawing"> <data name="txtFilepath.Location" type="System.Drawing.Point, System.Drawing">
<value>15, 27</value> <value>17, 36</value>
</data>
<data name="txtFilepath.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data> </data>
<data name="txtFilepath.Size" type="System.Drawing.Size, System.Drawing"> <data name="txtFilepath.Size" type="System.Drawing.Size, System.Drawing">
<value>574, 23</value> <value>655, 27</value>
</data> </data>
<data name="txtFilepath.TabIndex" type="System.Int32, mscorlib"> <data name="txtFilepath.TabIndex" type="System.Int32, mscorlib">
<value>1</value> <value>1</value>
@@ -271,10 +274,10 @@
<value>Segoe UI Semibold, 9.75pt, style=Bold</value> <value>Segoe UI Semibold, 9.75pt, style=Bold</value>
</data> </data>
<data name="Label2.Location" type="System.Drawing.Point, System.Drawing"> <data name="Label2.Location" type="System.Drawing.Point, System.Drawing">
<value>12, 58</value> <value>14, 77</value>
</data> </data>
<data name="Label2.Size" type="System.Drawing.Size, System.Drawing"> <data name="Label2.Size" type="System.Drawing.Size, System.Drawing">
<value>188, 17</value> <value>238, 23</value>
</data> </data>
<data name="Label2.TabIndex" type="System.Int32, mscorlib"> <data name="Label2.TabIndex" type="System.Int32, mscorlib">
<value>2</value> <value>2</value>
@@ -298,10 +301,13 @@
<value>Segoe UI Semibold, 9.75pt, style=Bold</value> <value>Segoe UI Semibold, 9.75pt, style=Bold</value>
</data> </data>
<data name="cmbDokumentart.Location" type="System.Drawing.Point, System.Drawing"> <data name="cmbDokumentart.Location" type="System.Drawing.Point, System.Drawing">
<value>15, 78</value> <value>17, 104</value>
</data>
<data name="cmbDokumentart.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data> </data>
<data name="cmbDokumentart.Size" type="System.Drawing.Size, System.Drawing"> <data name="cmbDokumentart.Size" type="System.Drawing.Size, System.Drawing">
<value>203, 25</value> <value>231, 29</value>
</data> </data>
<data name="cmbDokumentart.TabIndex" type="System.Int32, mscorlib"> <data name="cmbDokumentart.TabIndex" type="System.Int32, mscorlib">
<value>3</value> <value>3</value>
@@ -340,10 +346,13 @@
<value>MiddleLeft</value> <value>MiddleLeft</value>
</data> </data>
<data name="btnindex.Location" type="System.Drawing.Point, System.Drawing"> <data name="btnindex.Location" type="System.Drawing.Point, System.Drawing">
<value>431, 444</value> <value>493, 592</value>
</data>
<data name="btnindex.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data> </data>
<data name="btnindex.Size" type="System.Drawing.Size, System.Drawing"> <data name="btnindex.Size" type="System.Drawing.Size, System.Drawing">
<value>158, 28</value> <value>181, 37</value>
</data> </data>
<data name="btnindex.TabIndex" type="System.Int32, mscorlib"> <data name="btnindex.TabIndex" type="System.Int32, mscorlib">
<value>4</value> <value>4</value>
@@ -370,10 +379,13 @@
<value>Top, Left, Right</value> <value>Top, Left, Right</value>
</data> </data>
<data name="OBJECT_TYPETextBox.Location" type="System.Drawing.Point, System.Drawing"> <data name="OBJECT_TYPETextBox.Location" type="System.Drawing.Point, System.Drawing">
<value>85, 22</value> <value>97, 29</value>
</data>
<data name="OBJECT_TYPETextBox.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data> </data>
<data name="OBJECT_TYPETextBox.Size" type="System.Drawing.Size, System.Drawing"> <data name="OBJECT_TYPETextBox.Size" type="System.Drawing.Size, System.Drawing">
<value>281, 23</value> <value>321, 27</value>
</data> </data>
<data name="OBJECT_TYPETextBox.TabIndex" type="System.Int32, mscorlib"> <data name="OBJECT_TYPETextBox.TabIndex" type="System.Int32, mscorlib">
<value>6</value> <value>6</value>
@@ -394,10 +406,13 @@
<value>Top, Left, Right</value> <value>Top, Left, Right</value>
</data> </data>
<data name="PATHTextBox.Location" type="System.Drawing.Point, System.Drawing"> <data name="PATHTextBox.Location" type="System.Drawing.Point, System.Drawing">
<value>85, 51</value> <value>97, 68</value>
</data>
<data name="PATHTextBox.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data> </data>
<data name="PATHTextBox.Size" type="System.Drawing.Size, System.Drawing"> <data name="PATHTextBox.Size" type="System.Drawing.Size, System.Drawing">
<value>469, 23</value> <value>535, 27</value>
</data> </data>
<data name="PATHTextBox.TabIndex" type="System.Int32, mscorlib"> <data name="PATHTextBox.TabIndex" type="System.Int32, mscorlib">
<value>9</value> <value>9</value>
@@ -418,10 +433,13 @@
<value>Top, Right</value> <value>Top, Right</value>
</data> </data>
<data name="DOCTYPE_IDTextBox.Location" type="System.Drawing.Point, System.Drawing"> <data name="DOCTYPE_IDTextBox.Location" type="System.Drawing.Point, System.Drawing">
<value>504, 22</value> <value>576, 29</value>
</data>
<data name="DOCTYPE_IDTextBox.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data> </data>
<data name="DOCTYPE_IDTextBox.Size" type="System.Drawing.Size, System.Drawing"> <data name="DOCTYPE_IDTextBox.Size" type="System.Drawing.Size, System.Drawing">
<value>50, 23</value> <value>57, 27</value>
</data> </data>
<data name="DOCTYPE_IDTextBox.TabIndex" type="System.Int32, mscorlib"> <data name="DOCTYPE_IDTextBox.TabIndex" type="System.Int32, mscorlib">
<value>7</value> <value>7</value>
@@ -442,10 +460,16 @@
<value>Segoe UI, 9pt, style=Italic</value> <value>Segoe UI, 9pt, style=Italic</value>
</data> </data>
<data name="GroupBox1.Location" type="System.Drawing.Point, System.Drawing"> <data name="GroupBox1.Location" type="System.Drawing.Point, System.Drawing">
<value>15, 117</value> <value>17, 156</value>
</data>
<data name="GroupBox1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data>
<data name="GroupBox1.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data> </data>
<data name="GroupBox1.Size" type="System.Drawing.Size, System.Drawing"> <data name="GroupBox1.Size" type="System.Drawing.Size, System.Drawing">
<value>560, 80</value> <value>640, 107</value>
</data> </data>
<data name="GroupBox1.TabIndex" type="System.Int32, mscorlib"> <data name="GroupBox1.TabIndex" type="System.Int32, mscorlib">
<value>7</value> <value>7</value>
@@ -475,10 +499,13 @@
<value>Verdana, 9.75pt, style=Italic</value> <value>Verdana, 9.75pt, style=Italic</value>
</data> </data>
<data name="chkdelete_origin.Location" type="System.Drawing.Point, System.Drawing"> <data name="chkdelete_origin.Location" type="System.Drawing.Point, System.Drawing">
<value>24, 450</value> <value>27, 603</value>
</data>
<data name="chkdelete_origin.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data> </data>
<data name="chkdelete_origin.Size" type="System.Drawing.Size, System.Drawing"> <data name="chkdelete_origin.Size" type="System.Drawing.Size, System.Drawing">
<value>177, 20</value> <value>226, 24</value>
</data> </data>
<data name="chkdelete_origin.TabIndex" type="System.Int32, mscorlib"> <data name="chkdelete_origin.TabIndex" type="System.Int32, mscorlib">
<value>8</value> <value>8</value>
@@ -511,10 +538,13 @@
<value>Verdana, 9.75pt, style=Bold, Italic</value> <value>Verdana, 9.75pt, style=Bold, Italic</value>
</data> </data>
<data name="chkMultiIndexer.Location" type="System.Drawing.Point, System.Drawing"> <data name="chkMultiIndexer.Location" type="System.Drawing.Point, System.Drawing">
<value>24, 476</value> <value>27, 638</value>
</data>
<data name="chkMultiIndexer.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data> </data>
<data name="chkMultiIndexer.Size" type="System.Drawing.Size, System.Drawing"> <data name="chkMultiIndexer.Size" type="System.Drawing.Size, System.Drawing">
<value>519, 20</value> <value>688, 24</value>
</data> </data>
<data name="chkMultiIndexer.TabIndex" type="System.Int32, mscorlib"> <data name="chkMultiIndexer.TabIndex" type="System.Int32, mscorlib">
<value>9</value> <value>9</value>
@@ -547,10 +577,16 @@
<value>Top, Bottom, Left, Right</value> <value>Top, Bottom, Left, Right</value>
</data> </data>
<data name="grbxControls.Location" type="System.Drawing.Point, System.Drawing"> <data name="grbxControls.Location" type="System.Drawing.Point, System.Drawing">
<value>15, 203</value> <value>17, 271</value>
</data>
<data name="grbxControls.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data>
<data name="grbxControls.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data> </data>
<data name="grbxControls.Size" type="System.Drawing.Size, System.Drawing"> <data name="grbxControls.Size" type="System.Drawing.Size, System.Drawing">
<value>574, 191</value> <value>656, 255</value>
</data> </data>
<data name="grbxControls.TabIndex" type="System.Int32, mscorlib"> <data name="grbxControls.TabIndex" type="System.Int32, mscorlib">
<value>10</value> <value>10</value>
@@ -583,10 +619,10 @@
<value>Segoe UI Semibold, 9pt, style=Bold, Italic</value> <value>Segoe UI Semibold, 9pt, style=Bold, Italic</value>
</data> </data>
<data name="lblSubfolder.Location" type="System.Drawing.Point, System.Drawing"> <data name="lblSubfolder.Location" type="System.Drawing.Point, System.Drawing">
<value>21, 397</value> <value>24, 529</value>
</data> </data>
<data name="lblSubfolder.Size" type="System.Drawing.Size, System.Drawing"> <data name="lblSubfolder.Size" type="System.Drawing.Size, System.Drawing">
<value>134, 15</value> <value>172, 20</value>
</data> </data>
<data name="lblSubfolder.TabIndex" type="System.Int32, mscorlib"> <data name="lblSubfolder.TabIndex" type="System.Int32, mscorlib">
<value>11</value> <value>11</value>
@@ -616,10 +652,13 @@
<value>Segoe UI Semibold, 9pt, style=Bold, Italic</value> <value>Segoe UI Semibold, 9pt, style=Bold, Italic</value>
</data> </data>
<data name="txtSubfolder.Location" type="System.Drawing.Point, System.Drawing"> <data name="txtSubfolder.Location" type="System.Drawing.Point, System.Drawing">
<value>24, 415</value> <value>27, 553</value>
</data>
<data name="txtSubfolder.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data> </data>
<data name="txtSubfolder.Size" type="System.Drawing.Size, System.Drawing"> <data name="txtSubfolder.Size" type="System.Drawing.Size, System.Drawing">
<value>551, 24</value> <value>629, 28</value>
</data> </data>
<data name="txtSubfolder.TabIndex" type="System.Int32, mscorlib"> <data name="txtSubfolder.TabIndex" type="System.Int32, mscorlib">
<value>12</value> <value>12</value>
@@ -643,10 +682,10 @@
<value>True</value> <value>True</value>
</metadata> </metadata>
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing"> <data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
<value>7, 15</value> <value>8, 20</value>
</data> </data>
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing"> <data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
<value>604, 513</value> <value>690, 684</value>
</data> </data>
<data name="$this.Font" type="System.Drawing.Font, System.Drawing"> <data name="$this.Font" type="System.Drawing.Font, System.Drawing">
<value>Segoe UI, 9pt</value> <value>Segoe UI, 9pt</value>
@@ -1100,6 +1139,9 @@
wAH//wAA///AAf//AAD//8AB//8AAP//wAH//wAA///AD///AAD///H///8AAP///////wAA wAH//wAA///AAf//AAD//8AB//8AAP//wAH//wAA///AD///AAD///H///8AAP///////wAA
</value> </value>
</data> </data>
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 4, 3, 4</value>
</data>
<data name="$this.Text" xml:space="preserve"> <data name="$this.Text" xml:space="preserve">
<value>Import nach windream:</value> <value>Import nach windream:</value>
</data> </data>

View File

@@ -41,11 +41,18 @@ Public Class frmWM_IndexFile
Function WORK_FILE(ImportFilePath As String, VerzeichnisZiel As String, vDokart_ID As Integer, vDokart As String, multiindex As Boolean) Function WORK_FILE(ImportFilePath As String, VerzeichnisZiel As String, vDokart_ID As Integer, vDokart As String, multiindex As Boolean)
'Dim swWORK_FILE As New SW("WORK_FILE: " & DOCTYPE_IDTextBox.Text) 'Dim swWORK_FILE As New SW("WORK_FILE: " & DOCTYPE_IDTextBox.Text)
Try Try
LOGGER.Debug($" WORK_FILE aufgerufen: CURRENT_FILEID={CURRENT_FILEID}, Datei={Me.txtFilepath.Text}")
LOGGER.Debug($"=== WORK_FILE START: multiindex={multiindex} ===")
LOGGER.Debug($" Datei: {ImportFilePath}")
LOGGER.Debug($" Flags: _multiIndexDecisionMade={_multiIndexDecisionMade}, _multiIndexOverwriteExisting={_multiIndexOverwriteExisting}")
CURRENT_DOC_ID = Nothing CURRENT_DOC_ID = Nothing
Dim odeleteRights As Boolean = True Dim odeleteRights As Boolean = True
Dim oSQL = $"SELECT GUID FROM TBPMO_FILES_USER WHERE FILENAME2WORK = '{ImportFilePath}' AND WORKED = 0 AND USER_WORK = '{Environment.UserName}'"
CURRENT_FILEID = MYDB_ECM.GetScalarValue(oSQL)
If CURRENT_FILEID = 0 OrElse CURRENT_FILEID = Nothing Then
LOGGER.Error("WORK_FILE: CURRENT_FILEID ist ungültig (0 oder Nothing)!")
Return False
End If
CURRENT_DOKARTSTRING = vDokart CURRENT_DOKARTSTRING = vDokart
Dim err As Boolean = False Dim err As Boolean = False
'################################################################# '#################################################################
@@ -64,6 +71,7 @@ Public Class frmWM_IndexFile
If multiindex = True Then If multiindex = True Then
If _multiIndexDecisionMade = False Then If _multiIndexDecisionMade = False Then
LOGGER.Debug(" ZEIGE DIALOG für Multi-Index-Entscheidung")
' Erste Kollision → Benutzer fragen ' Erste Kollision → Benutzer fragen
Dim msg As String Dim msg As String
If USER_LANGUAGE <> "de-DE" Then If USER_LANGUAGE <> "de-DE" Then
@@ -84,12 +92,16 @@ Public Class frmWM_IndexFile
_multiIndexOverwriteExisting = (result = MsgBoxResult.Yes) _multiIndexOverwriteExisting = (result = MsgBoxResult.Yes)
_multiIndexDecisionMade = True _multiIndexDecisionMade = True
LOGGER.Info($"Multi-Indexing: User decision for file conflicts = {If(_multiIndexOverwriteExisting, "OVERWRITE", "VERSION")}") LOGGER.Debug($" Benutzer-Entscheidung: {If(_multiIndexOverwriteExisting, "OVERWRITE", "VERSION")}")
LOGGER.Debug($" Flags NACH Dialog: _multiIndexDecisionMade={_multiIndexDecisionMade}, _multiIndexOverwriteExisting={_multiIndexOverwriteExisting}")
Else
LOGGER.Debug($" Verwende GESPEICHERTE Entscheidung: {If(_multiIndexOverwriteExisting, "OVERWRITE", "VERSION")}")
End If End If
shouldOverwrite = _multiIndexOverwriteExisting shouldOverwrite = _multiIndexOverwriteExisting
Else Else
' Einzeldatei → wie bisher ' Einzeldatei → wie bisher
LOGGER.Debug(" Einzeldatei: Zeige Dialog")
Dim msg As String Dim msg As String
If USER_LANGUAGE <> "de-DE" Then If USER_LANGUAGE <> "de-DE" Then
msg = "A file with the same name already exists!" & vbCrLf & msg = "A file with the same name already exists!" & vbCrLf &
@@ -104,10 +116,12 @@ Public Class frmWM_IndexFile
Dim result As MsgBoxResult = MessageBox.Show(msg, "File already exists:", Dim result As MsgBoxResult = MessageBox.Show(msg, "File already exists:",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) MessageBoxButtons.YesNo, MessageBoxIcon.Question)
shouldOverwrite = (result = MsgBoxResult.Yes) shouldOverwrite = (result = MsgBoxResult.Yes)
LOGGER.Debug($" Einzeldatei-Entscheidung: {If(shouldOverwrite, "OVERWRITE", "VERSION")}")
End If End If
' ── Entscheidung ausführen ──────────────────────────────────── ' ── Entscheidung ausführen ────────────────────────────────────
If shouldOverwrite Then If shouldOverwrite Then
LOGGER.Debug(" Führe OVERWRITE aus")
If WMMOD.RemoveFile(CURRENT_NEWFILENAME) = False Then If WMMOD.RemoveFile(CURRENT_NEWFILENAME) = False Then
Return False Return False
Else Else
@@ -127,8 +141,12 @@ Public Class frmWM_IndexFile
Next Next
End If End If
Else Else
LOGGER.Debug(" Führe VERSIONIERUNG aus")
CURRENT_NEWFILENAME = ClassHelper.Versionierung_Datei(CURRENT_NEWFILENAME) CURRENT_NEWFILENAME = ClassHelper.Versionierung_Datei(CURRENT_NEWFILENAME)
LOGGER.Debug($" Neuer Dateiname: {CURRENT_NEWFILENAME}")
End If End If
Else
LOGGER.Debug(" Datei existiert NICHT, kein Konflikt")
End If End If
sw.Done() sw.Done()
'################################################################# '#################################################################
@@ -291,15 +309,23 @@ Public Class frmWM_IndexFile
stg1 = "Success:" stg1 = "Success:"
End If End If
If multiindex = False Then CURRENT_NOTIFICATION_MSG = stg If multiindex = False Then CURRENT_NOTIFICATION_MSG = stg
MYDB_ECM.GetScalarValue("UPDATE TBPMO_FILES_USER SET WORKED = 1 WHERE GUID = " & CURRENT_FILEID)
For Each row As DataRow In CURRENT_TBPMO_FILES_USER.Rows ' Neu - NUR wenn NICHT im Multi-Index-Modus:
If row.Item("GUID") = CURRENT_FILEID Then If multiindex = False Then
row.Item("WORKED") = 1 MYDB_ECM.ExecuteNonQuery("UPDATE TBPMO_FILES_USER SET WORKED = 1 WHERE GUID = " & CURRENT_FILEID)
If IsNothing(droptype) Then LOGGER.Debug($" Einzeldatei als WORKED markiert: GUID={CURRENT_FILEID}")
droptype = row.Item("HANDLE_TYPE")
End If ' ✅ DEBUG: Was steht JETZT in der DB?
End If Dim debugSQL = $"SELECT GUID, WORKED, FILENAME_ONLY FROM TBPMO_FILES_USER WHERE USER_WORK = '{USER_USERNAME}' ORDER BY GUID DESC"
Next Dim debugDT = MYDB_ECM.GetDatatable(debugSQL)
LOGGER.Debug($" ═══ DEBUG NACH UPDATE ═══")
LOGGER.Debug($" Anzahl Dateien in DB: {debugDT.Rows.Count}")
For Each row As DataRow In debugDT.Rows
LOGGER.Debug($" - GUID={row("GUID")}, WORKED={row("WORKED")}, Datei={row("FILENAME_ONLY")}")
Next
LOGGER.Debug($" ═══════════════════════")
End If
If IsNothing(CURRENT_DOC_ID) Then If IsNothing(CURRENT_DOC_ID) Then
sw = New SW("GettingDocID") sw = New SW("GettingDocID")
sql = String.Format("SELECT DocID FROM VWPMO_DOC_SYNC WHERE FULL_FILENAME = '{0}' AND CONVERT(DATE,Change_DateTime) = CONVERT(DATE,GETDATE())", CURRENT_FILEIN_WD) sql = String.Format("SELECT DocID FROM VWPMO_DOC_SYNC WHERE FULL_FILENAME = '{0}' AND CONVERT(DATE,Change_DateTime) = CONVERT(DATE,GETDATE())", CURRENT_FILEIN_WD)
@@ -425,31 +451,70 @@ Public Class frmWM_IndexFile
Me.Cursor = Cursors.WaitCursor Me.Cursor = Cursors.WaitCursor
SaveMySettingsValue("WD_IndexDeleteDocs", WD_IndexDeleteDocs, "ConfigMain") SaveMySettingsValue("WD_IndexDeleteDocs", WD_IndexDeleteDocs, "ConfigMain")
' ── Multi-Indexing-Flags zurücksetzen beim Start ────────────────── LOGGER.Debug("=== HANDLE_FILE START ===")
LOGGER.Debug($" Flags VOR Reset: _multiIndexDecisionMade={_multiIndexDecisionMade}, _multiIndexOverwriteExisting={_multiIndexOverwriteExisting}")
_multiIndexDecisionMade = False _multiIndexDecisionMade = False
_multiIndexOverwriteExisting = False _multiIndexOverwriteExisting = False
LOGGER.Debug($" Flags NACH Reset: _multiIndexDecisionMade={_multiIndexDecisionMade}, _multiIndexOverwriteExisting={_multiIndexOverwriteExisting}")
LOGGER.Debug($" chkMultiIndexer: Visible={chkMultiIndexer.Visible}, Checked={chkMultiIndexer.Checked}")
If chkMultiIndexer.Visible = True And chkMultiIndexer.Checked = True Then If chkMultiIndexer.Visible = True And chkMultiIndexer.Checked = True Then
' ── Erste Datei: FILE_HASH sicherstellen ─────────────────────── LOGGER.Debug("=== MULTI-INDEXING MODUS AKTIV ===")
' ── Erste Datei: FILE_HASH und CURRENT_FILEID sicherstellen ───
Dim firstFileId As Integer = CURRENT_FILEID
Dim firstFileName As String = CURRENT_FILENAME
For Each oRow As DataRow In CURRENT_TBPMO_FILES_USER.Rows For Each oRow As DataRow In CURRENT_TBPMO_FILES_USER.Rows
If oRow.Item("GUID") = CURRENT_FILEID Then If oRow.Item("GUID") = CURRENT_FILEID Then
FILE_HASH = oRow.Item("FILE_HASH") FILE_HASH = oRow.Item("FILE_HASH")
firstFileName = oRow.Item("FILENAME2WORK")
Exit For Exit For
End If End If
Next Next
If WORK_FILE(Me.txtFilepath.Text, Me.PATHTextBox.Text, doctype_id, My.Settings.WD_INDEXDOKART_SAVE, True) = False Then LOGGER.Debug($" Verarbeite erste Datei (CURRENT_FILEID={firstFileId}): {firstFileName}")
If WORK_FILE(firstFileName, Me.PATHTextBox.Text, doctype_id, My.Settings.WD_INDEXDOKART_SAVE, True) = False Then
Me.Cursor = Cursors.Default Me.Cursor = Cursors.Default
LOGGER.Warn(" Erste Datei fehlgeschlagen!")
Return False Return False
End If End If
' ── Erste Datei erfolgreich: GUID merken, Folgedateien laden ── LOGGER.Debug(" Erste Datei erfolgreich verarbeitet")
Dim firstFileId = CURRENT_FILEID
Dim DTFiles2Work As DataTable = MYDB_ECM.GetDatatable(
"SELECT * FROM TBPMO_FILES_USER WHERE WORKED = 0 " &
"AND GUID <> " & firstFileId & " AND USER_WORK = '" & USER_USERNAME & "'")
If DTFiles2Work Is Nothing OrElse DTFiles2Work.Rows.Count = 0 Then ' ── WICHTIG: Erste Datei als WORKED markieren UND DataTable neu laden ──
LOGGER.Debug($" Markiere erste Datei als WORKED: GUID={firstFileId}")
MYDB_ECM.ExecuteNonQuery($"UPDATE TBPMO_FILES_USER SET WORKED = 1 WHERE GUID = {firstFileId}")
LOGGER.Debug(" Lade aktualisierte Dateiliste aus Datenbank...")
' ✅ SCHRITT 1: Prüfe mit COUNT(*), wie viele Dateien in der DB sind
Dim countSQL = $"SELECT COUNT(*) FROM TBPMO_FILES_USER WHERE USER_WORK = '{USER_USERNAME}' AND WORKED = 0"
Dim remainingCount = CInt(MYDB_ECM.GetScalarValue(countSQL))
LOGGER.Debug($" SQL COUNT ergab: {remainingCount} verbleibende Dateien")
' ✅ SCHRITT 2: Nur wenn COUNT > 0, dann DataTable laden
If remainingCount > 0 Then
CURRENT_TBPMO_FILES_USER = MYDB_ECM.GetDatatable("SELECT *, CONVERT(BIT,0) AS DELETE_FILE FROM TBPMO_FILES_USER " &
"WHERE USER_WORK = '" & USER_USERNAME & "' AND WORKED = 0")
If CURRENT_TBPMO_FILES_USER Is Nothing Then
LOGGER.Error(" WARNUNG: GetDatatable gab Nothing zurück, obwohl COUNT > 0!")
CURRENT_TBPMO_FILES_USER = New DataTable()
Else
LOGGER.Debug($" DataTable geladen: {CURRENT_TBPMO_FILES_USER.Rows.Count} Zeilen")
End If
Else
LOGGER.Info(" SQL COUNT ergab 0 Dateien")
CURRENT_TBPMO_FILES_USER = New DataTable()
End If
' ── Folgedateien aus aktualierter DataTable verarbeiten ──
If CURRENT_TBPMO_FILES_USER Is Nothing OrElse CURRENT_TBPMO_FILES_USER.Rows.Count = 0 Then
LOGGER.Info(" Keine weiteren Dateien vorhanden")
NEW_FILES_ADDED = True NEW_FILES_ADDED = True
FILE_WORKED = True FILE_WORKED = True
Me.Cursor = Cursors.Default Me.Cursor = Cursors.Default
@@ -457,12 +522,24 @@ Public Class frmWM_IndexFile
Return True Return True
End If End If
LOGGER.Debug($" Weitere Dateien gefunden: {CURRENT_TBPMO_FILES_USER.Rows.Count}")
LOGGER.Debug($" Flags VOR Schleife: _multiIndexDecisionMade={_multiIndexDecisionMade}, _multiIndexOverwriteExisting={_multiIndexOverwriteExisting}")
Dim err As Boolean = False Dim err As Boolean = False
For Each filerow As DataRow In DTFiles2Work.Rows Dim fileCount As Integer = 0
CURRENT_FILEID = filerow.Item("GUID") For Each filerow As DataRow In CURRENT_TBPMO_FILES_USER.Rows
CURRENT_FILENAME = filerow.Item("FILENAME2WORK") fileCount += 1
FILE_HASH = filerow.Item("FILE_HASH") Dim currentFileId As Integer = filerow.Item("GUID")
aktFiledropped = CURRENT_FILENAME Dim currentFileName As String = filerow.Item("FILENAME2WORK")
Dim currentFileHash As String = filerow.Item("FILE_HASH")
CURRENT_FILEID = currentFileId
CURRENT_FILENAME = currentFileName
FILE_HASH = currentFileHash
aktFiledropped = currentFileName
LOGGER.Debug($" [{fileCount}/{CURRENT_TBPMO_FILES_USER.Rows.Count}] Verarbeite Datei: {currentFileName}, FILEID={currentFileId}")
LOGGER.Debug($" Flags: _multiIndexDecisionMade={_multiIndexDecisionMade}, _multiIndexOverwriteExisting={_multiIndexOverwriteExisting}")
Dim handleType As String = filerow.Item("HANDLE_TYPE") Dim handleType As String = filerow.Item("HANDLE_TYPE")
Select Case handleType Select Case handleType
@@ -476,10 +553,15 @@ Public Class frmWM_IndexFile
droptype = handleType droptype = handleType
End Select End Select
If WORK_FILE(CURRENT_FILENAME, Me.PATHTextBox.Text, doctype_id, My.Settings.WD_INDEXDOKART_SAVE, True) = False Then If WORK_FILE(currentFileName, Me.PATHTextBox.Text, doctype_id, My.Settings.WD_INDEXDOKART_SAVE, True) = False Then
err = True err = True
LOGGER.Warn($" Datei fehlgeschlagen!")
Exit For Exit For
End If End If
LOGGER.Debug($" Datei erfolgreich verarbeitet")
LOGGER.Debug($" Markiere Datei als WORKED: GUID={currentFileId}")
MYDB_ECM.ExecuteNonQuery($"UPDATE TBPMO_FILES_USER SET WORKED = 1 WHERE GUID = {currentFileId}")
Next Next
Me.Cursor = Cursors.Default Me.Cursor = Cursors.Default
@@ -493,6 +575,7 @@ Public Class frmWM_IndexFile
stg = "All files were transferred via Multiindexing to windream" stg = "All files were transferred via Multiindexing to windream"
stg1 = "Success:" stg1 = "Success:"
End If End If
LOGGER.Info("=== MULTI-INDEXING ERFOLGREICH ABGESCHLOSSEN ===")
MsgBox(stg, MsgBoxStyle.Information, stg1) MsgBox(stg, MsgBoxStyle.Information, stg1)
Me.Close() Me.Close()
Return True Return True
@@ -501,25 +584,123 @@ Public Class frmWM_IndexFile
Return False Return False
Else Else
' ── Einzeldatei ─────────────────────────────────────────────── ' ✅ EINZELDATEI MODUS
If WORK_FILE(Me.txtFilepath.Text, Me.PATHTextBox.Text, doctype_id, My.Settings.WD_INDEXDOKART_SAVE, False) = True Then LOGGER.Debug("=== EINZELDATEI MODUS ===")
NEW_FILES_ADDED = True
FILE_WORKED = True ' ✅ WICHTIG: CURRENT_FILEID VOR WORK_FILE setzen!
For Each oRow As DataRow In CURRENT_TBPMO_FILES_USER.Rows
If oRow.Item("FILENAME2WORK") = Me.txtFilepath.Text Then
CURRENT_FILEID = CInt(oRow("GUID"))
FILE_HASH = oRow("FILE_HASH").ToString()
LOGGER.Debug($" Datei gefunden in CURRENT_TBPMO_FILES_USER: FILEID={CURRENT_FILEID}")
Exit For
End If
Next
' ✅ Validierung NACH Schleife
If CURRENT_FILEID = 0 Then
LOGGER.Error($" Datei nicht gefunden in CURRENT_TBPMO_FILES_USER: {Me.txtFilepath.Text}")
Me.Cursor = Cursors.Default
MessageBox.Show("Die Datei konnte nicht in der Verarbeitungsliste gefunden werden!",
"Fehler:", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return False
End If
If WORK_FILE(Me.txtFilepath.Text, Me.PATHTextBox.Text, doctype_id, My.Settings.WD_INDEXDOKART_SAVE, False) = False Then
Me.Cursor = Cursors.Default
MessageBox.Show("Import to windream was not successful." & vbCrLf &
"Check the log for further information!",
"Unexpected Error in windream-Stream:",
MessageBoxButtons.OK, MessageBoxIcon.Error)
Return False
End If
' ── Datei erfolgreich verarbeitet ──
NEW_FILES_ADDED = True
FILE_WORKED = True
LOGGER.Debug(" Einzeldatei erfolgreich verarbeitet")
' ✅ Prüfen, ob weitere Dateien vorhanden sind
LOGGER.Debug(" Lade aktualisierte Dateiliste für Einzeldatei-Check...")
' ✅ SCHRITT 1: Prüfe mit COUNT(*), wie viele Dateien in der DB sind
Dim countSQL = $"SELECT COUNT(*) FROM TBPMO_FILES_USER WHERE USER_WORK = '{USER_USERNAME}' AND WORKED = 0"
Dim remainingCount = CInt(MYDB_ECM.GetScalarValue(countSQL))
LOGGER.Debug($" ═══ SQL COUNT NACH WORK_FILE ═══")
LOGGER.Debug($" COUNT(*) ergab: {remainingCount} verbleibende Dateien")
' ✅ SCHRITT 2: Dateiliste laden UND vergleichen
ClassHelper.Create_USER_FILE_TABLE()
If CURRENT_TBPMO_FILES_USER Is Nothing Then
LOGGER.Error($" ❌ KRITISCHER FEHLER: Create_USER_FILE_TABLE gab Nothing zurück!")
ElseIf CURRENT_TBPMO_FILES_USER.Rows.Count <> remainingCount Then
LOGGER.Error($" ❌ KRITISCHER FEHLER: COUNT ergab {remainingCount}, aber DataTable hat {CURRENT_TBPMO_FILES_USER.Rows.Count} Zeilen!")
LOGGER.Error($" ❌ VERDACHT: Race-Condition oder Transaction-Problem!")
Else
LOGGER.Debug($" ✅ OK: COUNT und DataTable stimmen überein ({remainingCount} Dateien)")
End If
LOGGER.Debug($" ═══════════════════════════════")
If CURRENT_TBPMO_FILES_USER IsNot Nothing AndAlso CURRENT_TBPMO_FILES_USER.Rows.Count > 0 Then
LOGGER.Info($" Einzeldatei-Modus: Weitere {CURRENT_TBPMO_FILES_USER.Rows.Count} Dateien vorhanden - aktualisiere Formular")
' ── Lade ERSTE Datei aus der NEUEN Liste ──
Dim nextFile = CURRENT_TBPMO_FILES_USER.Rows(0)
CURRENT_FILEID = CInt(nextFile("GUID"))
CURRENT_FILENAME = nextFile("FILENAME2WORK").ToString()
FILE_HASH = nextFile("FILE_HASH").ToString()
aktFiledropped = CURRENT_FILENAME
txtFilepath.Text = CURRENT_FILENAME
LOGGER.Debug($" Nächste Datei geladen: FILEID={CURRENT_FILEID}, Datei={CURRENT_FILENAME}")
' ── Update MULTIFILES-Anzeige ──
MULTIFILES = CURRENT_TBPMO_FILES_USER.Rows.Count - 1
If MULTIFILES > 0 Then
chkMultiIndexer.Text = "Multi-Indexing - Alle nachfolgenden Dateien (" & MULTIFILES & ") identisch indexieren"
chkMultiIndexer.Visible = True
chkMultiIndexer.Checked = False
Else
chkMultiIndexer.Visible = False
End If
' ── Handle-Type setzen ──
Dim handleType As String = nextFile("HANDLE_TYPE").ToString()
Select Case handleType
Case "@DROPFROMFSYSTEM@"
droptype = "dragdrop file"
chkdelete_origin.Visible = True
Case "@OUTLOOK_ATTMNT@"
droptype = "dragdrop attachment"
chkdelete_origin.Visible = True
Case "@OUTLOOKMESSAGE@"
droptype = "dragdrop message"
chkdelete_origin.Visible = True
Case "SCAN"
droptype = "scan"
chkdelete_origin.Visible = False
Case Else
droptype = handleType
chkdelete_origin.Visible = False
End Select
Me.Cursor = Cursors.Default
LOGGER.Debug(" Formular bleibt offen für nächste Datei")
Return True ' ← Formular bleibt offen!
Else
' ✅ Keine weiteren Dateien → Formular schließen
LOGGER.Info(" Einzeldatei-Modus: Keine weiteren Dateien - schließe Formular")
Me.Cursor = Cursors.Default Me.Cursor = Cursors.Default
Me.Close() Me.Close()
Return True Return True
Else
Me.Cursor = Cursors.Default
MessageBox.Show("Import to windream was not successful." & vbCrLf &
"Check the log for further information!",
"Unexpected Error in windream-Stream:",
MessageBoxButtons.OK, MessageBoxIcon.Error)
Return False
End If End If
End If End If
Catch ex As Exception Catch ex As Exception
MsgBox("Error in Indexing_File:" & vbCrLf & ex.Message, MsgBoxStyle.Critical) MsgBox("Error in Indexing_File:" & vbCrLf & ex.Message, MsgBoxStyle.Critical)
LOGGER.Error($"Handle_File Exception: {ex.Message}{vbCrLf}{ex.StackTrace}")
Return False Return False
Finally Finally
Me.Cursor = Cursors.Default Me.Cursor = Cursors.Default
@@ -1113,37 +1294,63 @@ Public Class frmWM_IndexFile
CURRENT_FILENAME = "" CURRENT_FILENAME = ""
Me.VWDDINDEX_AUTOMTableAdapter.Connection.ConnectionString = MYDB_ECM.CurrentConnectionString Me.VWDDINDEX_AUTOMTableAdapter.Connection.ConnectionString = MYDB_ECM.CurrentConnectionString
chkMultiIndexer.Checked = False chkMultiIndexer.Checked = False
' ── Multi-Indexing-Flags beim Formular-Load zurücksetzen ──
LOGGER.Debug("=== FORM LOAD: Flags zurücksetzen ===")
LOGGER.Debug($" VOR Reset: _multiIndexDecisionMade = {_multiIndexDecisionMade}, _multiIndexOverwriteExisting = {_multiIndexOverwriteExisting}")
_multiIndexDecisionMade = False
_multiIndexOverwriteExisting = False
_processedFileIds.Clear()
LOGGER.Debug($" NACH Reset: _multiIndexDecisionMade = {_multiIndexDecisionMade}, _multiIndexOverwriteExisting = {_multiIndexOverwriteExisting}")
LOGGER.Debug($" ProcessedFileIds Count: {_processedFileIds.Count}")
LOGGER.Debug("frmWD_Index_Dokart_Load") LOGGER.Debug("frmWD_Index_Dokart_Load")
chkdelete_origin.Checked = False chkdelete_origin.Checked = False
chkdelete_origin.Visible = False chkdelete_origin.Visible = False
Dim oReconnect = WMMOD.SessionReconnect Dim oReconnect = WMMOD.SessionReconnect
'= New Windream(LOGCONFIG, False, WMDriveLetter, WMPATH_PREFIX, True, WM_SERVER, WM_USER, WM_USER_PW, WM_DOMAIN)
' ── WICHTIG: Prüfen, ob überhaupt Dateien vorhanden sind ──
If CURRENT_TBPMO_FILES_USER Is Nothing OrElse CURRENT_TBPMO_FILES_USER.Rows.Count = 0 Then
LOGGER.Info("frmWD_Index_Dokart_Load: Keine Dateien vorhanden - Formular wird geschlossen")
Me.Close()
Exit Sub
End If
Dim oHandleType As String Dim oHandleType As String
For Each oRow As DataRow In CURRENT_TBPMO_FILES_USER.Rows For Each oRow As DataRow In CURRENT_TBPMO_FILES_USER.Rows
If oRow.Item("GUID") = CURRENT_FILEID Then If oRow.Item("GUID") = CURRENT_FILEID Then
CURRENT_FILENAME = oRow.Item("FILENAME2WORK") CURRENT_FILENAME = oRow.Item("FILENAME2WORK")
oHandleType = oRow.Item("HANDLE_TYPE") oHandleType = oRow.Item("HANDLE_TYPE")
FILE_HASH = oRow.Item("FILE_HASH") FILE_HASH = oRow.Item("FILE_HASH")
Exit For ' ← Hinzugefügt: Schleife verlassen, wenn gefunden
End If End If
Next Next
If CURRENT_FILENAME = "" Then If CURRENT_FILENAME = "" Then
MsgBox("Chekc the Temp Files Table, as it seems to be empty!", MsgBoxStyle.Exclamation) LOGGER.Warn("Check the Temp Files Table, as it seems to be empty or CURRENT_FILEID not found!")
MsgBox("Check the Temp Files Table, as it seems to be empty!", MsgBoxStyle.Exclamation)
Me.Close() ' ← Formular schließen statt Exit Sub
Exit Sub Exit Sub
End If End If
MULTIFILES = 0
For Each row As DataRow In CURRENT_TBPMO_FILES_USER.Rows ' ── KORREKTUR: Zähle alle Dateien außer der aktuellen ──
If row.Item("GUID") <> CURRENT_FILEID Then MULTIFILES = CURRENT_TBPMO_FILES_USER.Rows.Count - 1
MULTIFILES += 1 LOGGER.Debug($" MULTIFILES berechnet: Gesamt={CURRENT_TBPMO_FILES_USER.Rows.Count}, MULTIFILES={MULTIFILES}")
End If
Next
If MULTIFILES > 0 Then If MULTIFILES > 0 Then
chkMultiIndexer.Text = "Multi-Indexing - Alle nachfolgenden Dateien (" & MULTIFILES & ") identisch indexieren" chkMultiIndexer.Text = "Multi-Indexing - Alle nachfolgenden Dateien (" & MULTIFILES & ") identisch indexieren"
chkMultiIndexer.Visible = True chkMultiIndexer.Visible = True
LOGGER.Debug($" chkMultiIndexer: Visible=True, Text={chkMultiIndexer.Text}")
Else Else
chkMultiIndexer.Visible = False chkMultiIndexer.Visible = False
LOGGER.Debug(" chkMultiIndexer: Visible=False (keine weiteren Dateien)")
End If End If
aktFiledropped = CURRENT_FILENAME aktFiledropped = CURRENT_FILENAME
txtFilepath.Text = aktFiledropped txtFilepath.Text = aktFiledropped
If oHandleType = "@DROPFROMFSYSTEM@" Then If oHandleType = "@DROPFROMFSYSTEM@" Then
droptype = "dragdrop file" droptype = "dragdrop file"
chkdelete_origin.Visible = True chkdelete_origin.Visible = True
@@ -1159,21 +1366,19 @@ Public Class frmWM_IndexFile
ElseIf oHandleType = "SCAM" Then ElseIf oHandleType = "SCAM" Then
droptype = "scan" droptype = "scan"
End If End If
Dim sql = String.Format("SELECT FORMVIEW_ID, FORM_ID, FORM_TITLE, DOKUMENTTYPE_ID, DOKUMENTTYPE, PATH, SHORTNAME, OBJECT_TYPE, FW_DOCTYPE_ID FROM VWPMO_DOKUMENTTYPES WHERE (FORMVIEW_ID = {0}) " &
"ORDER BY SEQUENCE, DOKUMENTTYPE", CURRENT_FORMVIEW_ID)
DTVWPMO_DOKUMENTTYPES = MYDB_ECM.GetDatatable(sql)
'VWPMO_DOKUMENTTYPESTableAdapter.Connection.ConnectionString = MYDB_ECM.CurrentConnectionString Dim sql = String.Format("SELECT FORMVIEW_ID, FORM_ID, FORM_TITLE, DOKUMENTTYPE_ID, DOKUMENTTYPE, PATH, SHORTNAME, OBJECT_TYPE, FW_DOCTYPE_ID FROM VWPMO_DOKUMENTTYPES WHERE (FORMVIEW_ID = {0}) " &
'Me.VWPMO_DOKUMENTTYPESTableAdapter.Fill(Me.DD_DMSDataSet.VWPMO_DOKUMENTTYPES, CURRENT_FORMVIEW_ID) "ORDER BY SEQUENCE, DOKUMENTTYPE", CURRENT_FORMVIEW_ID)
DTVWPMO_DOKUMENTTYPES = MYDB_ECM.GetDatatable(sql)
CURRENT_REDUNDANT_FORM_ID = 0 CURRENT_REDUNDANT_FORM_ID = 0
CURRENT_REDUNDANT_FORMVIEW_ID = 0 CURRENT_REDUNDANT_FORMVIEW_ID = 0
If DTVWPMO_DOKUMENTTYPES.Rows.Count = 0 Then ' DD_DMSDataSet.VWPMO_DOKUMENTTYPES.Rows.Count = 0 Then If DTVWPMO_DOKUMENTTYPES.Rows.Count = 0 Then
If CURRENT_ENTITY_REDUNDANT_ID <> 0 Then If CURRENT_ENTITY_REDUNDANT_ID <> 0 Then
Dim FVID = MYDB_ECM.GetScalarValue(String.Format("SELECT GUID FROM TBPMO_FORM_VIEW WHERE FORM_ID = {0} and SCREEN_ID = 1", CURRENT_ENTITY_REDUNDANT_ID), True) Dim FVID = MYDB_ECM.GetScalarValue(String.Format("SELECT GUID FROM TBPMO_FORM_VIEW WHERE FORM_ID = {0} and SCREEN_ID = 1", CURRENT_ENTITY_REDUNDANT_ID), True)
'Me.VWPMO_DOKUMENTTYPESTableAdapter.Fill(Me.DD_DMSDataSet.VWPMO_DOKUMENTTYPES, FVID) If DTVWPMO_DOKUMENTTYPES.Rows.Count = 0 Then
If DTVWPMO_DOKUMENTTYPES.Rows.Count = 0 Then 'DD_DMSDataSet.VWPMO_DOKUMENTTYPES.Rows.Count = 0 Then
MsgBox("No documenttypes for the redundant entity configured either! Indexing is not possible!" & vbCrLf & "Please check the configuration!", MsgBoxStyle.Exclamation) MsgBox("No documenttypes for the redundant entity configured either! Indexing is not possible!" & vbCrLf & "Please check the configuration!", MsgBoxStyle.Exclamation)
Me.Close()
Exit Sub Exit Sub
Else Else
LOGGER.Debug("Redundant EntityID: " & CURRENT_ENTITY_REDUNDANT_ID) LOGGER.Debug("Redundant EntityID: " & CURRENT_ENTITY_REDUNDANT_ID)
@@ -1184,12 +1389,15 @@ Public Class frmWM_IndexFile
End If End If
Else Else
MsgBox("No documenttypes for this entity configured! Indexing is not possible!" & vbCrLf & "Please check the configuration!", MsgBoxStyle.Exclamation) MsgBox("No documenttypes for this entity configured! Indexing is not possible!" & vbCrLf & "Please check the configuration!", MsgBoxStyle.Exclamation)
Me.Close()
Exit Sub Exit Sub
End If End If
End If End If
Catch ex As Exception Catch ex As Exception
LOGGER.Error($"Error in frmWD_Index_Dokart_Load: {ex.Message}")
MsgBox("Error in frmWD_Index_Dokart_Load:" & vbCrLf & ex.Message, MsgBoxStyle.Critical) MsgBox("Error in frmWD_Index_Dokart_Load:" & vbCrLf & ex.Message, MsgBoxStyle.Critical)
Me.Close()
End Try End Try
End Sub End Sub
@@ -1242,19 +1450,63 @@ Public Class frmWM_IndexFile
Private Sub frmWM_IndexFile_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing Private Sub frmWM_IndexFile_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
Try Try
' Alle nicht-verarbeiteten Dateien löschen (außer den erfolgreichen) ' ── Multi-Indexing-Flags zurücksetzen ──
Dim processedIds = String.Join(",", _processedFileIds) _multiIndexDecisionMade = False
Dim oDelete = $"DELETE FROM TBPMO_FILES_USER WHERE USER_WORK = '{USER_USERNAME}' AND WORKED = 0" _multiIndexOverwriteExisting = False
If _processedFileIds.Count > 0 Then
oDelete &= $" AND GUID NOT IN ({processedIds})" ' ✅ WICHTIG: Liste NEU LADEN, bevor wir zählen!
LOGGER.Debug("=== CLOSING: Lade aktuelle Dateiliste ===")
ClassHelper.Create_USER_FILE_TABLE() ' ← Lädt CURRENT_TBPMO_FILES_USER NEU!
' ── Prüfen, ob noch Dateien zu verarbeiten sind ──
If CURRENT_TBPMO_FILES_USER IsNot Nothing AndAlso CURRENT_TBPMO_FILES_USER.Rows.Count > 0 Then
' Es gibt noch nicht verarbeitete Dateien → Benutzer fragen
LOGGER.Debug($"TBPMO_FILES_USER: Formular wird geschlossen, aber {CURRENT_TBPMO_FILES_USER.Rows.Count} Dateien sind noch vorhanden.")
Dim msg As String
Dim title As String
If USER_LANGUAGE <> "de-DE" Then
msg = $"There are still {CURRENT_TBPMO_FILES_USER.Rows.Count} unprocessed file(s)!" & vbCrLf & vbCrLf &
"Do you really want to cancel the import?" & vbCrLf & vbCrLf &
"YES → Cancel import and delete all pending files" & vbCrLf &
"NO → Continue indexing"
title = "Cancel Import?"
Else
msg = $"Es sind noch {CURRENT_TBPMO_FILES_USER.Rows.Count} nicht verarbeitete Datei(en) vorhanden!" & vbCrLf & vbCrLf &
"Möchten Sie den Import wirklich abbrechen?" & vbCrLf & vbCrLf &
"JA → Import abbrechen und alle ausstehenden Dateien löschen" & vbCrLf &
"NEIN → Indexierung fortsetzen"
title = "Import abbrechen?"
End If
Dim result As MsgBoxResult = MessageBox.Show(msg, title, MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
If result = MsgBoxResult.No Then
' Benutzer will NICHT abbrechen → Formular-Schließen verhindern
LOGGER.Info("Benutzer hat Abbruch verhindert - Formular bleibt offen")
e.Cancel = True
Exit Sub
Else
' Benutzer will abbrechen → Alle Dateien löschen
LOGGER.Info("Benutzer hat Abbruch bestätigt - Lösche alle ausstehenden Dateien")
Dim oDelete = $"DELETE FROM TBPMO_FILES_USER WHERE USER_WORK = '{USER_USERNAME}' AND WORKED = 0"
MYDB_ECM.ExecuteNonQuery(oDelete)
LOGGER.Info($"TBPMO_FILES_USER: {CURRENT_TBPMO_FILES_USER.Rows.Count} nicht-verarbeitete Einträge wurden gelöscht (User: {USER_USERNAME})")
' ── WICHTIG: DataTable leeren, damit Load-Event korrekt reagiert ──
CURRENT_TBPMO_FILES_USER.Clear()
LOGGER.Debug("CURRENT_TBPMO_FILES_USER wurde geleert")
End If
Else
' Keine Dateien mehr vorhanden → Normal schließen, aufräumen
LOGGER.Debug("Keine ausstehenden Dateien mehr vorhanden ")
End If End If
MYDB_ECM.ExecuteNonQuery(oDelete)
LOGGER.Info($"TBPMO_FILES_USER: Nicht-verarbeitete Einträge bereinigt (User: {USER_USERNAME})")
Catch ex As Exception Catch ex As Exception
LOGGER.Warn($"Fehler beim Bereinigen von TBPMO_FILES_USER (Closing): {ex.Message}") LOGGER.Warn($"Fehler beim Bereinigen von TBPMO_FILES_USER (Closing): {ex.Message}")
End Try End Try
End Sub End Sub
Private Sub frmWM_IndexFile_Closed(sender As Object, e As EventArgs) Handles Me.Closed Private Sub frmWM_IndexFile_Closed(sender As Object, e As EventArgs) Handles Me.Closed
Try Try
Cursor = Cursors.Default Cursor = Cursors.Default
@@ -1262,4 +1514,8 @@ Public Class frmWM_IndexFile
End Try End Try
End Sub End Sub
Private Sub chkMultiIndexer_CheckedChanged(sender As Object, e As EventArgs) Handles chkMultiIndexer.CheckedChanged
LOGGER.Debug($"chkMultiIndexer.CheckedChanged: {chkMultiIndexer.Checked}")
End Sub
End Class End Class