I want to choice a beam, and get the FamilySymbol.
use that FamilySymbol to creat a new beam,
but my code always return FamilySymbol is null,
so i try to test
using System; using System.Windows.Forms; using Autodesk.Revit.UI; using Autodesk.Revit.DB; using System.Collections.Generic; using Autodesk.Revit.UI.Selection; using Autodesk.Revit.DB.Structure; namespace Training { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] internal class CreatBeam : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIDocument uidoc = commandData.Application.ActiveUIDocument; Document doc = uidoc.Document; Reference pickBeam = uidoc.Selection.PickObject(ObjectType.Element, "Selection beam"); ElementId beamid = pickBeam.ElementId; FamilySymbol beamSymbol = doc.GetElement(beamid) as FamilySymbol; if (beamSymbol != null) { MessageBox.Show(beamSymbol.FamilyName); } else { MessageBox.Show("null"); } /* Level beamlevel = doc.GetElement(new ElementId(6095635)) as Level; using (Transaction trans = new Transaction(doc)) { trans.Start("creat beam"); //creat beam FamilyInstance familyInstance = doc.Create.NewFamilyInstance(Arc.Create(XYZ.Zero, 10, 0, 2.5, new XYZ(1, 0, 0), new XYZ(0, 1, 0)), beamSymbol, beamlevel, StructuralType.Beam); trans.Commit(); } */ return Result.Succeeded; } } }
Why is it so? Is it less some code?
thank you for answer this question.
Solved! Go to Solution.
Maybe this will help. It helps me to include something in the variable names that aids in keeping track of what the object are as I go through the code chain involved when using PickObject to finally arrive at the desired item. This is especially helpful when dealing with Revit families.
.PickObject returns a Reference. Change your code to
"Reference pickBeamRef = uidoc.Selection.PickObject(..."
The next task is to get the Element this pickBeamRef refers to. Doing that involves .GetElement with an ElementId passed to it. Change your code to
"ElementId pickBeamRefId = pickBeamRef.ElementId"
You would then pass that "beamRefId" to .GetElement. Add to your code to
"Element pickBeamElem = doc.GetElement(pickBeamRefId)"
This step above is missing in your code. Note that you can combine these last two code changes into one line and still be able to follow the changes going on via the explicit names.
"Element pickBeamElem = doc.GetElement(pickBeamRef.ElementId)"
At this point "pickBeamElem" is the Element that corresponds to the item returned by PickObject. Even though it maybe a FamilyInstance, it needs to be framed (cast) as a FamilyInstance in order to look at it's FamilyInstance parts, like its "Symbol" or Family Type. Add to your code
"FamilyInstance pickBeamFi = pickBeamElem as FamilyInstance"
Now you have the FamilyInstance for this picked item. The FamilySymbol you are trying to get is returned by "pickBeamFi.Symbol". Change your FamilySymbol code line to
"FamilySymbol pickBeamFiFs = pickBeamFi.Symbol"
pickBeamFiFs is the "Family Type" for the "Family" object that was picked. Its name is probably "pickBeamFiFs.Name". The name of the "Family" that "Family Type" belongs to is probably "pickBeamFiFs.FamilyName". I don't know for sure. I just know to always double check documentation when dealing with Families and Family Symbols.
Conversation about this topic is always very confusing because the words used for what these items are on printed plans, the words used in the Revit user interface for these items, the words used in the Revit API for these items and the words used in common computer code terminology are the same but have totally different meanings.