Merkmalbaum & Breadcrumbs
Zuletzt geändert: 19.04.2026 04:52

Merkmalbaum & Breadcrumbs #

EULANDA hat für Adressen und Artikel einen Merkmalbaum – eine hierarchische Klassifizierung, mit der Datensätze frei kategorisiert werden können. Ein Artikel kann z.B. den Merkmalen \KEYWORDS\Software, \KEYWORDS\Warenwirtschaft und \Shop\Software gleichzeitig zugeordnet sein.

Die Pfade durch diesen Baum heißen Breadcrumbs. Ein Breadcrumb-Pfad beginnt immer mit einem Backslash und listet die Knotennamen durch weitere Backslashes getrennt auf. Ein Tabellenpräfix (:AR@..., :AD@...) wird auf PowerShell-Ebene nicht verwendet – der Tabellenbezug kommt über den Parameter -TableName.

Struktur am Beispiel #

flowchart TD Root["Artikel-Merkmalbaum
(TableName = Artikel)"]:::anlegen Root --> K["\KEYWORDS"]:::umwandlung K --> K1["\KEYWORDS\Software"]:::buchen K --> K2["\KEYWORDS\Warenwirtschaft"]:::buchen K --> K3["\KEYWORDS\BMEcat"]:::buchen K --> K4["\KEYWORDS\EANCOM"]:::buchen K1 ~~~ K2 K2 ~~~ K3 K3 ~~~ K4 Root --> S["\Shop"]:::umwandlung S --> S1["\Shop\Software"]:::buchen S --> S2["\Shop\Startseite"]:::buchen S1 ~~~ S2 K ~~~ S A1["Artikel 1
EulandaERP Basis"]:::item A1 -.->|zugeordnet| K1 A1 -.->|zugeordnet| K2 A1 -.->|zugeordnet| S1 A1 -.->|zugeordnet| S2 classDef anlegen fill:#2e86c1,color:#fff,stroke:#1a5276 classDef buchen fill:#27ae60,color:#fff,stroke:#196f3d classDef umwandlung fill:#8e44ad,color:#fff,stroke:#5b2c6f classDef item fill:#e67e22,color:#fff,stroke:#af601a

Ein Datensatz kann an mehrere Knoten im Baum gleichzeitig hängen – die Zuordnung ist eine M:N-Relation.

Alle Merkmale eines Datensatzes lesen #

Get-Breadcrumbs liefert die Merkmale eines Datensatzes als XML-String im Format <MERKMALLISTE><MERKMAL><PFAD>...</PFAD></MERKMAL></MERKMALLISTE>. Den String in [xml] casten und iterieren.

Import-Module EulandaXtools
$udl  = 'C:\Eulanda\mandant.udl'
$conn = Get-ConnByUdl -Udl $udl

try {
  # Ersten Artikel holen, der ueberhaupt Merkmale zugeordnet hat
  $rs = $conn.Execute(@'
    SELECT TOP 1 me.ObjektId
    FROM MerkmalElement me
    JOIN Merkmal m ON m.Id = me.KopfId
    WHERE m.Tabelle = 'Artikel' AND m.MerkmalTyp = 1
'@)
  if ($rs.EOF) { throw 'Kein Artikel mit Merkmalen in dieser DB' }
  $artikelId = [int]$rs.Fields.Item('ObjektId').Value

  $roh = Get-Breadcrumbs -Conn $conn -Tablename 'Artikel' -Id $artikelId
  ([xml]$roh).MERKMALLISTE.MERKMAL | ForEach-Object { $_.PFAD }
  # Beispielausgabe:
  # \KEYWORDS\Software
  # \KEYWORDS\Warenwirtschaft
  # \Shop\Software
  # \Shop\Startseite
}
finally {
  $conn.Close()
}
Nur auf Datensätze mit mindestens einem Merkmal anwenden. Get-Breadcrumbs wirft aktuell einen StrictMode-Fehler (“Variable $result nicht gesetzt”), wenn der gefragte Datensatz keine Merkmal-Zuordnung hat. Vorher prüfen oder den Aufruf in einen try/catch-Block packen.

Einen Merkmal-Pfad in eine ID auflösen #

Für Filter-Abfragen braucht man oft die interne ID eines Knotens. Get-BreadcrumbId liefert -1 zurück, wenn der Pfad nicht existiert (keine Exception).

$id = Get-BreadcrumbId -Conn $conn `
  -TableName 'Artikel' `
  -BreadcrumbPath '\KEYWORDS\Software'
# Ergebnis: z.B. 104

$id = Get-BreadcrumbId -Conn $conn `
  -TableName 'Artikel' `
  -BreadcrumbPath '\Unbekannt\Pfad'
# Ergebnis: -1

Der umgekehrte Weg – aus einer ID den Pfad zurückermitteln – geht mit Get-BreadcrumbPath.

Datensätze nach Merkmalen filtern #

Drei-Listen-Logik (AND / OR / NOT). New-SqlWhereForBreadcrumb kombiniert drei Listen von Pfaden zu einer einzigen SQL-WHERE-Bedingung: Pflicht, Alternative, Ausschluss. So lassen sich komplexe Abfragen deklarativ formulieren, ohne manuell mit EXISTS / JOIN Merkmal zu hantieren.
# Artikel, die in \KEYWORDS\Software UND in \Shop\Software liegen:
$where = New-SqlWhereForBreadcrumb -Conn $conn `
  -TableName 'Artikel' `
  -AndPathList @('\KEYWORDS\Software', '\Shop\Software')

# Ergebnis-String, z.B.:
# (id IN (SELECT ObjektID FROM [Eulanda].[dbo].[MerkmalElement]
#   WHERE KopfID IN (104))) AND (id IN (...))

$sql = "SELECT ArtNummer, Kurztext1 FROM Artikel WHERE $where"
$rs = $conn.Execute($sql)
while (-not $rs.EOF) {
  "{0,-12} {1}" -f $rs.Fields.Item('ArtNummer').Value,
                   $rs.Fields.Item('Kurztext1').Value
  $rs.MoveNext() | Out-Null
}

AND / OR / NOT lassen sich kombinieren:

$where = New-SqlWhereForBreadcrumb -Conn $conn `
  -TableName 'Artikel' `
  -AndPathList @('\KEYWORDS\Software') `
  -OrPathList  @('\Shop\Software', '\Shop\Startseite') `
  -NotPathList @('\KEYWORDS\Entfernt')

Wer eine Liste von Datensätzen (z.B. für einen Shopify-Export) aufbereitet und jedem Eintrag die Merkmale mitgeben will, nutzt Add-BreadcrumbsToHashtable. Die Funktion erwartet eine Liste von Hashtables mit jeweils einer Id-Spalte und ergänzt einen Breadcrumb-Key.

XML-Export eines Teilbaums #

Um den gesamten Merkmalbaum unterhalb eines Knotens zu exportieren (z.B. zum Befüllen einer Shopify-Collection-Struktur):

$xml = Get-BreadcrumbXml -Conn $conn `
  -TableName 'Artikel' `
  -StartPath '\KEYWORDS'

# Rueckgabe ist [XmlElement] -- direkt verwendbar
$xml.OuterXml

Einstieg – typische Anwendungsfälle #

  • Newsletter-Empfänger: Adressen nach Merkmalen \Newsletter\Kunden filtern und mit Send-Newsletter versenden.
  • Shopify-Export: Artikel nach Merkmal \Shop\Online exportieren, Collections anhand der Merkmal-Struktur anlegen.
  • Preislisten: Artikel nach \Kundengruppe\Haendler exportieren.
  • Statistik: Umsätze pro Merkmal-Gruppe auswerten (Artikel mit MerkmalElement joinen, dann per SUM/GROUP BY).