テキストファイルの読み込みと処理
今日、インターネットでは、ストリート名の検索などのさまざまなサービスを利用できます。このチュートリアルでは、アクティブなインターネット接続を必要としない、ストリート名の検索ヘルプを実装する方法を示します。
まず、ドイツにあるすべてのストリートを列挙したリスト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
結果:
 

