Tip pro VBScript: Práce se seznamem objektů
26. listopadu 2014 | Reliance SCADA
V některých aplikacích se systémem Reliance je potřeba ve skriptu ukládat data do seznamu s proměnlivým počtem prvků a následně je procházet, vyhledávat nebo mazat. Pro pokrytí této potřeby je možné založit proměnnou typu pole a naprogramovat funkce pro příslušné operace. Toto je však pracné a především zbytečné, protože existují hotová řešení v podobě objektů Scripting.Dictionary nebo několika tříd .NET Frameworku, jako je např. System.Collections.ArrayList.
Scripting.Dictionary je objekt seznamu, který umožňuje ukládat párová data (klíč-hodnota) a následně je vyhledávat. Objekt Scripting.Dictionary je součástí skriptovacího jádra jazyka VBScript a nevyžaduje tedy žádnou instalaci. Následující příklad demonstruje jeho použití na seznamu uživatelů (jméno uživatele je klíč, emailová adresa je hodnota).
Dim recipients, email, items, i, s
' Vytvoří objekt.
Set recipients = CreateObject("Scripting.Dictionary")
' Naplní seznam.
recipients.Add "bill", "bill.gates@microsoft.com"
recipients.Add "mark", "mark.zuckerberg@facebook.com"
recipients.Add "larry", "larry.page@google.com"
recipients.Add "steve", "steve.jobs@apple.com"
' Vyhledá adresu uživatele larry.
email = recipients.Item("larry")
' Zobrazí výsledek hledání.
MsgBox "You can email larry on " & email, vbSystemModal
' Změní adresu uživatele bill.
recipients.Key("bill") = "bill@gatesfoundation.org"
' Odstraní uživatele mark.
recipients.Remove "mark"
' Provede seřazení.
SortDict recipients
' Projde seznam a zjistí všechny adresy.
s = ""
items = recipients.Items
For i = 0 To recipients.Count - 1
s = s & " " & items(i)
Next
MsgBox "All recipents are: " & s, vbSystemModal
' Uvolní seznam.
Set recipients = Nothing
Objekt Scripting.Dictionary nepodporuje řazení prvků seznamu. Pokud je potřeba prvky seznamu seřadit, je možné zavést funkci SortDict:
' Funkce pro seřazení prvků v objektu Scripting.Dictionary.
Function SortDict(ByVal dict)
Dim i, j, temp
For Each i In dict
For Each j In dict
If(dict.Item(i) <= dict.Item(j)) Then
temp = dict.Item(i)
dict.Item(i) = dict.Item(j)
dict.Item(j) = temp
End If
Next
Next
Set SortDict = dict
End Function
Vlastní řazení se provede jednoduchým voláním funkce SortDict:
SortDict recipients
Výše uvedený příklad ukazuje, jak pracovat se seznamem objektů typu řetězec. Do seznamu lze pochopitelně přidávat objekty jiného typu, např. čísla, předdefinované objekty nebo uživatelsky definované objekty (třídy), ale pak je nutné programový kód odpovídajícím způsobem upravit.
Běhové prostředí .NET Framework obsahuje další objekty pro práci se seznamem, které je možné použít v jazyku VBScript, a tedy i ve skriptech systému Reliance:
- System.Collections.ArrayList
- System.Collections.SortedList
- System.Collections.Stack
- System.Collections.Queue
Všechny uvedené objekty vyžadují nainstalovaný .NET Framework (minimálně verze 1.0).
System.Collections.ArrayList je seznam typu pole. Na rozdíl od objektu Scripting.Dictionary nepracuje s párovými daty (klíč-hodnota).
Dim Message, ArrayList
' Inicializuje zprávu.
Message = ""
' Vytvoří seznam.
Set ArrayList = CreateObject("System.Collections.ArrayList")
' Naplní seznam.
ArrayList.Add 6
ArrayList.Add 8
ArrayList.Add 2
ArrayList.Add 4
ArrayList.Add 1
ArrayList.Add 5
ArrayList.Add 3
ArrayList.Add 3
ArrayList.Add 7
' Převede seznam na pole.
Message = Message & "1: " & Join(ArrayList.ToArray, ",") & vbCrLf
' Vrátí prvek na zadaném indexu.
Message = Message & "2: " & ArrayList(0) & vbCrLf
' Vrátí počet prvků.
Message = Message & "3: " & ArrayList.Count & vbCrLf
' Zjistí, zda seznam obsahuje prvek.
Message = Message & "4: " & ArrayList.Contains(5) & vbCrLf
' Seřadí seznam.
ArrayList.Sort
Message = Message & "5: " & Join(ArrayList.ToArray, ",") & vbCrLf
' Otočí směr řazení.
ArrayList.Reverse
Message = Message & "6: " & Join(ArrayList.ToArray, ",") & vbCrLf
' Odstraní prvek.
ArrayList.Remove 8
' Odstraní prvek na zadaném indexu.
ArrayList.RemoveAt 6
' Odstraní všechny prvky.
ArrayList.Clear
' Uvolní seznam.
Set ArrayList = Nothing
' Zobrazí výsledek.
MsgBox Message, vbSystemModal
System.Collections.SortedList umožňuje práci s párovými daty a přitom přistupovat k položkám seznamu pomocí indexu. Z hlediska možností jde tedy o kombinaci objektu Scripting.Dictionary a System.Collections.ArrayList. Při každém přidání páru do seznamu je tento automaticky seřazen.
Dim Message, SortedList, i, s
' Inicializuje zprávu.
Message = ""
' Vytvoří seznam.
Set SortedList = CreateObject("System.Collections.SortedList")
' Naplní seznam.
SortedList.Add "Point", 1
SortedList.Add "Point Cloud", 2
SortedList.Add "Curve", 4
SortedList.Add "Surface", 8
SortedList.Add "Polysurface", 16
SortedList.Add "Mesh", 32
' Vrátí počet prvků.
Message = Message & "1: " & SortedList.Count & vbCrLf
' Vrátí hodnotu podle klíče.
Message = Message & "2: " & SortedList("Surface") & vbCrLf
' Vrátí hodnotu na indexu.
s = ""
For i = 0 To SortedList.Count - 1
s = s & CStr(SortedList.GetByIndex(i)) & " "
Next
Message = Message & "3: " & s & vbCrLf
' Ověří existenci klíče.
Message = Message & "4: " & SortedList.ContainsKey("Polysurface") & vbCrLf
' Ověří existenci hodnoty.
Message = Message & "5: " & SortedList.ContainsValue(16) & vbCrLf
' Vrátí index klíče (vyhledá prvek podle klíče).
Message = Message & "6: " & SortedList.IndexOfKey("Polysurface") & vbCrLf
' Vrátí index hodnoty (vyhledá prvek podle hodnoty).
Message = Message & "7: " & SortedList.IndexOfValue(16) & vbCrLf
' Odstraní prvek podle klíče.
SortedList.Remove "Polysurface" & vbCrLf
' Odstraní prvek na zadaném indexu.
SortedList.RemoveAt 0
' Odstraní všechny prvky.
SortedList.Clear
' Uvolní seznam.
Set SortedList = Nothing
' Zobrazí výsledek.
MsgBox Message, vbSystemModal
System.Collections.Stack je seznam objektů typu zásobník, tj. last-in-first-out (LIFO). Prvky vložené do seznamu naposled jsou z něj vyjmuty jako první.
Dim Message, Stack, Item, s
' Inicializuje zprávu.
Message = ""
' Vytvoří seznam.
Set Stack = CreateObject("System.Collections.Stack")
' Naplní seznam.
Stack.Push "Item_1"
Stack.Push "Item_2"
Stack.Push "Item_3"
Stack.Push "Item_4"
' Projde prvky seznamu.
s = ""
For Each Item In Stack
s = s & Item & " "
Next
Message = Message & "1: " & s & vbCrLf
' Převede seznam na pole.
Message = Message & "2: " & Join(Stack.ToArray, ",") & vbCrLf
' Vrátí počet prvků.
Message = Message & "3: " & Stack.Count & vbCrLf
' Ověří existenci hodnoty.
Message = Message & "4: " & Stack.Contains("Item_2") & vbCrLf
' Vyjme a vrátí poslední prvek.
Message = Message & "5: " & Stack.Pop & vbCrLf
' Vrátí poslední prvek (bez vyjmutí).
Message = Message & "6: " & Stack.Peek & vbCrLf
' Vyprázdní seznam.
Stack.Clear
' Uvolní seznam.
Set Stack = Nothing
' Zobrazí výsledek.
MsgBox Message, vbSystemModal
System.Collections.Queue je seznam objektů typu fronta, tj. first-in-first-out (FIFO). Prvky vložené do seznamu jako první jsou z něj vyjmuty jako první.
Dim Message, Queue, Item, s
' Inicializuje zprávu.
Message = ""
' Vytvoří seznam.
Set Queue = CreateObject("System.Collections.Queue")
' Naplní seznam.
Queue.Enqueue "Item_1"
Queue.Enqueue "Item_2"
Queue.Enqueue "Item_3"
Queue.Enqueue "Item_4"
' Projde prvky seznamu.
s = ""
For Each Item In Queue
s = s & Item & " "
Next
Message = Message & "1: " & s & vbCrLf
' Převede seznam na pole.
Message = Message & "2: " & Join(Queue.ToArray, ",") & vbCrLf
' Vrátí počet prvků.
Message = Message & "3: " & Queue.Count & vbCrLf
' Ověří existenci hodnoty.
Message = Message & "4: " & Queue.Contains("Item_2") & vbCrLf
' Vyjme a vrátí první prvek.
Message = Message & "5: " & Queue.Dequeue & vbCrLf
' Vrátí první prvek (bez vyjmutí).
Message = Message & "6: " & Queue.Peek & vbCrLf
' Vyprázdní seznam.
Queue.Clear
' Uvolní seznam.
Set Queue = Nothing
' Zobrazí výsledek.
MsgBox Message, vbSystemModal