Revit API 无效对象

问题描述 投票:0回答:3

下面的代码片段应该删除不在工作表上的任何视图,或者在名为“视图所有者”的项目视图参数中没有值的视图。 我已经在一个空白项目上对此进行了测试,它似乎按计划工作。然而,在“真实”的项目中,经过反复搅拌后,返回以下错误....

Autodesk.Revit.Exceptions.InvalidObjectException:引用的对象无效,可能是因为它已从数据库中删除,或者其创建已撤消。在 validateNativeInstance(Void* ptr) 在 Autodesk.Revit.RevitAPIManagedWeakPointer.getValidPtr() 在 Autodesk.Revit.DB.Element.get_Id() 在 Microsoft.Scripting.Interpreter.FuncCallInstruction

2.Invoke(Object arg0) at IronPython.Runtime.Binding.PythonGetMemberBinder.FastPropertyGet
1.GetProperty(CallSite 站点,TSelfType 目标, CodeContext 上下文)位于 Microsoft.Scripting.Interpreter.DynamicInstruction`3.Run(InterpretedFrame 框架)位于 Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame 框架)位于 Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet] (T0 arg0, T1 arg1) 在 IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx) 在 Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope 范围) 在 RevitPythonShell.RpsRuntime.ScriptExecutor.ExecuteScript(字符串源)...

我不太确定该怎么做。 首先,它是什么以及它意味着什么? 其次 - 我如何“捕获”这个并防止它抛出错误? 我认为收集的元素之一是“无效的”? 有没有办法确定一个对象是否无效并忽略它? 有没有办法摆脱无效对象?是什么让一个对象无效?

__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

我进行了以下编辑,允许脚本继续运行,但是,每个“可能从数据库中删除”错误的处理都非常耗时......

for el in viewstodelete:
    t.Start()
    try:
        doc.Delete(el.Id)
    except Exception as e:
        print("Error: %s" %str(e))
    t.Commit()
revit-api revit
3个回答
2
投票

所有 Revit 图元都有一个

IsValidObject
方法。您可以使用它来检查您的 .NET 包装器是否仍然有效。

文档说:

如果相应的 Revit 本机对象被销毁,或者相应对象的创建被撤消,则包含该对象的托管 API 对象将不再有效。无法在无效的包装对象上调用 API 方法。

在您的情况下,视图之间可能存在某种依赖关系,因此当您删除一个视图时,另一个视图也会通过传播被删除。


0
投票

您正在检索的某些元素可能是系统所需的,并且无法删除。您的异常处理程序看起来是朝着正确方向迈出的良好一步。查看该打印输出以识别有问题的视图并确定如何首先跳过它们。它们无法删除可能有充分的理由。以下是对相关问题的进一步分析:

http://thebuildingcoder.typepad.com/blog/2012/03/melbourne-devlab.html

http://thebuildingcoder.typepad.com/blog/2015/10/rtc-classes-and-getting-started-with-revit-macros.html#24


0
投票

因为你使用了静态变量来存储Revit的CommandData,但是Revit的CommandData可以改变,所以存储CommandData的静态变量不会相应改变。这将导致 Revit 报告一些错误。

© www.soinside.com 2019 - 2024. All rights reserved.