Probeleme beim Netzwerkzugriff auf DB

  • 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
    [autoit]

    #include<WindowsConstants.au3>
    #include<ListViewConstants.au3>
    #include<ButtonConstants.au3>
    #include<GUIConstantsEx.au3>
    #include<Guilistview.au3>
    #include<String.au3>
    #Include<Date.au3>

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    #Region Hauptfenster
    Global $hGui = GUICreate("Ausfall Lz-Nummern", 560, 500) ; Hauptfenster erstellen
    Global $hListView = GUICtrlCreateListView($sHeader, 2, 3, 420, 470, $LVS_SHOWSELALWAYS) ; Listview erstellen

    [/autoit] [autoit][/autoit] [autoit]

    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)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    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)

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    #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

    [/autoit] [autoit][/autoit] [autoit]

    _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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    Func End() ; Funktion zum Speicher und Beenden der Datenbank
    ConsoleWrite('End() aufgerufen' & @LF)
    _GUICtrlListView_UnRegisterSortCallBack($hLVHandle) ; Sortierroutine wieder de-registrieren
    Exit
    EndFunc ;==>End

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit]

    VG Jescho

    MfG Jescho

    Jeder hat mal klein angefangen - aber nicht jeder kommt groß raus!

    Einmal editiert, zuletzt von Jescho (25. Januar 2012 um 00:47)

    • Offizieller Beitrag

    Der Denkfehler besteht darin, dass meine "Datenbank" nie für einen Mehrbenutzerzugriff gedacht war. :D

    Im Ernst: Da musst Du Vorkehrungen treffen, damit die Speicherfunktion nicht zeitgleich ausgeführt wird. Das kannst Du z.B. dadurch machen, dass Du vor dem Speichern das Dateiattribut "O = offline" bei der Datenbankdatei setzt und danach wieder löschst. Also die Savefunktion umschreiben: Prüfen, ob Attribut "O" gesetzt ist, wenn ja, dann so lange warten bis es nicht mehr gesetzt ist. Wenn es dann nicht mehr gesetzt ist, muss erst die Ladefunktion aufgerufen werden, um die neuen Daten des anderen Benutzers einzulesen. Das heißt aber, dass auch die Ladefunktion geändert werden muss, weil ja die Änderungen, die man selbst gerade gemacht hat, nicht überschrieben werden sollen.