Analyses, modifications, import de données, transfert vers une application tierce, transmissions de quantitatifs, etc..., dans l'écosystème du BIM, l'utilisation d'Excel devient incontournable.
Le plus souvent la nécessité d'exporter vers Excel provient des Nomenclatures, plusieurs méthodes pour y parvenir.
- Avec l'export natif de Revit
Après export de rapport de nomenclatures au format texte avec choix du délimiteur, il suffit de d'importer le fichier txt en tant que données depuis Excel ou de changer directement l'extension "txt" en "csv" puis de l'ouvrir avec Excel.
- Avec des Add-Ins
Ce n'est pas le choix qui manque, exemple sur l'AutodeskAppStore
voici mes préférés (gratuit) :- Import/Export Excel de BIM One (export - import de nomenclatures, modification possible des paramètres d’Occurrence)
- SheetLink de Diroots (export - import de nomenclatures et bien plus, modification possible des paramètres d’Occurrence et de Type avec précautions)
- Avec Dynamo
- avec ses 2 nœuds natifs
- Par programmation avec les API(s)
- Pour des besoins très spécifiques, on peut également personnaliser ses propres exports avec les API de Revit et de Microsoft, par exemple pour exporter des données spécifiques ou pour personnaliser la mise en page des données sur Excel.
Pour rappel les nomenclatures sont des vues... on peut donc parcourir les éléments via la méthode
FilteredElementCollector Ici les données sont stockées dans un Array puis transférées dans un Range via la variable Value2 (sauf pour les couleurs de cellules 😕...y'en a qui ont essayé ils ont eu des problèmes 😅... bref, obligé de passer une boucle)
Plus d'informations ici
# Copyright (c) 20119- POUPIN.C
import clr
import re
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
app = DocumentManager.Instance.CurrentUIApplication.Application
clr.AddReference('System.Drawing')
from System import Array
from System.Drawing import *
clr.AddReferenceByName('Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c')
from Microsoft.Office.Interop import Excel
from System.Runtime.InteropServices import Marshal
import sys
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Lib')
import os
class ParameterProp():
def __init__(self, para):
self._para = para
self._pname = para.Definition.Name
self._pisinstance = para.IsInstance
class FamiliesCheck():
def __init__(self, dirpath):
self.dirpath = dirpath
self.full_lstP = []
for dir, subdir, files in os.walk(dirpath):
for file in files:
if file.endswith(".rfa") and re.search(r'\.\d+.rfa$', file) is None and re.search(r'[aA]ncien', dir) is None:
famDoc = app.OpenDocumentFile(dir + '\\' + file)
if famDoc.IsFamilyDocument:
famManager = famDoc.FamilyManager
lst_para = [ ParameterProp(x) for x in famManager.Parameters]
lst_para.sort(key = lambda x : x._pname)
lst_para[0:0] = [file]
self.full_lstP.append(lst_para)
famDoc.Close(False)
def XlsWriter(self):
ex = Excel.ApplicationClass()
ex.Visible = True
ex.DisplayAlerts = False
workbook = ex.Workbooks.Add()
workbook.SaveAs(self.dirpath + "\\reportFamilies.xlsx")
ws = workbook.Worksheets[1]
nbr_row = 1
for sub_lst in self.full_lstP:
nbr_col = len(sub_lst)
xlrange = ws.Range[ws.Cells(nbr_row, 1), ws.Cells(nbr_row, len(sub_lst))]
a = Array.CreateInstance(object, 1, len(sub_lst))
b = Array.CreateInstance(object, 1, len(sub_lst))
for index, i in enumerate(sub_lst):
# if i is string
if isinstance(i, str):
a[0,index] = i
#else i is a ParameterProp objet
else:
a[0,index] = i._pname
if i._pisinstance == False:
b[0,index] = 6
elif i._pisinstance == True:
b[0,index] = 8
else:
b[0,index] = None
#copy Array in range
xlrange.Value2 = a
for cell, color_index in zip(xlrange, b):
cell.Interior.ColorIndex = color_index
nbr_row += 1
used_range = ws.UsedRange
for column in used_range.Columns:
column.AutoFit()
workbook.Save()
dirpath = IN[0]
obj_check = FamiliesCheck(dirpath)
obj_check.XlsWriter()
OUT = obj_check.full_lstP
Aperçu en Vidéo avec quelques lignes supplémentaire
un 2ᵉ exemple ou l'on exporte des preview des familles vers Excel
(avec les méthodes Clipboard et Paste )
# coding: utf-8
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc = uiapp.ActiveUIDocument
import System
from System import Environment
from System import Array
from System.Collections.Generic import *
clr.AddReference('System.Drawing')
import System.Drawing
from System.Drawing import *
clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import Clipboard
clr.AddReferenceByName('Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' )
from Microsoft.Office.Interop import Excel
from System.Runtime.InteropServices import Marshal
class ExcelUtils():
def __init__(self, expSettings, filepath, sizebitmap):
self.expSettings = expSettings
self.filepath = filepath
self.sizebitmap = sizebitmap
print self.filepath
def exportXls(self):
ex = Excel.ApplicationClass()
ex.Visible = True
ex.DisplayAlerts = False
workbook = ex.Workbooks.Add()
workbook.SaveAs(self.filepath)
ws = workbook.Worksheets[1]
nbr_row = len(self.expSettings)
nbr_colum = len(self.expSettings[0])
#
xlrange = ws.Range[ws.Cells(1, 2), ws.Cells(nbr_row, nbr_colum )]
xlrange.EntireRow.RowHeight = self.sizebitmap.Height
ws.Range("a1").EntireColumn.ColumnWidth = self.sizebitmap.Width / 4
a = Array.CreateInstance(object, nbr_row, nbr_colum - 1)
#
for indexR, row in enumerate(self.expSettings):
for indexC , value in enumerate(row):
if indexC == 0 and value is not None:
Clipboard.SetDataObject(value)
rng = ws.Range[ws.Cells(indexR + 1, 1), ws.Cells(indexR + 1 , 1)]
ws.Paste(rng, False)
else:
a[indexR, indexC - 1] = value
#copy Array in range
xlrange.Value2 = a
used_range = ws.UsedRange
for column in used_range.Columns:
column.AutoFit()
toList = lambda x : x if hasattr(x, '__iter__') else [x]
listcat = toList(UnwrapElement(IN[0]))
#make filter
lstbipCat = [System.Enum.ToObject(BuiltInCategory, x.Id.IntegerValue) for x in listcat]
filtercat = ElementMulticategoryFilter(List[BuiltInCategory](lstbipCat))
#collector
fecSymb = FilteredElementCollector(doc).WherePasses(filtercat).WhereElementIsElementType().ToElements()
outdata = []
imgSize = Size( 100, 100 )
for symb in fecSymb:
bitm = symb.GetPreviewImage(imgSize)
famName = symb.Family.Name
symbName = Element.Name.GetValue(symb)
outdata.append([bitm, famName, symbName])
#define folder to export
directory = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
objXls = ExcelUtils(outdata, directory + '\\test.xls', imgSize)
objXls.exportXls()
OUT = directory
Bonne Année et Meilleurs vœux
0 commentaires:
Enregistrer un commentaire