Wir haben bisher Attribute eines Controls gesetzt und seine Funktionen aufgerufen. Wenn wir allerdings auf Benutzeraktionen, z.B. einen Mausklick, reagieren wollen, ist der umgekehrte Ablauf nötig: das Control soll unsere Funktion aufrufen, sobald die Benutzeraktion stattfindet. Das bezeichnet man als "event handling".

In der Schnittstellenbeschreibung eines Controls sind die möglichen Ereignisse ("events") mit ihren Parametern aufgeführt (Beispiel aus VBSEdit):

Wie können wir nun dem Control mitteilen, dass eine bestimmte Funktion aufgerufen werden soll, sobald das Ereignis ausgelöst wird? Dazu bietet GuiXT Controls die Funktion

guixt.SetEventHandler(obj1, obj2)

an. Die Funktion erwartet zwei Objekte: als erstes das Objekt obj1, dessen Ereignisse wir behandeln wollen, als zweites das Objekt obj2, das die Ereignisse entgegennimmt. Wenn das Objekt obj1 ein Ereignis, z.B. "ColumnClick" auslöst, wird die Funktion "OnColumnClick" von Objekt obj2 mit den entsprechenden Parametern aufgerufen. Es wird also zu dem Ereignisnamen immer noch ein "On" gesetzt. Wenn die Funktion in obj2 nicht existiert, geschieht nichts.

Wir knüpfen an das ListView-Beispiel aus Tutorial 4 an. Das Objekt obj1 ist das ListView Control, das dort durch die Variable lh adressiert wird. Wie legen wir nun Objekt obj2 in VBScript an? Dazu definiert man sich mit Class ... End Class eine eigene Klasse - die Bezeichnung ist beliebig -, die alle gewünschten "event handler" Funktionen enthält:

Class va03_list_events

  Function OnDblClick        
         
        
  EndFunction
    

  Function OnColumnClick(ColumnHeader)
        
       
  EndFunction
    
    
EndClass

In der Initialisierung des ListView Controls erzeugen wir mit New ein Objekt dieser Klasse und legen es als "event handler" fest:

Function va03_init(lv, date_from)
...

  ' handle  events
    Set e = New va03_list_events
    Call guixt.SetEventHandler(lv, e)  
    
EndFunction
  

Sobald ein "event handler" existiert, können Sie sich im GuiXT Window die Events mit ihren Parametern anschauen; hierzu einfach den normalen Trace einschalten und eine Benutzeraktion im Control durchführen:

Es ist oft nützlich, in der von Ihnen angelegten event-handler-Klasse auch das Objekt zu vermerken, dessen events Sie behandeln, damit man in der Eventbehandlung einfach darauf zugreifen kann. Das geht so:

   

Function va03_init(lv, date_from)
...


    ' handle  events
    Set e = New va03_list_events
    Set e.ListView = lv
    Call guixt.SetEventHandler(lv, e)  
    
EndFunction


Class va03_list_events
    
    Dim ListView
    
    ' double click    
    Function OnDblClick
        
  
        
    EndFunction
    
    
      
    Function OnColumnClick(ColumnHeader)
        
   
        
    EndFunction
    
    
    
EndClass


Jetzt müssen wir nur noch die gewünschten Aktionen durchführen, wenn uns die Ereignisse durch den Funktionsaufruf mitgeteilt werden. Bei Klick auf eine Spaltenüberschrift sortieren wir die Zeilen nach der betreffenden Spalte, abwechselnd aufsteigend und absteigend. Bei Doppelklick auf eine Zeile rufen wir VA03 für den betreffenden Auftrag auf. Das geschieht über die Funktion guixt.input(...), mit der wir SAP-Eingabefelder setzen können, einen SAP-Funktionscode auslösen und ein InputScript mit Parameterübergabe prozessieren können. Insgesamt sieht das VBScript Coding dann wie folgt aus, wobei der unveränderte Teil aus Tutorial 4 in grau dargestellt ist:

' Utility function: cut or enlarge a string to the specified length
Function xlen(f,n)
    xlen = Mid(f,1,n)
    If Len(xlen) < n Then
        xlen = xlen + Space(n-Len(xlen))
    End If
    
End Function


' Utility function:  build up a select option line for SAP RFCs
Function set_selopt(name,field,sign,opt,val1,val2)
    set_selopt = xlen(name,30) & xlen(field,30) & xlen(sign,1) & xlen(opt,2) & xlen(val1,45) & xlen(val2,45)   
End Function


