Studio Matrx Monthly · Volume 1 · Issue 3 · August 2026
Amogh N P
 In loving memory of Amogh N P — Architect · Designer · Visionary 
Automating BIM TasksLesson 7.3
PSD for Architecture, Planning & Urban Design/Module 7 · Scripting Revit & Dynamo

Lesson 7.3 · Scripting Revit & Dynamo

Automating BIM Tasks

The drudgery scripting removes - renaming views and sheets, bulk parameters, tagging, and auditing for missing data

13 min Interactive lessonFree · open lessonByAmogh N P· Architect & interior designer
The hook

Renaming three hundred views by hand is an afternoon. As a script it is one loop, one transaction, and about four seconds - and it runs identically every time you issue.

Most of what makes BIM tedious is repetition with a rule. Rename every view to a convention. Stamp a fire rating onto a hundred walls. Tag every door on a plan. Find the rooms someone forgot to name. None of these need design judgement - they need the same small action applied faithfully, hundreds of times, without a slip.

That is exactly what the previous two lessons prepared you for. Every automation here is the same shape: collect the elements you mean, loop over them doing one thing each, and - when you are changing the model - do it inside a single transaction. This lesson walks four automations that pay for themselves the first week: renaming views and sheets, bulk-setting parameters, placing tags, and auditing for missing data. The code is short. The time it gives back is not.

Collect. Loop. Change (in a transaction) - or just read, for an audit. Four tasks, one pattern.

Renaming views and sheets to a convention

Naming conventions are the first casualty of a deadline, and fixing them by hand is soul-destroying. Scripting makes it reliable. A view's name is just a settable property, so renaming is a collect-and-loop with a string transformation in the middle. Suppose your team ended up with a pile of views prefixed Copy of and you want them gone:

python
count = 0
for v in views:                      # views collected earlier
    if v.Name.startswith("Copy of "):
        v.Name = v.Name.replace("Copy of ", "")
        count += 1
print(count, "views renamed")

Sheets work the same way, with two settable properties - SheetNumber and Name - so you can renumber a whole set to a prefix in one pass:

python
for s in sheets:
    s.SheetNumber = "A-" + s.SheetNumber

Both of these change the model, so remember the rule from the last lesson: they only run inside a transaction. In pyRevit you wrap the loop in with revit.Transaction("Rename views"):; in a Dynamo Python node you bracket it with TransactionManager.Instance.EnsureInTransaction(doc) and ...TransactionTaskDone(). Two honest cautions: names and sheet numbers must stay unique - Revit rejects a duplicate, so a blind prefix that collides will error, and you should skip or handle clashes. And test the string logic on a copy first; a replace with the wrong text can rename things you did not mean. Done carefully, though, a convention that took an intern an afternoon becomes a button that runs in seconds and never mistypes.

A subtlety worth flagging: not every view can or should be renamed the same way. A collector on views returns schedules, legends, sheets-as-views and templates alongside plans and elevations, so a blanket rename can touch things you did not intend. Filter to the view types you mean - by checking v.ViewType, or excluding templates with v.IsTemplate - before you loop. The same care applies to sheets, where placeholder and real sheets both appear. The habit is general and worth forming now - collect precisely, then rename - because most rename bugs are really selection bugs, fixed not in the string logic but in narrowing the set before the loop ever runs.

Setting parameters in bulk

The single most useful BIM automation is writing the same parameter value across many elements - a fire rating on a wall type's instances, a phase on a batch of elements, a project code onto every sheet. It is the collect-loop-change pattern in its purest form. Here it is in a Dynamo Python node, which forces two habits worth seeing: unwrap the elements coming from the graph, and manage the transaction through Dynamo's TransactionManager:

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

doc = DocumentManager.Instance.CurrentDBDocument
elements = UnwrapElement(IN[0])      # raw Revit elements
value = IN[1]                        # e.g. "2 hr"

TransactionManager.Instance.EnsureInTransaction(doc)
changed = 0
for el in elements:
    p = el.LookupParameter("Fire Rating")
    if p and not p.IsReadOnly:
        p.Set(value)
    changed += 1
