Auf einmal Fehler im Array: "Subscript used on non-accessible variable"

  • Hallo zusammen,

    ich habe mir ein kleines Script zusammengestellt, um unterwegs Zahlungsbelege drucken zu können.

    Da ich ein völliger AU-Noob bin, wollte erst einmal die Kernfunktion sicherstellen und dann das Script langsam erweitern. Nachdem alles funktionierte, habe ich mich an die zusätzliche Speicherung eines Hash-Wertes gemacht, um den rechtlichen Vorschriften bez. Veränderungssicherheit zu entsprechen. Das klappte auch wunderbar.

    Dann fiel mir ein, dass der Hash-Wert sowie der Grund der Zahlung vielleicht auch in meinem ListView angezeigt werden sollten, der Vollständigkeit halber. Und schon ist es passiert: Seit ich die Variablen für Grund und Hash eingebaut habe, bricht das Script genau an der Stelle (Zeile 35 im nachstehenden Code) ab mit:

    AutoIt: Fehlermeldung
    Subscript used on non-accessible variable.:
    _ArrayAdd( $aGrundRes , $aGrund[0] )
    _ArrayAdd( $aGrundRes , $aGrund^ ERROR


    Hier das Script:

    In data.txt steht Folgendes:

    Code: data.txt
    10001;29.01.2017;88888;Eisen-Schmidt;Erwin Meier;Teststraße 99;55555;Testort;123,99;Testgrund;srgrewfwredgfsfd
    10002;30.01.2017;99999;Holzwurm e.K.;Walter Schmitt;Probestraße 4;66666;Probeort;321,50;Probentest;43262465565247657

    Und in der settings.ini die laufende Nummer:

    Code: settings.ini
    [CurrentData]
    LfdNr=10003


    Mich würde der Fehler ja nicht verblüffen, wenn es bis zur Hinzunahme von $aGrund / $aGrundRes bzw. $aSHA256 / $aSHA256Res nicht wunderbar geklappt hätte. Und wenn Globals nicht accessible sind, tja; irgendwas läuft da verkehrt. 8|

    (Die lange String-Wurst zum Auslesen der Zeilen mag eleganter gehen, aber so funktionierte es erst mal)

    Fällt Euch vielleicht etwas dazu ein, woran mein Problem liegen könnte?

  • Hallo @Dexter,

    Nach deinen letzten _StringBetween-OPs hast du einfach vergessen das Element anzugeben und hast das Array wie eine Variable angegeben.

    AutoIt
    $aSHA256 = _StringBetween( $sLine , $aLfdNr[0] & ";" & $aDate[0] & ";" & $aKundenNr[0] & ";" & $aKunde[0] & ";" & $aKundeZusatz[0] & ";" & $aStrasze[0] & ";" & $aPLZ[0] & ";" & $aOrt[0] & ";" & $aBetrag & ";" & $aGrund & ";" , "" ) ; müsste doch auch $aBetrag[0] und $aGrund[0] sein..

    Statt den ganzen _StringBetween wäre es einfacher du würdest nach dem Einlesen die aktuelle Zeile mit StringSplit in ein Array trennen. Dann wäre das erste Element des entstandenen Arrays $LfdNr, das zweite $Date usw. ..


    Alternativ könntest du die Datei auch gleich mit _FileReadToArray in ein Array lesen. Da kann man als Parameter ein Trennzeichen angeben (hier ;). Dann hast du schon alles gesplittet.

    Da du ja weißt, dass bspw. $Date ist immer Index 1 ist, bietet sich hier mal Enum an, wenn man die Elemente dennoch bezeichnen möchte (was natürlich nicht notwendig ist).

    Spoiler anzeigen

    Vom _ArrayAdd könnte man auch noch weg. Allerdings verstehe ich nicht, warum du die Werte überhaupt in unterschiedliche Arrays speicherst. Das ist wahrscheinlich gar nicht notwendig. Du kannst deine Gedanken ja nochmal erklären, wenn du magst.

    Grüße autoiter

  • AutoIt
    $aGrund = _StringBetween( $sLine , $aLfdNr[0] & ";" & $aDate[0] & ";" & $aKundenNr[0] & ";" & $aKunde[0] & ";" & $aKundeZusatz[0] & ";" & $aStrasze[0] & ";" & $aPLZ[0] & ";" & $aOrt[0] & ";" & $aBetrag & ";" , ";" )
    		_ArrayAdd( $aGrundRes , $aGrund[0] )
    		$aSHA256 = _StringBetween( $sLine , $aLfdNr[0] & ";" & $aDate[0] & ";" & $aKundenNr[0] & ";" & $aKunde[0] & ";" & $aKundeZusatz[0] & ";" & $aStrasze[0] & ";" & $aPLZ[0] & ";" & $aOrt[0] & ";" & $aBetrag & ";" & $aGrund & ";" , "" )


    Zeile 33: Hinter $aBetrag fehlt das [0]
    Zeile 35: Hinter $aBetrag und $aGrund fehlt das [0]

    Richtig wäre:

    AutoIt
    $aGrund = _StringBetween( $sLine , $aLfdNr[0] & ";" & $aDate[0] & ";" & $aKundenNr[0] & ";" & $aKunde[0] & ";" & $aKundeZusatz[0] & ";" & $aStrasze[0] & ";" & $aPLZ[0] & ";" & $aOrt[0] & ";" & $aBetrag[0] & ";" , ";" )
    		_ArrayAdd( $aGrundRes , $aGrund[0] )
    		$aSHA256 = _StringBetween( $sLine , $aLfdNr[0] & ";" & $aDate[0] & ";" & $aKundenNr[0] & ";" & $aKunde[0] & ";" & $aKundeZusatz[0] & ";" & $aStrasze[0] & ";" & $aPLZ[0] & ";" & $aOrt[0] & ";" & $aBetrag[0] & ";" & $aGrund[0] & ";" , "" )
    		_ArrayAdd( $aSHA256Res , $aSHA256[0] )


    Doch schau mal hier:

  • Lieber @autoiter, lieber @Bitnugger,

    es ist unglaublich. Man sieht manchmal echt den Wald vor lauter Bäumen nicht, wenn man vor dem eigenen Code sitzt. Ihr glaubt nicht, wie oft ich mir genau diese Stellen angeschaut habe... :Face:

    Hallo @Dexter,

    Nach deinen letzten _StringBetween-OPs hast du einfach vergessen das Element anzugeben und hast das Array wie eine Variable angegeben.
    [...]
    Vom _ArrayAdd könnte man auch noch weg. Allerdings verstehe ich nicht, warum du die Werte überhaupt in unterschiedliche Arrays speicherst. Das ist wahrscheinlich gar nicht notwendig. Du kannst deine Gedanken ja nochmal erklären, wenn du magst.

    Vielen Dank für die schnelle Hilfe und natürlich auch für Eure Beispiele, die sind natürlich Gold wert und wesentlich eleganter gelöst als mein planloses Geschreibsel. :thumbup:
    Ich werde mal schauen, ob ich die so auch bei mir integrieren kann.

    Kurz zur Erklärung: Mein geposteter Teil bezieht sich auf das Auslesen der Daten für den ListView. Dargestellt werden die dann anschließend so:

    Jetzt muss ich nur noch herausfinden, wie ich in dem ListView eine Zeile auswählen und per Klick auf einen Button eine Belegkopie drucken kann. Soll ich das vielleicht nochmal in einen anderen Thread packen?

    LG

    Dexter :)

  • Hi @Dexter

    dachte ich mir schon. Hier ist es wirklich nicht notwendig, dass du alles in eigenen Arrays speicherst. Wenn du alles schon in einem Array hast, wie im Skript von @Bitnugger oder mir ($aFile[$i][$eLfdNr], $aFile[$i][$eDate] usw.), dann kannst du auch einfach damit weiter arbeiten. Wenn du sprechende Variablennamen bei den Enums nimmst ($eLfdNr ..) müsste das doch auch so für dich nachvollziehbar bleiben, oder?

    Die Klicks sind ganz einfach. Du kannst beim Buttonclick z.B. einfach _GUICtrlListView_GetSelectionMark auswerten.
    EDIT: (Falls es bei deiner weiteren Frage nur um die Listview ging. Ansonsten nochmal fragen ;) ).

    Grüße autoiter

  • Danke, ich werde das definitiv noch umstellen, sobald die sonstige Funktionalität steht. Allein schon, damit ich es künftig direkt weniger umständlich machen kann. :)

    Ich habe das mit dem _GUICtrlListView_GetSelectionMark mal ausprobiert. In der MsgBox steht dann aber letztendlich nur "Selected Mark: 1", wenn ich eine Zeile in der ListView markiere und dann auf den Button $btnPrintCopy klicke.

    Muss ich da vielleicht noch was übergeben, damit ich den Inhalt der ganzen Zeile bekomme? (Es soll nach Möglichkeit auch nur eine Zeile auswählbar sein, falls das einen Unterschied macht.)

  • Hallo @Dexter,

    Nein so nicht.

    AutoIt
    _GUICtrlListView_SetSelectionMark($hListview, 1)
    				MsgBox($MB_SYSTEMMODAL, "Information", "Selected Mark: " & _GUICtrlListView_GetSelectionMark($hListview))

    Hier markierst du ja erst den ersten Eintrag:

    AutoIt
    _GUICtrlListView_SetSelectionMark($hListview, 1)

    und dann wertest du das in der nächsten Zeile aus. :D

    Lass das _GUICtrlListView_SetSelectionMark mal weg und schau, was dann heraus kommt. Du hast dann den Indexwert. Den kannst du auf dein Array anwenden.

    AutoIt
    $iIndex = _GUICtrlListView_GetSelectionMark($hListview)
    
    
    ....
    
    
    $aFile[$iIndex][$eLfdNr] ; So wie es bei mir aussah. Bei dir vllt. $aLfdNrRes[$iIndex]

    EDIT: PS: Bei der Listview gibt's viele Wege an die Daten zu kommen. Du kannst auch alles wieder direkt aus der Listview auslesen. _GUICtrlListView_GetSelectionMark ist nur eine von vielen Varianten. Kannst dich ja mal bei den _GUICtrlListView_-Funktionen umschauen.

    Grüße autoiter

    Einmal editiert, zuletzt von autoiter (31. Januar 2017 um 15:37)

  • Ganz tolle Hilfe zur Selbsthilfe, wirklich! :)

    Der folgende Code gibt mir alles schön in einer MsgBox aus:

    AutoIt: Markiertes ListViewItem auslesen
    Case $btnPrintCopy
    	$iIndex = _GUICtrlListView_GetSelectionMark( $hListview )
    	$text =   _GUICtrlListView_GetItemTextString( $hListview , $iIndex )
    	MsgBox( 0 , " " , $text )

    Und was in einer MsgBox lesbar ist, kann man ja auch prima zerpflücken und weiterverarbeiten. :thumbup:

    Euch beiden noch mal vielen herzlichen Dank; mir wäre alleine ein Bart gewachsen, bis ich das hinbekommen hätte. Ihr rockt! :rock: