CSV Datei auslesen und bearbeiten; Script von Oscar

  • Vorwort: :D
    Diesen Post hab ich bereits in einem anderen Thread gestellt, dieser war jedoch schon gelöst und ist sicherlich in der breiten Masse untergegangen. Siehe diesen Thread hier... Deshalb mach ich ihn nochmal neu und bitte hiermit die Moderatoren mich nicht zu tadeln :whistling:

    Das Script im Spoiler ist das, was Oscar gebaut hat, deshalb ist mein Anliegen mehr an ihn gerichtet. Aber nicht falsch verstehen, jede hilfreiche Antwort ist willkommen ;)


    Hi Oscar,

    ich find dein Script echt klasse, sowas hab ich auch schon versucht zu basteln. Leider bin ich immer noch nicht gut genug für sowas, deshalb hab ich auchnach genau solch einem Script gesucht.

    Spoiler anzeigen
    [autoit]


    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <ListViewConstants.au3>
    #include <WindowsConstants.au3>

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

    Global $sHeader = "Artikelnummer|Art|Nummer|Baureihe|Name" ; 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("Listview-Datenbank-Beispiel", 600, 480) ; Hauptfenster erstellen
    GUISetBkColor(0xCCCCCC)

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

    Global $hListView = GUICtrlCreateListView($sHeader, 0, 0, 600, 400, $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, "Artikelnummer", 120, 1) ; 1. Spalte = 120 Px breit, rechts ausgerichtet
    _GUICtrlListView_SetColumn($hLVHandle, 1, "Art", 60, 0) ; 2. Spalte = 60 Px breit, links ausgerichtet
    _GUICtrlListView_SetColumn($hLVHandle, 2, "Nummer", 90, 0) ; 3. Spalte = 90 Px breit, links ausgerichtet
    _GUICtrlListView_SetColumn($hLVHandle, 3, "Baureihe", 100, 0) ; 4. Spalte = 100 Px breit, links ausgerichtet
    _GUICtrlListView_SetColumn($hLVHandle, 4, "Name", 120, 0) ; 5. Spalte = 120 Px breit, links ausgerichtet

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

    Global $hSearchListView = GUICtrlCreateListView($sHeader, 0, 0, 600, 400, $LVS_SHOWSELALWAYS) ; Listview für die Suche erstellen
    GUICtrlSetState(-1, $GUI_HIDE)
    Global $hSearchLVHandle = GUICtrlGetHandle($hSearchListView) ; das Handle vom Listview wird für die UDF-Listview-Funktionen benötigt
    _GUICtrlListView_SetColumn($hSearchLVHandle, 0, "Artikelnummer", 120, 1) ; 1. Spalte = 120 Px breit, rechts ausgerichtet
    _GUICtrlListView_SetColumn($hSearchLVHandle, 1, "Art", 60, 0) ; 2. Spalte = 60 Px breit, links ausgerichtet
    _GUICtrlListView_SetColumn($hSearchLVHandle, 2, "Nummer", 90, 0) ; 3. Spalte = 90 Px breit, links ausgerichtet
    _GUICtrlListView_SetColumn($hSearchLVHandle, 3, "Baureihe", 100, 0) ; 4. Spalte = 100 Px breit, links ausgerichtet
    _GUICtrlListView_SetColumn($hSearchLVHandle, 4, "Name", 120, 0) ; 5. Spalte = 120 Px breit, links ausgerichtet

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

    GUICtrlCreateLabel("Suchbegriff:", 10, 412, 90, 20)
    GUICtrlSetFont(-1, 11)
    Global $hSearch = GUICtrlCreateInput("", 100, 410, 390, 20)
    GUICtrlSetFont(-1, 11)
    Global $hSearchStart = GUICtrlCreateButton("Suche...", 500, 410, 60, 20, $BS_DEFPUSHBUTTON) ; Dieser Button ist der Default-Push-Button (wenn der User [Enter] drückt)
    GUICtrlSetFont(-1, 9)
    Global $hSearchReset = GUICtrlCreateButton("<-", 562, 410, 28, 20)
    GUICtrlSetFont(-1, 8, 600, 0, "Verdana")
    GUICtrlSetState(-1, $GUI_DISABLE)

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

    Global $hNew = GUICtrlCreateButton("Neuer Eintrag", 5, 440, 80, 35)
    Global $hEdit = GUICtrlCreateButton("Markierten Eintrag bearbeiten", 95, 440, 110, 35, $BS_MULTILINE) ; $BS_Multiline für mehrzeiligen Button
    Global $hLoad = GUICtrlCreateButton("Laden", 230, 440, 70, 35)
    Global $hSave = GUICtrlCreateButton("Speichern", 310, 440, 70, 35)
    Global $hDel = GUICtrlCreateButton("Markierte Einträge löschen", 400, 440, 90, 35, $BS_MULTILINE)
    Global $hDelAll = GUICtrlCreateButton("Alle Einträge löschen", 500, 440, 90, 35, $BS_MULTILINE)

    [/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("Neuer Eintrag", 632, 140, -1, -1, $WS_SYSMENU) ; das Fenster "Neuer Eintrag" erstellen
    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) * 125, 15, 110, 20) ; Überschriften-Label erstellen
    GUICtrlSetFont(-1, 8, 400, 0, 'Verdana') ; Schriftgröße und -art der Überschriften festlegen
    $aNew[$i - 1] = GUICtrlCreateInput("", 2 + ($i - 1) * 125, 30, 120, 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", 254, 65, 120, 25, $BS_DEFPUSHBUTTON) ; Button zum speichern
    #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]

    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 $hSearchStart
    GUICtrlSetState($hSearchStart, $GUI_DISABLE)
    _GUICtrlListView_DeleteAllItems($hSearchLVHandle)
    Dim $sSearch = GUICtrlRead($hSearch), $sItem
    For $i = 0 To _GUICtrlListView_GetItemCount($hLVHandle) - 1
    $sItem = _GUICtrlListView_GetItemTextString($hLVHandle, $i)
    If StringInStr($sItem, $sSearch) Then GUICtrlCreateListViewItem($sItem, $hSearchListView)
    Next
    GUICtrlSetState($hListView, $GUI_HIDE)
    GUICtrlSetState($hSearchListView, $GUI_SHOW)
    GUICtrlSetState($hSearchReset, $GUI_ENABLE)
    Case $hSearchReset
    GUICtrlSetData($hSearch, "")
    GUICtrlSetState($hSearchListView, $GUI_HIDE)
    GUICtrlSetState($hListView, $GUI_SHOW)
    GUICtrlSetState($hSearchStart, $GUI_ENABLE)
    GUICtrlSetState($hSearchReset, $GUI_DISABLE)
    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()
    Case $hLoad ; User hat auf "Laden" geklickt
    Load()
    Case $hSave ; User hat auf "Laden" geklickt
    Save()
    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)
    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)
    Case $hCreate ; User hat auf "Eintrag speichern" im Fenster "Neuer Eintrag" geklickt
    NewItem()
    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 End()
    ;~ Save() ; wenn der vordere Kommentar entfernt wird, dann werden vor dem beenden noch die Daten gespeichert
    _GUICtrlListView_UnRegisterSortCallBack($hLVHandle) ; Sortierroutine wieder de-registrieren
    Exit ; Programm beenden
    EndFunc ;==>End

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

    Func NewItem() ; Funktion zum auslesen der Eingabefelder (Neuer Eintrag bzw. Eintrag bearbeiten)
    Local $sItem = ""
    For $i = 0 To UBound($aNew) - 1 ; Schleife, um alle Eingabefelder durchzugehen
    If $iEdit > -1 Then ; wenn $iEdit > -1 (Eintrag bearbeiten), dann...
    _GUICtrlListView_SetItemText($hLVHandle, $iEdit, GUICtrlRead($aNew[$i]), $i) ; den Eintrag aus dem Eingabefeld ins Listview schreiben
    Else ; sonst $iEdit = -1 (neuer Eintrag)
    $sItem &= GUICtrlRead($aNew[$i]) & "|" ; den Eintrag aus dem Eingabefeld erstmal in einer Variablen ($sItem) speichern
    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)
    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
    EndFunc ;==>NewItem

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

    Func Edit() ; Funktion zum bearbeiten eines Listview-Eintrags im "Eintrag bearbeiten"-Fenster
    $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
    Local $hFile, $sContent, $aNewItems
    $hFile = FileOpen($sDBFile, 0) ; Datei zum lesen öffnen
    If $hFile <> -1 Then ; wenn das öffnen erfolgreich war, dann...
    $sContent = FileRead($hFile) ; Datei komplett einlesen
    FileClose($hFile) ; Datei schließen
    $sContent = StringTrimRight($sContent, 2) ; das letzte @CRLF entfernen
    $aNewItems = StringSplit($sContent, @CRLF, 1) ; Den Dateiinhalt am Zeilenende splitten
    If Not IsArray($aNewItems) Then Return ; Wenn $aNewItems kein Array ist, dann Funktion verlassen
    _GUICtrlListView_BeginUpdate($hLVHandle) ; Listview sperren
    For $i = 1 To $aNewItems[0] ; Alle Einträge des Arrays durchgehen
    GUICtrlCreateListViewItem($aNewItems[$i], $hListView) ; mit den eingelesenen Daten einen neuen Listview-Eintrag erstellen
    Next
    _GUICtrlListView_EndUpdate($hLVHandle) ; Listview wieder freigeben
    EndIf
    EndFunc ;==>Load

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

    Func Save() ; Datenbank-Datei speichern
    Local $sItem, $hFile, $iCount
    $iCount = _GUICtrlListView_GetItemCount($hLVHandle) - 1 ; Anzahl der Listview-Einträge holen
    If $iCount = -1 Then Return FileDelete($sDBFile) ; Wenn das Listview keine Einträge enthält, dann Datei löschen und Funktion verlassen
    $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
    FileWriteLine($hFile, $sItem) ; und in die Datei schreiben
    Next
    FileClose($hFile) ; Datei schließen
    EndIf
    EndFunc ;==>Save

    [/autoit]

    Meine Frage:
    Wenn ich auf den Button "neuer Eintrag" klicke erscheint ja ne neue GUI mit den Eingabefeldern. Die Eingabefelder hab ich bereits für mich angepasst, es sind nun mehr (12 Stück). Leider passt das nicht mit der GUI. Es werden nicht alle Eingabefelder angezeigt, denn die Felder sind nebeneinander angeordnet. Gibt es eine Möglichkeit, die Eingabefelder untereinander aufzulisten?

    Für mich persönlich wär das echt wichtig.

  • Hi Lottich,
    herzlich willkommen. Um GUI's (graphic user interface) wie in deinem Fall mit den Buttons zu bearbeiten würde ich dir einfach empfehlen den Kodak Form Designer zu holen (hier z.B.:http://www.autoitscript.com/fileman/users/…formdesign.html) Mit dem kannst du in Zukunft dein GUI schnell und einfach erstellen und per Klick sogar in einen Autoit-Code umwandeln.

    Nun noch direkt zu deiner Frage: Die Größe des gesamten GUI's kannst du bei dessen Erstellung ändern (GuiCreate). Zwei dieser Parameter sind Länge und Breite, diese musst du erweitern, wie du sie brauchst (nutze dazu am besten die Hilfe - einfach GUICreate anklicken und F1 drücken)

    Viel Erfolg ;)
    Aquaplant

  • Zeile 62 bis 72:

    Spoiler anzeigen
    [autoit]

    Global $hGuiNew = GUICreate("Neuer Eintrag", 400, 400, -1, -1, $WS_SYSMENU) ; das Fenster "Neuer Eintrag" erstellen
    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 , 18 + ($i - 1) * 28, 110, 20) ; Überschriften-Label erstellen
    GUICtrlSetFont(-1, 8, 400, 0, 'Verdana') ; Schriftgröße und -art der Überschriften festlegen
    $aNew[$i - 1] = GUICtrlCreateInput("", 110, 15 + ($i - 1) * 28, 120, 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", 254, 15 + ($i - 2) * 28, 120, 25, $BS_DEFPUSHBUTTON) ; Button zum speichern

    [/autoit]


    Koda wird hier nicht viel helfen. Die Controls werden dynamisch in einer Schleife erstellt.

  • Alter, wie g**l!!!
    Genau das ist es! Vielen Dank !!! :rock:

    Und mal ganz nebenbei erwähnt:

    Hier gibt es so viele User die hervorragende und exellente Hilfe bieten und Lösungswege aufzeigen! Das ist wirklich beeindruckend!
    Ihr macht hier nen echt Klasse Job!!!

    *musste ich mal los werden*

    Edit:
    Ich setz den Themenstatus mal noch nicht auf gelöst, denn ich muss hier noch ein paar Sachen hinzufügen. da werd ich vermutlich noch 1 - 2 mal auf eure
    unterstützung zurückgreifen müssen.
    Doch zunächst versuch ich es erstmal selbst 8)

    Bis die Tage, man liest sich....