|
|
| Menüeintrag |
|---|
| Verwalten → Bericht-Werkzeuge → BIM Bericht |
| Arbeitsbereich |
| BIM |
| Standardtastenkürzel |
| Keiner |
| Eingeführt in Version |
| 1.2 |
| Siehe auch |
| Keiner |
Der BIM-Bericht ist ein Werkzeug zur Erstellung von Zeitplänen und Datenberichten aus einem FreeCAD-Modell. Er verwendet eine SQL-ähnliche Abfragesprache zum Auswählen, Filtern und Aggregieren von Daten und bietet damit eine deklarative Alternative zu anderen Planungswerkzeugen. Letztendlich ermöglicht es Benutzern, eine Kalkulationstabelle zu erstellen und automatisch mit Daten aus dem Modell zu füllen.
Das Werkzeug BIM Bericht auswählen, wenn Folgendes ausgeführt werden muss:
Das BIM Bericht-System besteht aus drei Hauptkomponenten: Das Report-Objekt in der Baumansicht, dem Ziel Spreadsheet für die Ergebnisse, und dem Aufgaben-Fenster wo der Bericht eingestellt werden kann.
Wenn ein neuer Bericht erstellt wird, werden in der Baumansicht zwei neue Objekte angezeigt: das Berichtsobjekt, in dem alle Einstellungen gespeichert sind, und die zugehörige ReportResult-Tabelle.
Durch Doppelklicken auf das Objekt Daten-EigenschaftReport wird das Aufgaben-Fenster geöffnet, das der primäre Arbeitsbereich für die Bearbeitung des Berichts ist. Das Fenster ist in zwei Hauptbereiche unterteilt: die Report Statements (Berichts-Ausdrücke) und der Statement Editor (Ausdrucks-Editor).

Dieser Abschnitt ist immer oben im Aufgaben-Fenster sichtbar und enthält eine Zusammenfassung aller Abfragen (oder „Anweisungen“), aus denen der Bericht besteht.
Das Hauptmerkmal ist eine Tabelle, in der jede Anweisung aufgeführt ist. Von hier aus kann die Beschreibung angezeigt und direkt bearbeitet werden sowie wichtige Optionen für jede Abfrage umgeschaltet werden:
Label, Area) als Kopfzeile für die Ergebnisse dieser Anweisung.Durch Doppelklicken auf eine Zeile des Ausdrucks wird dieser zur Bearbeitung geöffnet. Durch Drücken der Taste F2 in einer Zeile des Ausdrucks kann die Beschreibung des Ausdrucks direkt bearbeitet werden, ohne dass der vollständige Editor geladen werden muss.
Unter der Tabelle sind Schaltflächen zum Hinzufügen,
Entfernen,
Duplizieren, oder
Bearbeiten der ausgewählten Anweisung.
Schließlich können über das Dropdown-Menü Berichtsvorlagen vollständige, vorkonfigurierte Berichte geladen werden, wie beispielsweise ein „Raum- und Flächenplan“.
Dieser Abschnitt wird unten im Aufgaben-Fenster angezeigt, wenn eine Anweisung ausgewählt und auf Ausgewählte bearbeiten geklickt wird. Hier wird eine individuelle SQL-Abfrage geschrieben und konfiguriert.

