Hallo Helferleins,
ich habe mal wieder ein Progblem. Ich habe aus dem wunderbaren Bsp. von Oskar eine Datenbank erstellt. Die ersten Tests liefen auch wunderbar. Als von mehreren Benutzern ein Datensatz zur gleichen Zeit eingegeben wurde, stellte ich aber fest, das nur ein Datensatz gespeichert wurde. Mache ich einen Denkfehler oder möchte ich da etwas was nur richtige Datenbanken haben? Hier mein bisheriges Werk:
Spoiler anzeigen
#include<WindowsConstants.au3>
#include<ListViewConstants.au3>
#include<ButtonConstants.au3>
#include<GUIConstantsEx.au3>
#include<Guilistview.au3>
#include<String.au3>
#Include<Date.au3>
Global $ver = 'Ver. 0.2' ; Versionsnummer auf Label
[/autoit] [autoit][/autoit] [autoit]Global $sHeader = "Tfz|Lz-Nummer|von|nach|Zeit|Datum" ; Die Überschriften für das Listview und für das "Neuer Eintrag"-Fenster
Global $sDBFile = @ScriptDir & "\datenbank.txt" ; Pfad und Name der Datenbank-Datei
Global $iEdit = -1 ; Wert auf -1 setzen, weil _GUICtrlListView_GetSelectionMark() einen Nullbasierten Wert liefert
#Region Hauptfenster
Global $hGui = GUICreate("Ausfall Lz-Nummern", 560, 500) ; Hauptfenster erstellen
Global $hListView = GUICtrlCreateListView($sHeader, 2, 3, 420, 470, $LVS_SHOWSELALWAYS) ; Listview erstellen
Global $hLVHandle = GUICtrlGetHandle($hListView) ; das Handle vom Listview wird für die UDF-Listview-Funktionen benötigt
_GUICtrlListView_SetColumn($hLVHandle, 0, "Tfz" , 60, 0)
_GUICtrlListView_SetColumn($hLVHandle, 1, "Lz-Nummer" , 80, 0)
_GUICtrlListView_SetColumn($hLVHandle, 2, "von" , 60, 0)
_GUICtrlListView_SetColumn($hLVHandle, 3, "nach" , 60, 0)
_GUICtrlListView_SetColumn($hLVHandle, 4, "Zeit" , 60, 0)
_GUICtrlListView_SetColumn($hLVHandle, 5, "Datum" ,100, 0)
Global $hNew = GUICtrlCreateButton("Neuer Eintrag" , 435, 10, 115, 30, $BS_DEFPUSHBUTTON) ; ist Default-Push-Button (User = [Enter])
Global $hEdit = GUICtrlCreateButton("Eintrag bearbeiten" , 435, 50, 115, 30)
Global $hDel = GUICtrlCreateButton("Eintrag löschen" , 435, 90, 115, 30)
Global $hSave = GUICtrlCreateButton("Speichern" , 435, 130, 115, 30)
Global $hLoad = GUICtrlCreateButton("Neu laden" , 435, 170, 115, 30)
Global $hClose = GUICtrlCreateButton("Programm Schließen" , 457, 250, 70, 40, $BS_MULTILINE) ; Zeilenumbruch
Global $hDelAll = GUICtrlCreateButton("Alle Einträge löschen", 435, 444, 115, 30)
Global $hCM = GUICtrlCreateContextMenu($hListView) ; ein Kontextmenü für das Listview erstellen
Global $hCMNew = GUICtrlCreateMenuItem("Neuer Eintrag", $hCM) ; der 1. Kontextmenüeintrag
Global $hCMEdit = GUICtrlCreateMenuItem("Eintrag bearbeiten", $hCM) ; der 2. Kontextmenüeintrag
Global $hCMDel = GUICtrlCreateMenuItem("Markierte Einträge löschen", $hCM) ; der 3. Kontextmenüeintrag
#EndRegion Hauptfenster
#Region Fenster für neuen Eintrag
Global $hGuiNew = GUICreate("Neue Lz-Nummer", 636, 140, -1, -1, $WS_SYSMENU) ; das Fenster "Neuer Eintrag" erstellen (größer)
Global $aHeader = StringSplit($sHeader, '|') ; Überschriften-Array
Global $aNew[$aHeader[0]] ; Array für die Input-IDs
For $i = 1 To $aHeader[0]
GUICtrlCreateLabel($aHeader[$i], 4 + ($i - 1) * 105, 15, 90, 20); Überschriften-Label erstellen
GUICtrlSetFont(-1, 9, 400, 0, 'Verdana') ; Schriftgröße und -art der Überschriften festlegen
$aNew[$i - 1] = GUICtrlCreateInput("", 2 + ($i - 1) * 105, 30, 100, 20, Default, $WS_EX_STATICEDGE) ; Eingabefelder erstellen
GUICtrlSetFont(-1, 10, 600, 0, 'Verdana') ; Schriftgröße und -art der Eingabefelder festlegen
Next
Global $hCreate = GUICtrlCreateButton("Eintrag speichern", 140, 65, 150, 35) ; Button zum speichern
Global $hCreateSave = GUICtrlCreateButton("Speichern und schließen", 310, 65, 150, 35, $BS_DEFPUSHBUTTON) ; Button zum speichern und schließen
#EndRegion Fenster für neuen Eintrag
_GUICtrlListView_RegisterSortCallBack($hLVHandle) ; damit man das Listview (mit Klick auf die Spaltenüberschrift) sortieren kann
[/autoit] [autoit][/autoit] [autoit]GUISetState(@SW_SHOW, $hGui) ; Hauptfenster sichtbar machen
[/autoit] [autoit][/autoit] [autoit]If FileExists($sDBFile) Then Load() ; wenn Datenbank-Datei existiert, dann Datenbank laden
[/autoit] [autoit][/autoit] [autoit]AdlibRegister('Load', 60000) ; zum automatischen Aktualisieren 60000 ms = 1 min
[/autoit] [autoit][/autoit] [autoit]While 1
$nMsg = GUIGetMsg(1) ; Message-Event holen (1) = erweiterter Modus
Switch $nMsg[0] ; anhand der Control-ID das entsprechende Case aufrufen
Case $hListView ; User hat auf eine Spaltenüberschrift geklickt
_GUICtrlListView_SortItems($hLVHandle, GUICtrlGetState($hListView)) ; Einträge entsprechend sortieren
Case $hNew, $hCMNew ; User hat auf "Neuer Eintrag" geklickt
WinSetTitle($hGuiNew, "", "Neuer Eintrag") ; den Titel des Fenster anpassen
GUISetState(@SW_SHOW, $hGuiNew) ; das Fenster "Neuer Eintrag" anzeigen
GUISetState(@SW_DISABLE, $hGui) ; das Hauptfenster deaktivieren
Case $hEdit, $hCMEdit ; User hat auf "Eintrag bearbeiten" geklickt
WinSetTitle($hGuiNew, "", "Eintrag bearbeiten") ; den Titel des Fenster anpassen
GUISetState(@SW_SHOW, $hGuiNew) ; das Fenster "Neuer Eintrag" anzeigen
GUISetState(@SW_DISABLE, $hGui) ; das Hauptfenster deaktivieren
Edit() ; Daten aus dem Listview ins Formular einlesen
Load() ; aktuelle Daten aus DB laden
Case $hLoad ; User hat auf "Aktualisieren" geklickt
Load() ; aktuelle Daten aus DB laden
Case $hSave ; User hat auf "Speichern" geklickt
Save() ; geänderte Daten in DB speichern
Load() ; aktuelle Daten aus DB laden
Case $hDel, $hCMDel ; User hat auf "Markierte Einträge löschen" geklickt
If MsgBox(256 + 32 + 4, "Einträge löschen", "Wollen sie die markierten Einträge wirklich löschen?") = 6 Then
_GUICtrlListView_DeleteItemsSelected($hLVHandle)
Save() ; geänderte Daten in DB speichern
Load() ; aktuelle Daten aus DB laden
EndIf
Case $hDelAll ; User hat auf "Alle Einträge löschen" geklickt
If MsgBox(256 + 32 + 4, "Einträge löschen", "Wollen sie wirklich alle Einträge löschen?") = 6 Then
_GUICtrlListView_DeleteAllItems($hLVHandle)
Save() ; geänderte Daten in DB speichern
Load() ; aktuelle Daten aus DB laden
EndIf
Case $hCreate ; User hat auf "Eintrag speichern" im Fenster "Neuer Eintrag" geklickt
Load() ; Daten aktualiesierern
NewItem() ; Daten bearbeiten
Save() ; Daten prüfen und speichern
Load() ; Daten neu einlesen
Case $hCreateSave ; User hat auf "Speichern und schließen" im Fenster "Neuer Eintrag" geklickt
Load() ; Daten aktualiesierern
NewItem() ; Daten bearbeiten
Save() ; Daten prüfen und speichern
GUISetState(@SW_HIDE, $hGuiNew)
GUISetState(@SW_ENABLE, $hGui)
WinActivate($hGui)
Load() ; Daten neu einlesen
Case $hClose ; User hat auf "Programm schließen" geklickt
If MsgBox(32 + 4, "Beenden", "Wollen sie das Programm wirklich beenden?") = 6 Then End() ; wenn ja, dann End-Funktion aufrufen
Case $GUI_EVENT_CLOSE ; User hat auf das Schließen-Symbol geklickt (bzw. die ESC-Taste gedrückt)
Switch $nMsg[1] ; erweiterte Abfrage für welches Fenster
Case $hGui ; User will das Hauptfenster schließen
If MsgBox(32 + 4, "Beenden", "Wollen sie das Programm wirklich beenden?") = 6 Then End() ; wenn ja, dann End-Funktion aufrufen
Case $hGuiNew ; User will das "Neuer Eintrag"-Fenster schließen
$iEdit = -1
For $i = 0 To UBound($aNew) - 1
GUICtrlSetData($aNew[$i], "") ; Alle Eingabefelder leeren
Next
GUISetState(@SW_HIDE, $hGuiNew) ; "Neuer Eintrag"-Fenster verstecken
GUISetState(@SW_ENABLE, $hGui) ; Hauptfenster wieder aktivieren
WinActivate($hGui) ; und in den Vordergrund holen
EndSwitch
EndSwitch
WEnd
Func NewItem() ; Funktion zum auslesen der Eingabefelder (Neuer Eintrag bzw. Eintrag bearbeiten)
ConsoleWrite('NewItem() aufgerufen' & @LF)
Dim $sTime, $sDate
Local $sItem = ""
For $i = 0 To UBound($aNew) - 1 ; Schleife, um alle Eingabefelder durchzugehen
If $iEdit > -1 Then ; wenn $iEdit > -1 (Eintrag bearbeiten), dann...
Switch $i
Case 0 ; Tfz
_GUICtrlListView_SetItemText($hLVHandle, $iEdit, GUICtrlRead($aNew[$i]), $i) ; den Eintrag aus dem Eingabefeld ins Listview schreiben
Case 1 ; Lz-Nummer
If StringLen(GUICtrlRead($aNew[$i])) < 6 Then
_GUICtrlListView_SetItemText($hLVHandle, $iEdit, GUICtrlRead($aNew[$i]), $i) ; den Eintrag aus dem Eingabefeld ins Listview schreiben
Else
_GUICtrlListView_SetItemText($hLVHandle, $iEdit, StringLeft(GUICtrlRead($aNew[$i]), 5), $i) ; nur die ersten 5 Zeichen nehmen
EndIf
Case 2 ; von Bst
_GUICtrlListView_SetItemText($hLVHandle, $iEdit, StringUpper(GUICtrlRead($aNew[$i])), $i) ; den Eintrag aus dem Eingabefeld ins Listview schreiben
Case 3 ; nach Bst
_GUICtrlListView_SetItemText($hLVHandle, $iEdit, StringUpper(GUICtrlRead($aNew[$i])), $i) ; den Eintrag aus dem Eingabefeld ins Listview schreiben
Case 4 ; Zeit
If StringInStr(GUICtrlRead($aNew[$i]), ':') = 0 Then ; Doppelpunkt ist noch nicht vorhanden
$sTime = '0' & _StringInsert(GUICtrlRead($aNew[$i]), ':' , -2) ; einfügen des Doppelpunktes
_GUICtrlListView_SetItemText($hLVHandle, $iEdit, $sTime, $i) ; den Eintrag aus dem Eingabefeld ins Listview schreiben
Else ; Doppelpunkt bereits vorhanden
If StringLen(GUICtrlRead($aNew[$i])) = 4 Then
_GUICtrlListView_SetItemText($hLVHandle, $iEdit, '0'&GUICtrlRead($aNew[$i]), $i) ; Uhrzeitformat vervollständigen
Else
_GUICtrlListView_SetItemText($hLVHandle, $iEdit, GUICtrlRead($aNew[$i]), $i) ; den Eintrag aus dem Eingabefeld ins Listview schreiben
EndIf
EndIf
Case 5 ; Datum
$sDate = GUICtrlRead($aNew[$i])
If StringLen($sDate) < 2 Then
$sDate = '0'&$sDate ; auffüllen des Datums
Else
$sDate = StringLeft($sDate, 2) ; nur den Tag extrahieren
EndIf
If StringRight(_NowCalcDate(), 2) = $sDate Then ; passt die eingabe zu heute?
_GUICtrlListView_SetItemText($hLVHandle, $iEdit, _NowCalcDate(), $i)
ElseIf StringRight(_DateAdd('d', 1, _NowCalcDate()), 2) = $sDate Then ; passt die eingabe zu morgen
_GUICtrlListView_SetItemText($hLVHandle, $iEdit, _DateAdd('d', 1, _NowCalcDate()), $i)
ElseIf StringRight(_DateAdd('d', -1, _NowCalcDate()), 2) = $sDate Then ; passt die eingabe zu gestern
_GUICtrlListView_SetItemText($hLVHandle, $iEdit, _DateAdd('d', -1, _NowCalcDate()), $i)
Else
_GUICtrlListView_SetItemText($hLVHandle, $iEdit, GUICtrlRead($aNew[$i]), $i) ; leeren Eintrag ins Listview schreiben
EndIf
EndSwitch
Else ; sonst $iEdit = -1 (neuer Eintrag)
ConsoleWrite('$i= '&$i&' >> $sItem= ' & $sItem & @LF)
Switch $i
Case 0 ; Tfz
$sItem &= GUICtrlRead($aNew[$i]) & "|" ; den Eintrag aus dem Eingabefeld erstmal in einer Variablen ($sItem) speichern
Case 1 ; Lz-Nummer
If StringLen(GUICtrlRead($aNew[$i])) < 6 Then
$sItem &= GUICtrlRead($aNew[$i]) & "|" ; den Eintrag aus dem Eingabefeld erstmal in einer Variablen ($sItem) speichern
Else
$sItem &= StringLeft(GUICtrlRead($aNew[$i]), 5) & "|" ; nur die ersten 5 Zeichen nehmen
EndIf
Case 2 ; von Bst
$sItem &= StringUpper(GUICtrlRead($aNew[$i])) & "|" ; den Eintrag aus dem Eingabefeld erstmal in einer Variablen ($sItem) speichern
Case 3 ; nach Bst
$sItem &= StringUpper(GUICtrlRead($aNew[$i])) & "|" ; den Eintrag aus dem Eingabefeld erstmal in einer Variablen ($sItem) speichern
Case 4 ; Zeit
If StringInStr(GUICtrlRead($aNew[$i]), ':') = 0 Then ; Doppelpunkt ist noch nicht vorhanden
If StringLen(GUICtrlRead($aNew[$i])) = 3 Then
$sTime = '0' & _StringInsert(GUICtrlRead($aNew[$i]), ':' , -2)
$sItem &= $sTime & "|" ; den Eintrag aus dem Eingabefeld erstmal in einer Variablen ($sItem) speichern
Else
$sTime = _StringInsert(GUICtrlRead($aNew[$i]), ':' , -2)
$sItem &= $sTime & "|" ; den Eintrag aus dem Eingabefeld erstmal in einer Variablen ($sItem) speichern
EndIf
ElseIf StringLen(GUICtrlRead($aNew[$i])) = 4 Then
$sItem &= '0' & GUICtrlRead($aNew[$i]) & "|" ; den Eintrag aus dem Eingabefeld erstmal in einer Variablen ($sItem) speichern
Else
$sItem &= GUICtrlRead($aNew[$i]) & "|" ; den Eintrag aus dem Eingabefeld erstmal in einer Variablen ($sItem) speichern
EndIf
Case 5 ; Datum
$sDate = GUICtrlRead($aNew[$i])
If StringLen($sDate) < 2 Then
$sDate = '0'&$sDate ; auffüllen des Datums
Else
$sDate = StringLeft($sDate, 2) ; nur den Tag extrahieren
EndIf
If StringRight(_NowCalcDate(), 2) = $sDate Then ; passt die eingabe zu heute?
$sItem &= _NowCalcDate() & '|'
ElseIf StringRight(_DateAdd('d', 1, _NowCalcDate()), 2) = $sDate Then ; passt die eingabe zu morgen
$sItem &= _DateAdd('d', 1, _NowCalcDate()) & '|'
ElseIf StringRight(_DateAdd('d', -1, _NowCalcDate()), 2) = $sDate Then ; passt die eingabe zu morgen
$sItem &= _DateAdd('d', -1, _NowCalcDate()) & '|'
Else
$sItem &= '' & '|' ;
EndIf
EndSwitch
EndIf
GUICtrlSetData($aNew[$i], "") ; das entsprechende Eingabefeld leeren
Next
If $iEdit > -1 Then ; wenn $iEdit > -1 (Eintrag bearbeiten), dann...
$iEdit = -1
GUISetState(@SW_HIDE, $hGuiNew) ; "Neuer Eintrag"-Fenster verstecken
GUISetState(@SW_ENABLE, $hGui) ; Hauptfenster wieder aktivieren
Sleep(300)
WinActivate($hGui) ; und in den Vordergrund holen
Else ; sonst $iEdit = -1 (neuer Eintrag)
If $sItem<>"||||||" Then ; bei Leeres Eingabfenster nichts
GUICtrlSetState($aNew[0], $GUI_FOCUS) ; den Focus wieder auf das erste Eingabefeld setzen, für weitere Eingaben
GUICtrlCreateListViewItem(StringTrimRight($sItem, 1), $hListView) ; mit den Werten aus $sItem einen neuen Listview-Eintrag hinzufügen
EndIf
EndIf
EndFunc ;==>NewItem
Func Edit() ; Funktion zum bearbeiten eines Listview-Eintrags im "Eintrag bearbeiten"-Fenster
ConsoleWrite('Edit() aufgerufen' & @LF)
$iEdit = _GUICtrlListView_GetSelectionMark($hLVHandle) ; auslesen, welcher Listview-Eintrag markiert (bei mehreren, den obersten) ist
If $iEdit > -1 Then
Local $aItem = _GUICtrlListView_GetItemTextArray($hLVHandle, $iEdit) ; die Einträge aus dem Listview in ein Array holen
For $i = 1 To $aItem[0]
GUICtrlSetData($aNew[$i - 1], $aItem[$i]) ; und in die entsprechenden Eingabefelder schreiben
Next
EndIf
EndFunc ;==>Edit
Func Load() ; Datenbank-Datei laden
ConsoleWrite('Load() aufgerufen' & @LF)
_GUICtrlListView_DeleteAllItems($hLVHandle) ; löscht alle Items des ListViews
Local $sItem
Local $hFile = FileOpen($sDBFile, 0) ; Datei zum lesen öffnen
If $hFile <> -1 Then ; wenn das öffnen erfolgreich war, dann...
_GUICtrlListView_BeginUpdate($hLVHandle) ; Listview sperren
While True ; Endlosschleife
$sItem = FileReadLine($hFile) ; Zeile aus der Datei lesen
If @error Then ExitLoop ; wenn das Ende der Datei erreicht ist, dann Endlosschleife verlassen
GUICtrlCreateListViewItem($sItem, $hListView) ; mit den eingelesenen Daten einen neuen Listview-Eintrag erstellen
WEnd
_GUICtrlListView_EndUpdate($hLVHandle) ; Listview wieder freigeben
FileClose($hFile) ; Datei schließen
EndIf
EndFunc ;==>Load
Func Save() ; Datenbank-Datei speichern
ConsoleWrite('Save() aufgerufen' & @LF)
Local $sItem, $sSplit, $vTrain, $Msg
Local $iCount = _GUICtrlListView_GetItemCount($hLVHandle) - 1 ; Anzahl der Listview-Einträge holen
Local $hFile = FileOpen($sDBFile, 2) ; Datei zum speichern (überschreiben) öffnen
If $hFile <> -1 Then ; wenn das öffnen erfolgreich war, dann...
For $i = 0 To $iCount ; Schleife, um alle Listview-Einträge durchzugehen
$sItem = _GUICtrlListView_GetItemTextString($hLVHandle, $i) ; die Werte aus dem Listview-Eintrag holen
$sSplit = StringSplit($sItem, '|') ; aufsplitten der Eintrags
$vTrain = _getValidTrain($sSplit[6], $sSplit[5]) ; überprüfen ob noch nicht abgelaufen
If $vTrain = 1 Then
FileWriteLine($hFile, $sItem) ; und in die Datei schreiben
Else
$Msg = MsgBox(4,'','Der Eintrag ' & $sSplit[2] & ' ist abgelaufen oder falsch und wird gelöscht.')
If $Msg = 7 Then FileWriteLine($hFile, $sItem) ; und in die Datei schreiben
EndIf
Next
FileClose($hFile) ; Datei schließen
ElseIf $hFile = -1 Then ; wenn das öffnen nicht erfolgreich war, dann...
MsgBox(16,'Fehler', 'Leider konnte die Datenbank nicht zum schreiben geöffnet werden.')
EndIf
EndFunc ;==>Save
Func End() ; Funktion zum Speicher und Beenden der Datenbank
ConsoleWrite('End() aufgerufen' & @LF)
_GUICtrlListView_UnRegisterSortCallBack($hLVHandle) ; Sortierroutine wieder de-registrieren
Exit
EndFunc ;==>End
Func _getValidTrain($sDate, $sTime) ; prüft die Gültigkeit des Eintrages
;ReturnWert 0 = Zug zu alt
;ReturnWert 1 = Zug noch gültig
;Returnwert 2 = Falsches Datumsformat
Dim $svalidityTime = '1200' ; angabe in Min
$sDatetime = $sDate & ' ' & $sTime ; zusammenfassen der Var
If _DateIsValid($sDatetime) Then ; prüft auf Gültigkeit
Dim $iDateCalc = _DateDiff('n', $sDatetime, _NowCalc())
;~ ConsoleWrite('$iDateCalc= ' & $iDateCalc & @LF) ; mur zu testzwecken
If $iDateCalc > $svalidityTime Then ; Abfrage
Return 0
Else
Return 1
EndIf
Else
Return 2
EndIf
EndFunc ; ==>_getValidTrain
VG Jescho