User Tools

Site Tools


vba:classes:liststream

Table of Contents

[VBA] ListStream

Simuliert einen Stream über eine Liste (Array, Dict etc)

Version 1.9.0 02.11.2022

Das Modul hat versteckte Attribute. Damit diese aktiv übernommen werden reicht es nicht aus, den Code in ein neues Modul zu kopieren. Man muss das Modul aus der Datei nach VBA importieren.
Bild zum Import

Download liststream.cls (V-1.9.0)

Angeregt durch Java wollte ich eine Möglichkeit, Funktionen auf alle Listenelement vereinfachen, so dass man nicht hunderte Schleifen programmieren muss.

Bei der Streamverarbeitung wird immer mit einem Klon gearbeitet. Das heisst, dass die Verarbeitung keinen Einfluss auf die Ursprungsliste hat.

Die Klasse ist vor allem für GUI-Sachene etc. geeignet. Ich würde sie aber nicht für grössere Datenverarbeitungen verwenden.

  • Für die Ausgabe der Testresultate verwendete ich die Funktion d()
  • Achtung! Objekte innerhalb der Liste werden nicht geklont

Einführung

Es geht bei den ListStream darum, mehrere Methoden hintereinander auf eine Liste anzuwenden.

Bsp. Array → Reduzieren auf die eindeutigen Werte (unique) → mischen

arr = array(1,2,1,3,1,4)
d ListStream(arr).unique.shuffle(true).list
<Dictionary>  (
    [0] => <Integer> 2
    [1] => <Integer> 3
    [2] => <Integer> 1
    [3] => <Integer> 4
)
 
