Revit Transactions

Revit Transactions

As the class name suggests, a Transaction is used to make any change to a Revit model.

The using statement statement defines a scope at the end of which an object will be disposed. We can think of it as telling Revit to dispose the transaction after completion as a housekeeping measure and to allow the user to perform other actions in Revit thereafter.

The following code highlights the use of the Transaction Class.

public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
    UIApplication uiapp = commandData.Application;
    UIDocument uidoc = uiapp.ActiveUIDocument;
    Application app = uiapp.Application;
    Document doc = uidoc.Document;
            
    using (Transaction tx = new Transaction(doc))
    {
        tx.Start("New Transaction Name");
        //Do something to Revit model
        tx.Commit();
    }
    return Result.Succeeded;
}

Some things to take note about the Transaction class:

  1. Only one Transaction can be opened at a time
  2. Nesting of Transactions is not allowed
  3. Each transaction must have a name, which will be listed on the Undo menu in Revit once a transaction is successfully committed.

For more information about the Transaction Class, you can refer to the Autodesk Knowledge Network page on Transactions

Practically, you are going to have to do some changes to the Revit model. The following sample code creates a pipe in the Transaction “New Transaction Name”.

#region Namespaces
using System;
using System.Collections.Generic;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.UI;
using System.Linq;
#endregion
 
namespace AECTechy
{
    [Transaction(TransactionMode.Manual)]
    public class Command : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Application app = uiapp.Application;
            Document doc = uidoc.Document;
 
            using (Transaction tx = new Transaction(doc))
            {
                tx.Start("New Transaction Name");
 
                Pipe newPipe = CreatePipe(doc);
 
                tx.Commit();
            }
            return Result.Succeeded;
        }
        //Input Document
        //Function returns pipe created
        public Pipe CreatePipe(Document doc)
        {
            //System Type (DomesticHotWater, DomesticColdWater, Sanitary, etc)
            MEPSystemType mepSystemType = new FilteredElementCollector(doc)
                .OfClass(typeof(MEPSystemType))
                .Cast<MEPSystemType>()
                .FirstOrDefault(sysType => sysType.SystemClassification == MEPSystemClassification.DomesticColdWater);
 
            //Pipe Type (Standard, ChilledWater)
            PipeType pipeType = new FilteredElementCollector(doc)
                .OfClass(typeof(PipeType))
                .Cast<PipeType>()
                .FirstOrDefault();
 
            //Level
            Level level = new FilteredElementCollector(doc)
                .OfClass(typeof(Level))
                .Cast<Level>()
                .FirstOrDefault();
 
            Pipe newPipe = Pipe.Create(doc, mepSystemType.Id, pipeType.Id, level.Id, XYZ.Zero, new XYZ(0, 0, 50));
 
            return newPipe;
        }
    }
}

You can find the source code for the full implementation HERE! Happy coding!

Leave a Reply