Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Copyright(c) 2016, Team Awesome
- import clr
- import sys
- import System
- from System import Array
- from System.Collections.Generic import *
- from math import ceil, floor
- import time
- clr.AddReference("RevitAPI")
- import Autodesk
- from Autodesk.Revit.DB import *
- # Import DocumentManager and TransactionManager
- clr.AddReference("RevitServices")
- import RevitServices
- from RevitServices.Persistence import DocumentManager
- from RevitServices.Transactions import TransactionManager
- # Import ToDSType(bool) extension method
- clr.AddReference("RevitNodes")
- import Revit
- clr.ImportExtensions(Revit.Elements)
- # Start Transaction
- doc = DocumentManager.Instance.CurrentDBDocument
- TransactionManager.Instance.EnsureInTransaction(doc)
- clr.AddReferenceByName('Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c')
- from Microsoft.Office.Interop import Excel
- System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo("en-US")
- from System.Runtime.InteropServices import Marshal
- pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
- sys.path.append(pyt_path)
- #Declare variables
- start_time = time.clock()
- output=[]
- RunIt = IN[0]
- familyTypes=IN[1]
- elements=IN[2]
- templateFile=IN[3]
- sheetName=IN[4]
- outFile=IN[5]
- if outFile[-5:] != ".xlsx":
- outFile+=".xlsx"
- roomList=IN[6]
- rooms=roomList[1]
- roomParam = roomList[0]
- elementParams=IN[7]
- headers=IN[8]
- sheetLimiter=IN[9]
- roomOutputNr=IN[10]
- columnPrint=IN[11]
- rowPrint=IN[12]
- #always add new stuff at the bottom so you dont need to change the indexes around
- #sets up excel file
- def SetUp(xlApp):
- # supress updates and warning pop ups
- xlApp.Visible = False
- xlApp.DisplayAlerts = False
- xlApp.ScreenUpdating = False
- return xlApp
- def ExitExcel(filePath, xlApp, wb, ws):
- # clean up before exiting excel, if any COM object remains
- # unreleased then excel crashes on open following time
- def CleanUp(_list):
- if isinstance(_list, list):
- for i in _list:
- Marshal.ReleaseComObject(i)
- else:
- Marshal.ReleaseComObject(_list)
- return None
- wb.SaveAs(unicode(filePath))
- xlApp.ActiveWorkbook.Close(False)
- xlApp.ScreenUpdating = True
- xlApp.Quit()
- CleanUp([ws,wb,xlApp])
- return None
- #searches worksheet for a value and returns that value's position in the worksheet
- def searchVal(ws, key):
- originX = ws.UsedRange.Row
- originY = ws.UsedRange.Column
- boundX = ws.UsedRange.Rows(ws.UsedRange.Rows.Count).Row
- boundY = ws.UsedRange.Columns(ws.UsedRange.Columns.Count).Column
- xlAfter = ws.Cells(originY, originX)
- xlLookIn = -4163
- xlLookAt = "&H2"
- xlSearchOrder = "&H1"
- xlSearchDirection = 1
- xlMatchCase = False
- xlMatchByte = False
- xlSearchFormat = False
- cell = ws.Cells.Find(key, xlAfter, xlLookIn, xlLookAt, xlSearchOrder, xlSearchDirection, xlMatchCase, xlMatchByte, xlSearchFormat)
- if cell != None:
- cellAddress = cell.Address(False, False)
- addressX = xlApp.Range(cellAddress).Row
- addressY = xlApp.Range(cellAddress).Column
- result=[]
- result.append(addressX)
- result.append(addressY)
- return result
- return False
- #gets room information based on the parameter we sent in
- def roomInfo(elem):
- info = {}
- uElement = UnwrapElement(elem)
- try:
- for room in rooms:
- info[room]=0
- for j in uElement:
- for phase in doc.Phases:
- if j.CreatedPhaseId == phase.Id:
- try:
- room = j.Room[phase]
- for p in room.Parameters:
- if p.Definition.Name == roomParam:
- geonum = p.AsString()
- info[geonum]+=1
- except:
- continue
- except:
- pass
- return info
- #checks design option, and returns only those elements in Main Model or primary
- def desOpts(elem):
- if elem.GetParameterValueByName("Design Option") == "-1":
- return True
- try:
- if "primary" in elem.GetParameterValueByName("Design Option").InternalElement.Name:
- return True
- except:
- return False
- return False
- def elDictionary():
- elDict = {}
- for elem in elements:
- if desOpts(elem):
- type = elem.GetParameterValueByName("Type Id")
- if type not in elDict:
- elDict[type] = []
- elDict[type].append(elem)
- return elDict
- #resizes the images
- def scaleImg(maxWidth, maxHeight, imgWidth, imgHeight):
- ratio = min(maxWidth/imgWidth, maxHeight/imgHeight)
- return imgWidth*ratio, imgHeight*ratio
- #replaces placeholder values in cells with actual values and adjusts row height
- def fixValues(ws, name, val):
- char_width=1.55
- position = searchVal(ws, name)
- if position:
- tc = ns[counter].Cells(position[0], position[1])
- lineBreaks = tc.Value.ToString().count('\n')
- try:
- num_chars = len(val)
- chars_per_row = floor(tc.Width / char_width)
- if num_chars * char_width > tc.Width:
- num_rows = ceil((num_chars*char_width) / tc.Width)
- tc.Value = val
- """tc.RowHeight = num_rows * tc.Height + (3 * num_rows)
- tc.Style.WrapText = True
- actualRows = tc.Rows.Count
- lineBreaks = tc.Value.ToString().count(str(unichr(10)))
- #lineBreaks2 = tc.Value.ToString().count(char(10))
- output.append("Height is " +str(tc.Height))
- output.append("Width is " + str(tc.Width))
- output.append("Chars per row is " + str(chars_per_row))
- output.append("Num rows is " + str(num_rows))
- output.append("Width is " +str(tc.Width))
- output.append("num chars is " + str(num_chars))
- output.append("actual rows is " + str(actualRows))
- output.append("linebreaks is " +str(lineBreaks))
- #output.append("linebreaks2 is " +str(lineBreaks2))
- output.append(repr(val))
- output.append("*"*20)"""
- else:
- tc.Value = val
- except:
- tc.Value = val
- def getRoomPos(ws, name):
- return searchVal(ws, name)
- #replaces placeholder values in cells with actual values
- def fixHeader(ws, name, val):
- position = searchVal(ws, name)
- if position:
- tc = ws.Cells(position[0],position[1])
- tc.Value = val
- def fixHeaders(ws):
- numHeaders = len(headers)
- for index,key in enumerate(headers):
- if index < numHeaders/2:
- valIndex = index + numHeaders/2
- fixHeader(ws, "#"+key+"#", headers[valIndex])
- #gets rooms elements are in and counts totals
- def fixRooms(ws, elems):
- roomData = roomInfo(elems)
- roomString = []
- row = 0
- col = 0
- roomPos = getRoomPos(ws, "#ROOMNR#")
- try:
- startRow = roomPos[0]
- startCol = roomPos[1]
- except TypeError:
- pass
- #output.append("Could not find #ROOMNR# in the template")
- lastRow = None
- try:
- for index, room in enumerate(sorted(rooms)):
- if roomData[room]>0:
- if roomOutputNr:
- s = "%s (%s)" % (room, str(roomData[room]))
- else:
- s = "%s" % (room)
- if s not in roomString:
- insertRow = startRow + row
- insertCol = startCol + col
- tc = ns[counter].Cells(insertRow, insertCol)
- tc.Value =s
- lastRow = insertRow
- col +=1
- if len(rooms) > index+2 and sorted(rooms)[index+1][0] != room[0]:
- col = 0
- row +=2
- if col == 4:
- col = 0
- row +=1
- roomString.append(s)
- except:
- output.append("I found no rooms. Check input parameter for Room Element Collector!")
- return lastRow
- #this runs the boolean
- if RunIt:
- xlApp = Excel.ApplicationClass()
- SetUp(xlApp)
- xlApp.Workbooks.Open(unicode(templateFile))
- wb = xlApp.ActiveWorkbook
- ws = xlApp.Sheets(sheetName)
- originalSheet = wb.Sheets(1)
- ns = {}
- counter = 0
- fixHeaders(ws)
- #Build an element dictionary we can use later:
- elDict = elDictionary()
- #Let's iterate over all our family types we got in
- for index, familyType in enumerate(familyTypes):
- #Find all elements that belong to this family type
- if familyType in elDict:
- elems = elDict[familyType]
- if len(elems) > 0 :
- originalSheet.Copy(after=wb.Sheets(wb.Sheets.Count))
- ns[counter] = wb.Sheets(wb.Sheets.Count)
- ns[counter].Activate
- if familyType.GetParameterValueByName("Type Mark") != "":
- try:
- ns[counter].Name = familyType.GetParameterValueByName("Type Mark")
- except:
- output.append("Was unable to create sheet due to duplicate type marks\nThe type mark in question is: "+familyType.GetParameterValueByName("Type Mark")+"\nPlease check and correct the model.")
- else:
- ns[counter].Name = "FAIL"+str(counter)
- output.append("Type marks missing, correct your in data")
- fixValues(ws, "#TOTAL#", str(len(elems)))
- #Room counter
- lastRow = fixRooms(ws, elems)
- if lastRow == None:
- lastRow = 30
- #Fix print area and set print area and header rows
- print_vals = columnPrint.split(":")
- print_start=print_vals[0]
- print_end=print_vals[1]
- ns[counter].PageSetup.PrintArea = print_start+"1:"+print_end + str(lastRow)
- ns[counter].PageSetup.PrintTitleRows = rowPrint
- #Iterate over all the elementParams and replace the template placeholder values one by one
- for ep in elementParams:
- if ep == "Type Image":
- position = searchVal(ws, "#"+str(ep)+"#")
- if position:
- tc = ns[counter].Cells(position[0], position[1])
- maxWidth=0
- for i in xrange(1,6):
- tcc = ns[counter].Cells(position[0], position[1]+i)
- maxWidth+=tcc.Width
- val = familyType.GetParameterValueByName(ep)
- fixValues(ws, "#"+str(ep)+"#","")
- try:
- fp = val.GetParameterValueByName("Loaded from file")
- w,h = scaleImg(maxWidth, tc.Height, val.GetParameterValueByName("Width"), val.GetParameterValueByName("Height"))
- ns[counter].Shapes.AddPicture(FileName = fp, LinkToFile=False, SaveWithDocument=True, Left=tc.Left, Top=tc.Top, Width=w, Height=h)
- except:
- pass
- else:
- val = familyType.GetParameterValueByName(ep) or elems[0].GetParameterValueByName(ep)
- fixValues(ws, "#"+str(ep)+"#", val)
- counter +=1
- #This limits the number of sheets created if boolean is true
- if sheetLimiter == True and index>=9:
- break
- originalSheet.Delete()
- output.append("success")
- ExitExcel(str(outFile), xlApp, xlApp.ActiveWorkbook, ws)
- else:
- output.append("Run is disabled")
- exec_time = "Execution time was " + str(time.clock() - start_time) + "seconds"
- output.append(exec_time)
- OUT = output
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement