2D Array und Variablen Problem

  • Hoi zusammen,

    anbei mein kleines Problemchen....

    [autoit]

    For $l = 0 To $rows Step 1

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

    GUICtrlSetData($Edit_Base,$array[$l][0],"")

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

    Next

    [/autoit]

    Warum bekomme ich immer diesen Fehler: Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
    Wenn ich eine andere Variable FEST definiere z.b. $r = 0 und $array[$r][0] dann funktioniert es einwandfrei...
    Was mach ich falsch? :)

    Danke schonmal :)

    Einmal editiert, zuletzt von kev84 (18. April 2011 um 11:30)

  • Wo der Fehler liegt können wir aus dem Codefetzen hier nicht sehen da wir nicht erahnen können welche Dimensionen das Array hat.
    Der Fehler liegt aber genau da.
    Du sprichst einen Index des Arrays an den es gar nicht besitzt.
    Beispiel: Dein Array besitzt folgende Dimension: $array[4][3].
    In dem Fall wirst du eine solche Fehlermeldung erhalten sobald $l > 3 (also 4) ist (warum? - 0-basiert).

  • der Array wird bis maximal $array[3][5] gefüllt an dieser Stelle, wenn ich die Variable in irgend einer Form hochzähle, bekomme ich den Fehler, definiere ich die Zahl fest, ist es kein Problem.

  • Jep hab ich, danke ^^ ist eigentlich auch total logisch, aber manchmal sitzt man auf dem Schlauch...

  • Hallo hab auch ein Array-Problem:

    [autoit]


    Dim $kunden[100]
    Dim $kunden1[100]

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

    $i = 1000
    $j = 0
    While $i < 1100
    $var1 = IniRead("kunden.ini",$i,"name","")
    If $var1 = "" Then
    Else
    $var2 = IniRead("kunden.ini",$i & "-v1","lauf","")
    $var3 = IniRead("kunden.ini",$i & "-v2","lauf","")
    $j = $j + 1
    GuiCtrlCreateLabel($var1, 15, 20*$j+30, 180, 20)
    $kunden1[$i] = $kunden[$i]
    GuiCtrlCreateLabel($i, 200, 20*$j+30, 180, 20)
    GUICtrlSetOnEvent(-1, "_KundenVerwaltung")
    GuiCtrlCreateLabel($var2, 250, 20*$j+30, 80, 20)
    GuiCtrlCreateLabel($var3, 340, 20*$j+30, 80, 20)
    EndIf
    $i = $i + 1
    WEnd

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

    Func _KundenVerwaltung()
    ; $arSplit = [$i]
    ; _ArrayDisplay($kunden1)
    MsgBox(64,$kunden1, GUICtrlRead($kunden1))
    ; Exit
    EndFunc

    [/autoit]

    Bei OnEvent soll $i (=Kundennummer) zur MsgBox übertragen werden, ich bekomme immer dieselbe Zahl oder Fehlermeldung.

  • Ich hab dir mal ein paar Zeilen aus deinem Skript herausgezogen und bisschen kommentiert.
    So solltest du selbst sehen wo das Problem liegt:

    Spoiler anzeigen
    [autoit]

    Dim $kunden1[100] ; Array mit Platz für 100 Einträge

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

    $i = 1000 ; beginne mit 1000

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

    While $i < 1100 ; Solange bis $i = 1099

    $kunden1[$i] = $kunden[$i]
    ; Im Ersten Durchlauf bedeutet das:
    ; $kunden1[1000] = $kunden[1000]

    [/autoit]
  • Ich hab dir mal ein paar Zeilen aus deinem Skript herausgezogen und bisschen kommentiert.
    So solltest du selbst sehen wo das Problem liegt:

    Spoiler anzeigen
    [autoit]

    Dim $kunden1[100]; Array mit Platz für 100 Einträge

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

    $i = 1000; beginne mit 1000

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

    While $i < 1100; Solange bis $i = 1099

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

    $kunden1[$i] = $kunden[$i]
    ; Im Ersten Durchlauf bedeutet das:
    ; $kunden1[1000] = $kunden[1000]

    [/autoit]

    Na gut dann Dim $kunden1[1000] oder Dim $kunden1[10000], bringt mir aber trotzdem nicht $i zur MsgBox. Es wird eine Liste erzeugt, und beim Klick auf

    [autoit]


    GuiCtrlCreateLabel($i, 200, 20*$j+30, 180, 20)
    GUICtrlSetOnEvent(-1, "_KundenVerwaltung")

    [/autoit]


    soll $i ausgegeben werden.
    Die Liste ist übrigens ok.

  • Wenn du den Index 1000 eines Arrays ansprichst welches nur 100 Elemente beinhaltet willst du auf Speicher zugreifen der dir gar nicht zur Verfügung steht.
    Das muss in einem Fehler enden.
    Bevor du also dich auf weitere Aufgabe stürzt solltest du erstmal diese Fehler beseitigen.
    Und ein Dim $kunden1[1000] wird dir nichts bringen wenn $i bis 1099 geht...

    Ansonsten wär ein Minimalbeispiel welches bis auf dein Onevent-Problem mit $i funktioniert schon besser zum Helfen.
    Es wird bei dir ja weder eine GUI erstellt noch eine Endlosschleife durchgeführt.
    Zum Testen ist dieser Codeschnipsel daher ungeeignet.

  • Ja gut aber diesen Fehler finde ich nicht weil ich von Arrays doch nicht soviel Ahnung habe, aber wie gesagt, die Liste selbst funktioniert ja, es wird jede Zeile der Liste sauber geschrieben, nun will ich, das ich in jeder Zeile ein Event auslösen kann. Der Sinn ist, das $i der Kundennummer entspricht und pro Zeile ausgegeben werden soll.
    Eine GUI gibt es auch:

    [autoit]


    Dim $kunden[10000]
    Dim $kunden1[10000]

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

    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>
    #include <Constants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <Array.au3>
    Opt('MustDeclareVars', 0)
    Opt("GUIOnEventMode", 1)
    $MainGUI = GUICreate("", 440, 600)
    GUISetBkColor(0xffffff)
    ;GUISetFont(9, 300)
    HotKeySet("{ESC}", "MeinExit")
    GUISetOnEvent($GUI_EVENT_CLOSE, "MeinExit")

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

    GuiCtrlCreateLabel("Handy", 25, 20, 240, 20)
    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
    GUICtrlSetFont (-1,11,800,4,$font1)
    GUICtrlSetColor(-1,0x0000ff)

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

    $i = 1000
    $j = 0
    While $i < 1100
    ; Kd.-Nr. 1000 - 1100
    $var1 = IniRead("sim.ini",$i,"name","")
    If $var1 = "" Then
    Else
    $var2 = IniRead("sim.ini",$i & "-v1","lauf","")
    $var3 = IniRead("sim.ini",$i & "-v2","lauf","")
    $j = $j + 1
    $kunden = GuiCtrlCreateLabel($var1, 15, 20*$j+150, 240, 20)
    GUICtrlSetOnEvent(-1, "_KundenVerwaltung")
    GuiCtrlCreateLabel($var2, 250, 20*$j+150, 80, 20)
    GuiCtrlCreateLabel($var3, 340, 20*$j+150, 80, 20)
    EndIf
    $i = $i + 1
    WEnd

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

    ;Liste()

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

    GUISetState(@SW_SHOW, $MainGUI)

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

    ; Funktionen
    While 1
    Sleep(100)
    WEnd

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

    Func MeinExit()
    Exit
    EndFunc

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

    Func _KundenVerwaltung()
    ; $arSplit = [$i]
    _ArrayToString($kunden1)
    ; $aArrayNr = _R($kunden1, 1, 1, 100, 1)
    ; MsgBox(64,$aArrayNr, GUICtrlRead($aArrayNr))
    ; Exit
    EndFunc

    [/autoit]


    Das ist das Script

    Einmal editiert, zuletzt von moppel11 (3. Mai 2011 um 12:15)

  • Glaub mir - dein Problem ist nicht das OnEvent.
    Wenn du nicht verstehst was dein Skript macht wirst du nicht weit kommen.
    Du solltest dich wirklich erstmal daran machen zu verstehen was dein Programm macht und was du wirklich willst.
    Es ist unverständlich ein Array mit 10000 Elementen zu erzeugen bei dem nur die Elemente 1000-1099 genutzt werden.
    Auch ist immer noch ein Fehler im Skript ($font1 wurde nie deklariert).

    Wenn ich dir jetzt erzähle wie man dein Ansinnen mit OnEvent lösen kann glaube ich nicht das dir das wirklich viel bringt da du ja schon Probleme hast deinen eigenen Code zu verstehen.
    Dennoch:

    Jedes GUI-Element was erzeugt wird bekommt eine Control-ID.
    Das ist eine eindeutige Nummer in der GUI welche das Control eindeutig identifizieren.
    Man erhält es als Rückgabewert von der Funktion welche das Control erstellt (In deinem Fall das GuiCtrlCreateLabel).
    Die Control-IDs werden dabei in der Reihenfolge ihrer Erstellung durchnummeriert.
    Desweiteren bekommt man die Control-ID des gedrückten Controls in einer OnEvent-Funktion mit dem Makro @GUI_CtrlId heraus.
    Mit diesem Wissen haben wir 2 Möglichkeiten um zu einer Control-ID das passende $i zu ermitteln:

    Möglichkeit 1: Wir erstellen eine globale Tabelle welche zu jedem Control-ID das $i einträgt und schlagen dieses dann anhand @GUI_CtrlId in der OnEvent-Funktion nach.
    Implementiert werden könnte eine solche Tabelle z.B. durch ein 2D-Array, ein abwechselnd zu beschreibendes 1D-Array oder ein Dictionary.

    Möglichkeit 2: Es gibt einen funktionalen Zusammenhang zwischen $i und der Control-ID.
    Dann können wir anhand der Control-ID das $i auch berechnen.
    In deinem Fall werden immer 3 Elemente hintereinander erzeugt. Also jedes 3. Element ist ein Control-ID des ersten Labels.
    Mit dem richtigen Offset erhält man dann das korrekte $i wenn man @GUI_CtrlId durch 3 teilt.
    Das ganze ist aber sehr ineffektiv da die Rechnung nicht mehr stimmt wenn du z.B. doch auf einmal 4 Labels in einer Zeile eintragen willst.
    Aber mal als Beispiel für deine KundenVerwaltung-Funktion:

    [autoit]

    Func _KundenVerwaltung()
    MsgBox(0,"", "Geklicktes Element: " & (@GUI_CtrlId / 3) - (4/3))
    EndFunc

    [/autoit]
  • Danke für deine Hilfe, auch wenn ich die Array nicht verstanden habe (ich brauch ja nur die Elemente 1000-1099 und die Elemente 9000-9010), funzt es nun - die Kd.-Nr. wird ausgegeben.

    [autoit]


    Func _KundenVerwaltung()
    $ergebnis = GUICtrlRead(@GUI_CtrlId)
    MsgBox(0,"", "Geklicktes Element: " & $ergebnis)
    EndFunc

    [/autoit]

    Die DIMs hab ich rausgenommen, werden gar nicht gebraucht.

    Einmal editiert, zuletzt von moppel11 (3. Mai 2011 um 13:27)