'und wieder als Array
arr = array(1,2,1,3,1,4)
d ListStream(arr).unique.shuffle(true).toArray
<Variant()>  (
    [#0] => <Integer> 2
    [#1] => <Integer> 3
    [#2] => <Integer> 1
    [#3] => <Integer> 4
)
 
'und fals man kein Variant-Array sondern ein String-Array braucht:
d ListStream(arr).unique.shuffle(true).toArray(vbString).list
<String()>  (
    [#0] => <String> '4'
    [#1] => <String> '3'
    [#2] => <String> '1'
    [#3] => <String> '2'
)

Oder der Klassiker. Man hat ein Array mit Namen und sollte für diese einen SQL-String zusammensetzen, den man nachher in einem IN() verwenden kann.

arr = array("Mari", "Hans", "Bert", "Vreni",null)
u_names = ListStream(arr).trim.mapToSqlStr(vbString).join(", ")
 
? u_names
'Mari', 'Hans', 'Bert', 'Vreni'
 
? "select * from t where v_name in (" & u_names & ")"
select * from t where v_name in ('Mari', 'Hans', 'Bert', 'Vreni')

Ebenfalls ein Klassiker, man hat eine lIste von Objekten und will aber eine Liste mit jeweils einer Eigenschaft der Objekte. Ich nehme für das Beispiel [VBA] DateTime + DateInterval

arr = array(DateTime(Now), DateTime(Now+1), DateTime(Now+2))
d ListStream(arr).mapObiProp("dateValue",VbGet).list
<Dictionary>  (
    [0] => <Date> 21.01.2020
    [1] => <Date> 22.01.2020
    [2] => <Date> 23.01.2020
)
'Zuerst noch ein Methode auf jedes Element anwenden. In dem Fall addiere 2 Monate dazu
d ListStream(arr).mapCallObjMethode("addSingleValue", VbMethod, "m", 2).mapObiProp("dateValue",VbGet).list
<Dictionary>  (
    [0] => <Date> 21.03.2020
    [1] => <Date> 22.03.2020
    [2] => <Date> 23.03.2020
)

Achtung! ListStream kann auch statisch verwendet werden. Muss dann aber über initialize() gefüttert werden

ListStream.initialize("[a,b,c]")
d ListStream.list
<Dictionary>  (
    [0] => <String> 'a'
    [1] => <String> 'b'
    [2] => <String> 'c'
)
Public Sub test1()
    ListStream.initialize ("[a,b,c]")
End Sub
 
Public Sub test2()
    d ListStream.list
End Sub
'Direktfenster:
test1
test2
<Dictionary>  (
    [0] => <String> 'a'
    [1] => <String> 'b'
    [2] => <String> 'c'
)

Settings

Konstanten / Bedingte Kompilierung

Bei einer so einer grossen Klasse gibt es wie meistens einige Settings. Die findet man ganz am Anfang vom Code. Einige sind normale VBA-Konstanten, das andere sind Konstanten für die bedingte Kompilierung. Die Steuerung kann auch den Funktionsumfang beinträchtigeng .

Konstante Varianten Modul Beschreibung
ms_product Access / Excel Legt fest um welches MS Produkt es sich handelt, da nicht beide alle Methoden gemeinsam haben. Alle Eval-Funktionen sind nur in Access verfügbar
JSF True / False [VBA] JSF Wenn meine Klasse [VBA] JSF vorhanden ist, dann kann dieses Flag aktiviert werden. Es gibt bei einigen Methoden erweiterte Möglichkeiten
Iterator True / False [VBA] Iterator Falls meine Klasse [VBA] Iterator vorhanden ist, dann kann aus dem Stream direkt in eine Iterator geparst werden
Log4vba True / False [VBA] Log4vba Mit [VBA] Log4vba kann das Error-Handling besser gestgeuert werden
C_ERROR_LOG_SETTINGS 13 (eprOutConsole + eprReturnAssert + eprOutMsgBox) Falls Log4vba gesetzt ist, können so die Definitionen für den Error-logger gesetzt werden
strToDate True / False [VBA] strToDate() Erweitert mapToDate um die Möglichkeiten von
DEBUG_MODE True / False Ich glaube, der Name ist Program
C_ERR_HANDLER_DEFAULT enuErrHandler Steuerung des Error-Handlings falls Log4vba nicht gesetzt ist. Siehe dazu den Enum enuErrHandler

Externe Module/Klassen die selbstädnig erkannt werden

Die folgenden Module werden benutzt, falls sie im Projekt vorhanden sind. Wenn sie fehlen kommen bei einzelnen Methoden entsprechende Fehlermeldungen. Sie sind nicht notwendig, aber erleichtern das Eine oder Andere

Modul abhängige Methoden Beschreibung
[VBA] JSON json(), toJSON() Wandelt JSON-Strings in Arrays und Dictionaries und wendelt dieselben wieder zurück
[VBA] cast() Alle möglichen Cast-Methoden Erweitert die Cast-Methoden

Definitionen

Funktions-Aliase

Für einige Methoden gibt es noch Aliase.

  • k{Methode}: Dieselbe Methode, aber auf den Key angewendet. zB. obj.diff(.., ctKey) → obj.kDiff(..)
  • i{Methode}: Dieselbe Methode, aber auf den Index angewendet. zB. obj.remove(1, ctKey) → obj.iRemove(1)
  • v{Methode}: Dieselbe Methode, aber auf den Value angewendet. zB. obj.diff(.., ctValue) → obj.vDiff(..)
  • t{Methode}: Wendet die Methode auf die Keys und die Values gleichzeitig an.
  • n{Methode}: Wenn eine Liste Unterlisten hat, dann wird die Funktion auf ein Element der Unterliste angewendet
  • {Methode}A: Dieselbe Methode, aber anstele eines ParamArray wird ein Array verwendet. zB: obj.mapObiProp(..,param1, param2..) → obj.mapObiPropA(.., array(param1, param2) )
  • {Methode}V: Dieselbe Methode, gibt aber kein ListSream zurück sondern den Value. zB: value = obj.popV()
  • {Methode}K: Dieselbe Methode, gibt aber kein ListSream zurück sondern den Key. zB: Key = obj.popK()
  • {Methode}LS: Bei Methoden die normalerweise einen Wert zurückgeben, gibt es hier den LS zurück
  • {Methode}N: Dieselbe Methode, gibt aber kein ListSream zurück sondern den Node. zB: node = obj.popN()
  • {Methode}E: Dieselbe Methode, gibt aber kein ListSream zurück sondern die ListStreamEntity.

Es gibt auch kombinationan davon. zB. kRemoveV()

Node

Als Node wird ein einzelner Eintrag bezeichnet inkl. des Keys und der Position in der Liste. Damit es keine weitere Klasse braucht, ist das in dem Fall ein Array(1 to 3).

Die einzelnen Elemente könne über den Array-Index abgerufen werden. Die Array-Indexe der einzelnene Teile sind im Enum enuWorkWith hinterlegt. Das ergibt eine Array(key, value, index)

d listStream("{a:1,b:2,c:3}").getNode(1)
<Variant()>  (
    [#1] => <String> 'b'
    [#2] => <Long> 2
    [#3] => <Integer> 1
)
 
d listStream("{a:1,b:2,c:3}").getNode(1)(wwKey)
<String> 'b'
 
set ls = listStream("{a:1,b:2,c:3}")
ls.toNext
d ls.getNode
<Variant()>  (
    [#1] => <String> 'b'
    [#2] => <Long> 2
    [#3] => <Long> 1
)

Zugriff auf das Listenobjekt

Auf die aktuelle Liste, ein Dictionary, kann jederzeit von aussen mit der Eigenschaft list zugegriffen werden

Set ls = ListStream(array(1,2))
? TypeName(ls.list)
Dictionary
 
print_r ls.list
<Dictionary>  (
    [0] => <Integer> 1
    [1] => <Integer> 2
)

List / Quelle

Als List bezeichne ich hier immer die Quellen. Das können im Moment folgendes sein. In der Klasse selber werden die Daten als Dictionary geführt.

Typ / Klasse Beschreibung
Array
Dictionary scripting.Dictionary
Collection
Iterator Falls [VBA] Iterator installiert ist, geht auch der
ListStream Ein anderer ListStream
DAO.Recordset Falls es ein Access-Projekt ist
ADODB.Recordset
Excel.Range
json Falls [VBA] JSON installiert ist, können auch JSON-Strings verwendet werden
JSF Falls [VBA] JSF installiert ist, geht auch das
RegEx Matches

Weitere Listen können in der Private Function x__toDict() einprogrammiert werden

Ersetzungen / Pattern

Bei einigen Methoden, kann oder muss man Stringersetzungen einbauen. Der Pattern lehnt sich an jsf an. #{name}

Der ListStream kennt 3 Parameter pro Eintrag: Key, Index und der Wert. Key und Index ist bei Arrays nach der Erstellung identisch. Nachher kann das auseinander gehen. Der Index ist immer durchgehen aufsteigend.

Wenn [VBA] JSF installiert ist, dann können diese noch durch Formatierungen ergänzt werden

Paramter gültige Patterns
Key #{key}
Index #{index}, #{id}, #{pos}, #{idx}
Wert #{item}, #{value}, #{val}
arr = array("Mari", "Hans", "Bert", "Vreni")
d ListStream(arr).mapParse("Hallo #{item}, du hast die id #{index}").list
<Dictionary>  (
    [0] => <String> 'Hallo Mari, du hast die id 0'
    [1] => <String> 'Hallo Hans, du hast die id 1'
    [2] => <String> 'Hallo Bert, du hast die id 2'
    [3] => <String> 'Hallo Vreni, du hast die id 3'
)

Falls mit JSF gearbeitet wird, dann können auch die Modifiers genutzt werden

d ListStream(array("Mari", "Hans", "Bert", "Vreni")).mapParseJsf("He #{item|upper}!").list
<Dictionary>  (
    [0] => <String> 'He MARI!'
    [1] => <String> 'He HANS!'
    [2] => <String> 'He BERT!'
    [3] => <String> 'He VRENI!'
)

ByReference

Normalerweise ist ListStream byReference. Das heisst, das jeder weitere Schritt das Original mitverändert.
Man kann es auf 2 Arten überschreiben.

  1. Beim Erstellen den Paramteter auf True setzen: Set ls_1 = ListStream(Array(1, 2, 3, 4), , True)
  2. Nachträglich das Property byReference auf True stellen: ls_1.byReference = True

Hier ein Test um das Verhalten zu zeigen. Man sieht gut, wi das Original mit angepasst wurde, da ls_2.list nur eine Referenz auf ls_1.list hat.

Public Sub test()
    Dim ls_1 As ListStream
    Dim ls_2 As ListStream
 
    Set ls_1 = ListStream(Array(1, 2, 3, 4), , False)   'Hier wird mit False byRef ausgeschaltet
    Set ls_2 = ls_1.filterByEval("#{item} mod 2 = 0")
 
    Debug.Print "==Ohne Referenz =="
    Debug.Print "Orignal: ", ls_1.toJSON(ltArray)
    Debug.Print "Ableitung", ls_2.toJSON(ltArray)
 
    'Auf Referenz umschalten
    ls_1.byReference = True
    Set ls_2 = ls_1.filterByEval("#{item} mod 2 = 0")
 
    Debug.Print "==Mit Referenz =="
    Debug.Print "Orignal: ", ls_1.toJSON(ltArray)
    Debug.Print "Ableitung", ls_2.toJSON(ltArray)
 
    'Methode innerhalb der Verarbeitung die Reference mittels clone() zu unterbreuchen
    Set ls_1 = ListStream(Array(1, 2, 3, 4))
    Set ls_2 = ls_1.mapEval("#{value}+2").clone.filterByEval("#{item} mod 2 = 0")
    Debug.Print "==Mit Referenz, nach dem ersten Arbeitsschritt unterbrochen =="
    Debug.Print "Orignal: ", ls_1.toJSON(ltArray)
    Debug.Print "Ableitung", ls_2.toJSON(ltArray)
End Sub
==Ohne Referenz ==
Orignal:      [1,2,3,4]
Ableitung     [2,4]
==Mit Referenz ==
Orignal:      [2,4]
Ableitung     [2,4]
==Mit Referenz, nach dem ersten Arbeitsschritt unterbrochen ==
Orignal:      [3,4,5,6]
Ableitung     [4,6]

Übersicht über die Methoden

Methode Beschreibung Rückgabewert Einchränkung
Initialisierungs-Methoden
Mit diesen Methoden wird ein ListStream-Objekt erstellt
instance Erstellt eine neue Instanz aus einer Liste ListStream
initialize Initializiert ein Objekt ListStream
init Erstellt einen ListStream aus einzelnen Elementen ListStream
initCombine Erstellt einen ListStream aus einzelnen Elementen, wobei immer einer als Key, der nächste als Wert ListStream
initRs Erstellt ein ListTsream anhand eines SQL-Statements/View Name/Table Name. Es wird ein currentDb.OpenRecordset() ausgeführt ListStream
initRange Erstellt eine Instanz aus einem Excel.Worksheet oder Excel.Range ListStream
range Erstellt eine Instanz aus einem Bereich ListStream
fill Eine Instanz. Definiert über Start, Länge und Fix-Wert ListStream
fillkey Erstellt eine Liste aus einer Auflistung von Keys und einem Standardwert ListStream
clone Ein Klon der bestehenden Liste ListStream
combine Kombiniert 2 LIsten. Die erste als Keys, die Zweite als Werte ListStream
mergelists Kombiniert mehrere Listen zu einem Stream ListStream
Listengrössen Methoden
Direktes Hinzufügen und Entfernen von Elementen
remove Entfernt ein Item anhand des Indexes aus der Liste Item & ListStream
shift Entfernt das erste Item Erstes Item & ListStream
pop Entfernt das letzte Item Letztes Item & ListStream
add Fügt ein neues Item hinzu ListStream
replaceKeys Ersetzt die alle Keys ListStream
resetIndex Setzt numerische Keys auf den Index zurück ListStream
merge Fügt eine Liste hinzu ListStream
pad Füllt die Liste mit einem Festwert auf ListStream
countValues Zählt gleiche Elemente ListStream
slice Extrahiert einen Teil der Liste ListStream
Vergleichs Methoden
Vergleicht 2 Listen miteinander
intersec Schnittmenge mit einer zweiten Liste ListStream
diff Unterschied zu einer zweiten Liste ListStream
Sortierungs Methoden
Verändern die Reihenfolge der Elemente
shuffle Items mischen ListStream
sort Sortieren nach Key oder Wert ListStream
sortObjProp Bei einer Objekt-Liste, nach einer Objekteigenschaft sortieren ListStream
sortByEval Führt zuerst ein eval() durch und sortiert dann ListStream nur Access
sortByList Sortiert nach einer zweiten Liste ListStream
Listenveräderungsmethoden
Verändern die Liste
flip Tauscht Key und Wert miteinander aus ListStream
values Entfernt die Keys ListStream
keys Gibt die Keys als neuen ListStream aus ListStream]
collect Wandelt den ListStream in eine Liste um Variant
toArray Wandelt den ListStream in einen Array um Array
toCollection Wandelt den ListStream in eine Collection um Collection
toDictionary Wandelt den ListStream in ein Dictionary um Dictionary
toIterator Wandelt den ListStream in ein Iterator um Iterator Nur mit Iterator
Filter Methoden
Elemente ausfiltern
unique Entfernt doppelte Werte ListStream
trim Entfernt Null, Empty und Nothing Werte ListStream
filterByValue Nach einem Wert filtern (=, =<, <> etc.) ListStream
filterByEval Führt einen Eval() aus und filtert nach dessem Resultat ListStream nur Access
filterByObjProp Bei einer Objektliste kann nach einem Property oder einer Methode der Objekte gefiltert werden ListStream
filterByRegEx Filtert nach einem RegEx ListStream
filterInList Filtert nach Index/Keys anhand der Werte einer Liste ListStream
filterInListAssoc Analog zu filterInList, es werden aber Wert & Key/Index verglichen ListStream
filterListNode Die Items sind selber Listen. Die Funktion Filtert nach Werten an der xten (index oder Key) Postion ListTream
Reduktionsmethoden
Reduziert die Liste auf einen einzelnen Wert
sum Summiert alle numerischen Werte zusammen Number
join Analog zum vba.join() fügt alle Werte mittels eines Delimiters zusammen String
max Grösster Wert Variant
min Kleinster Wert Variant
first Erster Wert Variant
last Letzter Wert Variant
getItem Gibt den Wert an einer bestimmten Position zurück. Variant
getKey Gibt den Key an einer bestimmten Position zurück. Variant
getItemSpecial Gibt den Wert eines speziellen Keys zurück Variant
getKeySpecial Gibt einen speziellen Key Variant
getRand Gibt ein oder mehrere zufällige Elemente aus Variant
search Sucht nach einem Value und gibt den ersten passenden Key zurück Variant
parseToString Ein jsf.parse String nur mit JSF
reduceByUdf Reduktion über eine User Defined Funktion Variant
parseByRegExReplace Iterative Reduktion eines Arrays zu einem Wert mittels einer RegReplace String
Key Methoden
Nur der Key wird verändert
mapKeysToStr Wandelt alle Keys in SQL-Strings um ListStream
Mappings
Verändert die einzelnen Items
mapTrim Ein Trim auf alle Items ListStream
mapRegExReplace Ein RegExp.Replace auf elle Items ListStream
mapFormat Formatbefehl auf alle Items ListStream
mapCast Typenumawndlung über alle Items ListStream
mapParse JSF-Parse über alle Items ListStream
mapToSqlStr Alle Items in SQL-Strings wandeln ListStream
mapEval Ersetzt alle Items mit einem eval() ListStream nur Access
mapWalk Führt eine Funktion auf jedes Item aus ListStream nur Access
mapObjProp Ersetzt die Item-Objekte mit dem Rückgabewert einer Methode oder eines Paramters ListStrem
mapCallObjMethode Führt auf jedem Item-Objekt eine Methode aus ListStream
mapListNode Die Items sind selber Listen. Dann nimmt die Funktion die Werte an der xten (index oder Key) Postion ListStream
mapToBool Castet alle Werte in ein Boolean ListStream
mapToLng Castet alle Werte in ein Long ListStream
mapToDbl Castet alle Werte in ein Double ListStream
mapToStr Castet alle Werte in ein String ListStream
mapToDate Castet alle Werte in ein Datum ListStream
Iterator Methoden
Methoden die man zum Iterieren über die liste verwenden kann
for_each ListStream
tofirst_tonext_toprev_tolast Boolean
bof_eof Boolean
pos long
value Variant
setPos ListStream
Statische Hilfsmethoden
Zusätzliche Funktionen, die nicht direkt auf die Liste bezogen sind
var2CodeStr Gibt den Value in VBA-Code Form zurück. Kann für Evals etc. benutzt werden Variant

Methoden & Besipiele

Für die Ausgabe der Resultate verwendete ich die Funktion d()
In meinen Beispielen ist das [VBA] JSON im Projekt vorhanden. Das vereinfacht grad für Beispiele das Initialisieren des Objektes

Um das Resultat der Beispiele zeige ich jeweil das Resultat des list Property. Die anderen Paramater sind irrelevant.
So würde es aussehen, wenn ich jedes mal alles ausgeben würde

Set ls = ListStream.init(11,22,33)
'Alle Properties des Obektes
d ls
<Class Module::ListStream>  (
    [withKeys] => <Boolean> False
    [byReference] => <Boolean> False
    [compareMode] => <Long> 1
    [list] => <Dictionary>  (
        [0] => <Integer> 11
        [1] => <Integer> 22
        [2] => <Integer> 33
    )
    [json] => <String> '{0:11,1:22,2:33}'
    [count] => <Long> 3
)
 
'Wirklich interessant ist nur die list
d ls.list
<Dictionary>  (
    [0] => <Integer> 11
    [1] => <Integer> 22
    [2] => <Integer> 33
)

Initialisierungs-Methoden

instance()

instance() ist die Standardmethode der Klasse und gibt eine neue Instanz zurück

ListStream = ListStream.instance([list], [compareMeode], [byReference])
ListStream = ListStream([list], [compareMeode], [byReference])
Parameter Typ Standard Beschreibung
list Variant (siehe listquelle) Die Liste, über welche Iteriert werden soll
compareMeode CompareMethod nicht überschreiben Vergleichsmethode
byReference Boolean false Flag ob das Resultat jeweils als Referenz des Originals gehandhabt wird oder nicht
return ListStream Rückgabewert
'Array
d ListStream(array("a","b")).list
<Dictionary>  (
    [0] => <String> 'a'
    [1] => <String> 'b'
)
 
'Dictionary
Set dict = CreateObject("scripting.Dictionary")
dict.add "AA", "a"
dict.add "BB", "b"
d ListStream(dict).list
<Dictionary>  (
    [AA] => <String> 'a'
    [BB] => <String> 'b'
)
 
'JSON Array
d ListStream("[a,b,c]").list
<Dictionary>  (
    [0] => <String> 'a'
    [1] => <String> 'b'
    [2] => <String> 'c'
)
 
'JSON Dictionary
d ListStream("[{AA:a,BB:b,CC:c}").list
<Dictionary>  (
    [AA] => <String> 'a'
    [BB] => <String> 'b'
    [CC] => <String> 'c'
)

initialize()

Initializiert ein Objekt

ListStream = Objekt.initialize([list], [compareMeode], [byReference])
Parameter Typ Standard Beschreibung
list Variant (siehe listquelle) Die Liste, über welche Iteriert werden soll
compareMeode CompareMethod nicht überschreiben Vergleichsmethode
byReference Boolean false Flag ob das Resultat jeweils als Referenz des Originals gehandhabt wird oder nicht
return ListStream Rückgabewert
Dim ls as new ListStream
ls.Initialisiert(array(1,2,3))

init()

Erstellt einen ListStream aus einzelnen Elementen

ListStream = ListStream.init(parameter-1 .. parameter-X)
Parameter Typ Standard Beschreibung
paramter Variant Items
return ListStream Rückgabewert
d ListStream.init("a", "b", "c").list
<Dictionary>  (
    [0] => <String> 'a'
    [1] => <String> 'b'
    [2] => <String> 'c'
)

initCombine()

Erstellt einen ListStream aus einzelnen Elementen, wobei es abwechslend Key und Value ist.

ListStream = ListStream.init(key-1, value-1, key-2, value-2..., key-X, value-X)
Parameter Typ Standard Beschreibung
paramter Variant Keys/Items
return ListStream Rückgabewert
d ListStream.initCombine("a", "A", "b", "B", "c").list
<Dictionary>  (
    [a] => <String> 'A'
    [b] => <String> 'B'
    [c] => <Null> 
)

initRs

Erstellt ein ListTsream anhand eines SQL-Statements/View Name/Table Name. Es wird ein currentDb.OpenRecordset() auugeführt

ListStream = Objekt.iniRs([sql], [compareMeode], [byReference])
Parameter Typ Standard Beschreibung
sql String Sql/Tablename/Queryname
compareMeode CompareMethod na Vergleichsmethode
byReference Boolean false Flag ob das Resultat jeweils als Referenz des Originals gehandhabt wird oder nicht
return ListStream Rückgabewert
d ListStream.initRs("SELECT * FROM T_JSF_EXAMPLE WHERE id in (1, 2)").list
<Dictionary>  (
    [1] => <Dictionary>  (
        [ID] => <Byte> 1
        [USER] => <String> 'Stefan'
        [VULGO] => <String> 'Yaslaw'
        [LOCATION] => <String> 'Büro 1A'
        [START_DATE] => <Date> 01.10.2018
        [IS_IMPORTANT] => <Boolean> True
    )
    [2] => <Dictionary>  (
        [ID] => <Byte> 2
        [USER] => <String> 'Sandra'
        [VULGO] => <Null> 
        [LOCATION] => <String> 'Büro 3'
        [START_DATE] => <Date> 01.11.2018
        [IS_IMPORTANT] => <Boolean> False
    )
)

initRange()

Erstellt ein ListStream aus einem Excel-Range. Diese Methode hat noch zusätzliche Parameter

ListStream = ListStream.initRange(range, [withHeader], [keyColumn], [compareMode])
Parameter Typ Standard Beschreibung
range Excel.Worksheet/Excel.Range
withHeader Boolean True Die Erste Zeile beinhaltet ein Header
keyColumn Long/String -1 Name der Spalte innerhalb des Ranges, der als Key verwendet werden soll. -1 bedeutet, dass die Zeilennummer als Key verwendet wird
compareMeode CompareMethod nicht überschreiben Vergleichsmethode
return ListStream Rückgabewert

Excelsheet Sheet1

A B
1 ID NAME
2 1Hans
3 2Sonja
d ListStream.initRange(Sheets("Sheet1")).list
<Dictionary>  (
    [1] => <Dictionary>  (
        [ID] => <Double> 1
        [NAME] => <String> 'Hans'
    )
    [2] => <Dictionary>  (
        [ID] => <Double> 2
        [NAME] => <String> 'Sonja'
    )
)
 
'Ein Range, der keinen Header beinhaltet
d ListStream.initRange(Sheets("Sheet1").Range("A2:B3"), False).list
<Dictionary>  (
    [0] => <Dictionary>  (
        [F1] => <Double> 1
        [F2] => <String> 'Hans'
    )
    [1] => <Dictionary>  (
        [F1] => <Double> 2
        [F2] => <String> 'Sonja'
    )
)
 
'Mit dem Feld [name] als Schlüssel
d ListStream.initRange(Sheets("Sheet1"), ,"name").list
<Dictionary>  (
    [Hans] => <Dictionary>  (
        [ID] => <Double> 1
        [NAME] => <String> 'Hans'
    )
    [Sonja] => <Dictionary>  (
        [ID] => <Double> 2
        [NAME] => <String> 'Sonja'
    )
)
 
'Dito wenn kein Header vorhanden ist. Die Spalten sind dann F & Spaltennummer
d ListStream.initRange(Sheets("Sheet1").Range("A2:B3"), False, "F2").list
<Dictionary>  (
    [Hans] => <Dictionary>  (
        [F1] => <Double> 1
        [F2] => <String> 'Hans'
    )
    [Sonja] => <Dictionary>  (
        [F1] => <Double> 2
        [F2] => <String> 'Sonja'
    )
)

range()

Erstellt eine Instanz aus einem Bereich .
Erstellt einen ListStream mit Elementen im Bereich von low bis high . Wenn low > high, wird die Sequenz von high nach low sein.

ListStream = ListStream.Range(low, high, [step], [compareMode])
Parameter Typ Standard Beschreibung
low Long/Integer/Char Unterster Wert
high Long/Integer/Char Oberster Wert
step Long 1 Schrittgrösse
compareMeode CompareMethod nicht überschreiben Vergleichsmethode
return ListStream Rückgabewert
Dim ls as ListStream
Set ls = ListStream.range(2,5)
d ls.list
<Dictionary>  (
    [0] => <Long> 2
    [1] => <Long> 3
    [2] => <Long> 4
    [3] => <Long> 5
)
 
'Und mit Buchstaben
d ListStream.range("a", "d").list
<Dictionary>  (
    [0] => <String> 'a'
    [1] => <String> 'b'
    [2] => <String> 'c'
    [3] => <String> 'd'
)

fill()

Eine Instanz. Definiert über Start, Länge und Fix-Wert

ListStream = ListStream.fill([start], [size], [wert], [compareMode])
Parameter Typ Standard Beschreibung
start Long 0 numerischer Startkey
size Long 1 Länge (Anzahl Einträge)
wert Variant NULL Der Wert, dier bei allen eingetragen wird
compareMeode CompareMethod nicht überschreiben Vergleichsmethode
return ListStream Rückgabewert
Dim ls As ListStream
Set ls = ListSTream.fill(0, 3, "a")
d ls.list
<Dictionary>  (
    [0] => <String> 'a'
    [1] => <String> 'a'
    [2] => <String> 'a'
)

fillKey()

Erstellt eine Liste aus einer AUflistung von Keys und einem Standardwert

ListStream = ListStream.fillKey(list<Keys>, value, compaireMode)
Parameter Typ Standard Beschreibung
list List Liste der Keys
value Variant NULL Der Wert, dier bei allen eingetragen wird
compareMeode CompareMethod nicht überschreiben Vergleichsmethode
return ListStream Rückgabewert
d ListStream.fillKey("[a,b,c]", "NA").list
<Dictionary>  (
    [a] => <String> 'NA'
    [b] => <String> 'NA'
    [c] => <String> 'NA'
)
d ListStream.fillKey(Array(11,22,23)).list
<Dictionary>  (
    [11] => <Null> 
    [22] => <Null> 
    [23] => <Null> 
)

clone()

Erstellt ein Clone des ListStreams. Achtung, Wenn Objekte in der Liste sind, werden diese nicht geklont

ListStream = ListStream.clone([compareMode])
Parameter Typ Standard Beschreibung
compareMeode CompareMethod nicht überschreiben Vergleichsmethode
return ListStream Rückgabewert

—-

combine()

Kombiniert 2 LIsten. Die erste als Keys, die Zweite als Werte

ListStream = ListStream.combine(keys, values, [compareMode])
Parameter Typ Standard Beschreibung
keys Variant (siehe listquelle) Die Liste der Keys
values Variant (siehe listquelle) Die Liste der Werte
compareMeode CompareMethod nicht überschreiben Vergleichsmethode
return ListStream Rückgabewert
'Gleich viele Keys wie Werte
d ListStream.combine(array("a", "b"), array("AA", "BB")).list
<Dictionary>  (
    [a] => <String> 'AA'
    [b] => <String> 'BB'
)
 
'Mehr Keys als Werte
d ListStream.combine(array("a", "b", "c"), array("AA", "BB")).list
<Dictionary>  (
    [a] => <String> 'AA'
    [b] => <String> 'BB'
    [c] => <Null> 
)
 
'Mehr Werte als Keys
'Gleich viele Keys wie Werte
d ListStream.combine(array("a", "b"), array("AA", "BB", "CC")).list
<Dictionary>  (
    [a] => <String> 'AA'
    [b] => <String> 'BB'
    [2] => <String> 'CC'
)

mergeLists()

Kombiniert mehrere Listen zu einem ListStream

ListStream = ListStream.mergeLists(list1, list2, .., listX)
ListStream = ListStream.mergeLists(overwrite, list1, list2, .., listX)
ListStream = ListStream.mergeListsA(Array<list>(), overwrite)
Parameter Typ Standard Beschreibung
overwrite boolean False Flag ob bei gleichem Key der Wert überschrieben werden soll
listX Variant (siehe listquelle) Liste
return ListStream Rückgabewert
'Normal
d ListStream.mergeLists("{a:1,b:2}", "{x:11, y:22}").list
<Dictionary>  (
    [a] => <Long> 1
    [b] => <Long> 2
    [x] => <Long> 11
    [y] => <Long> 22
)
 
'Mit identischen keys
d ListStream.mergeLists("{a:1,b:2}", "{a:11, c:33}").list
<Dictionary>  (
    [a] => <Long> 1
    [b] => <Long> 2
    [c] => <Long> 33
)
 
'dito, aber zusätzlich das Flag, dass die Keys überschrieben werden sollen
d ListStream.mergeLists(true, "{a:1,b:2}", "{a:11, c:33}").list
<Dictionary>  (
    [a] => <Long> 11
    [b] => <Long> 2
    [c] => <Long> 33
)
 
'Mit Array wird immer angehängt, da kein Key existiert
d ListStream.mergeLists(array(1,2), "[3,4]").list
<Dictionary>  (
    [0] => <Integer> 1
    [1] => <Integer> 2
    [2] => <Long> 3
    [3] => <Long> 4
)

Listengrössen Methoden

Bei diesen Methoden wird die Grösse der Liste verändert. Der Wert des Eintrages wird als Paramter zurückgegeben

remove()

Entfernt ein Item anhand des Indexes aus der Liste

ListStream = obj.remove([key], [keyTypeFlag], [outVlaue], [outKey])
ListStream = obj.kRemove(key, [outVlaue])
ListStream = obj.iRemove(index, [outVlaue], [outKey])
value = obj.kRemoveV(key, [outKey])
key = obj.kRemoveK(key, [outValue])
value = obj.iRemoveV(index, [outKey])
key = obj.iRemoveK(index, [outValue])
Parameter Typ Beschreibung
key Variant Index oder Key des Datensatzen
keyTypeFlag enuIndexOrKey Flag der aussagt, ob der Paramter key ein Key oder ein Index ist
outVlaue Variant Wert der entfernt wird - schau myVar im Beispiel
outKey Variant Key/Index der entfernt wird
return ListStream Rückgabewert
? ListStream(array("a","b","c")).remove(1, , myVar).dump
{0 => a, 2 => c}
? myVar
b
'kRemove()
d ListStream("{a:1,b:2,c:3}").kRemove("b", v).list
<Dictionary>  (
    [a] => <Long> 1
    [c] => <Long> 3
)
d v
<Long> 2
 
'iRemoveK
Set ls = ListStream("{a:1,b:2,c:3}")
d ls.iRemoveV(1, k)
<Long> 2
d k
<String> 'b'
d ls.list
<Dictionary>  (
    [a] => <Long> 1
    [c] => <Long> 3
)

shift()

Shift ist vor allem in Stacks sehr nützlich. Obersten Eintrag herausnehmen. Wenn keine Keys vorhanden sind, wird der Index nachgeführt.

ListStream = obj.shift([outValue], [outKey])
Variant = obj.shiftV([outKey])
Variant = obj.shiftK([outValue])
Parameter Typ Beschreibung
outValue Variant Wert der entfernt wird - schau myVar im Beispiel
outKey Variant Key der entfernt wird
return ListStream Rückgabewert
d ListStream("{a:1,b:2,c:3}").shift().list
<Dictionary>  (
    [b] => <Long> 2
    [c] => <Long> 3
)
d ListStream("{a:1,b:2,c:3}").shiftV()
<Long> 1
d ListStream("{a:1,b:2,c:3}").shiftK()
<String> 'a'
 
'Den Wert und Key auslesen
d ListStream("{a:1,b:2,c:3}").shift(v, k).list
<Dictionary>  (
    [b] => <Long> 2
    [c] => <Long> 3
)
d v
<Long> 1
d k
<String> 'a'

pop()

Wie shift, aber mit dem letzten Eintrag

ListStream = obj.pop([outValue], [outKey])
Variant = obj.popV([[outKey])
Variant = obj.popK([[outValue])
Parameter Typ Beschreibung
outValue Variant Wert der entfernt wird - schau myVar im Beispiel
outKey Variant Key der entfernt wird
return ListStream Rückgabewert
arr = array("a","b","c")
'Erster Eintrag rausnehmen und in myVar speichern
d ListStream(arr).pop(myVar).list
<Dictionary>  (
    [0] => <String> 'a'
    [1] => <String> 'b'
)
d myVar.list
<String> 'c'
 
'Hat die Liste einen key, dann wird er beibehalten
d ListStream("{A:a,B:b,C:c}").pop(myVar).list
<Dictionary>  (
    [A] => <String> 'a'
    [B] => <String> 'b'
)
d myVar.list
<String> 'c'

add()

Fügt ein neues Item hinzu

ListStream = obj.add([key], wert)
ListStream = obj.add(wert)
Parameter Typ Beschreibung
key Variant Key des Datensatzen
wert Variant Wert der hinzugefügt wird
return ListStream Rückgabewert

Wird kein Key mitgegeben werden, dann kann der Value auch auf der Ersten Position mitgegeben werden

'arr = array("a","b")
d ListStream(arr).add("c").list
<Dictionary>  (
    [0] => <String> 'a'
    [1] => <String> 'b'
    [2] => <String> 'c'
)
 
 
d ListStream("{A:a,B:b}").add("C", "c").list
<Dictionary>  (
    [A] => <String> 'a'
    [B] => <String> 'b'
    [C] => <String> 'c'
)

replaceKeys

Ersetzt die Keys in der Liste. Im gegensatz zu den kMap-Methoden sind hier die neuen Keys nicht generiert sondern werden als Liste übergeben

ListStream = obj.replaceKeys(list)
Parameter Typ Beschreibung
list Variant (siehe listquelle) Die Listeder neuen Keys
return ListStream Rückgabewert
? ListStream("[a,b,c]").replaceKeys("[x,y,z]").dump
{x => a, y => b, z => c}
 
'Zu wenig Keys
? ListStream("[a,b,c]").replaceKeys("[x,y]").dump
{x => a, y => b, 2 => c}
 
'Zu viele Keys
? ListStream("[a,b,c]").replaceKeys("[x,y,z,o]").dump
{x => a, y => b, z => c, o => NULL}

resetIndex()

Wenn keine Keys vorhanden sind, dann wird der Index der Ursprungsliste als Keys verwendet. Nach einigen Opationen kann der nicht mehr in der Reihenfolge sein (gewollt, da es dem Index der Ursprungsliste entspricht). Mit dieser Methode kann der Index zurückgesetzt werden

ListStream = obj.resetIndex
Parameter Typ Beschreibung
return ListStream Rückgabewert
Set ls = ListStream(array("a","b","c"))
'Orignal:
? ls.dump
{0 => a, 1 => b, 2 => c}
'Nach einer Methode
Set ls = ls.shuffle
? ls.dump
{2 => c, 1 => b, 0 => a}
'Und Index zurücksetzen
Set ls = ls.resetIndex
? ls.dump
{0 => c, 1 => b, 2 => a}

merge()

Hat die LIste Keys, dann werden nur die Einträge angefügt, dern Key noch nicht vorhanden ist. Bei Index werden alle Neuen angefügt

ListStream = obj.merge(list, [compareMode], [overwrite])
Parameter Typ Beschreibung
list Variant (siehe listquelle) Die Liste, über welche Iteriert werden soll
compareMode CompareMethod Vergleichsmethode
overwrite boolean Flag ob bei gleichem Key/Index der Wert überschrieben werden soll
return ListStream Rückgabewert
'Liste ohne Keys
d ListStream(array("a", "b")).merge(array("b","c")).list
<Dictionary>  (
    [0] => <String> 'a'
    [1] => <String> 'b'
    [2] => <String> 'b'
    [3] => <String> 'c'
)
 
'Liste mit Keys. Bereits vergebene Keys werden ignoriert
d ListStream("{AA:a,BB:b}").merge("{BB:b1,CC:c}").list
<Dictionary>  (
    [AA] => <String> 'a'
    [BB] => <String> 'b'
    [CC] => <String> 'c'
)
 
'dito, aber mit overwrite
d ListStream("{AA:a,BB:b}").merge("{BB:b1,CC:c}",,True).list
<Dictionary>  (
    [AA] => <String> 'a'
    [BB] => <String> 'b1'
    [CC] => <String> 'c'
)

pad()

Füllt die Liste mit einem Festwert auf.

ListStream = obj.pad(size[, value])
Parameter Typ Beschreibung
size Long Die Grösse des Array: Positiv: die Werte werdem am Ende hinzugefügt, Negativ: die Wert werden am Anfang hinzugefügt, Kleiner als die Listengrösse: Befehl wird ignoriert
value Variant Wer der gesetzt wird
'SIze ist grösser als die Liste
d listStream("{a:1,b:2}").pad(4,"x").list
<Dictionary>  (
    [a] => <Long> 1
    [b] => <Long> 2
    [0] => <String> 'x'
    [1] => <String> 'x'
)
 
'Size ist kleiner als die Liste
d listStream("[1,2,3]").pad(2,"x").list
<Dictionary>  (
    [0] => <Long> 1
    [1] => <Long> 2
    [2] => <Long> 3
)

Vergleichs Methoden

intersec()

Schnittmenge mit einer zweiten Liste

ListStream = obj.intersec(list, [compareType], [compareMode])
Parameter Typ Standard Beschreibung
list Variant (siehe listquelle) Die Listemit der verglichen wird
compareType enuCompaireType Wert Was verglichen werden soll. Key oder Wert
compareMode CompareMethod nicht überschreiben Vergleichsmethode
return ListStream Rückgabewert
'Vergleich über den Wert
Set ls = ListStream(array("a","b","c"))
d ls.intersec(array("b","c","d")).list
<Dictionary>  (
    [1] => <String> 'b'
    [2] => <String> 'c'
)
 
'Vergleich über den Key
Set ls = ListStream("{AA:a,BB:b,CC:c}")
d ls.intersec("{BB:bbb,CC:null,DD:d}", ctKey).list
<Dictionary>  (
    [BB] => <String> 'b'
    [CC] => <String> 'c'
)

diff()

Unterschied zu einer zweiten Liste

ListStream = obj.diff(list, [compareType], [compareMode])
Parameter Typ Standard Beschreibung
list Variant (siehe listquelle) Die Listemit der verglichen wird
compareType enuCompaireType Wert Was verglichen werden soll. Key oder Wert
compareMode CompareMethod nicht überschreiben Vergleichsmethode
return ListStream Rückgabewert
'Vergleich über den Wert
Set ls = ListStream(array("a","b","c"))
d ls.diff(array("b","c","d")).list
<Dictionary>  (
    [0] => <String> 'a'
)
 
'Vergleich über den Key
Set ls = ListStream("{AA:a,BB:b,CC:c}")
d ls.diff("{BB:bbb,CC:null,DD:d}", ctKey).list
<Dictionary>  (
    [AA] => <String> 'a'
)

Sortierungs Methoden

shuffle()

Items mischen

ListStream = obj.shuffle([resetIndex])
Parameter Typ Standard Beschreibung
resetIndex Boolean False Nach dem mischen numerische Keys zurücksetzen
return ListStream Rückgabewert
'Normal, ohne den Index zurückzusetzen
d ListStream.init("a","b","c").shuffle.list
<Dictionary>  (
    [1] => <String> 'b'
    [2] => <String> 'c'
    [0] => <String> 'a'
)
 
'Den Index zurückzusetzen
d ListStream.init("a","b","c").shuffle(True).list
<Dictionary>  (
    [0] => <String> 'c'
    [1] => <String> 'b'
    [2] => <String> 'a'
)

sort(), kSort(), nSort()

Einfaces Sortieren nach Value oder Key

ListStream = obj.sort([richtung], [compareType], [resetIndex])
ListStream = obj.kSort([richtung], [resetIndex])
ListStream = obj.nSort([richtung], [compareType], [resetIndex])
Parameter Typ Standard Beschreibung
richtung Sortierrichtung Aufsteigend
compareType enuCompiareType Wert Was verglichen werden soll. Key oder Wert
resetIndex Boolean False Nach dem mischen numerische Keys zurücksetzen
return ListStream Rückgabewert
'Aufsteigend nach Wert 
d ListStream.init("X","a","w").sort.list
<Dictionary>  (
    [1] => <String> 'a'
    [2] => <String> 'w'
    [0] => <String> 'X'
)
 
'Absteigend nach Key
d ListStream("{BB:0,AA:1,CC:2}").sort(soDescending,ctKey).list
<Dictionary>  (
    [CC] => <Long> 2
    [BB] => <Long> 0
    [AA] => <Long> 1
)
 
'Mit nSort nach einem Eintrag in einer Unterliste
d ListStream("[{sort:5,val:A},{sort:0,val:B},{sort:1,val:C}]").nSort("sort").list
<Dictionary>  (
    [1] => <Dictionary>  (
        [sort] => <Long> 0
        [val] => <String> 'B'
    )
    [2] => <Dictionary>  (
        [sort] => <Long> 1
        [val] => <String> 'C'
    )
    [0] => <Dictionary>  (
        [sort] => <Long> 5
        [val] => <String> 'A'
    )
)

sortObjProp(), sortByObjPropA()

Bei einer Objekt-Liste, nach einer Objekteigenschaft sortieren

ListStream = obj.sortObjProp(methodenName, methodenType, richtung, parameter-1 .. parameter-X)
ListStream = obj.sortObjPropA(methodenName, methodenType, richtung, array(parameter-1 .. parameter-X))
Parameter Typ Standard Beschreibung
methodenName String Name der Methode
methodenType vbCallType Art der Methode. Get/Set/Let/Method
richtung Sortierrichtung Aufsteigend
parameter Variant Die Paramter der Methode
return ListStream Rückgabewert

Für diese Beispiel verwende ich die Klasse [VBA] DateTime Für die Resultatausgabe verwende ich auch noch mapObiProp()

'Daten vorbereiten
Set ls = ListStream.init(DateTime(#2015-01-01#), DateTime(#2019-12-01#), DateTime(#2018-06-01#))
 
d ls.mapObiProp("dateValue", VbGet).list
<Dictionary>  (
    [0] => <Date> 01.01.2015
    [1] => <Date> 01.12.2019
    [2] => <Date> 01.06.2018
)
 
'Nach Monat sortiert
d ls.sortByObjProp("format", VbMethod, soAscending, "MM").mapObiProp("dateValue", VbGet).list
<Dictionary>  (
    [0] => <Date> 01.01.2015
    [2] => <Date> 01.06.2018
    [1] => <Date> 01.12.2019
)
Aliasse zu sortObjProp()
  • sortObjPropA(): Anstelle eines Param-Arrays wird ein Array verwendet

sortByEval(), nSortByEval()

Führt einen eval() aus und Sortiert nach dem Resultat

ListStream = obj.sortByEval(code, [richtung])
ListStream = obj.nSortByEval(index, code, [richtung])
Parameter Typ Standard Beschreibung
index Number/String Wird nur bei der n* Methode gebraucht. Index im Subnode, nachdem sortiert werden soll
code String Eval-Code mit Ersetzungen / Pattern
richtung Sortierrichtung Aufsteigend
resetIndex Boolean False Nach dem mischen numerische Keys zurücksetzen
return ListStream Rückgabewert
'Liste mit Nummern als String
Set ls = ListStream.init("11","4","303")
 
'Normale Sortierung
d ls.sort.list
<Dictionary>  (
    [0] => <String> '11'
    [2] => <String> '303'
    [1] => <String> '4'
)
 
'Sortierung mit einem Eval
d ls.sortByEval("cLng(#{item})").list
<Dictionary>  (
    [1] => <String> '4'
    [0] => <String> '11'
    [2] => <String> '303'
)
'nSortByEval
 
'Direktauswertung des Wertes. In dem fall sortieren nach eval(value)
Set ls = ListStream("/[{id:1,value:'1+2'},{id:2,value:'44'},{id:3,value:'2^4'}]/n")
d ls.nSortByEval(1, "#{value}").list
<Dictionary>  (
    [0] => <Dictionary>  (
        [id] => <String> '1'
        [value] => <String> '1+2'
    )
    [2] => <Dictionary>  (
        [id] => <String> '3'
        [value] => <String> '2^4'
    )
    [1] => <Dictionary>  (
        [id] => <String> '2'
        [value] => <String> '44'
    )
)
 
'value mod 4
Set ls = ListStream("/[{id:1,value:3},{id:2,value:1},{id:3,value:4}]/n")
d ls.nSortByEval(1, "#{value} mod 4").list
<Dictionary>  (
    [2] => <Dictionary>  (
        [id] => <String> '3'
        [value] => <String> '4'
    )
    [1] => <Dictionary>  (
        [id] => <String> '2'
        [value] => <String> '1'
    )
    [0] => <Dictionary>  (
        [id] => <String> '1'
        [value] => <String> '3'
    )
)

sortByList(), kSortByList(), nSortByList()

Sortiert nach einer andere Liste, die die Index oder Keys in der gewünschten Reihenfolge hat.
Siehe auch [VBA] multiSort()

ListStream = obj.sortByList(list, [indexOderKey], [resetIndex])
ListStream = obj.kSortByList(list, [resetIndex])
ListStream = obj.nSortByList(index, list, [resetIndex])
Parameter Typ Standard Beschreibung
index Number/String Wird nur bei der n* Methode gebraucht. Index im Subnode, nachdem sortiert werden soll
list Variant (siehe listquelle) Eine Liste mit den Keys in der gewünschten Reihenfolge
indexOderKey iIndexOrKey Key Was verglichen werden soll. Key oder Index
resetIndex Boolean False Nach dem mischen numerische Keys zurücksetzen
return ListStream Rückgabewert
Set ls = ListStream.init("a","b","c")
 
d ls.sortByList(array(1,0,2)).list
<Dictionary>  (
    [1] => <String> 'b'
    [0] => <String> 'a'
    [2] => <String> 'c'
)
 
Set ls = ListStream("{AA:a,BB:b,CC:c}")
 
d ls.sortByList("[BB,CC,AA]").list
<Dictionary>  (
    [BB] => <String> 'b'
    [CC] => <String> 'c'
    [AA] => <String> 'a'
)
 
'kSortByList
d ListStream("{a:11,b:22,c:33}").ksortByList("[b,a,c]").list
<Dictionary>  (
    [b] => <Long> 22
    [a] => <Long> 11
    [c] => <Long> 33
)
 
'nSortByList
d ListStream("[{id:1,value:'A'},{id:2,value:'B'},{id:3,value:'C'}]").nsortbylist("id", "[2,3,1]", true).list
<Dictionary>  (
    [0] => <Dictionary>  (
        [id] => <Long> 2
        [value] => <String> 'B'
    )
    [1] => <Dictionary>  (
        [id] => <Long> 3
        [value] => <String> 'C'
    )
    [2] => <Dictionary>  (
        [id] => <Long> 1
        [value] => <String> 'A'
    )
)

Listenveräderungsmethoden

flip()

Tauscht Key und Value aus.

ListStream = obj.flip(unique)
Parameter Typ Standard Beschreibung
unique Booelan False Doppelte Keys unterdrücken und nur den ersten Eintrag übernehmen
return ListStream Rückgabewert
'Original ohne Keys
Set ls = ListStream.init("a","b","c")
d ls.flip.list
<Dictionary>  (
    [a] => <Long> 0
    [b] => <Long> 1
    [c] => <Long> 2
)
 
'Original mit Keys
Set ls = ListStream("{AA:a,BB:b,CC:c}")
d ls.flip.list
<Dictionary>  (
    [a] => <String> 'AA'
    [b] => <String> 'BB'
    [c] => <String> 'CC'
)
 
'Original mit doppelten Werten, flip ohne unique
'Die doppelten KEys werde durchnummeriert
Set ls = ListStream("{AA:a,BB:a,CC:c,DD:a,EE:c}")
d ls.flip.list
<Dictionary>  (
    [a] => <String> 'AA'
    [a#{1}] => <String> 'BB'
    [c] => <String> 'CC'
    [a#{2}] => <String> 'DD'
    [c#{1}] => <String> 'EE'
)
 
'Paramter unique unterdrückt achfolgende Einträge mit demselben Wert, später Key
d ls.flip(true).list
<Dictionary>  (
    [a] => <String> 'AA'
    [c] => <String> 'CC'
)

values()

Gibt nur die Values zurück, ohne die Keys

ListStream = obj.values()
Parameter Typ Standard Beschreibung
return ListStream Rückgabewert
Set ls = ListStream("{AA:a,BB:b,CC:c}")
d ls.list
<Dictionary>  (
    [AA] => <String> 'a'
    [BB] => <String> 'b'
    [CC] => <String> 'c'
)
 
d ls.values.list
<Dictionary>  (
    [0] => <String> 'a'
    [1] => <String> 'b'
    [2] => <String> 'c'
)

keys()

Extrahiert alle Keys zu einer Array-Liste

ListStream = obj.keys()
Parameter Typ Standard Beschreibung
return ListStream Rückgabewert
Set ls = ListStream("{AA:a,BB:b,CC:c}")
d ls.keys.list
<Dictionary>  (
    [0] => <String> 'AA'
    [1] => <String> 'BB'
    [2] => <String> 'CC'
)

collect()

Wandelt in einen anderen Typ. Achtung, der Rückgabewert ist nicht mehr ein ListStream. Siehe auch toArray(), toDictionary und toCollection()

'/**
' * Wandelt in eine andere Art von Liste
' * @param  enuListType     Art der Liste
' * @return Variant         Dictionary/Array/Collection
' */
Public Function collect(ByVal iListType As enuListType, Optional ByVal iVarType As VbVarType = vbVariant) As Variant
Set ls = ListStream.combine(array("a","b"), array("AA", "BB"))
print_r ls.collect(ltCollection)
<Collection>  (
    [a] => <String> 'AA'
    [b] => <String> 'BB'
)

toArray()

Wandelt die list in ein Array

Array() = obj.toArray([varType])
Parameter Typ Standard Beschreibung
varType vbVarType Variant Wandelt die Werte in diesen Typ und der Array wird auch von diesem Typ sein
return Array Rückgabewert
Set ls = ListStream("{AA:1,BB:b,CC:null}")
'Normaler toArray
d ls.toArray
<Variant()>  (
    [#0] => <Long> 1
    [#1] => <String> 'b'
    [#2] => <Null> 
)
 
'Mit Cast. Auch der Array ist kein Varant() mehr sondern ein String()
d ls.toArray(vbString)
<String()>  (
    [#0] => <String> '1'
    [#1] => <String> 'b'
    [#2] => <String> ''
)

toCollection()

Wandelt die list in eine Collection

Collection = obj.toCollection([varType])
Parameter Typ Standard Beschreibung
varType vbVarType Variant Wandelt die Werte in diesen Typ
return Collection Rückgabewert
Set ls = ListStream("{AA:1,BB:b,CC:null}")
d ls.toCollection
<Collection>  (
    [AA] => <Long> 1
    [BB] => <String> 'b'
    [CC] => <Null> 
)
 
'Mit Cast.
d ls.toCollection(vbString)
<Collection>  (
    [AA] => <String> '1'
    [BB] => <String> 'b'
    [CC] => <String> ''
)

toDictionary()

Wandelt die list in ein Dictionary

Dictionary = obj.toDictionary([varType])
Parameter Typ Standard Beschreibung
varType vbVarType Variant Wandelt die Werte in diesen Typ
return Dictionary Rückgabewert
Set ls = ListStream("{AA:1,BB:b,CC:null}")
 
d ls.toDictionary
<Dictionary>  (
    [AA] => <Long> 1
    [BB] => <String> 'b'
    [CC] => <Null> 
)
 
'Mit Cast.
d ls.toDictionary(vbString)
<Dictionary>  (
    [AA] => <String> '1'
    [BB] => <String> 'b'
    [CC] => <String> ''
)

toIterator()

Sollte das Setting Iterator gesetzt ist, wird ein Iterator aus der List generiert

Iterator = obj.toIterator([varType][, iteratorParams])
Parameter Typ Standard Beschreibung
varType vbVarType Variant Wandelt die Werte in diesen Typ
iteratorParams itParams itDefault Paramter des Iterators
return [VBA] Iterator Rückgabewert
Set ls = ListStream("{AA:1,BB:b,CC:null}")
Set it = ls.toIterator()
d it.toFirst(key, value)
<Boolean> True
d key
<Long> 0
d Value
<Long> 1
 
 
d ListStream.range(1,6).mapEval("#{item} ^ 2").toIterator(vbString).toPosition1(3).current
<String> '16'

Filter Methoden

Filter die Daten nach gewissen Kriterien aus

unique()

Entfernt doppelte Werte

ListStream = obj.unique([resetIndex], [compareMode])
Parameter Typ Standard Beschreibung
resetIndex Boolean False Nach dem mischen numerische Keys zurücksetzen
compareMode CompareMethod nicht überschreiben Vergleichsmethode
return ListStream Rückgabewert
Set ls = ListStream.init(1,2,1,3,1,4,1)
d ls.unique.list
<Dictionary>  (
    [0] => <Integer> 1
    [1] => <Integer> 2
    [3] => <Integer> 3
    [5] => <Integer> 4
)
d ls.unique(true).list
<Dictionary>  (
    [0] => <Integer> 1
    [1] => <Integer> 2
    [2] => <Integer> 3
    [3] => <Integer> 4
)
 
'Mit Binary Vergleich
Set ls = ListStream("[A,a,b,c,C]")
d ls.unique(,vbBinaryCompare).list
<Dictionary>  (
    [0] => <String> 'A'
    [1] => <String> 'a'
    [2] => <String> 'b'
    [3] => <String> 'c'
    [4] => <String> 'C'
)
'Mit Text Vergleicgt
d ls.unique(,vbTextCompare).list
<Dictionary>  (
    [0] => <String> 'A'
    [2] => <String> 'b'
    [3] => <String> 'c'
)

trim()

Entfernt alle leeren Einträge (Null, Empty, Nothing, leerer Array etc)

ListStream = obj.trim([resetIndex])
Parameter Typ Standard Beschreibung
resetIndex Boolean False Nach dem mischen numerische Keys zurücksetzen
return ListStream Rückgabewert
Set ls = ListStream(array(null, "", 0, 1, "abc", now))
d ls.trim.list
<Dictionary>  (
    [2] => <Integer> 0
    [3] => <Integer> 1
    [4] => <String> 'abc'
    [5] => <Date> 15.10.2019 11:26:45
)
d ls.trim(true).list
<Dictionary>  (
    [0] => <Integer> 0
    [1] => <Integer> 1
    [2] => <String> 'abc'
    [3] => <Date> 15.10.2019 11:26:45
)

filterByValue()

Nach einem Wert filtern (=, =<, <> etc.)

ListStream = obj.filterByValue(wert, [vergleichsoperation], [wert2], [nullVergleichswert])
Parameter Typ Standard Beschreibung
wert Variant Wert mit dem verglichen werden soll
vergleichsoperation acFormatConditionOperator acEqual Vergleichsoperator
wert2 Variant NA Zweiter Wert für einen Betweenvergleich
nullVergleichswert Variant Empty Null Vergleichswert
return ListStream Rückgabewert
Set ls = ListSTream.init(1,2,3,4,5)
d ls.filterByValue(3, acGreaterThanOrEqual).list
<Dictionary>  (
    [2] => <Integer> 3
    [3] => <Integer> 4
    [4] => <Integer> 5
)
d ls.filterByValue(2, acBetween, 4).list
<Dictionary>  (
    [1] => <Integer> 2
    [2] => <Integer> 3
    [3] => <Integer> 4
)

filterByEval()

Führt einen Eval() aus und filtert nach dessem Resultat

ListStream = obj.filterByEval(code)
Parameter Typ Standard Beschreibung
code String Eval-Code mit Ersetzungen / Pattern
return ListStream Rückgabewert
Set ls = ListSTream.init(1,2,3,4)
d ls.filterByEval("(#{value} mod 2) = 0").list
<Dictionary>  (
    [1] => <Integer> 2
    [3] => <Integer> 4
)

filterByObjProp()

Bei einer Objektliste kann nach einem Property oder einer Methode der Objekte gefiltert werden

ListStream = obj.filterByObjProp(wert, methodenName, methodenType, parameter-1 .. parameter-X)
Parameter Typ Standard Beschreibung
methodenName String Name der Methode
methodenType vbCallType Art der Methode. Get/Set/Let/Method
parameter Variant Die Paramter der Methode
return ListStream Rückgabewert

Für diese Beispiel verwende ich die Klasse [VBA] DateTime Für die Resultatausgabe verwende ich auch noch mapObiProp()

Set ls = ListStream.init(DateTime(#2019-10-01#), DateTime(#2019-11-01#))
d ls.filterByObjProp(11, "month", vbGet).mapObiProp("dateValue", VbGet).list
<Dictionary>  (
    [1] => <Date> 01.11.2019
)
Alias zu filterByObjProp()
  • filterByObjPropA(): Anstelle eines Param-Arrays wird ein Array verwendet

filterByRegEx()

Filtern nach einem Regulären Ausdruck.

ListStream = obj.filterByRegEx(pattern, [part], [not])
Parameter Typ Standard Beschreibung
pattern String Pattern (gemäss https://wiki.yaslaw.info/doku.php/vba/cast/cregexp)
part enuWorkWith Index Was verglichen werden soll. Key, Indey oder Wert
not Boolean False Negative Liste. “Not In”
return ListStream Rückgabewert
'Nach Index
Set ls = ListStream.range(0,20)
d ls.filterByRegEx("/^1(?![34567])\d+/", wwIndex).list
<Dictionary>  (
    [10] => <Long> 10
    [11] => <Long> 11
    [12] => <Long> 12
    [18] => <Long> 18
    [19] => <Long> 19
)
 
'Nach Key
Set ls = ListStream("{'Namen':Stefan, 'Übernamen': Yaslaw, Ort:Winterthur, 'Namenstag': #2019-12-26#}")
d ls.filterByRegEx("/namen/i", wwKey).list
<Dictionary>  (
    [Namen] => <String> 'Stefan'
    [Übernamen] => <String> 'Yaslaw'
    [Namenstag] => <Date> 26.12.2019
)
 
'Nach Wert
Set ls = ListStream(array("1.1.2019", "1/1/2019", "01.1/2019"))
d ls.filterByRegEx("^\d+\.\d+[\.\/]\d{4}$").list
<Dictionary>  (
    [0] => <String> '1.1.2019'
    [2] => <String> '1.1/2019'
)

filterInList()

Filter: Filtert anhand der Werte einer Liste. Auch bei einem Dictionary und Key-Vergleich wird der Key vom Original mit dem Wert der Liste verglichen

ListStream = obj.filterInList(list, [part], [not], [compareMode])
Parameter Typ Standard Beschreibung
list Variant (siehe listquelle) zu vergleichende Liste
part enuWorkWith Index Was verglichen werden soll. Key, Indey oder Wert
not Boolean False Negative Liste. “Not In”
compareMode CompareMethod nicht überschreiben Vergleichsmethode
Set dict = new Dictionary
dict.add "a", 1     'Index 0
dict.add "b", 2     'Index 1
dict.add "c", 3     'Index 2
dict.add "d", 4     'Index 3
 
Set ls = ListStream(dict)
 
'Alle mit dem Index aus der Liste
d ls.filterInList(array(1,3), wwIndex).list
<Dictionary>  (
    [b] => <Integer> 2
    [d] => <Integer> 4
)
 
'Alle, deren INdex niocht in der Liste ist
d ls.filterInList(array(1,3), wwIndex, True).list
<Dictionary>  (
    [a] => <Integer> 1
    [c] => <Integer> 3
)
 
'Alle mit dem Key in der Liste
d ls.filterInList(array("a", "d"), wwKey).list
<Dictionary>  (
    [a] => <Integer> 1
    [d] => <Integer> 4
)
 
'Alle mit dem Wert in der Liste
d ls.filterInList(array(1,3), wwValue).list
<Dictionary>  (
    [a] => <Integer> 1
    [c] => <Integer> 3
)
Aliasse zu filterInList()

Es gibt die folgenden Aliasse, die weniger Parameter benutzen

  • inList(): Positiver List-Filter auf den Index
  • notInList(): Negativer List-Filter auf den Index
  • kInList(): Positiver List-Filter auf den Key
  • kNotInList(): Negativer List-Filter auf den Key
  • vInList(): Positiver List-Filter auf den Wert
  • vNotInList(): Negativer List-Filter auf den Wert
  • nFilterInList(): Filter auf eine Unterliste

nFilter()

Die Items sind selber Listen. Die Funktion Filtert nach Werten an der xten (index oder Key) Postion

ListStream = obj.filterListNode(index, wert, [vergleichsoperation], [wert2], [nullVergleichswert])
Parameter Typ Standard Beschreibung
index Variant Index oder Key der Sublist
wert Variant Wert mit dem verglichen werden soll
vergleichsoperation acFormatConditionOperator acEqual Vergleichsoperator
wert2 Variant NA Zweiter Wert für einen Betweenvergleich
nullVergleichswert Variant Empty Null Vergleichswert
return ListStream Rückgabewert
d ListStream("{a:[A1,A2], b:[A1,B2]}").filterListNode("1", "A2").list
<Dictionary>  (
    [a] => <Variant()>  (
        [#0] => <String> 'A1'
        [#1] => <String> 'A2'
    )
)
 
d ListStream("{a:{x:A1,y:A2}, b:{x:A1,y:B2}}").filterListNode("y", "A2").list
<Dictionary>  (
    [a] => <Dictionary>  (
        [x] => <String> 'A1'
        [y] => <String> 'A2'
    )
)
 
d ListStream("[[1,2,3], [2,3,4],[3,4,5],[4,5,6]]").filterListNode(0, 2, coBetween, 3).list
<Dictionary>  (
    [1] => <Variant()>  (
        [#0] => <Long> 2
        [#1] => <Long> 3
        [#2] => <Long> 4
    )
    [2] => <Variant()>  (
        [#0] => <Long> 3
        [#1] => <Long> 4
        [#2] => <Long> 5
    )
)

Reduktionsmethoden

Diese Mathode fassen die Liste in ein Wert zusammen

sum()

Berechnet die Summe von allen numerischen Werten. Nicht numerische Werte werden al 0 gerechnet

Numeric = obj.sum()
Parameter Typ Standard Beschreibung
return Variant Rückgabewert
?ListSTream(array(1,2,3,4,5)).sum
 15

join()

Analog zum vba.join() fügt alle Werte mittels eines Delimiters zusammen

String = obj.join([delimiter])
Parameter Typ Standard Beschreibung
delimiter String Empty Trennzeichen
return String Rückgabewert
?ListSTream(array(1,2,3,4,5)).join("-")
1-2-3-4-5

max()

Variant = obj.max()
Parameter Typ Standard Beschreibung
return Variant Rückgabewert
? ListStream("{a:11,x:99,c:33,m:44]").max
 99 

min()

Variant = obj.min()
Parameter Typ Standard Beschreibung
return Variant Rückgabewert
? ListStream("{a:11,x:99,c:33,m:44]").min
 11 

first()

Variant = obj.first
Parameter Typ Standard Beschreibung
return Variant Rückgabewert
? ListStream("{a:11,x:99,c:33,m:44]").first
 11 

last()

Variant = obj.last
Parameter Typ Standard Beschreibung
return Variant Rückgabewert
? ListStream("{a:11,x:99,c:33,m:44]").last
 44

getKey()

Gibt den Key an einer bestimmten Position zurück

Variant = obj.getItem([index/key][, flag Ob Index oder Key])
Parameter Typ Standard Beschreibung
iIndex Variant Key oder Index
iIndexOrKey enuIndexOrKey ikKey Angabe ob es isch um ein Key oder Index handelt
return Variant Rückgabewert Key
? ListStream("{a:11,x:99,c:33,m:44]").getKey(1)
x

getItem()

Variant = obj.getItem([index/key][, flag Ob Index oder Key][, out key])

Gibt den Wert an einer bestimmten Position zurück

Parameter Typ Standard Beschreibung
iIndex Variant Key oder Index
iIndexOrKey enuIndexOrKey ikKey Angabe ob es isch um ein Key oder Index handelt
oKey Variant Den ermittelten Key als Out-Paramter
return Variant Rückgabewert Item
? ListStream("{a:11,x:99,c:33,m:44]").getItem("c")
 33 
? ListStream("{a:11,x:99,c:33,m:44]").getItem(1, ikIndex, k)
 99 
?k
x

getKeySpecial()

Gibt einen speziellen Key

Variant = obj.getKeySpecial(GetItemSpecialType)
Parameter Typ Standard Beschreibung
iBy enuGetItemSpecialType Art der Spezialität
return Variant Rückgabewert Key
? ListStream("{a:11,x:99,c:33,m:44]").getKeySpecial(byMaxKey)
x
? ListStream("{a:11,x:99,c:33,m:44]").getKeySpecial(byLast)
m

getItemSpecial()

Gibt den Wert einsn speziellen Key

Variant = obj.getItemSpecial(GetItemSpecialType)
Parameter Typ Standard Beschreibung
iBy enuGetItemSpecialType Art der Spezialität
oKey Variant Den ermittelten Key als Out-Paramter
return Variant Rückgabewert Item
? ListStream("{a:11,x:99,c:33,m:44]").getItemSpecial(byMaxKey)
 99 
? ListStream("{a:11,x:99,c:33,m:44]").getItemSpecial(byLast , k)
 44 
?k
m

reduceByUdf()

Reduziert die Liste mit einer Funktion. Die Funktion muss mindestens 2 Paramter haben. Die Ersten 2 Parameter sind die werte, die kombiniert werden müssen. Der Erste Wert muss auf Null geprüft weren, da im ersten Durchgang diese Null ist.

Variant = obj.reduceByUdf(methodenName, parameter-1 .. parameter-X)
Parameter Typ Standard Beschreibung
methodenName String Name der Methode
parameter Variant Die Paramter der Methode
return Variant Rückgabewert
Public Function streamUdfTest_1(a, b) As String
    streamUdfTest_1 = "(" & format(b, "000") & ")"
    If Not IsNull(a) Then streamUdfTest_1 = a & " - " & streamUdfTest_1
End Function
? ListStream(array(1,2,3)).reduceByUdf("streamUdfTest_1")
(001) - (002) - (003)
 
Public Function streamUdfTest_2(a, b, Optional c = 0) As Long
    streamUdfTest_2 = NZ(a) ^ c + b ^ c
End Function
? ListStream(array(1,2,3)).reduceByUdf("streamUdfTest_2", 3)
 756 
Aliasse zu reduceByUdf()
  • reduceByUdfA(): Anstelle eines Param-Arrays wird ein Array verwendet

parseByRegExReplace()

Iterative Reduktion eines Arrays zu einem Wert mittels einer RegReplace. Die Funktion nimmt die Keys der liste als Suchpattern und den Wert als Ersetzungspattern und wendet diese auf den Eingabestring an

String = obj.parseByRegExReplace(String)
Parameter Typ Standard Beschreibung
pattern String Text auf den die Ersetzung angewendet wird
Rx-Params lsRxFlagsEnum Reg-Ex Flags, die für alle Patterns gelten gelten. Überschreibt die Patterns der der Keys. Globals ist immr gesetzt
return ListStream Rückgabewert

Die Keys der Liste sind Patterns gemäss https://wiki.yaslaw.info/doku.php/vba/cast/cregexp.

'RegEx-Replacex für Umlaute
? ListStream.initCombine("/ae/i", "Ä", "[\xD6\xF6]", "Oe").parseByRegExReplace("Aehm - aeh- öhm, das ist zu Öffentlich")
Ähm - Äh- Oehm, das ist zu Oeffentlich
 
'Der Text wird der Reihenfolge nach abgearbeitet. Darum wird hier Hans zu Fritz und dann wieder zu Hans
? ListStream("{Hans:Fritz, Fritz:Hans}").parseByRegExReplace("Hans schlägt Fritz worauf Fritz zu Boden geht")
Hans schlägt Hans worauf Hans zu Boden geht
'Mit einem Zwischenschritt kann man das lösen
? ListStream("{Hans:AAA, Fritz:Hans, AAA:Fritz}").parseByRegExReplace("Hans schlägt Fritz worauf Fritz zu Boden geht")
Fritz schlägt Hans worauf Hans zu Boden geht
 
'Es kann auch mit Ersetzungen von Substrings gearbeitet werden
? ListStream("{'(Hans|Fritz)-?ueli':'$1-Ulrich', '([^-])Ulrich':'$1Sepp'}").parseByRegExReplace("Hansueli und Fritz-Ueli heissen eben nicht Ulrich", lsRxIgnoreCase)
Hans-Ulrich und Fritz-Ulrich heissen eben nicht Sepp

Key Methoden

Methoden, die den Key verändern

mapKeysToStr()

Wandelt alle Keys in SQL-Strings um

ListStream = obj.mapKeysToStr()
Parameter Typ Standard Beschreibung
return ListStream Rückgabewert
Set ls = ListStream.combine(array(now, now+1), array("AA", "BB"))
d ls.keys.list
<Dictionary>  (
    [0] => <Date> 15.10.2019 10:40:07
    [1] => <Date> 16.10.2019 10:40:07
)
d ls.mapKeysToStr.keys.list
<Dictionary>  (
    [0] => <String> '#10/15/2019 10:40:07#'
    [1] => <String> '#10/16/2019 10:40:07#'
)

Mappings

Mappings sind methoden, die den Wert verändern

Für die meisten Mappingmethoden existiert auch eine Version für den Key. Diese hat denselben namen, jedoch mit dem Prefix 'k'. Beim Keymapping wird der Key verändert

mapTrim()

Führt ein Trim auf jedes Element aus. Im gegensatz zum VBA-Trim kann man mit diesem auch Nur Rechts oder Links trimmen. Zudem werden uach \t\n\r getretrimmt

ListStream = obj.mapTrim([trimType])
Parameter Typ Standard Beschreibung
trimType enuTrimType Trim LinksTrim/RechtsTrim/Trim (beide Seiten)
return ListStream Rückgabewert
Set ls = ListStream.init("   a", " b ")
'Beidseitig trimme
d ls.mapTrim.list
<Dictionary>  (
    [0] => <String> 'a'
    [1] => <String> 'b'
)
'Nur rechts trimmen
d ls.mapTrim(ttRTrim).list
<Dictionary>  (
    [0] => <String> '   a'
    [1] => <String> ' b'
)

mapRegExReplace()

Ein RegExp.Replace auf elle Items

ListStream = obj.mapRegExReplace(pattern, ersetzung)
Parameter Typ Standard Beschreibung
pattern String Pattern (gemäss https://wiki.yaslaw.info/doku.php/vba/cast/cregexp)
ersetzung String Erstzungspattern nach RegEx
return ListStream Rückgabewert
Set ls = ListStream.init("Es ist der 11-12-2019", "Und mOrgen 12-12-2019")
d ls.mapRegExReplace(".*?(\d{2})-(\d{2})-(\d{4}).*", "$1.$2.$3").list
<Dictionary>  (
    [0] => <String> '11.12.2019'
    [1] => <String> '12.12.2019'
)
Weitere mapRegExReplace Funktionen
  • kMapRegExReplace(): Dasselbe, jedoch wird der Key ersetzt

—-

mapFormat()

Formatiert jedes Item. Alle Paramters gemäss VBA.fromat()

ListStream = obj.mapFormat(format, [dayOfWeek], [firstWeekOfYear])
Parameter Typ Standard Beschreibung
format String
dayOfWeek VbDayOfWeek vbMonday
firstWeekOfYear VbFirstWeekOfYear vbFirstFourDays
return ListStream Rückgabewert
Set ls = ListStream.init(1,200,3000)
d ls.list
<Dictionary>  (
    [0] => <Integer> 1
    [1] => <Integer> 200
    [2] => <Integer> 3000
)
d ls.mapFormat("#,##0.00").list
<Dictionary>  (
    [0] => <String> '1.00'
    [1] => <String> '200.00'
    [2] => <String> '3'000.00'
)
Weitere mapFormat Funktionen
  • kMapFormat(): Der Format wird auf den Key angewendet

mapCast()

Wandelt den Typ über alle Einträge

ListStream = obj.mapCast(varType)
Parameter Typ Standard Beschreibung
varType vbVarType Variant Wandelt die Werte in diesen Typ
return ListStream Rückgabewert
Set ls = ListStream.init(1,200,3000)
d ls.list
<Dictionary>  (
    [0] => <Integer> 1
    [1] => <Integer> 200
    [2] => <Integer> 3000
)
d ls.mapCast(vbString).list
<Dictionary>  (
    [0] => <String> '1'
    [1] => <String> '200'
    [2] => <String> '3000'
)
d ls.mapCast(vbDouble).list
<Dictionary>  (
    [0] => <Double> 1
    [1] => <Double> 200
    [2] => <Double> 3000
)

mapToBool()

Wandelt den Typ über alle Einträge

ListStream = obj.mapToBool
Parameter Typ Standard Beschreibung
return ListStream Rückgabewert

—-

mapToLng()

Wandelt den Typ über alle Einträge

ListStream = obj.mapToInt
Parameter Typ Standard Beschreibung
return ListStream Rückgabewert

—-

mapToDbl()

Wandelt den Typ über alle Einträge

ListStream = obj.mapToDbl
Parameter Typ Standard Beschreibung
return ListStream Rückgabewert

—-

mapToStr()

Wandelt den Typ über alle Einträge

ListStream = obj.mapToStr
Parameter Typ Standard Beschreibung
return ListStream Rückgabewert

—-

mapToDate()

Wandelt den Typ über alle Einträge. \\Wenn [VBA] strToDate() installiert ist, kann dies auch genutzt werden

ListStream = obj.mapToDate()
ListStream = obj.mapToDate([format], [params], [firstDayOfWeek], [firstWeekOfYear])
Parameter Typ Standard Beschreibung
format String Das Datumsformat
params tdtParams tdtIgnoreCase Weitere Parameter
firstDayOfWeek VbDayOfWeek vbUseSystemDayOfWeek Angabe zum ersten Wochentag. Schweiz → Montag
firstWeekOfYear VbFirstWeekOfYear vbUseSystem Angabe zum ersten Woche im Jahr
return ListStream Rückgabewert
d ListStream("[9.8.2015, 15.5.2023]").mapToDate().list
<Dictionary>  (
    [0] => <Date> 09.08.2015
    [1] => <Date> 15.05.2023
)
 
'ohne strToDate()
d ListStream("[20120101, 20201231]").mapToDate().list
<Dictionary>  (
    [0] => <Date> 00:00:00
    [1] => <Date> 00:00:00
)
 
 
'mit strToDate()
d ListStream("[20120101, 20201231]").mapToDate("YYYYMMDD").list
<Dictionary>  (
    [0] => <Date> 01.01.2012
    [1] => <Date> 31.12.2020
)

mapParse()

Parst die Values, Keys und Indexies in einen String mittels Platzhalter, Wenn [VBA] JSF vorhanden ist, dann kann auch mit Formatierungen gearbeitet werden

ListStream = obj.mapParse([code], [varType], [withJsf])
Parameter Typ Standard Beschreibung
code String Eval-Code mit Ersetzungen / Pattern
varType vbVarType Variant Wandelt die Werte in diesen Typ
withJsf Boolean false Mit [VBA] JSF parsen. Lohnt sich nur, wenn man jsf spezifische Formate anwendet
return ListStream Rückgabewert
Set ls = ListStream.init(1,200,3000)
d ls.mapParse("Index #{index} = #{item}").list
<Dictionary>  (
    [0] => <String> 'Index 0 = 1'
    [1] => <String> 'Index 1 = 200'
    [2] => <String> 'Index 2 = 3000'
)
'Mit JSF
d ls.mapParse("Index #{index $3f} = #{item}", , true).list
<Dictionary>  (
    [0] => <String> 'Index 001 = 1'
    [1] => <String> 'Index 002 = 200'
    [2] => <String> 'Index 003 = 3000'
)
Weitere mapParse Funktionen
  • kMapParse(): Der Key wird ersetzt
  • tMapParse(): Der Key und der Value werden ersetzt
  • mapParseJsf(): Fals JSF aktiviert ist, dann wird der Parse mit JSF ausgeführt
  • kMapParseJsf(): Fals JSF aktiviert ist, dann wird der Key-Parse mit JSF ausgeführt

mapToSqlStr()

Wandelt alles in SQL-Strings. Es sind dieselben Settings wie in [VBA] toSqlStr()

ListStream = obj.mapToSqlStr([varType], [sqlParams], [nullWert])
Parameter Typ Standard Beschreibung
varType vbVarType Variant Wandelt die Werte in diesen Typ
sqlParams enuSqlParams zusätzliche Setting
nullWert Variant Null Mir dem Eert wird Null ersetzt
return ListStream Rückgabewert
'Frei nach dem jeweilgen Typ
Set ls = ListStream.init(3.123, now, "abc", null)
d ls.mapToSqlStr.list
<Dictionary>  (
    [0] => <String> '3.123'
    [1] => <String> '#10/17/2019 10:53:58#'
    [2] => <String> ''abc''
    [3] => <String> 'NULL'
)
 
'Nach einem bestimmten Typ
d ls.mapToSqlStr(vbString).list
<Dictionary>  (
    [0] => <String> ''3.123''
    [1] => <String> ''17.10.2019 10:53:58''
    [2] => <String> ''abc''
    [3] => <String> 'NULL'
)
Weitere mapToSqlStr Funktionen
  • kMapToSqlStr(): Dito auf den Key

mapEval()

Führt einen Access Application.Eval() auf jedes Element aus

ListStream = obj.mapEval(code, [varType])
Parameter Typ Standard Beschreibung
code String Eval-Code mit Ersetzungen / Pattern
varType vbVarType Variant Wandelt die Werte in diesen Typ
return ListStream Rückgabewert
Set ls = ListStream.init(1,2,3)
d ls.mapEval("2 ^#{item}").list
<Dictionary>  (
    [0] => <Double> 2
    [1] => <Double> 4
    [2] => <Double> 8
)
 
d ListStream.init(#10/1/2019#, #11/1/2019#).mapEval("dateAdd('d', 15, #{item})").list
<Dictionary>  (
    [0] => <Date> 16.10.2019
    [1] => <Date> 16.11.2019
)
Weitere mapEval Funktionen
  • kMapEval(): Dito auf den Key
  • tMapEval(): Dito auf Key und Value

mapWalk()

Führt ein User Defined Function (udf) auf jedes Element durch. Geht auch mit einigen VBA-Funktionen
Im ENdeffekt wird ein mapEval ausgeführt. es ist also häifig einfacher, diesen anzuwenden.

ListStream = obj.walk(methodenName, parameter-1 .. parameter-X)
ListStream = obj.kWalk(methodenName, parameter-1 .. parameter-X)
ListStream = obj.walkA(methodenName, array(parameter-1 .. parameter-X))
ListStream = obj.kWalkA(methodenName, array(parameter-1 .. parameter-X))
Parameter Typ Standard Beschreibung
methodenName String Name der Methode
parameter Variant Die Paramter der Methode
return ListStream Rückgabewert
Set ls = ListStream.init(#2019-10-01#, #2019-11-01#)
d ls.list
<Dictionary>  (
    [0] => <Date> 01.10.2019
    [1] => <Date> 01.11.2019
)
d ls.mapWalk("dateAdd", ListStream.var2CodeStr("d"), "15", "#{item}").list
<Dictionary>  (
    [0] => <Date> 16.10.2019
    [1] => <Date> 16.11.2019
)
Aliasse zu mapWalk()
  • mapWalkA(): Anstelle eines Param-Arrays wird ein Array verwendet
  • kMapWalk(): mapWalk auf den Key
  • kMapWalkA():

—-

mapObiProp()

Ersetzt die Items einer Liste durch den Rückgabewert eine itemProperty oder einer itemMethode

ListStream = obj.mapObiProp(methodenName, methodenType, parameter-1 .. parameter-X)
Parameter Typ Standard Beschreibung
methodenName String Name der Methode
methodenType vbCallType Art der Methode. Get/Set/Let/Method
parameter Variant Die Paramter der Methode
return ListStream Rückgabewert

Für diese Beispiel verwende ich die Klasse [VBA] DateTime

Set ls = ListStream.init(DateTime(#2019-10-01#), DateTime(#2019-11-01#))
d ls.mapObiProp("dateValue", VbGet).list
<Dictionary>  (
    [0] => <Date> 01.10.2019
    [1] => <Date> 01.11.2019
)

Aliasse zu mapObjProp()
  • mapObiPropA Anstelle eines Param-Arrays wird ein Array verwendet

—-

mapCallObjMethode()

Führt eine Methode auf allen Objekten einer Liste durch

ListStream = obj.mapObiProp(methodenName, methodenType, parameter-1 .. parameter-X)
Parameter Typ Standard Beschreibung
methodenName String Name der Methode
methodenType vbCallType Art der Methode. Get/Set/Let/Method
parameter Variant Die Paramter der Methode
return ListStream Rückgabewert

Für diese Beispiel verwende ich die Klasse [VBA] DateTime und für die einfachere Darstellung des Resultates die Methode mapObiProp()

Set ls = ListStream(array(DateTime(#2019-10-01#), DateTime(#2019-11-01#)))
d ls.mapObiProp("dateValue", VbGet).list
<Dictionary>  (
    [0] => <Date> 01.10.2019
    [1] => <Date> 01.11.2019
)
d ls.mapCallObjMethode("add", VbMethod, "P5D").mapObiProp("dateValue", VbGet).list
<Dictionary>  (
    [0] => <Date> 06.10.2019
    [1] => <Date> 06.11.2019
)

Aliasse zu mapCallObjMethode()
  • mapCallObjMethodeA(): Anstelle eines Param-Arrays wird ein Array verwendet

mapListNode()

Die Items sind selber Listen. Dann nimmt die Funktion die Werte an der xten (index oder Key) Postion

ListStream = obj.mapListNode(key)
ListStream = obj.mapListNode(index)
Parameter Typ Standard Beschreibung
index String oder Long Index oder Key
return ListStream Rückgabewert
'Liste ohne Mapping
d ListStream(currentdb.OpenRecordset("T_JSF_EXAMPLE")).list
<Dictionary>  (
    [1] => <Dictionary>  (
        [ID] => <Byte> 1
        [USER] => <String> 'Stefan'
        [VULGO] => <String> 'Yaslaw'
        [LOCATION] => <String> 'Büro 1A'
        [START_DATE] => <Date> 01.10.2018
        [IS_IMPORTANT] => <Boolean> True
    )
    ....
 
'Mit mapping
d ListStream(currentdb.OpenRecordset("T_JSF_EXAMPLE")).mapListNode("user").list
<Dictionary>  (
    [1] => <String> 'Stefan'
    [2] => <String> 'Sandra'
    [3] => <String> 'Manuela'
    [4] => <String> 'Thomas'
)
weitere mapListNode Funktionen
  • kMapListNode() Das Mapping wird auf den Key angewendet
  • tMapListNode() Das Mapping wird auf Key und Item angewendet
d ListStream(currentdb.OpenRecordset("T_JSF_EXAMPLE")).tMapListNode("user", "start_date").list
<Dictionary>  (
    [Stefan] => <Date> 01.10.2018
    [Sandra] => <Date> 01.11.2018
    [Manuela] => <Date> 29.10.2018
    [Thomas] => <Date> 31.10.2018
)

Iterator Methoden

Methoden die man zum Iterieren über die liste verwenden kann

For Each

Grundsätzliches Kann man mit einem For Each duchiterieren, wie man das von Array, Collection etc. kennt

Dim ls As ListStream: Set ls = ListStream("{AA:a,BB:b,CC:c}")
For Each var In ls.kInList(Array("AA", "CC"))
    Debug.Print var
Next
'Gibt a und b zurück

toFirst(), toNext(), toPrev(), toLast(), toPos(), toOffset()

Alle vier Funktionen toFirst(), toNext(), toPrev(), toLast() sind gleich aufgebaut. Ich nehme als Beispiel toNext(). Von all diesen Methoden gibt es auch die LS-Version. zB. ToNextLS()

ret = ls.toFirst([oKey, oValue]])
ret = ls.toNext([oKey[, oValue]])
ret = ls.toPrev([oKey[, oValue]])
ret = ls.toLast([oKey[, oValue]])
ret = ls.toPos(iPos, [oKey[, oValue]])
ret = ls.toOffset(iOffset, [oKey[, oValue]])
Parameter Typ Standard Beschreibung
iPos (in) Long Die Position, auf die gesprungen werden soll
iOffset (in) Long Versatz zur aktuellen Position
oValue (out) Variant Gibt den enstprchenden Key/Index zurück
oValue (out) Variant Ist eine Referenz und gibt den nächsten Wert zurück
return Boolean Information, ob ein passender Wert gefunden wurde. ALso der neue Index innerhalb des Liste ist
Dim ls As ListStream: Set ls = ListStream("{AA:a,BB:b,CC:c}")
Set ls = ls.kInList(Array("AA", "CC"))
Dim var: Do While ls.toNext(var)
    Debug.Print var
Loop

Eine Schleife über toNext() kann nicht direkt im Stream angewednet werden

'Führt zu einer Endlosschleife, da bei jedem Durchgang mit kInList() eine Kopie der Daten aus ls gezogen wird
Dim var: Do While ls.kInList(Array("AA", "CC")).toNext(var)
 
'Entweder den ListStream auf Referenz umschalten oder vorher die endgültige Liste auslesen
Set ls = ls.kInList(Array("AA", "CC"))
Do While ls.toNext(var)
'oder
Do While ls.setByReference(True).kInList(Array("AA", "CC")).toNext(var)

BOF, EOF

Die Properties BOF und EOF, wie man sie vom Recordset kennt. Sie gebe an, ob der Zeiger pos ausserhalb der Daten ist.

ret = ls.BOF
ret = ls.BOF
Parameter Typ Standard Beschreibung
return Boolean
Dim ls As ListStream:   Set ls = ListStream("{AA:a,BB:b,CC:c}")
ls.pos = -1
Debug.Print ls.BOF 'True

pos

Ein Property, das auch gesetzt werden kann. Es ist die Zeigerposition für toNext() etc.

actPosition = ls.pos
ls.pos = newPosition

value

Eintrag an der Position pos

value = ls.value([pos])
Set value = ls.value([pos])
Parameter Typ Standard Beschreibung
pos Long Aktuelle Position
return Variant
    Dim ls As ListStream:  Set ls = ListStream("{AA:a,BB:b,CC:c}")
    ls.toFirst
    Debug.Print ls.value        'a
    Debug.Print ls.value(1)     'b

node

node an der Position pos

node = ls.node([pos])
Parameter Typ Standard Beschreibung
pos Long Aktuelle Position
return Node
Set ls = ListStream("{AA:a,BB:b,CC:c}")
ls.toFirst
d ls.node()
<Variant()>  (
    [#1] => <String> 'AA'
    [#2] => <String> 'a'
    [#3] => <Long> 0
)

setPos()

setPos() ist im Gegensatz zu pos kein Property sondern eine Funktion. Diese führt set pos aus und gibt den neuen ListSTream zurück

Set ListStream = ls.setPos(Position)
Parameter Typ Standard Beschreibung
pos Long Aktuelle Position
return ListStream
    Dim ls1 As ListStream:  Set ls1 = ListStream("{AA:a,BB:b,CC:c}")
    Dim ls2 As ListStream:  Set ls2 = ls1.setPos(1)
 
    Debug.Print "origLs", ls1.pos   '-1  Ist noch am Start
    Debug.Print "newLs", ls2.pos    ' 1

Statische Hilfsmethoden

Das sind zusätzliche Funktionen, die nicht direkt auf die Liste bezogen sind. Sie werden intern genutzt, können aber auch anderwertig praktisch sein

isList()

Eine Prüfung ob ListStream die Variable als Liste und somit als Quelle akzeptiert.

Parameter Typ Standard Beschreibung
list Variant Variable die geprüft werden soll
return Boolean Formatierter Wert oder eine Liste mit den Formatierten Werten
?ListStream.isList(array(1,2,3))
True
 
'Json wird als Liste erkannt
?ListStream.isList("[1,2,3]")
True
 
?ListStream.isList(null)
False
 
?ListStream.isList("123")
False

var2CodeStr()

Gibt den Value in VBA-Code Form zurück. Kann für Evals etc. benutzt werden. Akzeptiert auch alle Listen wie sie mit der Methode isList() als True zurückgegeben wird

Parameter Typ Standard Beschreibung
item Variant Wert oder Array von Werten der zu Code-String umgewandelt werden soll
varType vbVarType
codeParams enuSqlParams sqlOnErrorReturnError + sqlIsNullable + sqlStringNoMaskQuotes Steuerparameters
nullDefault Variant Null Wert, falls iItem Null ist und sqlNullToEmpty nicht gesetzt ist
return String Formatierter Wert oder eine Liste mit den Formatierten Werten
? ListSTream.var2CodeStr(now,vbDate)
#02/13/2020 09:17:23#
 
? ListSTream.var2CodeStr("abc", vbString)
'abc'
 
? ListSTream.var2CodeStr(null,vbDate)
NULL
 
? ListSTream.var2CodeStr(null,vbString,sqlNullToEmpty)
''
 
? ListSTream.var2CodeStr(null,vbString,sqlNullToEmpty, "N/A")
'N/A'
 
Set dict = ListStream("[1,b]").add(DateTime.timeDT).add(null).list
? ListStream.var2CodeStr(dict, vbString)
'1', 'b', '01.02.2023 11:54:55', NULL

castValue()

d ListStream.castValue(date, vbString)
<String> '01.02.2023'

emptyArray()

d ListStream.createEmptyArray(vbDate)
<Date()>  ()
 
d ListStream.createEmptyArray(vbString, 2, 5)
<String()>  (
    [#5] => <String> ''
    [#6] => <String> ''
)

vba/classes/liststream.txt · Last modified: 02.08.2023 11:40:26 by yaslaw