TransactionManager.Instance.TransactionTaskDone()
OUT = changed

Three details make this robust. Guard for `None` - not every element has the parameter, and LookupParameter returns None when it is missing, which would crash the loop. Check `IsReadOnly` - some parameters are computed by Revit and cannot be set, so skip them rather than error. And `Set` expects the value in the parameter's type - a string for a text parameter, a number in internal units for a length, an integer 0 or 1 for a yes/no. Get those right and one node stamps a value across a thousand elements as easily as across ten - the leverage this whole course is about, aimed straight at BIM.

BULK SET: COLLECT -> LOOP -> SETcollectwallsunwrapraw APITRANSACTION: one bundle, one undofor eleach onep not Noneand writableguardp.Set(value)Guard for None and IsReadOnly, match the value type - then one loop stamps the whole set.
Zoom
Bulk-setting a parameter as a pipeline. Collect the elements, unwrap them for the API, then loop inside one transaction: for each element check the parameter exists and is writable, then Set the value. One transaction carries the whole batch, so a thousand edits cost the same as ten.

Placing and tagging elements

Automation is not only editing what exists - it can create. Tagging is the everyday example: dropping a tag on every door or room so a plan annotates itself. In the modern Revit API you create a door tag with IndependentTag.Create, which needs the document, the tag type, the view you are tagging in, a reference to the element, and a point. Conceptually the loop is: for each element, make a reference to it and place a tag near its location.

python
from Autodesk.Revit.DB import IndependentTag, Reference, TagMode, TagOrientation

# doors, tag_type_id, view, and t (a transaction) prepared earlier
for d in doors:
    ref = Reference(d)
    point = d.Location.Point            # the door's insertion point
    IndependentTag.Create(doc, tag_type_id, view.Id, ref,
                          False, TagOrientation.Horizontal, point)

The exact arguments shift a little between Revit versions - this is where you check the API docs for your release rather than trust an old snippet - but the shape holds: creation still happens inside a transaction, still one call per element in a loop, still driven by a collected set. Placing elements (a fixture at each grid intersection, a room-tag per room) follows the same rhythm. Two cautions: creation genuinely changes the model, so a mistake makes real objects you then have to delete - test on a copy and a small selection. And placement points matter; a tag created at the wrong point lands off the element. But once dialled in, self-annotating a plan of two hundred doors becomes a single click instead of an hour of careful clicking.

Creating elements is still collect-loop-change - just Create() instead of Set().

Auditing for missing data

The highest-value BIM script often changes nothing. A BIM model is only as trustworthy as its data, and the quiet failure is missing values: doors with no fire rating, rooms with no name, sheets with no discipline. Auditing is a read-only collect-and-loop that produces a list of problems - safe to run any time, no transaction needed, and perfect to run before every issue.

python
missing = []
for el in elements:
    p = el.LookupParameter("Fire Rating")
    if p is None or not p.AsString():        # absent or empty
        missing.append(el.Id.IntegerValue)

print(len(missing), "elements missing Fire Rating")
OUT = missing                                 # a list of ElementIds

The pattern generalises to any completeness check: swap the parameter name, and you audit for blank room names, unassigned phases, or untagged doors. Returning the ElementIds is deliberate - in Dynamo you can feed that list into a Select.ByElementId node to highlight the offenders directly in the model, turning an abstract count into a visible to-do list a designer can fix. This is where scripting quietly changes a practice: instead of discovering a hundred blank parameters at the coordination meeting, a fifteen-line audit run every Friday surfaces them while there is still time. It is unglamorous, it makes nothing, and it may be the most valuable script in your kit - because catching missing data early is worth far more than any single bulk edit.

