Issue spheres creation with Revit macro

My current work place uses Dynamo to generate issue spheres to visualize clash location. However, it requires a lot of user’s effort, from installing Dynamo to the system, to opening Dynamo file, etc. In this respect, using Revit API or macro to generate the spheres makes more sense. Below is a macro code written in C# that reads .csv file generated from Navisworks and place sphere family in Revit.

Capture
Spheres generated from the macro and color filtered with the attirbutes

 

/*
* Created by SharpDevelop.
* User: ChungHo
* Date: 16.03.2016
* Time: 10:50
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/

using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.IO;
using System.Text;

namespace Test
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.DB.Macros.AddInId(“B3D4E66D-7664-4199-BA14-AD9E63904275″)]
public partial class ThisApplication
{
FamilySymbol symbol1;

private void Module_Startup(object sender, EventArgs e)
{

}
private void Module_Shutdown(object sender, EventArgs e)
{

}

#region Revit Macros generated code
private void InternalStartup()
{
this.Startup += new System.EventHandler(Module_Startup);
this.Shutdown += new System.EventHandler(Module_Shutdown);
}
#endregion

//to ignore the warning message when the spheres are placed.
public class WarningSwallower : IFailuresPreprocessor
{
public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
{
IList<FailureMessageAccessor> failList = new List<FailureMessageAccessor>(); // Inside event handler, get all warnings
failList = failuresAccessor.GetFailureMessages();
foreach (FailureMessageAccessor failure in failList)
{
FailureDefinitionId failID = failure.GetFailureDefinitionId();  // check FailureDefinitionIds against ones that you want to dismiss
if (failID == BuiltInFailures.OverlapFailures.DuplicateInstances) // prevent Revit from showing Unenclosed room warnings
{
failuresAccessor.DeleteWarning(failure);
}
}
return FailureProcessingResult.Continue;
}
}

public void test()
{
Document doc = this.ActiveUIDocument.Document;

var reader = new StreamReader(File.OpenRead(@”C:\Users\ChungHo\Desktop\test4.csv”));
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(‘;’);

if (values.Length > 1)
{
double X = Double.Parse(values[7]);
double Y = Double.Parse(values[8]);
double Z = Double.Parse(values[9]);
XYZ origin = new XYZ(X,Y,Z);

using(Transaction t = new Transaction(doc))
{
if (t.Start(“Create issue spheres”) == TransactionStatus.Started)
{
string FamilyName = “sphere_active”;

FilteredElementCollector a = new FilteredElementCollector(doc).OfClass(typeof(Family));
Family family = a.FirstOrDefault<Element>(e => e.Name.Equals(FamilyName)) as Family;
ISet<ElementId> symbolIds = family.GetFamilySymbolIds();

FailureHandlingOptions failOpt = t.GetFailureHandlingOptions();
failOpt.SetFailuresPreprocessor(new WarningSwallower());
t.SetFailureHandlingOptions(failOpt);

foreach( ElementId id in symbolIds )
{
symbol1 = doc.GetElement( id ) as FamilySymbol;
break;
}

FamilyInstance familyInstance = doc.Create.NewFamilyInstance(origin, symbol1, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);

foreach (Parameter parameter in familyInstance.Parameters)
{
if (parameter.Definition.Name == “Smartsheet ID”){parameter.Set(values[0]);}
if (parameter.Definition.Name == “Clash”){parameter.Set(values[1]);}
if (parameter.Definition.Name == “Status”){parameter.Set(values[2]);}
if (parameter.Definition.Name == “Date”){parameter.Set(values[5]);}
if (parameter.Definition.Name == “Assigned to”){parameter.Set(values[6]);}
if (parameter.Definition.Name == “System1”){parameter.Set(values[11]);}
if (parameter.Definition.Name == “System2”){parameter.Set(values[12]);}
if (parameter.Definition.Name == “Comment”){parameter.Set(values[13]);}
}

t.Commit();
}
}
}

else{continue;}
}
}
}
}

Launching Revit from Excel with Journal file

So after few attempts to use journal file for automation, I was able to launch Revit from Excel, and added some worksets automatically and saved it into designated folder location. Here are some screenshots:

 

And the VBA code:

Option Explicit

Sub Project_Setter()

    Dim sSource(10) As String
    Dim rCrtCell As Range
    Dim i As Integer
    
    For i = 0 To UBound(sSource, 1)
        sSource(i) = "null"
    Next
    
    
    sSource(0) = ActiveWorkbook.Sheets("Project_Setter").Range("A2").Value
    Set rCrtCell = ActiveWorkbook.Sheets("Project_Setter").Range("A5")
    
    If (Len(rCrtCell.Value) > 0) Then
        
        createNewDirectory (Worksheets("Project_Setter").Range("A2").Value)
        sSource(1) = rCrtCell.Value
        Call moveCell(sSource(), rCrtCell)
    End If

End Sub

Sub moveCell(sSource() As String, rCrtCell As Range)
    Dim rng As Range
    Dim sWorksets As String
    sSource(rCrtCell.Column) = rCrtCell.Value
    
    'check if it is folder, revit file, or workset
    If (Len(rCrtCell.Value) > 0) Then
        If (rCrtCell.Font.Bold = True And rCrtCell.Font.Italic = False) Then
            Call makeFolder(sSource(), rCrtCell)
        ElseIf (rCrtCell.Font.Bold = False And rCrtCell.Font.Italic = False) Then
            sSource(rCrtCell.Column) = "null"
            If (Len(ActiveSheet.Cells(rCrtCell.Row, rCrtCell.Column + 1) > 0) And ActiveSheet.Cells(rCrtCell.Row, rCrtCell.Column + 1).Font.Italic = True) Then
                sWorksets = ActiveSheet.Cells(rCrtCell.Row, rCrtCell.Column + 1).Value
            End If
            Call makeRevit(sSource(), rCrtCell, sWorksets)
        ElseIf (rCrtCell.Font.Bold = False And rCrtCell.Font.Italic = True) Then
        
        ElseIf (rCrtCell.Font.Bold = True And rCrtCell.Font.Italic = True) Then
            MsgBox "Specify """"" & rCrtCell.Value & """"" if it is a folder or a workset"
        End If
    End If
    
    'determine next cell movement
    Dim nextMovement As Integer
    nextMovement = valueChecker(rCrtCell)
   
    If (nextMovement = 0) Then
        sSource(rCrtCell.Column) = "null"
        Call moveCell(sSource(), ActiveSheet.Cells(rCrtCell.Row, rCrtCell.Column - 1))
    ElseIf (nextMovement = 1) Then
        sSource(rCrtCell.Column) = "null"
        Call moveCell(sSource(), ActiveSheet.Cells(rCrtCell.Row + 1, rCrtCell.Column - 1))
    ElseIf (nextMovement = 2) Then
        Call moveCell(sSource(), ActiveSheet.Cells(rCrtCell.Row + 1, rCrtCell.Column))
    ElseIf (nextMovement = 3) Then
        Call moveCell(sSource(), ActiveSheet.Cells(rCrtCell.Row + 1, rCrtCell.Column + 1))
    Else
        MsgBox "Done!"
        Exit Sub
    End If

End Sub

Function valueChecker(rCrtCell As Range) As Integer
    Dim cCol, cRow As Integer
    cCol = rCrtCell.Column
    cRow = rCrtCell.Row
    
    If (cCol = 1) Then
        If (Len(ActiveSheet.Cells(cRow, cCol).Value) = 0) Then
            valueChecker = 4
        ElseIf (Len(ActiveSheet.Cells(cRow + 1, cCol).Value) > 0) Then
            valueChecker = 2
        ElseIf (Len(ActiveSheet.Cells(cRow + 1, cCol + 1).Value) > 0) Then
            valueChecker = 3
        End If
    ElseIf (cCol > 1) Then
        If (Len(ActiveSheet.Cells(cRow, cCol - 1).Value) > 0) Then
            valueChecker = 0
        ElseIf (Len(ActiveSheet.Cells(cRow + 1, cCol - 1).Value) > 0) Then
            valueChecker = 1
        ElseIf (Len(ActiveSheet.Cells(cRow + 1, cCol).Value) > 0) Then
            valueChecker = 2
        ElseIf (Len(ActiveSheet.Cells(cRow + 1, cCol + 1).Value) > 0) Then
            valueChecker = 3
        End If
    End If
    
End Function

Function makeFolder(sSource() As String, rCrtCell As Range)
    
    Dim sPath As String
    Dim i As Integer
    sPath = sSource(0)
    
    For i = 1 To rCrtCell.Column
            sPath = sPath & "\" & sSource(i)
            createNewDirectory (sPath)
    Next
    
    
    
End Function
Function makeRevit(sSource() As String, rCrtCell As Range, sWorksets As String)
    
    Dim worksetCollection As New Collection
    Dim sFileName, sPath, sFullPath, strProgramName, strArgument, sJrn1, sJrn2 As String
    Dim rng, c As Range
    Dim i, j, k As Integer
    Dim sWorksetArray, s As Variant
    

    
    
    'set saving path
    sFileName = rCrtCell.Value
    sPath = sSource(0)
    strProgramName = "C:\Program Files\Autodesk\Revit 2015\Revit.exe"
    strArgument = sPath & "\tempJrn.txt"
    
    For i = 1 To (rCrtCell.Column - 1)
        sPath = sPath & "\" & sSource(i)
    Next
    
    sFullPath = sPath & "\" & sFileName & ".rvt"
    
    'crate journal file
    k = 1
    Set rng = Worksheets("Make_Revit").Range("A1:A12")
    Open strArgument For Output As #1
        For Each c In rng 'add workset code between row 10 and 11
            If (k = 12) Then
                If (Len(sWorksets) > 0) Then
                    sWorksetArray = Split(sWorksets, ",")
                
                    j = 0
                
                    For Each s In sWorksetArray
                        worksetCollection.Add s
                        j = j + 1
                    Next
                    
                    Print #1, Worksheets("Make_Workset").Range("A1").Value
                    Print #1, Worksheets("Make_Workset").Range("A2").Value
                    Print #1, "Jrn.Edit" & " " & """" & "Modal" & " " & "," & " " & "Worksharing" & " " & "," & " " & "Dialog_Revit_PartitionsEnable" & """" & " " & "," & " " & """" & "Control_Revit_PartitionsEnableOthersEdit" & """" & "," & " " & """" & "ReplaceContents" & """" & "," & " " & """" & sWorksetArray(0) & """"
                    Print #1, Worksheets("Make_Workset").Range("A4").Value
                    Print #1, Worksheets("Make_Workset").Range("A5").Value 'Transaction Successful
                    
                    If (j > 1) Then
                        Dim h As Integer
                        For h = 1 To j - 1
                            Print #1, Worksheets("Make_Workset").Range("A6").Value
                            Print #1, "Jrn.Edit" & " " & """" & "Modal" & " " & "," & " " & "New Workset" & " " & "," & " " & "Dialog_Revit_NewPartition" & """" & "," & " " & """" & "Control_Revit_NewPartitionName" & """" & "," & " " & """" & "ReplaceContents" & """" & " " & "," & " " & """" & sWorksetArray(h) & """"
                            Print #1, Worksheets("Make_Workset").Range("A8").Value
                        Next
                        Print #1, "Jrn.ComboBox" & " " & """" & "Modal" & " " & "," & " " & "Worksets" & " " & "," & " " & "Dialog_Revit_Partitions" & """" & " " & "," & " " & """" & "Control_Revit_ActivePartitionCombo" & """" & "," & " " & """" & "SelEndOk" & """" & "," & " " & """" & sWorksetArray(j - 1) & """"
                        Print #1, "Jrn.ComboBox" & " " & """" & "Modal" & " " & "," & " " & "Worksets" & " " & "," & " " & "Dialog_Revit_Partitions" & """" & " " & "," & " " & """" & "Control_Revit_ActivePartitionCombo" & """" & "," & " " & """" & "Select" & """" & "," & " " & """" & sWorksetArray(j - 1) & """"
                        Print #1, Worksheets("Make_Workset").Range("A9").Value 'Jrn.PushButton "Modal , Worksets , Dialog_Revit_Partitions", "OK, IDOK"
                        Print #1, Worksheets("Make_Workset").Range("A10").Value 'Transaction Successful
                    ElseIf (j = 1) Then
                        Print #1, Worksheets("Make_Workset").Range("A9").Value 'Jrn.PushButton "Modal , Worksets , Dialog_Revit_Partitions", "OK, IDOK"
                    End If
                    
                    
                End If
            End If
        
            Print #1, c.Value
            k = k + 1
        Next
        
        sJrn1 = "Jrn.Data" & " " & """" & "File" & " " & "Name" & """" & "," & " " & """" & "IDOK" & """" & "," & " " & """" & sFullPath & """"
        sJrn2 = "Jrn.Command" & " " & """" & "SystemMenu" & """" & " " & "," & " " & """" & "Quit the application; prompts to save projects" & " " & "," & " " & "ID_APP_EXIT" & """"
            
        Print #1, sJrn1
        Print #1, sJrn2
    Close
    
    If (ShellAndWait("""" & strProgramName & """" & " " & strArgument, 1000000, vbNormalFocus, PromptUser) = 1) Then
        Call DeleteFile(strArgument)
    End If

    
    'Call Shell("""" & strProgramName & """" & " " & strArgument, vbNormalFocus)
    

End Function



Public Sub createNewDirectory(directoryName As String)
    
    If Not DirExists(directoryName) Then
        MkDir (directoryName)
    End If
    
End Sub
 
Function DirExists(DirName As String) As Boolean
    
    On Error GoTo ErrorHandler
    DirExists = GetAttr(DirName) And vbDirectory
ErrorHandler:

End Function

Sub DeleteFile(ByVal FileToDelete As String)
   If FileExists(FileToDelete) Then 'See above
      SetAttr FileToDelete, vbNormal
      Kill FileToDelete
   End If
End Sub

Function FileExists(ByVal FileToTest As String) As Boolean
   FileExists = (Dir(FileToTest) <> "")
End Function

Revit Journal Scripting

I’ve tried making new file from revit and adding worksets in it using journal file. Here’s an example code I’ve used. I will later use this journal file with Excel VBA to create folder structures and Revit files automatically.

‘ 0:< Initial VM: Avail 8388359 MB, Used 21 MB, Peak 45; RAM: Avail 11334 MB, Used 48 MB, Peak 45

Dim Jrn
Set Jrn = CrsJournalScript

Jrn.Command “Internal” , “Create a new project , ID_FILE_NEW_CHOOSE_TEMPLATE”

Jrn.ComboBox “Modal , New Project , Dialog_Revit_NewProject” _
, “Control_Revit_TemplateCombo” _
, “SelEndOk” , “<None>”

Jrn.ComboBox “Modal , New Project , Dialog_Revit_NewProject” _
, “Control_Revit_TemplateCombo” _
, “Select” , “<None>”

Jrn.PushButton “Modal , New Project , Dialog_Revit_NewProject” _
, “OK, IDOK”

Jrn.Directive “DocSymbol” _
, “[Project1]”

Jrn.Data “TaskDialogResult” _
, “Which system of measurement do you want to use in your project?”, _
“Metric”, “1002”

Jrn.Data “Transaction Successful”, “Create Type Previews”
Jrn.Directive “AllowPressAndDrag”, 0
‘workset setup
Jrn.RibbonEvent “TabActivated:Collaborate”
Jrn.Command “Internal” , “Workset control , ID_SETTINGS_PARTITIONS”
Jrn.Edit “Modal , Worksharing , Dialog_Revit_PartitionsEnable”, “Control_Revit_PartitionsEnableOthersEdit”, “ReplaceContents”, “Test1”
Jrn.PushButton “Modal , Worksharing , Dialog_Revit_PartitionsEnable”, “OK, IDOK”
Jrn.Data “Transaction Successful”, “Worksets”

Jrn.PushButton “Modal , Worksets , Dialog_Revit_Partitions”, “New, Control_Revit_New”
Jrn.Edit “Modal , New Workset , Dialog_Revit_NewPartition”, “Control_Revit_NewPartitionName”, “ReplaceContents” , “Test2”
Jrn.PushButton “Modal , New Workset , Dialog_Revit_NewPartition”, “OK, IDOK”

Jrn.PushButton “Modal , Worksets , Dialog_Revit_Partitions”, “New, Control_Revit_New”
Jrn.Edit “Modal , New Workset , Dialog_Revit_NewPartition”, “Control_Revit_NewPartitionName”, “ReplaceContents” , “Test3”
Jrn.PushButton “Modal , New Workset , Dialog_Revit_NewPartition”, “OK, IDOK”

Jrn.PushButton “Modal , Worksets , Dialog_Revit_Partitions”, “New, Control_Revit_New”
Jrn.Edit “Modal , New Workset , Dialog_Revit_NewPartition”, “Control_Revit_NewPartitionName”, “ReplaceContents” , “Test4”
Jrn.PushButton “Modal , New Workset , Dialog_Revit_NewPartition”, “OK, IDOK”

‘closing workset window
Jrn.PushButton “Modal , Worksets , Dialog_Revit_Partitions”, “OK, IDOK”
Jrn.Data “Transaction Successful”, “Worksets”
‘save
Jrn.Command “Internal” , “Save the active project , ID_REVIT_FILE_SAVE”
Jrn.Data “File Name”, “IDOK”, “C:\1\hi.rvt”

Jrn.Command “SystemMenu” , “Quit the application; prompts to save projects , ID_APP_EXIT”

Exploring scripting capability in Revit: Using journal file and batch script

I am currently exploring and teaching myself the Revit Journal script and the Batch script.

After spending somewhat 3 hours digging in, I was able to clean out the journal file and made sample code below for opening Revit file from journal script(.txt format) and changing color visualization of structural column.

One thing not sure: without the first line of the script, which is commented out with ‘ symbol, the revit wouldn’t open the designated .rvt file. I don’t know why this happens yet.

‘ 0:< Initial VM: Avail 8388359 MB, Used 21 MB, Peak 45; RAM: Avail 11334 MB, Used 48 MB, Peak 45

Dim Jrn
Set Jrn = CrsJournalScript

Jrn.Command “Internal” , “Open an existing project , ID_REVIT_FILE_OPEN”
Jrn.Data “File Name”, “IDOK”, “C:\1\rac_advanced_sample_project.rvt”

Jrn.Command “KeyboardShortcut” , “Control visibility and appearance of objects (applied only in the active view) , ID_VIEW_CATEGORY_VISIBILITY”

Jrn.TreeCtrl “0” , “IDC_TREE”,”ChangeSelection” , “>>Structural Columns>>”
Jrn.TreeCtrl “0” , “IDC_TREE”,”ChangeSelection” , “>>Structural Columns>>”
Jrn.Grid “ChildControl; Page , Model Categories , Dialog_Revit_ViewVisGraphicsModel; ID_TREEGRID_GRID”, “MoveCurrentCell” , “1” , “Projection Line Style”
Jrn.Grid “ChildControl; Page , Model Categories , Dialog_Revit_ViewVisGraphicsModel; ID_TREEGRID_GRID”, “Button” , “1” , “Projection Line Style”
Jrn.PushButton “Modal , Line Graphics , Dialog_Revit_OverrideLineStyle”, “Control_Revit_PenColor”
Jrn.Data “ColorDialog” , “IDOK”, “255, 0, 255”
Jrn.ComboBox “Modal , Line Graphics , Dialog_Revit_OverrideLineStyle”, “Control_Revit_PenNumber”, “SelEndOk” , “3”

Jrn.ComboBox “Modal , Line Graphics , Dialog_Revit_OverrideLineStyle”, “Control_Revit_PenNumber”, “Select” , “3”
Jrn.PushButton “Modal , Line Graphics , Dialog_Revit_OverrideLineStyle”, “OK, IDOK”
Jrn.Grid “ChildControl; Page , Model Categories , Dialog_Revit_ViewVisGraphicsModel; ID_TREEGRID_GRID”, “MoveCurrentCell” , “1” , “Projection Fill”
Jrn.Grid “ChildControl; Page , Model Categories , Dialog_Revit_ViewVisGraphicsModel; ID_TREEGRID_GRID”, “Button” , “1” , “Projection Fill”
Jrn.PushButton “Modal , Fill Pattern Graphics , Dialog_Revit_OverrideFill”, “Control_Revit_FillColor”
Jrn.Data “ColorDialog”, “IDOK”, “255, 0, 0”
Jrn.ComboBox “Modal , Fill Pattern Graphics , Dialog_Revit_OverrideFill”, “Control_Revit_FillPattern”, “SelEndOk” , “Solid fill”
Jrn.ComboBox “Modal , Fill Pattern Graphics , Dialog_Revit_OverrideFill”, “Control_Revit_FillPattern”, “Select” , “Solid fill”
Jrn.PushButton “Modal , Fill Pattern Graphics , Dialog_Revit_OverrideFill”, “OK, IDOK”
Jrn.PushButton “Modal , Visibility/Graphic Overrides for 3D View: {3D} , 0”, “Apply, ID_APPLY_NEW”
Jrn.Data “Transaction Successful”, “Visibility/Graphics”
Jrn.PushButton “Modal , Visibility/Graphic Overrides for 3D View: {3D} , 0”, “OK, IDOK”

‘Jrn.Command “SystemMenu” , “Quit the application; prompts to save projects , ID_APP_EXIT”