テキストファイルの読み込みと処理
今日、インターネットでは、ストリート名の検索などのさまざまなサービスを利用できます。このチュートリアルでは、アクティブなインターネット接続を必要としない、ストリート名の検索ヘルプを実装する方法を示します。
まず、ドイツにあるすべてのストリートを列挙したリストstrassen_osm.txtから始めます。
ファイルサイズは約1.50MBで、約96000のエントリが格納されています。
ストリート名(最初の文字があれば十分)を入力するGuiXTスクリプト、結果テーブルなどは、以下のようになります。
pushbutton (2,110) “search” process=“search_street_va03.txt”
pushbutton (2,115) “choose” process=“use_street_va03.txt”
inputfield (2,84) “Search for street” (3,100) size=“25” name=“searchstreet”
inputfield (3,84) “Results:” (3,100) size=“25” name=“chosenstreet”
Table (4,84) (17,140) name=“streettab” title=”Streets rows=10 -singlerowselection
Column “Street name” size=40 name=“streets”
InputScriptの”search_street_va03.txt”において、VB.NET関数を呼び出し、この関数から受け取ったデータをSAP画面のテーブルに設定します(ここでは、結果を10行までに制限します)。
// 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.
“tutorials.dll”クラスライブラリにある”utilities”クラスの”find_streets”関数において、テキストファイルを検索し、入力に一致するものを検索します。ここで、「一致する」とは、ユーザーが指定した文字でストリート名が始まることを意味します。その後、先のInputSript用に、この検索結果をGuiXTテキスト変数に代入します。
1 | Public Function find_streets(ByVal search As String) As String |
2 | |
3 | Try |
4 | If Not streets_read Then |
5 | streets = File.ReadAllLines(“c:\temp\strassen_osm.txt”) |
6 | streets_read = True |
7 | End If |
8 | |
9 | Dim index = Array.BinarySearch(streets, search, New MyStringComparer()) |
10 | |
11 | ‘Default: Emtpy cell |
12 | For c As Integer = 1 To 10 |
13 | g.SetText(“streets_results” + c.ToString, “”) |
14 | Next |
15 | |
16 | If index < 0 Then |
17 | Return “Kein Eintrag gefunden” |
18 | End If |
19 | |
20 | Dim mycomp As New MyStringComparer |
21 | Dim myIndex As Integer = index |
22 | |
23 | While myIndex – 1 > 0 And mycomp.Compare(streets.ElementAtOrDefault(myIndex – 1), search) = 0 |
24 | |
25 | myIndex -= 1 |
26 | |
27 | End While |
28 | |
29 | For c As Integer = 0 To 9 |
30 | |
31 | If mycomp.Compare(streets.ElementAtOrDefault(myIndex + c), search) = 0 Then |
32 | g.SetText(“streets_results” + (c + 1).ToString, streets.ElementAtOrDefault(myIndex + c)) |
33 | End If |
34 | Next |
35 | |
36 | |
37 | Catch ex As Exception |
38 | |
39 | Return ex.Message |
40 | |
41 | End Try |
42 | |
43 | Return “0” |
44 | |
45 | End Function |
注:
– 保存済みのリストを使用する場合、検索時間の大幅な短縮につながる(線形検索ではなく)バイナリ検索の使用を推奨します。
– ストリート名が格納されているテキストファイルは、ハードディスクから1度だけ読み込めば十分です。その後のデータ要求に対してはメモリのデータを利用できます。
ユーザーは、結果テーブルの任意の行をマークできます。その後、”choose”をクリックすると、選択したストリート名が入力フィールドに設定されます。
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
結果: