version=2.1.0 vdate=03.07.2017 fname=udf_dconcat.bas ns=%NAMESPACE% fpath=/vba/access/functions ====== [VBA][Access] DConcat() / groupConcat() ====== //Eine Aggregationsfumktion um Feldinhalte auf einer Spalte zu gruppieren. Entspricht etwa dem LISTAGG() aus Oracle oder GROUP_CONCAT() as %%MySQL%%.// ==Version %%version%% - %%vdate%%== {{%%fname%%|Download %%fname%% (V-%%version%%)}} Ich brauchte die Funktion GROUP_CONCAT(), wie man sie in MySQL kennt. Kurze Suche im Web hat mir gezeigt, dass man so was am besten über DAO macht. Unter [[http://blogannath.blogspot.ch/2011/01/microsoft-access-tips-tricks-flattening_28.html|Flatting a Table (Using VBA)]] wurde ich fündig. Doch irgendwie war die Funktion nicht nach meinem Geschmack. Darum habe ich kurzerhand selber eine Funktion geschrieben. >Die Funktion sollte nicht innerhalb eines SQL auf grössere Datenmengen angewendet werden. >Die Performance wird stark darunter leiden ===== Definition ===== Hier werden nur die Funktionsheader gezeigt. Den vollständigen [[#code|Code]] ist am Schluss der Seite. ==== DConcat() ==== Text = DConcat(Feld, Quelle [,Kriterium [,Delimiter [,Sortierung [,Eindeutigkeit]]]]) Public Function DConcat( _ ByVal iExpr As String, _ ByVal iDomain As String, _ Optional ByVal iCriteria As Variant = Null, _ Optional ByVal iDelimiter As String = ", ", _ Optional ByVal iOrderBy As Variant = Null, _ Optional ByVal iDistinct As Boolean = True _ ) As String ***iExpr** Feld das zusammnegeführt werden soll ***iDomain** Quelle (Tabelle, View) ***//iCriteria//** Where-Bedinung ohne WHERE ***//iDelemiter//** Delemiter ***//iOrderBy//** Order By Bedinung ***//iDistinct//** Werte als DISTINCT behandeln. Sprich doppelte Einträge werden unterdrückt Der Rückgabelwert ist entweder eine Stringliste oder ein leerer String falls keine Details gefunden wurden. Sollte ein Fehler auftreten, wird #ERR und der Fehlertext zurückgegeben. ==== groupConcat() ==== GroupConcat ist ein Alias zu DConcat. Die Funktion ist als veraltet markiert und ist nur noch Vorhanden, falls jemand die Funktion mit diesem Namen in seinem Proejkt führt. Einziger Unterschied nebst dem Funktionsnamen: iDistinct ist Default auf False. Text = groupConcat(Feld, Quelle [,Kriterium [,Delimiter [,Sortierung [,Eindeutigkeit]]]]) Public Function groupConcat( _ ByVal iExpr As String, _ ByVal iDomain As String, _ Optional ByVal iCriteria As Variant = Null, _ Optional ByVal iDelimiter As String = ", ", _ Optional ByVal iOrderBy As Varian = Null, _ Optional ByVal iDistinct As Boolean = False _ ) As String ===== Anwendungsbeispiele ===== ==== VBA-Beispiel ==== Eine einfache Abfrage auf eine Tabelle 'Enfache Abfrage. Duplikate werden nicht unterdrückt debug.print DConcat("set_name","my_table", "group_id=12") Montags-Report, TEST, TEST 'oder mit DConcat(). Duplikate werden standartmässig unterdrückt debug.print DConcat("set_name","my_table", "group_id=12") Montags-Report, TEST 'Die Unterdrückung kann auch aufgehoben werden. Zudem der Delimiter und die Sortierung angepasst debug.print DConcat("set_name","my_table", "group_id=12", "-", "mein_datum", false) TEST-Montags-Report-TEST ==== SQL-Beispiel ==== Die Funktion ist prädestiniert um innerhalb eines SQL-Statements anzuwenden. Damit wird die Funktion auf jede Zeile angewendet. SELECT t.group_id, DCONCAT("set_name","my_table","group_id=" & t.group_id, , "mein_datum") FROM my_table AS t GROUP BY t.group_id ==== In einem Reportfooter ==== Man kann die Funktion auch in einem berechneten Textfeld eines Report-Fusses (oder Kopf) verwenden. Dabei kann man die Quelle und den Filter des Reports automatisch übernhemen =DConcat("name";[RecordSource];IIf([FilterOn];[Filter];"")) Ebenfalls in einem Gruppenfuss. Der Filter muss um das Gruppierungsfeld erweitertwerden. In diesem Beispiel das Feld my_group_field. =DConcat("name";[RecordSource];IIf([FilterOn];[Filter];"TRUE") & " AND [my_group_field] = " & [my_group_field]) ==== Beispele zu den Feldtypen ==== Die meisten Felder sind normale SQL-String. Sprich es gelten die folgenden Regelen: * Feldnamen dürfen nur Zahlen und Buchstaben enthalten. Ansonsten müssen sie in ''[]'' geschrieben werden * Zahlen werden als SQL-Zahlen geschrieben, also ohne Begrenzungszeichen * String müssen als SQL-String erfasst werden. Also mit ' oder " als Begrenzungszeichen. * Datum müssen im SQL-Format erfasst werden: ''#MM/DD/YYYY#'', ''#HH:NN:SS#'' bzw. ''#MM/DD/YYYY HH:NN:SS#'' Siehe dazu auch [[vba:tutorials:filterstrings|]]. 'Felder mit Leerzeichen und Sonderzeichen DConcat("[Mein Feld]","[Meine Tabelle]","[Filter Code]='Zürich'", ".", "[Mein Soriterfeld Nr.3]") 'Filterwert als Datum DConcat("MeinFeld","MeineTabelle","[Von Datum]>=#11/01/2015#") DConcat("MeinFeld","MeineTabelle","[Von Datum]>=" & Format([meinDatumsFeld], "\#mm\/dd\/yyyy\#")) 'Filterwert als String mit ' DConcat("MeinFeld","MeineTabelle","FilterCode>='abc'") DConcat("MeinFeld","MeineTabelle","FilterCode>='" & [filerFeld] & "'") 'oder mit "" DConcat("MeinFeld","MeineTabelle","FilterCode>=""abc""") DConcat("MeinFeld","MeineTabelle","FilterCode>=""" & [filerFeld] & """") 'Filter ist ein Boolean DConcat("MeinFeld","MeineTabelle","FilterCode=True") DConcat("MeinFeld","MeineTabelle","FilterCode=" & [meinBooleanFeld]) 'Filter ist eine Zahl DConcat("MeinFeld","MeineTabelle","FilterCode>=123") DConcat("MeinFeld","MeineTabelle","FilterCode>=" & [meinZahlenFeld]) ===== Code ===== Der Code ist zum Importieren gedacht. Wenn du ihn einfach in ein neues Modul kopierst, musst du den Header (Attribute-Zeilen) löschen.