【OPMCE C#】创建管线编号问题

1、当我已有上图所示一条管线编号,名称为COG-1511-0001-CL01-300;

2、我想通过代码创建一条管线编号,名称为COG-1511-0001-CL01-350,相对上条管线编号只修改了管径。这时打印出来的名称还是第一条的管线编号,没有创建出第二条管线编号。

 ItemStatus status = NetworkSystem.CreatePipingNetworkSystem(out pipeline, namedItems, specification, nominalDiameter, number.ToString(), null);
MessageBox.Show(pipeline.Name.ToString(), "Name");

请问该如何成功创建第二条管线编号?

Parents
  • 创建第二条管线编号时返回的是Duplicate

  • 如果文件已有某管线编号,新管线编号只修改了管径。此时用程序创建是不成功的,但手动是可以的,这种情况只能用手动创建么?

  • 符老师,我这两天刚好也在用这个接口,看一下opm sdk,感觉是sdk封装有bug,软件本身是可以创建的,用sdk的接口不行,里面只判断了等级库和number,这个显然是不合理的

  • 管线号由那几位属性拼接成,是可以在schema中定义的,判断管线号是否重复,应该判断NAME属性值是否重复

  • 两位好!SDK中提供的API函数往往不是软件界面中工具的直接对应。一个工具的后台代码往往由很多行代码组成。这样做当然是为了SDK的灵活性。

    所以,是否可以推断工具的做法是:①先判断该管线号是否存在?②如果存在就删除它;③用新的管线参数创建该管线号。



  • private static ItemStatus CreateNetworkSystem(out NetworkSystem networkSystem, NetworkSystemType networkSystemType, List<NamedItem> namedItems, string specification, string number, Dictionary<string, string> properties)
    {
        networkSystem = null;
        if (namedItems == null)
        {
            return ItemStatus.Failed;
        }
    
        if (NetworkSystemExists(networkSystemType, namedItems, specification, number, out string name))
        {
            networkSystem = new NetworkSystem();
            networkSystem.m_name = name;
            networkSystem.m_type = networkSystemType;
            ComponentBase.SetActiveNetworkSystem(networkSystem);
            return ItemStatus.Duplicate;
        }
    
        try
        {
            BMECApi instance = BMECApi.Instance;
            string networkSystem2 = GetNetworkSystem(networkSystemType);
            IECInstance iECInstance = instance.InstanceManager.CreateECInstance(networkSystem2);
            iECInstance.InstanceId = "mechanical";
            if (!string.IsNullOrEmpty(specification))
            {
                iECInstance["SPECIFICATION"].StringValue = specification;
            }
    
            if (!string.IsNullOrEmpty(specification))
            {
                iECInstance["NUMBER"].StringValue = number;
            }
    
            SetNamedItemsAsProperties(iECInstance, networkSystemType, namedItems);
            DgnUtilities instance2 = DgnUtilities.GetInstance();
            instance2.WriteECInstanceToDgn(iECInstance, instance2.GetDGNConnection());
            SetNamedItems(iECInstance, networkSystemType, namedItems);
            SetProperties(iECInstance, properties);
            instance2.SaveModifiedInstance(iECInstance, instance2.GetDGNConnection());
            networkSystem = new NetworkSystem();
            networkSystem.m_specification = specification;
            networkSystem.m_number = number;
            networkSystem.m_namedItems = namedItems;
            networkSystem.m_name = iECInstance["NAME"].StringValue;
            networkSystem.m_type = networkSystemType;
            networkSystem.m_instance = iECInstance;
            ComponentBase.SetActiveNetworkSystem(networkSystem);
        }
        catch
        {
            return ItemStatus.Failed;
        }
    
        return ItemStatus.Success;
    }

    这个是SDK中创建管线号的逻辑,本质上是创建了ECInstance,然后设置相关属性,可以手动创建。

    但是如果想要正常使用SDK,必须设置ComponentBase的s_networkSystem,而对应的方法是internal static void SetActiveNetworkSystem(NetworkSystem networkSystem),可以考虑使用反射调用

    Type type = typeof(ComponentBase);
    MethodInfo methodInfo = type.GetMethod("SetActiveNetworkSystem", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
    methodInfo?.Invoke(null, new object[] { networkSystem });
    hvacIdentificationCode = networkSystem.Name;
    
    StandardPreferencesUtilities.SetActiveHVACNetworkSystem(networkSystem);

    SDK中很多非常有用的函数都是internal,不知道是为什么没有公开

Reply
  • private static ItemStatus CreateNetworkSystem(out NetworkSystem networkSystem, NetworkSystemType networkSystemType, List<NamedItem> namedItems, string specification, string number, Dictionary<string, string> properties)
    {
        networkSystem = null;
        if (namedItems == null)
        {
            return ItemStatus.Failed;
        }
    
        if (NetworkSystemExists(networkSystemType, namedItems, specification, number, out string name))
        {
            networkSystem = new NetworkSystem();
            networkSystem.m_name = name;
            networkSystem.m_type = networkSystemType;
            ComponentBase.SetActiveNetworkSystem(networkSystem);
            return ItemStatus.Duplicate;
        }
    
        try
        {
            BMECApi instance = BMECApi.Instance;
            string networkSystem2 = GetNetworkSystem(networkSystemType);
            IECInstance iECInstance = instance.InstanceManager.CreateECInstance(networkSystem2);
            iECInstance.InstanceId = "mechanical";
            if (!string.IsNullOrEmpty(specification))
            {
                iECInstance["SPECIFICATION"].StringValue = specification;
            }
    
            if (!string.IsNullOrEmpty(specification))
            {
                iECInstance["NUMBER"].StringValue = number;
            }
    
            SetNamedItemsAsProperties(iECInstance, networkSystemType, namedItems);
            DgnUtilities instance2 = DgnUtilities.GetInstance();
            instance2.WriteECInstanceToDgn(iECInstance, instance2.GetDGNConnection());
            SetNamedItems(iECInstance, networkSystemType, namedItems);
            SetProperties(iECInstance, properties);
            instance2.SaveModifiedInstance(iECInstance, instance2.GetDGNConnection());
            networkSystem = new NetworkSystem();
            networkSystem.m_specification = specification;
            networkSystem.m_number = number;
            networkSystem.m_namedItems = namedItems;
            networkSystem.m_name = iECInstance["NAME"].StringValue;
            networkSystem.m_type = networkSystemType;
            networkSystem.m_instance = iECInstance;
            ComponentBase.SetActiveNetworkSystem(networkSystem);
        }
        catch
        {
            return ItemStatus.Failed;
        }
    
        return ItemStatus.Success;
    }

    这个是SDK中创建管线号的逻辑,本质上是创建了ECInstance,然后设置相关属性,可以手动创建。

    但是如果想要正常使用SDK,必须设置ComponentBase的s_networkSystem,而对应的方法是internal static void SetActiveNetworkSystem(NetworkSystem networkSystem),可以考虑使用反射调用

    Type type = typeof(ComponentBase);
    MethodInfo methodInfo = type.GetMethod("SetActiveNetworkSystem", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
    methodInfo?.Invoke(null, new object[] { networkSystem });
    hvacIdentificationCode = networkSystem.Name;
    
    StandardPreferencesUtilities.SetActiveHVACNetworkSystem(networkSystem);

    SDK中很多非常有用的函数都是internal,不知道是为什么没有公开

Children
No Data