2 Diminsonale Array Einträge verschieben

  • Hallo zusammen,

    ich habe ein kleines Problem mit meinem Array. Ich lege ein 2 Diminsionales Array an, dass in einer Ini Datei gespeichert wird und anschließend in einer ListView eingelesen wird.

    Zum Hintergrund: Man kann aus der ListView über eine Button einträge löschen, diese werden in der Ini Datei und dem Array dann durch den Eintrag "leer" überschreiben, damit das anschließende einlesen einfacher ist.
    Diese Einträge "leer" werden dann beim Einlesen in die LsitView übersprungen.

    Mein Problem besteht jetzt darin, dass wenn diese Einträge "ller" beim einlesen übersprungen werden, ich anschließend keine weiteren Einträge löschen kann, da der Index im Array bzw. in der Ini Datei nicht mehr mit den Angaben in der ListView über einstimmt.

    Ich müsste also eigentlich nur Wissen, wie ich es schaffe dass die Einträge im 2 Diminsionalen Array anschließend getauscht werden, also z.B so

    Vor dem Löschen:

    1=abc
    2=def
    3=ghi
    4=jkl

    Nach dem Löschen:

    1=abc
    2=def
    3=leer
    4=jkl

    Was sein sollte:

    1=abc
    2=def
    3=jkl

    Habe bereits gefunden, dass man mit _SwapArray arbeiten kann, allerdings nur im 1Deminsioanlenbereich.

    Kann mir da vielleicht einer weiterhelfen???


    Quellcode:

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

    Func ListBox_Mitarbeiter_fuellen()


    $Array2 = IniReadSection($Pfad_Mitarbeiter&"\Mitarbeiter.ini", "Mitarbeiter")
    $LastIndex = $Array2[0][0]

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

    For $i = 1 To $LastIndex Step 1


    MsgBox(0,"",$Array2[$i][0]&" | "&$Array2[$i][1])

    If $Array2[$i][1] <> "leer" Then

    GUICtrlCreateListViewItem($Array2[$i][0] & "|" & $Array2[$i][1], $Mitarbeiter_List)

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

    ; Hier soll der Wechsel stattfinden
    ;If $Array2[$i][1] = "leer" Then

    ; _ArraySwap($Array2[$i][1], $Array[$i][1+1])

    ;EndIf

    EndIf


    Next
    Return $LastIndex
    EndFunc

    [/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit]
  • Ich hab so was ähnliches als Passwort Saver gemacht, vielleicht helfen dir diese Schnipsel einwenig weiter.

    Löschen

    [autoit]

    Func _Delete()
    If GUICtrlRead(GUICtrlRead($ListView1)) = "" Then
    MsgBox(16, "Meldung!", "Keine Zelle ausgewählt.")
    Else
    $Lst = GUICtrlRead(GUICtrlRead($ListView1))
    $Lst_Result = StringSplit($Lst, "|")
    Global $Section = $Lst_Result[1]
    IniDelete(@ScriptDir & "\Save.ini", "Save", $Section)
    _AkList()
    EndIf
    EndFunc ;==>_Delete

    [/autoit]

    Aktuallisieren von der ListView

    [autoit]

    Func _AkList()
    _GUICtrlListView_DeleteAllItems($ListView1)
    $List = IniReadSection(@ScriptDir & "\Save.ini", "Save")
    For $i = 1 To UBound($List) - 1
    GUICtrlCreateListViewItem($List[$i][0] & "|" & $List[$i][1], $ListView1)
    Next
    EndFunc ;==>_AkList

    [/autoit]

    AutoIt.de :love:

  • Danke für eure Unterstützung :)

    Musste nochmal den Thread öffen:

    Generell funktioniert die ArrayMore.au3 und lässt sich auch auf mein Problem ansetzten. Dafür auf jeden Fall ein großes Dankeschön :)
    Allerdings löscht die ArrayMore den Index nur nach dem Index z.B Index = 5, aber nicht nach dem kriterium Index = 5 Value = "leer".

    Soll heißen, dass ich wie schon gesagt alle Index Einträge mit der Value = leer aus dem Array löschen möchte noch nicht ganz funktioniert, da lediglich nach dem Index gefiltert wird.
    Da ich aber im Endeffekt nicht weiß, an welchem Index "leer" steht klappte es noch nicht ganz.

    Mein Array sieht z.B so aus (Eintrag leer steht nicht starr auf einem Index):

    [Abc]

    0= abc
    1=leer
    2=ghi
    3=jkl
    4=leer


    Mach ich irgendwas falsch?


    [autoit]


    Func ListBox_Mitarbeiter_fuellen()


    $Array2 = IniReadSection($Pfad_Mitarbeiter&"\Mitarbeiter.ini", "Mitarbeiter")
    $LastIndex = $Array2[0][0]

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

    For $i = 1 To $LastIndex Step 1
    $Col = 5


    ;~ MsgBox(0,"",$Array2[$i][0]&" | "&$Array2[$i][1])

    If $Array2[$i][1] <> "leer" Then

    GUICtrlCreateListViewItem($Array2[$i][0] & "|" & $Array2[$i][1], $Mitarbeiter_List)
    _ArrayDisplay($Array2)
    _Array2DDelete($Array2,$Col)
    ;~ _Array2DDelete(ByRef $ARRAY, $iDEL)

    EndIf

    Next
    Return $LastIndex
    EndFunc

    [/autoit]
  • könnt zwar sein das ich was falsch verstehe aber wo liegt das problem nicht einfach folgendes zu machen?

    [autoit]

    if $Array2[$i][1] == "leer" then _Array2DDelete($Array2,$i)

    [/autoit]

    mfg
    sgtigram

  • Das habe ich natürlich als erstes gemacht, es funktioniert aber nicht.

    Die Bedingung:

    [autoit]

    If $Array2[$i][1] = "leer" then _Array2DDelete($Array2, $i)

    [/autoit]

    wird einfach ignoriert

    Quellcode:

    [autoit]

    Func ListBox_Mitarbeiter_fuellen()

    $Array2 = IniReadSection($Pfad_Mitarbeiter&"\Mitarbeiter.ini", "Mitarbeiter")
    $LastIndex = $Array2[0][0]

    For $i = 1 To $LastIndex Step 1
    ;~ $Row = 12
    ;~ $Casesens=0
    ;~ $CASESENS=0

    If $Array2[$i][1] <> "leer" Then

    GUICtrlCreateListViewItem($Array2[$i][1], $Mitarbeiter_List)
    _ArrayDisplay($Array2, "Mitarbeiter")


    ;~ IniWrite($Pfad_Mitarbeiter&"\Mitarbeiter1.ini", "Mitarbeiter1", $i, $Array2[$i][1])
    ;~ GUICtrlCreateListViewItem($Array2[$i][0] & "|" & $Array2[$i][1], $Mitarbeiter_List)
    ;~ _Array2DDblDel($Array2)
    ;~ _Array2DDblDel($Array2, $Casesens)

    If $Array2[$i][1] = "leer" then _Array2DDelete($Array2, $i)


    ;~ _Array2DDelete($Array2,$i)
    ;~ _Array2DDblDel($Array2)
    ;~ _Array2DDblDel(ByRef $ARRAY [, $CASESENS=0])
    ;~ _Array2DDelete($Array2,$Row)
    ;~ _Array2DDelete(ByRef $ARRAY, $iDEL)
    ;~ $ArrayA = IniReadSection($Pfad_Mitarbeiter&"\Mitarbeiter1.ini", "Mitarbeiter1")
    ;~ GUICtrlCreateListViewItem($ArrayA[$i][1], $Mitarbeiter_List)

    EndIf

    Next
    Return $LastIndex
    EndFunc

    [/autoit]


    Wenn ich es mit eine ElseIf versuche bekomme ich die Fehlermeldung, die im Anhang zusehen ist angezeigt, die für mich keinen Sinn macht, aber da ich noch ziemlich Nobby im Thema Autoit bin...

    autoit.de/wcf/attachment/23775/

    Wenn ich die erste If-Bedingung weglasse:

    [autoit]

    If $Array2[$i][1] <> "leer" Then

    GUICtrlCreateListViewItem($Array2[$i][1], $Mitarbeiter_List)
    _ArrayDisplay($Array2, "Mitarbeiter")

    [/autoit]

    und nur

    [autoit]

    If $Array2[$i][1] = "leer" then _Array2DDelete($Array2, $i)

    [/autoit]

    dann klappt es insofern, dass die Einträge "leer" aus dem Array entfernt werden, allerding gibt es dann wieder eine Fehlermeldung. Der Error ist genau der Selbe, wie im Screenshot bei dem anderen Fehler.

    Ich finde das Problem aber nicht ?(?(

    • Offizieller Beitrag

    Die Fehlermeldung besagt, dass du auf ein Arrayelement verweisen willst, das gar nicht existiert. Indexfehler.
    Lass dir einfach beim Abarbeiten des Arrays in jedem Durchlauf den Index und zugehörige Werte ausgeben. Du wirst sehen das läuft durch und dann bricht es mit besagter Fehlermeldung ab, weil du plötzlich ausserhalb des Arrays adressierst.
    Verwende einfach mal Ubound($Array) -1 als letzten Index ;), dann kannst du nicht ausserhalb landen.

    • Offizieller Beitrag

    Ich vermute mal, das der Fehler kommt, weil mehrer Elemente aus dem Array gelöscht wurden.
    Wenn ein Element entfernt wird, verringert sich die Anzahl der Arrayelemente.
    Selbst wenn die For Schleife mit Ubound -1 als Zähler initialisiert wird, kann es zu dem Fehler kommen.
    Die Ubound Abfrage wird ja vor dem Löschen getätigt und somit kann diese Angabe bei gelöschen Arrayelementen nicht mehr stimmen.
    Einfachste Lösung: Array von hinten anfangen abzufragen und löschen.

    Die For Schleife also so ansetzen:

    [autoit]

    For $i = UBound($array2) -1 To 1 Step -1

    [/autoit]


    Da die Abfrage beim letzten Element beginnt, kann es nicht passieren, das versucht wird ein nicht mehr existierendes Element zu löschen. ;)

  • naja.. als erstes springt mir ins auge das dir eindeutig gewisse basics fehlen...
    wie kann denn die bedingung

    [autoit]

    If $Array2[$i][1] = "leer" then _Array2DDelete($Array2, $i)

    [/autoit]


    zutreffen wenn gleichzeitig

    [autoit]

    If $Array2[$i][1] <> "leer" Then

    [/autoit]


    zutrifft?!

    und der error kommt weil du natürlich wenn ein element gelöscht wird auch $lastindex - 1 rechnen musst.. da du ja jetzt ein element weniger drin hast..

    //edit: keine ahnung wie das meine vorrredner übersehen konnten :D.. bin zutiefst enttäuscht :D

    • Offizieller Beitrag

    Falsch.

    [autoit]

    If $Array2[$i][1] = "leer" then _Array2DDelete($Array2, $i)

    [/autoit]


    wird nach

    [autoit]

    If $Array2[$i][1] <> "leer" Then

    [/autoit]


    ausgeführt, also kommt der Fehler nicht daher :P

    • Offizieller Beitrag

    Ich hab das, glaub ich, vor deinem Edit anders gelesen, aber egal. Vielleicht habe ich Alzheimer. :rolleyes:

  • Ich hab das, glaub ich, vor deinem Edit anders gelesen, aber egal. Vielleicht habe ich Alzheimer. :rolleyes:

    nunja.. das liegt dann aber an dir.. bei meinem edit hab ich lediglich die editzeile angehängt.. so wie es sich gehört ;D.. und an seinem quellcode ändert das ja auch nichts das es unsinn ist dass das eine if im anderen ist..

    und nur ubound()-1 geht natürlich auch.. ich habe aber mit absicht $lastindex-1 geschrieben da er $lastindex als return zurückgibt.. da hat er dann ja nen falschen wert wenn er nur einmal ubound()-1 in der schleife verwendet

    • Offizieller Beitrag

    Hab doch geschrieben das ich Alzheimer habe. Kann auch sein das ich durch das C>odewirrwarr des TE durcheinander bin. :D

  • So Leute, ihr hab die ersten Fehler schonmal ausgemerzt und werde mal eure beiden Vorschläge versuchen :)

    Edit:

    Herzlichsten Dank Leute =) Der Tipp mit Ubound($Array2)-1 to 0 Step-1 war genau das was ich brauchte und ich noch nicht kannte :)


    Jetzt kann ich endlich weiter machen.

    Vielen vielen Dank =)