Label, Area) in the spreadsheet output for this statement.The Save button saves the modifications to the loaded statement. When the
Save and Next checkbox is ticked and the
Save button is pressed, in addition to the save operation a new statement will be created for a more streamlined edition experience. The ❌ Discard button closes the statement editor without saving any changes made.
Dieses kurze Tutorial führt durch die Erstellung eines vollständigen Raumplans, von einer einfachen Liste bis hin zu einem mehrteiligen Bericht mit berechneten Summen.
First, let's create a simple list of all spaces and their areas.
Room List.Spaces and sorts them alphabetically.SELECT Label, Area FROM document WHERE IfcType = 'Space' ORDER BY Label ASC
Now, let's add a second statement to calculate the total area.
Total Area.SELECT 'Total Usable Area', SUM(Area) FROM document WHERE IfcType = 'Space'
Mit Befehlsverknüpfung können Abfragen miteinander verknüpft werden, wobei die Ausgabe einer Abfrage als Eingabe für die nächste dient. Dies ist für komplexe hierarchische Auswahlen unerlässlich, beispielsweise bei Verwendung der Funktion CHILDREN(). Da es sich nicht um eine rekursive Funktion handelt, werden nur direkte Nachkommen gefunden.
Um beispielsweise alle Türen im „Erdgeschoss“ zu finden, muss eine mehrstufige Abfrage durchgeführt werden, da Türen Unterelemente von Wänden sind, die wiederum Unterelemente des Stockwerks sind.
Find Ground Floor.SELECT * FROM document WHERE Label = 'Ground Floor'
Find Walls on Floor.SELECT * FROM CHILDREN(SELECT * FROM document) WHERE IfcType = 'Wall'
Find Doors in Walls.SELECT Label, Width, Height FROM CHILDREN(SELECT * FROM document) WHERE IfcType = 'Door'
Das Ergebnis verstehen: Die endgültige Tabelle zeigt nur die Ergebnisse der letzten Anweisung in der Pipeline (die Liste der Türen). Die ersten beiden Anweisungen fungieren als Zwischenfilter, deren Ergebnisse im Speicher weitergegeben, aber nicht in die Tabelle gedruckt werden, sodass Sie einen übersichtlichen und präzisen Abschlussbericht erhalten.
Dieser Abschnitt enthält detaillierte Informationen zum SQL-Dialekt, der vom BIM Berichtswerkzeug verwendet wird.
Hinweis: Die aktuellsten Informationen zu allen Klauseln und Funktionen findet man jederzeit in der Benutzeroberfläche, indem man im Aufgaben-Fenster-Editor des Berichts auf die Schaltfläche Hilfe klickt.
SELECT: Specifies the columns of data to return. Can use * to select a default identifier for all objects.FROM: Specifies the data source. In a standalone query, this is always document. In a pipeline, document is a placeholder for the data from the previous step. Can also use the CHILDREN() function.WHERE: Filters objects based on conditions.GROUP BY: Groups rows that have the same values into summary rows, typically used with aggregate functions.ORDER BY: Sorts the final results. Can be followed by ASC (ascending, default) or DESC (descending). Supports sorting by multiple columns.AS: Creates an alias (a custom name) for a column in the SELECT clause, e.g., SELECT Area AS "My Area".
Der Dialekt hat spezifische Regeln für die Verwendung von Ausdrücken (wie Funktionen oder Arithmetik) in den Klauseln GROUP BY und ORDER BY.
GROUP BY: When grouping by an expression, you must repeat the entire expression in the GROUP BY clause. Using an alias from the SELECT list is not supported.
SELECT TYPE(*) … GROUP BY TYPE(*)
SELECT TYPE(*) AS BimType … GROUP BY BimType
ORDER BY: Conversely, sorting by a raw expression is not supported. To sort by the result of an expression, you must first include it in the SELECT list with an AS alias, and then refer to that alias in the ORDER BY clause.
SELECT Label, LOWER(Label) AS sort_key … ORDER BY sort_key
SELECT Label … ORDER BY LOWER(Label)
The dialect includes a library of built-in functions for data manipulation and analysis.
| Category | Function | Description |
|---|---|---|
| Aggregate | COUNT(property|*)
|
Counts the number of objects. COUNT(*) counts all rows; COUNT(property) counts rows where the specified property is not NULL.
|
SUM(property)
|
Calculates the sum of a numerical property. | |
MIN(property)
|
Finds the minimum value of a numerical property. | |
MAX(property)
|
Finds the maximum value of a numerical property. | |
| Hierarchical | PARENT(*)
|
Returns the architecturally significant parent of an object (e.g., the Wall a Window is in), transparently skipping over generic groups. |
CHILDREN(subquery)
|
A function used in the FROM clause. Returns all children of objects found by the subquery, resolving both containment (.Group) and hosting (.Hosts) relationships. This function is not recursive. To find grandchildren or deeper descendants, chain multiple CHILDREN() steps together using a pipeline.
| |
CHILDREN_RECURSIVE(subquery, max_depth=15)
|
A function used in the FROM clause. Returns all descendant objects of the subquery results by recursively traversing the hierarchy. It transparently skips generic groups. An optional max_depth can be specified (default: 15, 0 for unlimited). This replaces the need for complex pipelines to find nested objects.
| |
| Utility | TYPE(*)
|
Returns the object's user-facing type, as determined by its proxy (e.g., Wall, Space, Part::Box).
|
CONVERT(quantity, 'unit')
|
Converts a FreeCAD Quantity object to a new unit and returns it as a raw number. Example: CONVERT(Area, 'm^2').
| |
| String | LOWER(property)
|
Converts a text property to lowercase. |
UPPER(property)
|
Converts a text property to uppercase. | |
CONCAT(val1, val2, …)
|
Joins multiple text values and properties together into a single string. |
Es kann auf alle Eigenschaften eines Objekts zugegriffen werden, einschließlich verschachtelter Datenstrukturen.
Label, IfcTypeShape.Volume, Placement.Base.zPARENT().
PARENT(*).Label, PARENT(*).PARENT(*).Height
| Type | Operators | Description |
|---|---|---|
| Comparison | =, !=, >, <, >=, <=
|
Standard comparison operators. |
LIKE
|
Case-insensitive pattern matching. Use % for multiple characters and _ for a single character.
| |
IS NULL, IS NOT NULL
|
Checks if a property has a value. | |
IN (value1, value2, …)
|
Checks if a property's value is in a given list of literals. | |
| Logical | AND, OR
|
Used in the WHERE clause to combine multiple conditions.
|
| Arithmetic | +, -, *, /
|
Perform calculations on numerical properties. Obeys standard operator precedence; use () to override.
|
') and double quotes (") can be used for text literals (strings). For example, WHERE Label = 'Wall' and WHERE Label = "Wall" are equivalent.--, and multi-line comments, which are enclosed in /* … */.
Dieser Abschnitt enthält eine Sammlung praktischer Abfragen, die direkt verwendet werden oder für die Berichte angepasst werden können.
Alle Strukturelemente auswählen (Säulen und Träger):
SELECT Label, IfcType
FROM document
WHERE IfcType IN ('Column', 'Beam')
ORDER BY IfcType, Label
Alle Wände auswählen, deren Name „Außen“ enthält:
SELECT Label, Length, Height
FROM document
WHERE IfcType = 'Wall' AND Label LIKE '%Exterior%'
Alle BIM-Objekte zählen, gruppiert nach ihrem Typ:
SELECT IfcType, COUNT(*)
FROM document
WHERE IfcType IS NOT NULL
GROUP BY IfcType
ORDER BY IfcType ASC
Eine vollständige Mengenermittlung für alle Wände erhalten:
Diese Abfrage berechnet die Gesamtzahl der Wände, ihre Gesamtlänge sowie die minimale und maximale Wandhöhe.
SELECT
COUNT(*) AS "Total Count",
SUM(Length) AS "Total Length (mm)",
MIN(Height) AS "Min Height (mm)",
MAX(Height) AS "Max Height (mm)"
FROM document
WHERE IfcType = 'Wall'
Liste aller Objekte, die sich direkt im „Erdgeschoss“ befinden:
Hierbei wird die Funktion CHILDREN() verwendet, um den Inhalt eines bestimmten Containerobjekts abzufragen.
SELECT Label, IfcType
FROM CHILDREN(SELECT * FROM document WHERE Label = 'Ground Floor')
ORDER BY IfcType
Alle Türen und die jeweilige Wand auflisten, in der sie sich befinden:
Hierbei wird die Funktion PARENT() verwendet, um den Host jeder Tür zu ermitteln.
SELECT
Label AS "Door_Name",
PARENT(*).Label AS "Host_Wall_Name"
FROM document
WHERE IfcType = 'Door'
ORDER BY "Host_Wall_Name"
Alle Fenster im „Erdgeschoss“ finden (indem die Vorgänger überprüft werden):
Diese Abfrage findet Fenster, überprüft deren übergeordnetes Element (die Wand) und anschließend das übergeordnete Element dieser Wand (den Boden).
SELECT Label
FROM document
WHERE IfcType = 'Window' AND PARENT(*).PARENT(*).Label = 'Ground Floor'
Einen vollständigen Raum- und Flächenplan erstellen:
Diese Abfrage erzeugt eine formatierte Liste aller Räume, gruppiert nach der Etage, zu der sie gehören, mit ihrer Fläche umgerechnet in Quadratmeter.
SELECT
PARENT(*).Label AS "Floor",
Label AS "Room Name",
CONVERT(Area, 'm^2') AS "Area (m²)"
FROM document
WHERE IfcType = 'Space'
ORDER BY "Floor", "Room Name"
Wenn eine Eigenschaft ausgewählt wird, die Einheiten (eine „Quantität“) hat, wie z. B. „Länge“ oder „Fläche“, gibt die BIM-Report-Engine den rohen numerischen Wert dieser Eigenschaft zurück, wie er intern im FreeCAD-Dokument gespeichert ist. Die internen Einheiten von FreeCAD basieren immer auf Millimetern (mm).
Das bedeutet, dass die Standardausgabe unabhängig vom aktuellen Einheitenschema oder den Benutzereinstellungen in mm für Länge, mm² für Fläche und mm³ für Volumen erfolgt. Die automatisch generierte Spaltenüberschrift gibt diese interne Einheit korrekt wieder.
Beispiel: Standardverhalten
Wenn diese einfache Abfrage auf einer Fläche von 1 Meter mal 1 Meter ausgeführt wird:
SELECT Label, Area FROM document WHERE IfcType = 'Space'
Die resultierende Kalkulationstabelle zeigt:
Area (mm²)1000000.0<span id="Using_CONVERT()">
CONVERT()Um die Ergebnisse in den gewünschten Einheiten zu erhalten, kann die Funktion CONVERT() verwendet werden, die eine explizite Kontrolle über die Ausgabe ermöglicht. Um die Fläche in Quadratmetern zu erhalten, ändert man die Abfrage wie folgt:
SELECT Label, CONVERT(Area, 'm^2') AS "Area (m²)" FROM document WHERE IfcType = 'Space'
Diese Abfrage liefert nun das Ergebnis in der gewünschten Einheit.:
Area (m²)1.0Die Verwendung von CONVERT() garantiert, dass die Ausgabe des Berichts eindeutig ist und dass alle Berechnungen, die innerhalb der Abfrage durchgeführt werden (z. B. SUM(CONVERT(Area, 'm^2'))), mathematisch korrekt sind.
Ein Arch Report-Objekt stellt dem Benutzer die folgenden Eigenschaften zur Verfügung.
Report
SUM(Length) im Bericht nach der Neuberechnung automatisch aktualisiert. Bei sehr großen Modellen kann es aus Leistungsgründen ratsam sein, diese Option zu deaktivieren, wenn viele Änderungen vorgenommen werden. Wenn „AutoUpdate“ auf „False“ gesetzt ist, kann der Bericht jederzeit manuell aktualisiert werden, indem mit der rechten Maustaste auf das Berichtsobjekt in der Baumansicht geklickt wird und „Recompute“ ausgewählt oder indem auf die globale Schaltfläche „Recompute“ geklickt wird.
Die BIM Bericht-Engine ist vollständig über Python zugänglich, sodass die erweiterten Abfragefunktionen in die eigenen Skripte und Automatisierungen integrieren kann.
Dies ist die Hauptfunktion zum Ausführen einer einzelnen, einfachen SQL-Abfrage. Sie nimmt eine Abfragezeichenfolge als Eingabe entgegen und gibt eine Liste der FreeCAD-Dokumentobjekte zurück, die der Abfrage entsprechen. Wenn die Abfrage ungültig ist oder keine Objekte findet, gibt sie eine leere Liste zurück und gibt eine Fehlermeldung an die Konsole aus.
Beispiel: Alle Wandobjekte mit „Exterior“ (Außenbereich) im Namen abrufen
import FreeCAD
import Arch
# This query selects all Wall objects whose Label contains the substring "Exterior"
query = "SELECT * FROM document WHERE IfcType = 'Wall' AND Label LIKE '%Exterior%'"
exterior_walls = Arch.selectObjects(query)
# The result is a list of FreeCAD objects
FreeCAD.Console.PrintMessage(f"Found {len(exterior_walls)} exterior walls.\n")
for wall in exterior_walls:
FreeCAD.Console.PrintMessage(f"- {wall.Label} (Length: {wall.Length})\n")
Für komplexere, mehrstufige Auswahlen kann diese Funktion verwendet werden, um eine Pipeline auszuführen. Sie nimmt eine Liste von ArchSql.ReportStatement-Objekten entgegen und gibt die endgültige Liste der FreeCAD-Dokumentobjekte zurück, die aus der vollständigen Pipeline resultieren.
Dies entspricht programmatisch der Verwendung des Kontrollkästchens „Als Pipeline-Schritt verwenden“ in der Benutzeroberfläche.
Beispiel: Finde alle Türen im „Erdgeschoss“"
Dies ist ein klassisches hierarchisches Problem, das mehrere Schritte erfordert. Das Ziel besteht darin, die „Enkelkinder” (Türen) eines „Großelternteils” (des Stockwerks) zu finden. Da die Funktion CHILDREN() nicht rekursiv ist, müssen wir mehrere Schritte in einer Pipeline verketten.
'Ground Floor'.import FreeCAD
import Arch
import ArchSql
# Step 1: Define the pipeline statements.
# The ReportStatement class must be imported from the ArchSql module.
# Statement 1: Find the parent 'Ground Floor' object.
# Output of this step: [Ground_Floor_Object]
stmt1 = ArchSql.ReportStatement(
query_string="SELECT * FROM document WHERE Label = 'Ground Floor'"
)
# Statement 2: Find the direct children of the floor (walls, spaces, etc.).
# is_pipelined=True tells this to run on the output of stmt1.
# Output of this step: [Wall_Object_1, Wall_Object_2, Space_Object_1, …]
stmt2 = ArchSql.ReportStatement(
query_string="SELECT * FROM CHILDREN(SELECT * FROM document)",
is_pipelined=True
)
# Statement 3: Find the children of the objects from the previous step.
# This finds the doors and windows hosted by the walls.
# Output of this step: [Door_Object, Window_Object_1, …]
stmt3 = ArchSql.ReportStatement(
query_string="SELECT * FROM CHILDREN(SELECT * FROM document)",
is_pipelined=True
)
# Statement 4: Filter the final list to keep only the doors.
# This runs on the output of stmt3.
# Final Output: [Door_Object]
stmt4 = ArchSql.ReportStatement(
query_string="SELECT * FROM document WHERE IfcType = 'Door'",
is_pipelined=True
)
# Step 2: Execute the full pipeline.
pipeline_statements = [stmt1, stmt2, stmt3, stmt4]
doors_on_floor = Arch.selectObjectsFromPipeline(pipeline_statements)
# The result is the final list of door objects.
FreeCAD.Console.PrintMessage(f"Found {len(doors_on_floor)} doors on the ground floor.\n")
for door in doors_on_floor:
FreeCAD.Console.PrintMessage(f"- {door.Label}\n")
Zum Debuggen, Skripten oder Teilen der Arbeit mit anderen kann eine vollständige, für Menschen lesbare Zusammenfassung der Konfiguration eines Berichts direkt aus der Python-Konsole abgerufen werden.
Die benutzerdefinierte Logik und der detaillierte Inhalt eines BIM-Berichts werden in seinem „Proxy-Objekt” gespeichert. Durch Zugriff auf das Attribut .Proxy erhält man einen vollständigen Ausdruck aller Anweisungen und der SQL-Abfragen. Auf diese Weise kann man die gesamte Berichtsdefinition bequem in die Zwischenablage kopieren, um sie in einem Forum oder einem Fehlerbericht zu teilen.
Wie man es benutzt:
obj an die Python-Konsole gesendet.print(obj.Proxy)
Beispiel-Ausgabe:
>>> print(obj.Proxy)
BIM Report: 'My Door Schedule' (2 statements)
--- Statement [1]: Find All Walls on Ground Floor ---
SELECT *
FROM CHILDREN(SELECT * FROM document WHERE Label = 'Ground Floor')
WHERE IfcType = 'Wall'
--- Statement [2]: Final Door Schedule (Pipelined, Header) ---
SELECT
Tag,
COUNT(*) AS "Count"
FROM
document
GROUP BY
Tag