Convert Revit Macro to Revit API

Convert Revit Macro to Revit API

desdinova
Advocate Advocate
2,382 Views
5 Replies
Message 1 of 6

Convert Revit Macro to Revit API

desdinova
Advocate
Advocate

I am trying to convert this macro to revit api but i get "Expected class, delegate, enum, interface, or struct" error.
How can i solve this problem?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;

namespace Walls
{
public class WallPickFilter : ISelectionFilter
{
public bool AllowElement(Element e)
{
return (e.Category.Id.IntegerValue.Equals(
(int)BuiltInCategory.OST_Walls));
}

public bool AllowReference(Reference r, XYZ p)
{
return false;
}
}

public void WallJoinsMiterByPick()
{
UIDocument uidoc = this.ActiveUIDocument;
Document doc = uidoc.Document;
ISelectionFilter wallfilter=new WallPickFilter();
IList<Reference> refList = new List<Reference>();
try
{
// create a loop to repeatedly prompt the user to select a wall
while (true)
refList.Add(uidoc.Selection.PickObject(ObjectType. Element,wallfilter,
"Select elements in order to change join type to miter. ESC when finished."));
}
// When the user hits ESC Revit will throw an OperationCanceledException which will get them out of the while loop
catch
{ }
using(Transaction t = new Transaction(doc, "Wall joins to Miter"))
{
t.Start();
foreach (Reference r in refList)
{
Element wall1= doc.GetElement(r);
LocationCurve wCurve = wall1.Location as LocationCurve;
wCurve.set_JoinType(0,JoinType.Miter);
wCurve.set_JoinType(1,JoinType.Miter);
}
doc.Regenerate();
t.Commit();
}
}
}

0 Likes
Accepted solutions (2)
2,383 Views
5 Replies
Replies (5)
Message 2 of 6

jeremytammik
Autodesk
Autodesk

Dear Desdinova,

 

I would suggest that you work through the standard Revit API getting started material first to understand the architecture and installation of a normal Revit add-in, how it is installed and loaded by Revit on startup:

 

http://thebuildingcoder.typepad.com/blog/about-the-author.html#2

 

The easiest way to do that is to work throught the My First Revit plugin and DevTV tutorials provided in the Revit Developer Centre:

 

http://www.autodesk.com/developrevit

 

Then all will become clear and easy.

 

Good luck and have fun!

 

Best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 3 of 6

Anonymous
Not applicable
Accepted solution

Hello desdinova,

 

if I understand you correctly, you want to convert your macro into an external command. You need to implement an interface called IExternalCommand, and call an Execute method. Something like this :

namespace Walls
{
[Transaction(TransactionMode.Manual)] [RegenerationAttribute(RegenerationOption.Manual)] public class Command: IExternalCommand { UIDocument uidoc
Document _doc;
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication rvtUIApp = commandData.Application; uiDoc = rvtUIApp.ActiveUIDocument; doc = uiDoc.Document; WallJoinsMiterByPick()
return Result.Succeeded; }
}

 

And remove this part from your WallJoinMiterByPick()-method.

 

UIDocument uidoc = this.ActiveUIDocument;
Document doc = uidoc.Document;

 

But like Jeremy said, check out My first Revit plugin and all labs that are available, then this will be much easier. No prior programming experince needed 🙂

Good luck!

 

/Martin

 

Message 4 of 6

desdinova
Advocate
Advocate

Thank you for your answers

What is wrong in this code 

i get 

 

Walls_Miter.Command.Execute(Autodesk.Revit.UI.ExternalCommandData, ref string, Autodesk.Revit.DB.ElementSet)': not all code paths return a value
Since 'Walls_Miter.Command.WallJoinsMiterByPick()' returns void, a return keyword must not be followed by an object expression

 

error

 

namespace Walls_Miter
{
[Transaction(TransactionMode.Manual)]
public class Command : IExternalCommand
{
UIDocument uidoc;
Document doc;
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
UIApplication rvtUIApp = commandData.Application;
uidoc = rvtUIApp.ActiveUIDocument;
doc = uidoc.Document;
}
public class WallPickFilter : ISelectionFilter
{
public bool AllowElement(Element e)
{
return (e.Category.Id.IntegerValue.Equals(
(int)BuiltInCategory.OST_Walls));
}
public bool AllowReference(Reference r, XYZ p)
{
return false;
}
}
public void WallJoinsMiterByPick()
{

ISelectionFilter wallfilter=new WallPickFilter();
IList<Reference> refList = new List<Reference>();
try
{
// create a loop to repeatedly prompt the user to select a wall
while (true)
refList.Add(uidoc.Selection.PickObject(ObjectType.Element,wallfilter,
"Select elements in order to change join type to miter. ESC when finished."));
}
// When the user hits ESC Revit will throw an OperationCanceledException which will get them out of the while loop
catch
{
}
using(Transaction t = new Transaction(doc, "Wall joins to Miter"))
{
t.Start();
foreach (Reference r in refList)
{
Element wall1= doc.GetElement(r);
LocationCurve wCurve = wall1.Location as LocationCurve;
wCurve.set_JoinType(0,JoinType.Miter);
wCurve.set_JoinType(1,JoinType.Miter);
}
doc.Regenerate();
t.Commit();
}

return Result.Succeeded;
}
}
}

0 Likes
Message 5 of 6

Anonymous
Not applicable
Accepted solution

your execute method isn't returning a result:

Move this into the execute method.

return Result.Succeeded;

 

But right now it's not doing anything, you also have to call WallJoinsMiterByPick() inside the execute method.

 

.......ActiveUIDocument;

doc = uidoc.Document;

 

WallJoinsMiterByPick();

 

return Result.Succeeded;

}

......

 

And when posting code please use the insert code button to make the code more readable.

 

good luck

Message 6 of 6

desdinova
Advocate
Advocate
Dear Maer6427,
Thanks for reply
It worked...
0 Likes