AUDIT: READ-ONLY, NO TRANSACTIONeach elementread paramNone orempty?flag itmissing.append(Id)passdata is fineyesnoReturns a list of ElementIds. In Dynamo, wire it to Select.ByElementId to highlight the offenders in the model.
Zoom
A missing-data audit is a read-only loop. For each element, read the parameter; if it is absent or empty, record its ElementId in a problem list; otherwise pass. No transaction is needed because nothing changes. Feed the returned ids to Select.ByElementId and the offenders highlight in the model.

From a one-off script to a tool your team clicks

A script that only you can run, only when you remember how, delivers a fraction of its potential value. The leap that changes a practice is turning a working script into a tool - something a colleague clicks without knowing or caring that Python is underneath. Both hosts in this module support that leap, in different ways.

In Dynamo, a graph you save is already shareable: anyone with the file can open and run it. Better, Dynamo Player lets a user run a saved graph from a simple list, exposing only its inputs - pick a value, click play - with no canvas to understand. A missing-data audit or a batch-rename graph, dropped into a shared folder and run through Player, becomes a self-serve utility for the whole team. In pyRevit, the payoff is even more seamless: a .py script placed in the right folder appears as a button on a Revit ribbon tab, indistinguishable from any built-in command. Your audit becomes a button labelled "Check Marks" that a project architect clicks like any other tool.

Making a script tool-worthy asks a little more of it than a one-off does. Handle the empty and the awkward cases: what should the tool do if nothing is selected, or if a parameter is missing on every element? A one-off can crash and you shrug; a shared tool should report a clear message instead. Give feedback: print or show how many elements were changed, so the user trusts that something happened. Name the transaction descriptively, because the undo entry your colleague sees should read "Renumber sheets", not "transaction1". And guard the destructive paths - a tool that creates or deletes should confirm first, since the person clicking may never read the code.

There is judgement in when to make this leap, and it echoes this lesson's misconception. A script you will run once is not worth polishing into a tool; a check you run before every issue, or a rename your whole team needs, absolutely is. The cost is modest - a bit of error handling and a clear message - and the return compounds: every colleague who uses the tool multiplies the time your original hour of scripting gives back. This is how scripting stops being a personal trick and becomes practice infrastructure, and it is the natural destination of everything in this module - the collect-loop-change pattern, wrapped in a button, run by people who never see the code.

A saved graph, a Dynamo Player entry, or a pyRevit button turns your script into a tool the whole team clicks.

Tools & terms you'll meet in this lesson

collect-loop-change

The shape of nearly every BIM automation

Gather elements with a collector, loop over them doing one action each, and wrap any change in a single transaction.

IsReadOnly

A parameter flag you check before Set

Some parameters are computed by Revit and cannot be written; check IsReadOnly (and None) so a bulk-set skips them instead of crashing.

IndependentTag.Create

The API call that places a tag on an element

Needs the document, tag type, view, a Reference and a point; arguments shift a little between Revit versions, so check the docs for yours.

ElementId.IntegerValue

The numeric id of an element as a plain integer

Collect these in an audit; feed them to Select.ByElementId in Dynamo to highlight the offending elements in the model.

Hands-on workshop

Workshop - a missing-data audit

Build the most valuable script in the set: a read-only audit that finds elements with a blank parameter. It changes nothing, so it is safe on any model, and it teaches the whole collect-loop pattern.

Revit with Dynamo or pyRevit, and a model with a handful of doors - deliberately leave a few Marks blank so the audit has something to find.

Given & goal
Goal: list every door with a missing Mark, and highlight them
Inputs: a Revit model with some doors, run in Dynamo or pyRevit
Time: ~35 minutes
  1. 1Collect all placed doors with a FilteredElementCollector on OST_Doors plus WhereElementIsNotElementType, as in the previous lesson.
  2. 2Loop the doors. For each, read Mark with LookupParameter and test whether it is None or an empty string; if so, append el.Id.IntegerValue to a missing list.
  3. 3Print the count and return the missing list. Confirm you wrote NO transaction - an audit only reads.
  4. 4In Dynamo, wire the returned ids into a Select.ByElementId node so the offending doors highlight in an open view; in pyRevit, print the ids or select them. Now the audit is actionable.
  5. 5Generalise: change the parameter name to Comments or Fire Rating and re-run. One script, many completeness checks - the reusable payoff.

