version=1.9.0 vdate=02.11.2022 fname=liststream.cls fname= ns=%NAMESPACE% fpath=/vba/classes ======= [VBA] ListStream ======= //Simuliert einen Stream über eine Liste (Array, Dict etc)// ===Version %%version%% %%vdate%%=== >//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.// >{{popup>:vba:vba_importfile.png|Bild zum Import}} {{%%fname%%|Download %%fname%% (V-%%version%%)}} 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 [[vba:functions:print_r:index#aliase|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 ( [0] => 2 [1] => 3 [2] => 1 [3] => 4 ) 'und wieder als Array arr = array(1,2,1,3,1,4) d ListStream(arr).unique.shuffle(true).toArray ( [#0] => 2 [#1] => 3 [#2] => 1 [#3] => 4 ) 'und fals man kein Variant-Array sondern ein String-Array braucht: d ListStream(arr).unique.shuffle(true).toArray(vbString).list ( [#0] => '4' [#1] => '3' [#2] => '1' [#3] => '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:classes:date:index|]] arr = array(DateTime(Now), DateTime(Now+1), DateTime(Now+2)) d ListStream(arr).mapObiProp("dateValue",VbGet).list ( [0] => 21.01.2020 [1] => 22.01.2020 [2] => 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 ( [0] => 21.03.2020 [1] => 22.03.2020 [2] => 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 ( [0] => 'a' [1] => 'b' [2] => 'c' )Public Sub test1() ListStream.initialize ("[a,b,c]") End Sub Public Sub test2() d ListStream.list End Sub 'Direktfenster: test1 test2 ( [0] => 'a' [1] => 'b' [2] => '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:classes:jsf|]] | Wenn meine Klasse [[vba:classes:jsf|]] vorhanden ist, dann kann dieses Flag aktiviert werden. Es gibt bei einigen Methoden erweiterte Möglichkeiten | | Iterator | //True// / **False** | [[vba:classes:iterator:index|]] | Falls meine Klasse [[vba:classes:iterator:index|]] vorhanden ist, dann kann aus dem Stream direkt in eine Iterator geparst werden | | Log4vba | //True// / **False** | [[vba:classes:log4vba|]] | Mit [[vba:classes: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:cast: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:cast:json|]] | json(), toJSON() | Wandelt JSON-Strings in Arrays und Dictionaries und wendelt dieselben wieder zurück | | [[vba:cast: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. **k**Remove**V**() ==== 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) ( [#1] => 'b' [#2] => 2 [#3] => 1 ) d listStream("{a:1,b:2,c:3}").getNode(1)(wwKey) 'b' set ls = listStream("{a:1,b:2,c:3}") ls.toNext d ls.getNode ( [#1] => 'b' [#2] => 2 [#3] => 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 ( [0] => 1 [1] => 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:classes:iterator:index|]] installiert ist, geht auch der | | ListStream | Ein anderer ListStream | | DAO.Recordset | Falls es ein Access-Projekt ist | | ADODB.Recordset | | | Excel.Range | | | json | Falls [[vba:cast:json|]] installiert ist, können auch JSON-Strings verwendet werden | | JSF | Falls [[vba:classes: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:classes: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 ( [0] => 'Hallo Mari, du hast die id 0' [1] => 'Hallo Hans, du hast die id 1' [2] => 'Hallo Bert, du hast die id 2' [3] => 'Hallo Vreni, du hast die id 3' ) Falls mit JSF gearbeitet wird, dann können auch die [[vba:classes:jsf#modifiers|Modifiers]] genutzt werden d ListStream(array("Mari", "Hans", "Bert", "Vreni")).mapParseJsf("He #{item|upper}!").list ( [0] => 'He MARI!' [1] => 'He HANS!' [2] => 'He BERT!' [3] => 'He VRENI!' ) ==== ByReference ==== Normalerweise ist ListStream byReference. Das heisst, das jeder weitere Schritt das Original mitverändert. \\ Man kann es auf 2 Arten überschreiben. - Beim Erstellen den Paramteter auf True setzen: ''Set ls_1 = ListStream(Array(1, 2, 3, 4), , True)'' - 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 [[vba:classes:iterator:index|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 [[vba:classes:jsf|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 [[vba:functions:print_r:index#aliase|d()]] \\ In meinen Beispielen ist das [[vba:cast: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 ( [withKeys] => False [byReference] => False [compareMode] => 1 [list] => ( [0] => 11 [1] => 22 [2] => 33 ) [json] => '{0:11,1:22,2:33}' [count] => 3 ) 'Wirklich interessant ist nur die list d ls.list ( [0] => 11 [1] => 22 [2] => 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 ( [0] => 'a' [1] => 'b' ) 'Dictionary Set dict = CreateObject("scripting.Dictionary") dict.add "AA", "a" dict.add "BB", "b" d ListStream(dict).list ( [AA] => 'a' [BB] => 'b' ) 'JSON Array d ListStream("[a,b,c]").list ( [0] => 'a' [1] => 'b' [2] => 'c' ) 'JSON Dictionary d ListStream("[{AA:a,BB:b,CC:c}").list ( [AA] => 'a' [BB] => 'b' [CC] => '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 ( [0] => 'a' [1] => 'b' [2] => '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 ( [a] => 'A' [b] => 'B' [c] => ) === 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 ( [1] => ( [ID] => 1 [USER] => 'Stefan' [VULGO] => 'Yaslaw' [LOCATION] => 'Büro 1A' [START_DATE] => 01.10.2018 [IS_IMPORTANT] => True ) [2] => ( [ID] => 2 [USER] => 'Sandra' [VULGO] => [LOCATION] => 'Büro 3' [START_DATE] => 01.11.2018 [IS_IMPORTANT] => 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 | 1|Hans | ^ 3 | 2|Sonja | d ListStream.initRange(Sheets("Sheet1")).list ( [1] => ( [ID] => 1 [NAME] => 'Hans' ) [2] => ( [ID] => 2 [NAME] => 'Sonja' ) ) 'Ein Range, der keinen Header beinhaltet d ListStream.initRange(Sheets("Sheet1").Range("A2:B3"), False).list ( [0] => ( [F1] => 1 [F2] => 'Hans' ) [1] => ( [F1] => 2 [F2] => 'Sonja' ) ) 'Mit dem Feld [name] als Schlüssel d ListStream.initRange(Sheets("Sheet1"), ,"name").list ( [Hans] => ( [ID] => 1 [NAME] => 'Hans' ) [Sonja] => ( [ID] => 2 [NAME] => 'Sonja' ) ) 'Dito wenn kein Header vorhanden ist. Die Spalten sind dann F & Spaltennummer d ListStream.initRange(Sheets("Sheet1").Range("A2:B3"), False, "F2").list ( [Hans] => ( [F1] => 1 [F2] => 'Hans' ) [Sonja] => ( [F1] => 2 [F2] => '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 ( [0] => 2 [1] => 3 [2] => 4 [3] => 5 ) 'Und mit Buchstaben d ListStream.range("a", "d").list ( [0] => 'a' [1] => 'b' [2] => 'c' [3] => '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 ( [0] => 'a' [1] => 'a' [2] => 'a' ) ---- === fillKey() === Erstellt eine Liste aus einer AUflistung von Keys und einem Standardwert ListStream = ListStream.fillKey(list, 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 ( [a] => 'NA' [b] => 'NA' [c] => 'NA' ) d ListStream.fillKey(Array(11,22,23)).list ( [11] => [22] => [23] => ) ---- === 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 ( [a] => 'AA' [b] => 'BB' ) 'Mehr Keys als Werte d ListStream.combine(array("a", "b", "c"), array("AA", "BB")).list ( [a] => 'AA' [b] => 'BB' [c] => ) 'Mehr Werte als Keys 'Gleich viele Keys wie Werte d ListStream.combine(array("a", "b"), array("AA", "BB", "CC")).list ( [a] => 'AA' [b] => 'BB' [2] => '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(), 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 ( [a] => 1 [b] => 2 [x] => 11 [y] => 22 ) 'Mit identischen keys d ListStream.mergeLists("{a:1,b:2}", "{a:11, c:33}").list ( [a] => 1 [b] => 2 [c] => 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 ( [a] => 11 [b] => 2 [c] => 33 ) 'Mit Array wird immer angehängt, da kein Key existiert d ListStream.mergeLists(array(1,2), "[3,4]").list ( [0] => 1 [1] => 2 [2] => 3 [3] => 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 ( [a] => 1 [c] => 3 ) d v 2 'iRemoveK Set ls = ListStream("{a:1,b:2,c:3}") d ls.iRemoveV(1, k) 2 d k 'b' d ls.list ( [a] => 1 [c] => 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 ( [b] => 2 [c] => 3 ) d ListStream("{a:1,b:2,c:3}").shiftV() 1 d ListStream("{a:1,b:2,c:3}").shiftK() 'a' 'Den Wert und Key auslesen d ListStream("{a:1,b:2,c:3}").shift(v, k).list ( [b] => 2 [c] => 3 ) d v 1 d k '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 ( [0] => 'a' [1] => 'b' ) d myVar.list 'c' 'Hat die Liste einen key, dann wird er beibehalten d ListStream("{A:a,B:b,C:c}").pop(myVar).list ( [A] => 'a' [B] => 'b' ) d myVar.list '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 ( [0] => 'a' [1] => 'b' [2] => 'c' ) d ListStream("{A:a,B:b}").add("C", "c").list ( [A] => 'a' [B] => 'b' [C] => '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 ( [0] => 'a' [1] => 'b' [2] => 'b' [3] => 'c' ) 'Liste mit Keys. Bereits vergebene Keys werden ignoriert d ListStream("{AA:a,BB:b}").merge("{BB:b1,CC:c}").list ( [AA] => 'a' [BB] => 'b' [CC] => 'c' ) 'dito, aber mit overwrite d ListStream("{AA:a,BB:b}").merge("{BB:b1,CC:c}",,True).list ( [AA] => 'a' [BB] => 'b1' [CC] => '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 ( [a] => 1 [b] => 2 [0] => 'x' [1] => 'x' ) 'Size ist kleiner als die Liste d listStream("[1,2,3]").pad(2,"x").list ( [0] => 1 [1] => 2 [2] => 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 ( [1] => 'b' [2] => '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 ( [BB] => 'b' [CC] => '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 ( [0] => '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 ( [AA] => '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 ( [1] => 'b' [2] => 'c' [0] => 'a' ) 'Den Index zurückzusetzen d ListStream.init("a","b","c").shuffle(True).list ( [0] => 'c' [1] => 'b' [2] => '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 ( [1] => 'a' [2] => 'w' [0] => 'X' ) 'Absteigend nach Key d ListStream("{BB:0,AA:1,CC:2}").sort(soDescending,ctKey).list ( [CC] => 2 [BB] => 0 [AA] => 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 ( [1] => ( [sort] => 0 [val] => 'B' ) [2] => ( [sort] => 1 [val] => 'C' ) [0] => ( [sort] => 5 [val] => '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:classes:date:datetime:index|]] Für die Resultatausgabe verwende ich auch noch [[#mapobiprop|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 ( [0] => 01.01.2015 [1] => 01.12.2019 [2] => 01.06.2018 ) 'Nach Monat sortiert d ls.sortByObjProp("format", VbMethod, soAscending, "MM").mapObiProp("dateValue", VbGet).list ( [0] => 01.01.2015 [2] => 01.06.2018 [1] => 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 [[#ersetzungenpattern|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 ( [0] => '11' [2] => '303' [1] => '4' ) 'Sortierung mit einem Eval d ls.sortByEval("cLng(#{item})").list ( [1] => '4' [0] => '11' [2] => '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 ( [0] => ( [id] => '1' [value] => '1+2' ) [2] => ( [id] => '3' [value] => '2^4' ) [1] => ( [id] => '2' [value] => '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 ( [2] => ( [id] => '3' [value] => '4' ) [1] => ( [id] => '2' [value] => '1' ) [0] => ( [id] => '1' [value] => '3' ) ) ---- === sortByList(), kSortByList(), nSortByList() === Sortiert nach einer andere Liste, die die Index oder Keys in der gewünschten Reihenfolge hat. \\ Siehe auch [[vba:functions: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 ( [1] => 'b' [0] => 'a' [2] => 'c' ) Set ls = ListStream("{AA:a,BB:b,CC:c}") d ls.sortByList("[BB,CC,AA]").list ( [BB] => 'b' [CC] => 'c' [AA] => 'a' ) 'kSortByList d ListStream("{a:11,b:22,c:33}").ksortByList("[b,a,c]").list ( [b] => 22 [a] => 11 [c] => 33 ) 'nSortByList d ListStream("[{id:1,value:'A'},{id:2,value:'B'},{id:3,value:'C'}]").nsortbylist("id", "[2,3,1]", true).list ( [0] => ( [id] => 2 [value] => 'B' ) [1] => ( [id] => 3 [value] => 'C' ) [2] => ( [id] => 1 [value] => '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 ( [a] => 0 [b] => 1 [c] => 2 ) 'Original mit Keys Set ls = ListStream("{AA:a,BB:b,CC:c}") d ls.flip.list ( [a] => 'AA' [b] => 'BB' [c] => '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 ( [a] => 'AA' [a#{1}] => 'BB' [c] => 'CC' [a#{2}] => 'DD' [c#{1}] => 'EE' ) 'Paramter unique unterdrückt achfolgende Einträge mit demselben Wert, später Key d ls.flip(true).list ( [a] => 'AA' [c] => '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 ( [AA] => 'a' [BB] => 'b' [CC] => 'c' ) d ls.values.list ( [0] => 'a' [1] => 'b' [2] => '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 ( [0] => 'AA' [1] => 'BB' [2] => 'CC' ) ---- === collect() === Wandelt in einen anderen Typ. Achtung, der Rückgabewert ist nicht mehr ein ListStream. Siehe auch [[#toArray|toArray()]], [[#toDictionary|toDictionary]] und [[#toCollection|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) ( [a] => 'AA' [b] => '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 ( [#0] => 1 [#1] => 'b' [#2] => ) 'Mit Cast. Auch der Array ist kein Varant() mehr sondern ein String() d ls.toArray(vbString) ( [#0] => '1' [#1] => 'b' [#2] => '' ) ---- === 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 ( [AA] => 1 [BB] => 'b' [CC] => ) 'Mit Cast. d ls.toCollection(vbString) ( [AA] => '1' [BB] => 'b' [CC] => '' ) ---- === 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 ( [AA] => 1 [BB] => 'b' [CC] => ) 'Mit Cast. d ls.toDictionary(vbString) ( [AA] => '1' [BB] => 'b' [CC] => '' ) === 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 | [[vba:classes:iterator:index#itparams|Paramter des Iterators]] | | return | [[vba:classes:iterator:index|]] | | Rückgabewert | Set ls = ListStream("{AA:1,BB:b,CC:null}") Set it = ls.toIterator() d it.toFirst(key, value) True d key 0 d Value 1 d ListStream.range(1,6).mapEval("#{item} ^ 2").toIterator(vbString).toPosition1(3).current '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 ( [0] => 1 [1] => 2 [3] => 3 [5] => 4 ) d ls.unique(true).list ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) 'Mit Binary Vergleich Set ls = ListStream("[A,a,b,c,C]") d ls.unique(,vbBinaryCompare).list ( [0] => 'A' [1] => 'a' [2] => 'b' [3] => 'c' [4] => 'C' ) 'Mit Text Vergleicgt d ls.unique(,vbTextCompare).list ( [0] => 'A' [2] => 'b' [3] => '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 ( [2] => 0 [3] => 1 [4] => 'abc' [5] => 15.10.2019 11:26:45 ) d ls.trim(true).list ( [0] => 0 [1] => 1 [2] => 'abc' [3] => 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 ( [2] => 3 [3] => 4 [4] => 5 ) d ls.filterByValue(2, acBetween, 4).list ( [1] => 2 [2] => 3 [3] => 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 [[#ersetzungenpattern|Ersetzungen / Pattern]] | | return | ListStream | | Rückgabewert | Set ls = ListSTream.init(1,2,3,4) d ls.filterByEval("(#{value} mod 2) = 0").list ( [1] => 2 [3] => 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:classes:date:datetime:index|]] Für die Resultatausgabe verwende ich auch noch [[#mapobiprop|mapObiProp()]] Set ls = ListStream.init(DateTime(#2019-10-01#), DateTime(#2019-11-01#)) d ls.filterByObjProp(11, "month", vbGet).mapObiProp("dateValue", VbGet).list ( [1] => 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 ( [10] => 10 [11] => 11 [12] => 12 [18] => 18 [19] => 19 ) 'Nach Key Set ls = ListStream("{'Namen':Stefan, 'Übernamen': Yaslaw, Ort:Winterthur, 'Namenstag': #2019-12-26#}") d ls.filterByRegEx("/namen/i", wwKey).list ( [Namen] => 'Stefan' [Übernamen] => 'Yaslaw' [Namenstag] => 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 ( [0] => '1.1.2019' [2] => '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 ( [b] => 2 [d] => 4 ) 'Alle, deren INdex niocht in der Liste ist d ls.filterInList(array(1,3), wwIndex, True).list ( [a] => 1 [c] => 3 ) 'Alle mit dem Key in der Liste d ls.filterInList(array("a", "d"), wwKey).list ( [a] => 1 [d] => 4 ) 'Alle mit dem Wert in der Liste d ls.filterInList(array(1,3), wwValue).list ( [a] => 1 [c] => 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 ( [a] => ( [#0] => 'A1' [#1] => 'A2' ) ) d ListStream("{a:{x:A1,y:A2}, b:{x:A1,y:B2}}").filterListNode("y", "A2").list ( [a] => ( [x] => 'A1' [y] => 'A2' ) ) d ListStream("[[1,2,3], [2,3,4],[3,4,5],[4,5,6]]").filterListNode(0, 2, coBetween, 3).list ( [1] => ( [#0] => 2 [#1] => 3 [#2] => 4 ) [2] => ( [#0] => 3 [#1] => 4 [#2] => 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 ( [0] => 15.10.2019 10:40:07 [1] => 16.10.2019 10:40:07 ) d ls.mapKeysToStr.keys.list ( [0] => '#10/15/2019 10:40:07#' [1] => '#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 ( [0] => 'a' [1] => 'b' ) 'Nur rechts trimmen d ls.mapTrim(ttRTrim).list ( [0] => ' a' [1] => ' 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 ( [0] => '11.12.2019' [1] => '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 ( [0] => 1 [1] => 200 [2] => 3000 ) d ls.mapFormat("#,##0.00").list ( [0] => '1.00' [1] => '200.00' [2] => '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 ( [0] => 1 [1] => 200 [2] => 3000 ) d ls.mapCast(vbString).list ( [0] => '1' [1] => '200' [2] => '3000' ) d ls.mapCast(vbDouble).list ( [0] => 1 [1] => 200 [2] => 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:cast: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 ( [0] => 09.08.2015 [1] => 15.05.2023 ) 'ohne strToDate() d ListStream("[20120101, 20201231]").mapToDate().list ( [0] => 00:00:00 [1] => 00:00:00 ) 'mit strToDate() d ListStream("[20120101, 20201231]").mapToDate("YYYYMMDD").list ( [0] => 01.01.2012 [1] => 31.12.2020 ) ---- === mapParse() === Parst die Values, Keys und Indexies in einen String mittels Platzhalter, Wenn [[vba:classes: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 [[#ersetzungenpattern|Ersetzungen / Pattern]] | | varType | vbVarType | Variant | Wandelt die Werte in diesen Typ | | withJsf | Boolean | false | Mit [[vba:classes: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 ( [0] => 'Index 0 = 1' [1] => 'Index 1 = 200' [2] => 'Index 2 = 3000' ) 'Mit JSF d ls.mapParse("Index #{index $3f} = #{item}", , true).list ( [0] => 'Index 001 = 1' [1] => 'Index 002 = 200' [2] => '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:cast:ctosqlstr|]] 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 ( [0] => '3.123' [1] => '#10/17/2019 10:53:58#' [2] => ''abc'' [3] => 'NULL' ) 'Nach einem bestimmten Typ d ls.mapToSqlStr(vbString).list ( [0] => ''3.123'' [1] => ''17.10.2019 10:53:58'' [2] => ''abc'' [3] => '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 [[#ersetzungenpattern|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 ( [0] => 2 [1] => 4 [2] => 8 ) d ListStream.init(#10/1/2019#, #11/1/2019#).mapEval("dateAdd('d', 15, #{item})").list ( [0] => 16.10.2019 [1] => 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 ( [0] => 01.10.2019 [1] => 01.11.2019 ) d ls.mapWalk("dateAdd", ListStream.var2CodeStr("d"), "15", "#{item}").list ( [0] => 16.10.2019 [1] => 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:classes:date:datetime:index|]] Set ls = ListStream.init(DateTime(#2019-10-01#), DateTime(#2019-11-01#)) d ls.mapObiProp("dateValue", VbGet).list ( [0] => 01.10.2019 [1] => 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:classes:date:datetime:index|]] und für die einfachere Darstellung des Resultates die Methode [[#mapObiProp|mapObiProp()]] Set ls = ListStream(array(DateTime(#2019-10-01#), DateTime(#2019-11-01#))) d ls.mapObiProp("dateValue", VbGet).list ( [0] => 01.10.2019 [1] => 01.11.2019 ) d ls.mapCallObjMethode("add", VbMethod, "P5D").mapObiProp("dateValue", VbGet).list ( [0] => 06.10.2019 [1] => 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 ( [1] => ( [ID] => 1 [USER] => 'Stefan' [VULGO] => 'Yaslaw' [LOCATION] => 'Büro 1A' [START_DATE] => 01.10.2018 [IS_IMPORTANT] => True ) .... 'Mit mapping d ListStream(currentdb.OpenRecordset("T_JSF_EXAMPLE")).mapListNode("user").list ( [1] => 'Stefan' [2] => 'Sandra' [3] => 'Manuela' [4] => '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 ( [Stefan] => 01.10.2018 [Sandra] => 01.11.2018 [Manuela] => 29.10.2018 [Thomas] => 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() ( [#1] => 'AA' [#2] => 'a' [#3] => 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) '01.02.2023' === emptyArray() === d ListStream.createEmptyArray(vbDate) () d ListStream.createEmptyArray(vbString, 2, 5) ( [#5] => '' [#6] => '' ) ----