Is there a way to get the ViewSheet or ElementId of the ViewSheet from a View that is placed on that sheet? I can get the sheet name and sheet number from the provided parameters but do not see one for the actual ViewSheet. Am I missing something? The only thing i can think of to do without this info is to loop through all ViewSheets to match the one with the same sheet number (since sheet number is required to be unique). Thanks.
Dear Michael,
Thank you for your query.
Have you looked at the sample code provided in the description of the ViewSheet class?
http://www.revitapidocs.com/2017/af2ee879-173d-df3a-9793-8d5750a17b49.htm
ICollection<ElementId> views = viewSheet.GetAllPlacedViews(); message += "\nNumber of views in the sheet : " + views.Count;
If all else fails, you could use this relationship and invert it.
The View.Title property also generally consists of the view name plus other modifiers, such as the view type, sheet number, area scheme, and/or assembly type, depending on the specifics of the view:
http://www.revitapidocs.com/2017/bfa96650-310e-5385-3a9d-1a1248b623ce.htm
I hope this helps.
Best regards,
Jeremy
Hi Jeremy,
You must have misunderstood my question. I don't have the ViewSheet in order to use the method to get its placed views. I have a view, that I know is on a sheet (because its sheet number parameter is not null), but I want to get a direct reference to that sheet that it is placed on. It seems to me that you are still suggesting that I must loop through all ViewSheets to get the View that I'm concerned with. Thanks.
Dear Michael,
Thank you for your patience.
The new answer from respresso brought this issue to my attention again.
You say: It seems to me that you are still suggesting that I must loop through all ViewSheets to get the View that I'm concerned with.
Yes, indeed, that is exactly what I am suggesting.
Get all the view sheets, keep track of them and the views they host, and invert that relationship, as described in one of the very early discussions by The Building Coder back in 2008 on a relationship inverter:
http://thebuildingcoder.typepad.com/blog/2008/10/relationship-in.html
I hope this helps.
Best regards,
Jeremy
Hi,
Thank you Jeremy and respresso for bringing this topic to my attention.
I was not aware this question was raised a few years ago.
I maybe have a workaround for this question, something similar i assume.
Select some views in the Project Browser to know if the views are placed on sheet(s).
Then, run a macro or IExternalcommand to execute the command, something like inserted (macro)code as an example;
If view is placed on Sheet, then show the sheetnumber, sheetname or whatever data you interested in of the ViewSheet that is referenced to the selected views in the Project Browser.
Hope this is useful for you or point you to the right direction.
public void GetViewSheetFromView()
{
UIDocument uidoc = this.ActiveUIDocument;
Document doc = uidoc.Document;
string data = "";
ICollection<ElementId> selectedIds = uidoc.Selection.GetElementIds();
foreach (ElementId selectedid in selectedIds)
{
View e = doc.GetElement(selectedid) as View;
foreach (View v in new FilteredElementCollector(doc).OfClass(typeof(View)).Cast<View>().Where(q => q.Id.Equals(e.Id)))
{
string thisSheet = "";
foreach (ViewSheet vs in new FilteredElementCollector(doc).OfClass(typeof(ViewSheet)).Cast<ViewSheet>())
{
foreach (ElementId eid in vs.GetAllPlacedViews())
{
View ev = doc.GetElement(eid) as View;
if(ev.Id == v.Id)
{
thisSheet += vs.SheetNumber + " - " + vs.Name + Environment.NewLine ;
break;
}
}
}
if (thisSheet != "")
{
data += v.ViewType + ": " + v.Name + " " + Environment.NewLine + thisSheet.TrimEnd(' ',',') + Environment.NewLine;
}
else
{
data += v.ViewType + ": " + v.Name + " " + Environment.NewLine + thisSheet.TrimEnd(' ',',');
data += " NOT ON SHEET " + Environment.NewLine + "\n" ;
}
}
}
TaskDialog.Show("View Report", data);
}
As respresso suggests using the BIP for viewport sheet number with an ElementParameterFilter is probably the best approach. Sheet numbers are unique in each Revit model so it is safe to search by them and get the right result.
Public Function TObj43(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData, _ ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) As Result If commandData.Application.ActiveUIDocument Is Nothing Then Return Result.Cancelled Else Dim AcView As View = commandData.Application.ActiveUIDocument.ActiveGraphicalView Dim P_Ns As Parameter = AcView.Parameter(BuiltInParameter.VIEWPORT_SHEET_NUMBER) If P_Ns Is Nothing Then GoTo Monday End If Dim Txt As String = P_Ns.AsString If String.IsNullOrEmpty(Txt) Then GoTo Monday Else Dim SeFR As FilterRule = ParameterFilterRuleFactory.CreateEqualsRule(New ElementId(BuiltInParameter.SHEET_NUMBER), Txt, True) Dim PFilt As New ElementParameterFilter(SeFR, False) Dim FEC As New FilteredElementCollector(AcView.Document) Dim ECF As New ElementClassFilter(GetType(ViewSheet)) Dim LandF As New LogicalAndFilter(ECF, PFilt) Dim Els As List(Of Element) = FEC.WherePasses(LandF).ToElements If Els.Count <> 1 Then GoTo Monday Else Dim TD As New TaskDialog("Was this your sheet...") TD.MainInstruction = Txt & "-" & Els(0).Name TD.MainContent = "Note that view types that can appear on multiple sheets (Legends, Images, Schedules etc.) will not be returned by this method." TD.Show() GoTo Friday End If Monday: TaskDialog.Show("Something went amiss...", "We looked hard in many places but were unable to find your sheet on this occasion.") Return Result.Failed Friday: Return Result.Succeeded End Function
Here is a pretty quick way of checking for a specific sheet.
private ViewSheet CheckSheet(string _sheetNumber) { ParameterValueProvider pvp = new ParameterValueProvider(new ElementId(BuiltInParameter.SHEET_NUMBER)); FilterStringRuleEvaluator fsr = new FilterStringEquals(); FilterRule fRule = new FilterStringRule(pvp, fsr, _sheetNumber, true); ElementParameterFilter filter = new ElementParameterFilter(fRule); if (new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Sheets).WherePasses(filter).FirstOrDefault() is ViewSheet vs) { return vs; } else { return null; } }
I believe this solution is unbeatable if you are interested in one single lookup.
It uses a parameter filter and the SHEET_NUMBER built-in parameter.
Probably RPThomas' solution is similarly efficient.
So-chong demonstrates the lookup of the inverted relationship I described, but just for one single view.
His code could be used to store the entire sheet to hosted views and the inverted view to hosting sheet relationships for all views and sheets. That might possibly be more efficient if you frequently need to look up several different view to sheet relationships.
Thank you all for the very illuminating and helpful answers!
Cheers,
Jeremy
Thanks again for the interesting discussion.
Now summarised and cleaned up for posterity:
https://thebuildingcoder.typepad.com/blog/2020/02/get-title-block-data-and-viewsheet-from-view.html
For every python developer out there still looking for a solution:
You can use my snippet made with FilteredElementCollector and FilterStringRule:
Thank you for sharing your Python solution! Edited and preserved for posterity on the blog:
Can't find what you're looking for? Ask the community or share your knowledge.