You’ll walk away with
A read-only audit script that returns the ElementIds of every door missing a chosen parameter and highlights them in the model, generalisable to any parameter by changing one name.

The worked example

Three altitudes on the same idea

Read the band that fits you — or all three.

For the architectAutomate busywork & build custom tools

These four automations map straight onto your issue workflow. Rename and renumber a drawing set to the office convention in one pass; stamp phase or fire-rating data across a category; auto-tag a plan; and - most valuable - run a missing-data audit before every submission so nothing ships with blank parameters. Each is a graph or pyRevit button your whole team reuses, turning quality control from a hopeful manual check into a repeatable step.

For the interior designerScripts for data, schedules & layouts

Your model is full of families with codes, finishes and specs that must be complete and consistent. Bulk-set a product code across a fixture type, tag every piece of FF&E on a layout, and audit that no finish or material parameter is blank before a schedule goes out. The tedious consistency work that used to eat an evening becomes a script - and the audit means your finish schedules are trustworthy, not hopeful.

For the studentA hireable computational skill

A portfolio that shows a working audit script speaks louder than a list of software on a CV. Build the missing-data checker on a practice model and you have demonstrated the entire collect-loop-change pattern plus real BIM judgement about data quality. These are exactly the automations junior BIM and computational roles are hired to write, and each one is short enough to understand fully and explain in an interview.

Misconception check

If a task is repetitive, it is automatically worth scripting - automate everything you can.

Scripting is leverage, and leverage only pays when the task recurs or the batch is large. Automating a rename you will do once, on ten views, can cost more time to write, test and debug than the ten manual renames would - and a script you run once and never again rarely earns back the effort. The honest test is frequency times size: a rule you apply to hundreds of elements, or a check you run before every issue, is a clear win; a one-off tweak to a handful of items is often faster by hand. There is also a risk cost - a buggy bulk edit can damage a model at scale - so reserve automation for the repetitive, the large, and the recurring, and let small one-offs stay manual. Knowing what NOT to automate is part of the skill.
Try it

Do it yourself

Reason about the pattern.

  1. 1What three phases make up nearly every BIM automation in this lesson?
  2. 2Why does a bulk parameter-set guard against both None and IsReadOnly?
  3. 3Which of the four automations needs no transaction, and why?
  4. 4Renaming sheets can fail even when the code is correct - what model rule causes that?
  5. 5Give an example of a repetitive task that is NOT worth scripting, and say why.
Take this with you

The one line to carry out

Renaming, bulk-setting, tagging and auditing are one pattern wearing four hats: collect the elements, loop doing one thing each, and change inside a transaction (or, for an audit, do not change at all). Master the pattern and any BIM chore with a rule becomes a script.
Take it further
References & further reading

Peer-reviewed journals & authoritative standards

  1. 01Autodesk RevitWikipedia, 2026.
  2. 02Building information modelingWikipedia, 2026.
  3. 03For loopWikipedia, 2026.
  4. 04Dynamo (software)Wikipedia, 2026.
Related lessons
Recap
The core BIM automations all share the collect-loop-change shape. Renaming views and sheets sets a property in a loop inside a transaction, minding uniqueness. Bulk parameter-setting loops and calls Set, guarding for None and IsReadOnly and matching the parameter type. Tagging creates elements with IndependentTag.Create, still one call per element in a transaction. And auditing is a read-only loop that returns ElementIds of elements with missing data - often the most valuable script of all, run before every issue.
Carry forward →

Auditing gave us a list; bulk-setting pushed values in. The natural next step is to move model data out to a spreadsheet, edit it there, and push it back - a full round-trip that connects Revit to the data skills from Module 4.

A

The author

Amogh N P

Architect, interior designer, and creative polymath. Studio Matrx began in his notebooks — his vision of design made honest, useful, and open to everyone. Its Academy is written and taught in his memory, and free, forever.

More about Amogh →