Nowadays there are plenty of
services available on the internet, e.g. for searching street names.
This tutorial shows us how to implement a searchhelp for street names
that doesn't require an active internet connection.
Starting point is a list with all streets in Germany: strassen_osm.txt:
The file size is about 1.50 MB and contains around 96000 entries.
The GuiXT script for entering the name of the street (first letters
are sufficient), result table etc. looks like this:
In the InputScript "search_street_va03.txt" we call a VB.NET
function and then fill the table on the SAP screen with the data that we
recieve from the function. (We restrict the results to a maximum of 10
rows.)
GuiXT
// 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 the function "find_streets" of class "utilities" of our
class library "tutorials.dll" we search the textfile for
any matching entry. A match means that the street name starts with the
letters that the user has given. Then we put those results into a GuiXT
textvariable for the previous InputSript:
VB.NET
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
Notes:
- On using sorted lists we recommend you use a binary search (instead
of linear search) to significantly reduce the search time.
- The textfile containing the street names needs to be read only once from
the hard disk and is then available in memory for future requests.
The user can then mark any row of the result table and on
clicking "choose" the name of the chosen street is put into an
InputField:
GuiXT
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