' Utility function: pixel to twips ("TWentieth of an Inch Point")
' screen.deviceXDPI - Retrieves the actual number of horizontal dots per inch (DPI)
' screen.deviceYDPI - Retrieves the actual number of vertical dots per inch (DPI) 
Function Twips_x(x)
    Twips_x = x * (1440 / screen.deviceXDPI)
EndFunction

Function Twips_y(y)
    Twips_y = y * (1440 / screen.deviceYDPI)
EndFunction


Function va03_init(lv, date_from)
    
    If IsEmpty(lv) Then
        Set lv = CreateObject("ComCtl.ListViewCtrl")
    End If
    
    
    ' font
    lv.Font.Name = "Arial"
    lv.Font.Size = 10
    
    ' color
    lv.BackColor = RGB(240,240,240)  
    
    
    lv.View = 3    ' 3=lvwReport (from MS documentation)
    
    ' no label editing
    lv.LabelEdit = 1  ' 1=manually  (from MS documentation) 
    
    
    ' column headers       
    Call lv.ColumnHeaders.Add(,,guixt.get("coltitle_VBELN"), 1500)
    Call lv.ColumnHeaders.Add(,,guixt.get("coltitle_BSTDK"), 2000)
    Call lv.ColumnHeaders.Add(,,guixt.get("coltitle_KUNNR"), 2000)
    Call lv.ColumnHeaders.Add(,,guixt.get("coltitle_BSTKD"), 3000)
    
    
    
    ' array of select options
    Dim selopt(0)
    
    
    selopt(0) = set_selopt("VMVAA","BSTDK", "I", "GE",  date_from, "")
    
    ' array of orders
    Dim orders
    
    Call guixt.Rfc("Z_S10_SEARCHHELP", "in.SEARCHHELP", "VMVAA",  "in.COLUMNS",  "VBELN(10),BSTDK(10),KUNNR(10),BSTKD(20)", "table.SELOPT", selopt, "table.DATA(WIDTH:50)", orders) 
    
    
    For Each Order In  orders
        
        Dim itmX
        Set itmX = lv.ListItems.Add(,,Mid(Order,1,10))
        
        itmX.SubItems(1) = Mid(Order,11,10)
        itmX.SubItems(2) = Mid(Order,21,10)
        itmX.SubItems(3) = Mid(Order,31,20)
                       
    Next  
    
    
    ' handle  events
    Set e = New va03_list_events
    Set e.ListView = lv
    Call guixt.SetEventHandler(lv, e)  
    
EndFunction


Class va03_list_events
    
    Dim ListView
    
    
      
    Private ascending(4)
    
    Function OnColumnClick(ColumnHeader)
        
        Dim colno
        colno = ColumnHeader.Index - 1
        
        IfIsEmpty(ascending(colno)) Then
            ascending(colno) = 1
        EndIf
        
        ascending(colno) = 1 - ascending(colno)
        
        ListView.SortKey = colno
        ListView.SortOrder = ascending(colno)
        ListView.Sorted = True
        
        
    EndFunction
    
    
    
    
    ' mouse coordinates of last click
    Dim click_x
    Dim click_y
    
    
    ' Mouse down
    Function OnMouseDown(Button, Shift, x, y)
        
        ' save pixel coordinates 
        click_x = x
        click_y = y
        
    EndFunction
    
    
    
    
    ' double click    
    Function OnDblClick
        
        Dim item
        
        
        ' get clicked list item
             
        '   Remark:
        '   a simple way to get the clicked list item, without the need to 

        '  
capture the MouseDown coordinates, is to use 
        '     item = ListView.selectedItem
        '   but then the user has to double-click the order number column, 

        '  
not one of the other columns
        '   this is why we use mouse coordinates and HitTest
        
        ' HitTest requires coordinates in twips, not pixels !
        ' we use x-coordinate = 1 so that the user may click 

        '
anywhere in the list row
           
        Set item = ListView.HitTest(1, Twips_y(click_y))  
        
               
        IfNot item IsNothingthen
            
            guixt.input("U[VBELN]:" & item.Text)
            guixt.input("OK:/0,process=va03_enter.txt")
            
        EndIf    
        
        
        
    EndFunction
    
    
EndClass

Das InputScript "va03_enter.txt" setzt die Auftragsnummer und drückt die "Enter" Taste:

Parameter VBELN
Set F[VBAK-VBELN] "&U[VBELN]"
Enter

Ergebnis für den Benutzer:

Durch Klick auf z.B. "Bestelldatum": Umsortierung nach Bestelldatum, hier absteigend.

 

Durch Doppelklick auf eine Zeile: Anzeige des ausgewählten Auftrags