SortStructuredArray fehlerhaft?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Tommy
Spassvogel
Beiträge: 319
Registriert: 17.10.2013 14:36

SortStructuredArray fehlerhaft?

Beitrag von Tommy »

Bin gerade dabei für mein inzwischen großen Code eine Spalten Sortierung
zu entwickeln aber es klappt nich. Ich habe ein Array mit verknüpfter Struktur

Code: Alles auswählen

Structure TableStruct
  GadgetNr.i
  Content.s
  i.i
  j.i
EndStructure

Dim TableStruct.TableStruct(0, 0)
Soweit so gut. Jetz will ich mit SortStructuredArray nach "Content" sortieren aber
die anderen Structure Elemente wie GadgetNr und i und j sortieren sich nich mit. Die
werden von der Sortierung von SortStructuredArray nich verschoben. Warum nich?
Volständiger Code zum testen:

Code: Alles auswählen

;Programmierer: Tommy

Structure TableStruct
  GadgetNr.i
  Content.s
  i.i
  j.i
EndStructure

Dim TableStruct.TableStruct(0, 0)

LoadFont(0, "Arial", 10, #PB_Font_Bold)

; Verfügbare Flags
#PB_Table_BorderLess = 1
#PB_Table_ActiveHighlighting = 2
#PB_Table_Columns = 4

; Event Constanten
#PB_Table_Event_Key_Up = $A000
#PB_Table_Event_Key_Down = $A001
#PB_Table_Event_Key_Right = $A002
#PB_Table_Event_Key_Left = $A003

Procedure TableGadgetHandler()
  Protected DataValue, i, j, *this.TableStruct
  DataValue = GetGadgetData(EventGadget())
  *this.TableStruct = DataValue
  *this\Content = GetGadgetText(*this\GadgetNr)
EndProcedure

Procedure TableGadgetFocusHandler()
  SetGadgetColor(EventGadget(), #PB_Gadget_BackColor, RGB(255, 255, 220))
EndProcedure

Procedure TableGadgetLostFocusHandler()
  SetGadgetColor(EventGadget(), #PB_Gadget_BackColor, -1)
EndProcedure

Procedure TableGadgetKeyHandler(Array TableStruct.TableStruct(2), Key)
  Protected cGadget, *this.TableStruct, DataValue, maxWidthField, maxHeightField
  
  cGadget = GetActiveGadget()
  If IsGadget(cGadget)
    maxWidthField = ArraySize(TableStruct(), 1)
    maxHeightField = ArraySize(TableStruct(), 2)
    DataValue = GetGadgetData(cGadget)
    *this.TableStruct = DataValue
    If *this
      *this\Content = GetGadgetText(*this\GadgetNr)
      
      ; Mit Pfeiltasten steuerbar
      Select Key
          Case #PB_Table_Event_Key_Up : If *this\j <> 0: SetActiveGadget(TableStruct(*this\i, *this\j-1)\GadgetNr) : EndIf
          Case #PB_Table_Event_Key_Down : If *this\j <> maxHeightField-1: SetActiveGadget(TableStruct(*this\i, *this\j+1)\GadgetNr) : EndIf
          Case #PB_Table_Event_Key_Right: If *this\i <> maxWidthField-1: SetActiveGadget(TableStruct(*this\i+1, *this\j)\GadgetNr) : EndIf
          Case #PB_Table_Event_Key_Left : If *this\i <> 0: SetActiveGadget(TableStruct(*this\i-1, *this\j)\GadgetNr) : EndIf
      EndSelect
    EndIf
  EndIf
EndProcedure

Procedure TableColumnHandler()
  Protected DataValue, cGadget, ArrayY
  Shared TableStruct()
  
  cGadget = EventGadget()
  DataValue = GetGadgetData(cGadget)
  
  ; Sortieren
  SortStructuredArray(TableStruct(), #PB_Sort_Ascending, OffsetOf(TableStruct\Content), TypeOf(TableStruct\Content))
  
  ; Sortierte Inhalte anzeigen
  For ArrayY=1 To ArraySize(TableStruct(), 2)
    
    DisableGadget(TableStruct(DataValue, ArrayY)\GadgetNr, 1)
    ;SetGadgetText(TableStruct(DataValue, ArrayY)\GadgetNr, TableStruct(DataValue, ArrayY)\Content)
    
  Next ArrayY
  
EndProcedure

Procedure TableGadget(Array TableStruct.TableStruct(2), x, y, Width, Height, CellWidth = 100, CellHeight = 20, Flags = 0)
  Protected i, j, Gadget, sFlags, addColumns
  
  ; Mit Pfeiltasten steuerbar
  AddKeyboardShortcut(0, #PB_Shortcut_Up, #PB_Table_Event_Key_Up)
  AddKeyboardShortcut(0, #PB_Shortcut_Down, #PB_Table_Event_Key_Down)
  AddKeyboardShortcut(0, #PB_Shortcut_Right, #PB_Table_Event_Key_Right)
  AddKeyboardShortcut(0, #PB_Shortcut_Left, #PB_Table_Event_Key_Left)
  
  If Bool(Flags & #PB_Table_BorderLess)
    sFlags = #PB_String_BorderLess
  EndIf
  
  If Bool(Flags & #PB_Table_Columns)
    addColumns = 1
  EndIf
  
  ; Schleife für alle Spalten
  For j=0 To (Height/CellHeight)-1
    ; Schleife für alle Zeilen
    For i=0 To (Width/CellWidth)-1
      If addColumns = 1 And (i = 0 Or j=0)
        If i > 0 Or j > 0
          If j = 0
            Gadget = ButtonGadget(#PB_Any, i*CellWidth, j*CellHeight, CellWidth, CellHeight, Chr(i+64))
            BindGadgetEvent(Gadget, @TableColumnHandler())
          Else
            Gadget = ButtonGadget(#PB_Any, i*CellWidth, j*CellHeight, CellWidth, CellHeight, Str(j))
          EndIf
          SetGadgetData(Gadget, i)
          SetGadgetFont(Gadget, FontID(0))
        EndIf
      Else
        Gadget = StringGadget(#PB_Any, i*CellWidth, j*CellHeight, CellWidth, CellHeight, "", sFlags)
        ; Übergebenes TableStruct intern speichern
        SetGadgetData(Gadget, TableStruct(i, j))
        ; Eingegebener Inhalt bei Änderung automatisch ins TableStruct speichern
        BindGadgetEvent(Gadget, @TableGadgetHandler(), #PB_EventType_Change)
        
        ; Active Zelle färben
        If Flags & #PB_Table_ActiveHighlighting
          BindGadgetEvent(Gadget, @TableGadgetFocusHandler(), #PB_EventType_Focus)
          BindGadgetEvent(Gadget, @TableGadgetLostFocusHandler(), #PB_EventType_LostFocus)
        EndIf
        
        TableStruct(i, j)\GadgetNr = Gadget
        TableStruct(i, j)\i = i
        TableStruct(i, j)\j = j
        
        ;- Dbg
        SetGadgetText(Gadget, Str(Random(99)))
        PostEvent(#PB_Event_Gadget, 0, Gadget, #PB_EventType_Change)
        
      EndIf
      
      
    Next i
  Next j
EndProcedure

Define event
Define ArrayX
Define ArrayY

; Neues Fenster erstellen
OpenWindow(0, 0, 0, 800, 640, "", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

; Array für die Tabelle erstellen. Alle Daten werden automatisch darein gespeichert
Dim TableStruct.TableStruct(800/100, 600/20)
; Tabellen-Gadget erstellen. Zellen werden abhängig von der Breite und Höhe angelegt so viel da rein passen
TableGadget(TableStruct(), 0, 0, 800, 600, 100, 20, #PB_Table_ActiveHighlighting|#PB_Table_Columns)
ButtonGadget(0, 300, 610, 200, 20, "Gebe alle Daten aus", 0)

Repeat
  event = WaitWindowEvent()
  If event = #PB_Event_Menu
    Select EventMenu()
        ; Mit Pfeiltasten steuerbar
      Case #PB_Table_Event_Key_Up : TableGadgetKeyHandler(TableStruct(), #PB_Table_Event_Key_Up)
      Case #PB_Table_Event_Key_Down : TableGadgetKeyHandler(TableStruct(), #PB_Table_Event_Key_Down)
      Case #PB_Table_Event_Key_Right: TableGadgetKeyHandler(TableStruct(), #PB_Table_Event_Key_Right)
      Case #PB_Table_Event_Key_Left : TableGadgetKeyHandler(TableStruct(), #PB_Table_Event_Key_Left)
    EndSelect
  EndIf
  If event = #PB_Event_Gadget
    Select EventGadget()
      Case 0
        ; Ausgabe der Daten, kann auch in Datei exportiert werden
        For ArrayY=0 To ArraySize(TableStruct(), 2)
          For ArrayX=0 To ArraySize(TableStruct(), 1)
            Debug TableStruct(ArrayX, ArrayY)\Content
          Next ArrayX
        Next ArrayY
    EndSelect
  EndIf
Until event = #PB_Event_CloseWindow
Was ihr tun müsst so das ihr versteht was ich meine : Startet den Code und klickt auf
irgend eine Spalte. Um es zu visualisieren deaktiviere ich testweise die entsprechenden
Gadgets. Wie man gut sieht sind es die falschen Gadgets die deaktiviert werden. Es sieht
so aus als ob nur das Structure Element "Content" sortiert wird aber die anderen nich.
Wenn ich SortStructuredArray auskommentiere dann werden die richtigen Gadgets de-
aktiviert. Wie kann ich das jedes Structure Element miteinander verbunden bzw abhängig sind
so das sie ebenfalls mit sortiert werden?
PB 5.41 x64
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: SortStructuredArray fehlerhaft?

Beitrag von NicTheQuick »

Ich würde mal behaupten, dass 'SortStructuredArray()' mit zweidimensionalen Arrays nicht zurecht kommt.
am besten nutzt du dafür eine eigene Sortierroutine. Am einfachsten wird wohl Bubblesort sein um das schnell mal zu testen.

Und noch was anderes:
Anstatt 'CellWidth' und 'CellHeight' zu übergeben, nutze besser 'ArraySize()' innerhalb deiner 'TableGadget()'-Procedure und berechne die beiden Parameter selbst aus. Damit vermeidest du Redundanz.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: SortStructuredArray fehlerhaft?

Beitrag von NicTheQuick »

Mich hat's wieder gepackt. So könnte das aussehen:

Code: Alles auswählen

Procedure TableColumnHandler()
	Protected DataValue, cGadget, i, j, k
	Shared TableStruct()
	
	cGadget = EventGadget()
	DataValue = GetGadgetData(cGadget)
	
	Protected rows.i = ArraySize(TableStruct(), 2)
	Protected cols.i = ArraySize(TableStruct(), 1)
	
	For i = 0 To rows
		For j = i + 1 To rows
			If TableStruct(DataValue, i)\Content > TableStruct(DataValue, j)\Content
				For k = 0 To cols
					Swap TableStruct(k, i)\Content, TableStruct(k, j)\Content
				Next
			EndIf
		Next
		For k = 0 To cols
			SetGadgetText(TableStruct(k, i)\GadgetNr, TableStruct(k, i)\Content)
		Next
	Next
EndProcedure
Benutzeravatar
Tommy
Spassvogel
Beiträge: 319
Registriert: 17.10.2013 14:36

Re: SortStructuredArray fehlerhaft?

Beitrag von Tommy »

Tausend Dank :allright: :allright:
PB 5.41 x64
Antworten