Mittlerweile stehen umfangreiche Eingabehilfen z.B. für die Suche nach Straßennamen im Internet bereit. In diesem Tutorial möchten wir eine Suchhilfe für Straßennamen implementieren, die ohne aktive Internetverbindung auskommt.

Ausgangspunkt ist eine Liste mit allen Straßen in Deutschland: strassen_osm.txt
Diese Datei ist ca. 1,50 MB groß und enthält etwa 96.000 Einträge.

Das GuiXT Script für die Eingabe des Straßennamens (Anfangsbuchstaben genügen), Ergebnistabelle etc. sieht wie folgt aus:

pushbutton (2,110) "ok" process="search_street_va03.txt"
pushbutton
(2,115) "Übernehmen" process="use_street_va03.txt"
inputfield
(2,84) "Nach Straße suchen" (3,100) size="25" name="searchstreet"
inputfield
(3,84) "Ergebnisse" (3,100) size="25" name="chosenstreet"
Table
(4,84) (17,140) name="streettab" title="Straßen" rows=10 -singlerowselection
Column
"Straßenname" size=40 name="streets"

 Im Inputscript "search_street_va03.txt" rufen wir eine VB.NET Funktion auf und befüllen anschließend die Tabelle der SAP Maske mit den zurückgelieferten Werten. (Wir beschränkten uns dabei auf maximal 10 Zeilen).

// Clear table
Set
"V[streettab.*]"  ""
callvb
result = tutorials.utilities.find_streets "&V[searchstreet]"
if
not V[result=0]
 
message "&V[result]"
endif

copytext fromText="streets_results1" toString="streetTemp"
Set
"V[streettab.cell.streets.1]" "&V[streetTemp]" 

copytext fromText="streets_results2" toString="streetTemp"
Set
"V[streettab.cell.streets.2]" "&V[streetTemp]"

//etc.

In der Funktion "find_streets" der Klasse "utilities" in der Klassenbibliothek "tutorials.dll" suchen wir in der eingelesenen Textdatei nach entsprechenden Einträgen (also Straßennamen, die mit der vom Benutzer angegebenen Zeichenfolge beginnen) und stellen diese in eine GuiXT Textvariable für das vorherige Inputscript:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
   Public Function find_streets(ByVal search As String) As String

        Try
            If Not streets_read Then
                streets = File.ReadAllLines("c:\temp\strassen_osm.txt")
                streets_read = True
            End If

            Dim index = Array.BinarySearch(streets, search, New MyStringComparer())

            'Default: Emtpy cell
            For c As Integer = 1 To 10
                g.SetText("streets_results" + c.ToString, "")
            Next

            If index < 0 Then
                Return "Kein Eintrag gefunden"
            End If

            Dim mycomp As New MyStringComparer
            Dim myIndex As Integer = index

            While myIndex - 1 > 0 _ 
                And mycomp.Compare(streets.ElementAtOrDefault(myIndex - 1), search) = 0

                myIndex -= 1

            End While

            For c As Integer = 0 To 9

                If mycomp.Compare(streets.ElementAtOrDefault(myIndex + c), search) = 0 Then
                    g.SetText("streets_results" + (c + 1).ToString, _ 
                          streets.ElementAtOrDefault(myIndex + c))
                End If
            Next


        Catch ex As Exception

            Return ex.Message

        End Try

        Return "0"

    End Function

Hinweise:
 
  - Bei sortierten Listen empfiehlt es sich, eine binäre Suche zu verwenden, um die Suchzeit signifikant zu verkürzen.
  - Die Textdatei muss nur beim ersten Aufruf eingelesen werden und ist anschließend im Arbeitsspeicher verfügbar

Markiert der Benutzer nun eine Zeile der Tabelle und drückt auf "übernehmen", so wird mit folgenem InputScript der Name der Straße in ein Inputfeld gestellt:

Set V[i] "1"
label
selection
if
  V[streettab.stat.rowselection.&V[i]=X] 
 
set V[chosenstreet] "&V[streettab.cell.streets.&V[i]]"
endif

Set
V[i] "&V[i]" + 1
if
not V[i=11]
 
goto selection
endif


return


Ergebnis: