Reputation: 1503
The below snippet is supposed to delete any view that isn't on a sheet OR has no value present in the project view parameter called "View Owner". I've tested this on a blank project and it appears to work as planned. However, on the "real" project, after churning and churning the following error is returned....
Autodesk.Revit.Exceptions.InvalidObjectException: The referenced object is not valid, possibly because it has been deleted from the database, or its creation was undone. at validateNativeInstance(Void* ptr) at Autodesk.Revit.RevitAPIManagedWeakPointer.getValidPtr() at Autodesk.Revit.DB.Element.get_Id() at Microsoft.Scripting.Interpreter.FuncCallInstruction2.Invoke(Object arg0) at IronPython.Runtime.Binding.PythonGetMemberBinder.FastPropertyGet
1.GetProperty(CallSite site, TSelfType target, CodeContext context) at Microsoft.Scripting.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame) at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame) at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1) at IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx) at Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope scope) at RevitPythonShell.RpsRuntime.ScriptExecutor.ExecuteScript(String source)...
I'm not really sure what to make of this. For starters, what is it and what does it mean? Secondly - how would I "catch" this and prevent it from throwing the error? I assume that one of the collected elements is "invalid"? Is there some way to determine if an object is invalid and ignore it? is there a way to get rid of the invalid object? what makes an object invalid?
__window__.Width = 1100
from Autodesk.Revit.DB import FilteredElementCollector, BuiltInCategory, View, Transaction
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
selection = [ doc.GetElement( elId ) for elId in __revit__.ActiveUIDocument.Selection.GetElementIds() ]
views = []
viewstodelete = []
#Build the list full of views
if len(selection) == 0:
cl_views = FilteredElementCollector(doc)
views = cl_views.OfCategory( BuiltInCategory.OST_Views ).WhereElementIsNotElementType().ToElements()
else:
for sel in selection:
if isinstance(sel, View):
views.append(sel)
count = 0
#Get all views with a view owner
for v in views:
if (v.LookupParameter("Sheet Number") is None or v.LookupParameter("Sheet Number").AsString() == "---") and (v.LookupParameter("View Owner").AsString() is None or v.LookupParameter("View Owner").AsString() == ""):
if v.LookupParameter("View Name") is not None:
vOwner = v.LookupParameter("View Name").AsString()
count= count+1
viewstodelete.append(v)
else:
vOwner = "[View Template] - Not Deleted"
print(vOwner)
t = Transaction(doc, 'Delete Views')
t.Start()
for el in viewstodelete:
doc.Delete(el.Id)
t.Commit()
print "Views in Project: %s" % len(views)
print "Deleted views: %s" % count
I've made the following edit which allows the script to continue running, however, each of these "possibly deleted from the database" errors are quite time consuming to process...
for el in viewstodelete:
t.Start()
try:
doc.Delete(el.Id)
except Exception as e:
print("Error: %s" %str(e))
t.Commit()
Upvotes: 1
Views: 2736
Reputation: 1
Because you used a static variable to store Revit's CommandData, but Revit's CommandData can change, the static variable storing CommandData will not change accordingly. This will cause Revit to report some errors.
Upvotes: 0
Reputation: 13286
There is an IsValidObject
method on all Revit elements. You can use it to check if your .NET wrapper is still valid.
The documentation says:
If the corresponding Revit native object is destroyed, or creation of the corresponding object is undone, a managed API object containing it is no longer valid. API methods cannot be called on invalidated wrapper objects.
In your case, may be there is some dependency between the views, so when you delete one, another one is deleted by propagation.
Upvotes: 3
Reputation: 8294
Probably some of the elements you are retrieving are required by the system and are impossible to delete. Your exception handler looks like a good step in the right direction. Look at the printout of that to identify the problematic views and determine how to skip them in the first place. There is probably a good reason why they cannot be deleted. Here is some further analysis of related issues:
http://thebuildingcoder.typepad.com/blog/2012/03/melbourne-devlab.html
Upvotes: 0