You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

获取与设置Assembly Parameter异常:装配体参数无法访问求助

问题描述

我编写的代码可以获取选中的FabricationPart和AssemblyInstance元素列表,但处理Assembly的参数时完全失效。相关代码如下:

获取选中元素的方法

public IList<Element> SelectElement(UIDocument uiDoc, Document doc)
{
    List<Element> values = new List<Element>();
    try
    {
        IList<Reference> reference = uiDoc.Selection.PickObjects(ObjectType.Element);
        foreach (Reference r in reference)
        {
            Element el = doc.GetElement(r);
            Category bc = doc.GetElement(r).Category;
            if(el is FabricationPart)
            {
                values.Add(el);
            }
            if (el is AssemblyInstance)
            {
                values.Add(el);
            }
        }              
    }
    catch (Exception ex)
    {
        TaskDialog td = new TaskDialog("Selection");
        td.MainContent = "No Elements Have Been Selected";
        td.Show(); 
    }
    return values;
}

遍历元素处理参数的代码

List<Element> e = (List<Element>)SelectElement(uiDoc, doc);
foreach (Element element in e)
{
    Parameter p = element.LookupParameter("TPFullFabricationServiceName");

    // 参数处理逻辑...
}

针对FabricationPart可正常运行的参数处理逻辑

if (element.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_DATA_PRODUCT).AsString() == "Pipe" ||
    element.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_DATA_PRODUCT).AsString() == "Tee" ||
    element.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_DATA_PRODUCT).AsString() == "Elbow")
{
    p.Set(element.get_Parameter(BuiltInParameter.FABRICATION_SERVICE_NAME).AsString());
}

部分参数绑定到FabricationPart类别,另一部分绑定到Assembly类别。请问是否需要以不同方式访问Assembly?


解决方案

是的,AssemblyInstance和FabricationPart的参数访问逻辑完全不同——AssemblyInstance是容器元素,它自身的参数与内部构件的参数相互独立,你需要明确目标是访问Assembly自身参数,还是其内部构件的参数:

1. 访问AssemblyInstance自身的参数

如果TPFullFabricationServiceName是绑定到Assembly类别的共享/项目参数,直接用LookupParameter或get_Parameter即可,但需先判断元素类型,再针对性处理:

List<Element> e = SelectElement(uiDoc, doc).ToList(); // 用ToList()替代强制转换,避免异常
foreach (Element element in e)
{
    if (element is FabricationPart fabPart)
    {
        // 原有FabricationPart处理逻辑
        Parameter p = fabPart.LookupParameter("TPFullFabricationServiceName");
        string productType = fabPart.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_DATA_PRODUCT).AsString();
        if (productType is "Pipe" or "Tee" or "Elbow")
        {
            p.Set(fabPart.get_Parameter(BuiltInParameter.FABRICATION_SERVICE_NAME).AsString());
        }
    }
    else if (element is AssemblyInstance assembly)
    {
        // 访问Assembly自身参数
        Parameter p = assembly.LookupParameter("TPFullFabricationServiceName");
        if (p != null)
        {
            // 示例:从Assembly内部的FabricationPart提取服务名赋值给Assembly自身参数
            foreach (ElementId memberId in assembly.GetMemberIds())
            {
                Element member = doc.GetElement(memberId);
                if (member is FabricationPart fabMember)
                {
                    string serviceName = fabMember.get_Parameter(BuiltInParameter.FABRICATION_SERVICE_NAME).AsString();
                    p.Set(serviceName);
                    break; // 取第一个符合条件的构件值,可按需调整
                }
            }
        }
    }
}

2. 访问AssemblyInstance内部构件的参数

如果目标是修改Assembly内部FabricationPart的TPFullFabricationServiceName参数,需要先通过assembly.GetMemberIds()获取所有内部构件ID,再逐个处理:

else if (element is AssemblyInstance assembly)
{
    foreach (ElementId memberId in assembly.GetMemberIds())
    {
        Element member = doc.GetElement(memberId);
        if (member is FabricationPart fabMember)
        {
            Parameter p = fabMember.LookupParameter("TPFullFabricationServiceName");
            string productType = fabMember.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_DATA_PRODUCT).AsString();
            if (productType is "Pipe" or "Tee" or "Elbow")
            {
                p.Set(fabMember.get_Parameter(BuiltInParameter.FABRICATION_SERVICE_NAME).AsString());
            }
        }
    }
}

额外优化建议

  • 简化SelectElement方法的元素判断逻辑:
    if(el is FabricationPart || el is AssemblyInstance)
    {
        values.Add(el);
    }
    
  • 避免强制转换IList<Element>为List<Element>,改用ToList()方法保证类型安全:
    List<Element> e = SelectElement(uiDoc, doc).ToList();
    

内容的提问来源于stack exchange,提问作者nhilson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 18:50:37