Placing existing views on existing sheets with Excel and a reference sheet

Hi, I am using the Aussie BIM Guru’s video https://youtu.be/6W78HpuBXUE to place views on sheets by using an Excel file with sheet numbers and viewnames and a sheet in Revit with already placed viewports as a reference to find the right location for the viewports on the other sheets.

The script is working fine but what I’m trying to do now is change this script so that I can place multiple views at once. The only idea I got so far is by adding several tabs to the Excel file and changing the string for ‘sheetname’ in the script accordingly so that I can run the script over and over again to eventually place all the views on the sheets.

Anyone willing to take a look at the script below and provide me with some ideas and/or possible solutions?

Thanks in advance,

Selim

Place_Views on existing Sheets with Excel v1.dyn (80.6 KB)

Trying to place 3 types of floorplan views on 8 sheets, this is what my lists look like:


With this I am getting all the views on index 0 on every sheet, so only the ground floor views. How do I change the sheet list so that all three views are placed on each sheet?
This is what the excel looks like that I’m using for the script:

That custom node was last updated in Jan 2018. I’ve had to change the Python code in that node in Dynamo 1.x already to handle multiple views or multiple sheets, cannot recall exactly.

Change that Node to the Rhythm ones, the Create Viewport Node from that package will do exactly what you want here.

I have found the solution to place all 3 floor plans for the sheets! It’s done by counting the amount of views from the excel file, it looks like this:

So the script looks exactly like shown in the video of the Aussie BIM Guru with slight adjustments;

  • The indices taken at the start for the views are all of them except 0 (achieved with the node List.RemoveItemAtIndex 0)
  • End filtering shown like above
  • Excel with more than 1 column for the view names
  • Reference view has several views already placed on it to get the right coordinates

Thanks for the reply Bjorn, I managed to filter the script correctly to place the wanted multiple views on multiple sheets.

I didn’t know Steamnodes was last updated in 2018! :sweat_smile: Will definitely give the Rhythm node you mentioned a try later on!

1 Like

Yeah Steamnodes is a bit out of date - I didn’t use Rhythm as much when I made the tutorial for this one originally.

See below for the Pythonic way to achieve this workflow if it is of interest also (Rhythm buries it in a ZT node, so helpful, but can’t learn from it :slight_smile:):

# Made by Gavin Crump
# Free for use
# BIM Guru, www.bimguru.com.au

# Boilerplate text
import clr

import sys
sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')

import System
from System import Array
from System.Collections.Generic import *

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager 
from RevitServices.Transactions import TransactionManager 

clr.AddReference("RevitAPI")
import Autodesk 
from Autodesk.Revit.DB import *

# Current doc/app/ui
doc = DocumentManager.Instance.CurrentDBDocument

# Function for unwrapping and forcing lists
def uwlist(input):
	tolist = input if isinstance(input, list) else [input]
	unwrap = UnwrapElement(tolist)
	return unwrap

# Preparing input from dynamo to revit
views  = uwlist(IN[0])
sheets = uwlist(IN[1])
points = uwlist(IN[2])

# Do some action in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)

viewports = []
for v,s,p in zip(views,sheets,points):
	try:
		vp = Viewport.Create(doc, s.Id, v.Id, p.ToXyz())
		viewports.append(vp)
	except:
		viewports.append("View already placed!")

TransactionManager.Instance.TransactionTaskDone()

# Preparing output to Dynamo
OUT = viewports
1 Like

I’m very interested in Python but for now I’m still depended on nodes since I didn’t learn Python yet.
I hope to learn it soon by start watching your videos about Python soon!

1 Like

Thanks Selim, the specific example above is covered in detail in one of my latest videos;

1 Like

@GavinCrump dont develop BAD habbits :stuck_out_tongue_winking_eye:. If any other exception occurs you’ll never get to see it which makes it more difficult to debug, plus it just isn’t the proper use of try except (ambiguous code, unnecessary performance penalty etc etc). I’d avoid heterogeneous lists too; declare a dedicated list if you want to output a report:

report = []
viewports = []
for v,s,p in zip(views,sheets,points):
	unplacedView = Viewport.CanAddViewToSheet(doc, s.Id, v.Id)
	if not unplacedView:
		report.append("View already placed!") 
		continue
	
	vp = Viewport.Create(doc, s.Id, v.Id, p.ToXyz())
	viewports.append(vp)
3 Likes

Thanks Thomas, I like it - wasn’t familiar with the ‘continue’ statement, only ‘break’. Would you suggest still keeping the unsuccessful view/sheet pairs as a null though? This way it’s all kept parallel when a vp fails to be placed. If I’m interpreting the above correctly, the viewports list only grows when a viewport is placed successfully?

No problem mate, great to see you’ve jumped onto the programming bandwagon!

I suppose to answer your question in all depends on where its needed further down stream. My short answer would be no - if you are returning viewports (by way of successfully placed views) then that’s all that should be otherwise it creates downstream problems if the nulls are not handled. If data matching downstream is important then I can see where you are coming from, i.e. you essentially want the nulls to serve as placeholders so your indexing is consistent, but then you could always perform filtering to build your data structure when you need elsewhere in your script and keep what your code does very precise and more professional, even if it results in more nodes if you were to follow this approach.

And yeah, the vp list only gets appended if a view can be placed as the continue statement immediately returns the interpreter back to the next iteration of the for loop.

2 Likes

Thanks, enjoying the ride so far - get to put about a day towards it each week. I briefly delved into C# but doubled back to Python to keep exploring the API.

I’m thinking I’ll maintain the output order just in case, but feed out nulls where the report detects the issues so they can be masked over the views/sheets. I was speaking to Sean Page a while back via LinkedIn about these types of scenarios and we agreed typically retaining parallel data provides more possibilities, although sometimes it might confuse newer users who aren’t familiar with the IsNull / List.Clean nodes.

Appreciate the tips!

1 Like