Document Manager Configuration Specific Custom Properties

Hi All.

The code below is a combination of VBA code from CodeStack (thanks Artem)which has been converted to C# by GitHub Copilot and then modified further by GitHub Copilot to process all components within an assembly and map these properties to a part model. The code is mostly working as expected however the issue I'm having is that the GetCustomProperty2 method is not returning the evaluated values despite what the Solidworks documentation says.

If anyone could shed some light on why this is happening and what the solution might be it would be greatly appreciated.

 

 

public IEnumerable GetAllComponentCustomPropertiesRecursive(string assemblyPath)
    {
    const string swDocumentManagerKey = "LicenceKey";
    var comps = new List();
    SwDMClassFactory swClassFact = new SwDMClassFactory();
    SwDMApplication5 swDmApp = (SwDMApplication5)swClassFact.GetApplication(swDocumentManagerKey);

    if (swDmApp != null)
        {
        SwDmDocumentOpenError res;
        SwDMDocument29 swDmDoc = (SwDMDocument29)swDmApp.GetDocument(assemblyPath, SwDmDocumentType.swDmDocumentAssembly, true, out res);

        if (swDmDoc != null)
            {
            string activeConfName = swDmDoc.ConfigurationManager.GetActiveConfigurationName();
            SwDMConfiguration18 swDmConf = (SwDMConfiguration18)swDmDoc.ConfigurationManager.GetConfigurationByName(activeConfName);

            GetComponents(swDmConf, comps, true, activeConfName);

            swDmDoc.CloseDoc();
            }
        else
            {
            throw new Exception("Failed to open the document");
            }
        }
    else
        {
        throw new Exception("Failed to get Document Manager application");
        }

    return comps;
    }

private void GetComponents(SwDMConfiguration18 conf, List coll, bool recursive, string confName)
    {
    // Use a dictionary to track unique components and their quantities across all recursion
    var componentDict = coll.Count == 0
        ? new Dictionary(StringComparer.OrdinalIgnoreCase)
        : coll.ToDictionary(
            c => \$"{c.PartNo}|{c.BasePath}|{c.Configuration}",
            c => c,
            StringComparer.OrdinalIgnoreCase);

    TraverseComponents(conf, componentDict, recursive, confName);

    // Update the original collection with deduplicated components
    coll.Clear();
    coll.AddRange(componentDict.Values);
    }

private void TraverseComponents(
    SwDMConfiguration18 conf,
    Dictionary componentDict,
    bool recursive,
    string confName)
{
    object[] vComps = (object[])conf.GetComponents();

    if (vComps != null)
    {
        foreach (object compObj in vComps)
        {
            SwDMComponent12 swDmComp = (SwDMComponent12)compObj;

            string partNo = System.IO.Path.GetFileNameWithoutExtension(swDmComp.PathName);
            string basePath = System.IO.Path.GetFileName(swDmComp.PathName);
            string configuration = swDmComp.ConfigurationName;
            string key = \$"{partNo}|{basePath}|{configuration}";

            // Get configuration-specific properties
            SWIPartsModel comp;
            if (componentDict.TryGetValue(key, out SWIPartsModel existingComp))
            {
                comp = existingComp;
                comp.Quantity++;
            }
            else
            {
                comp = new SWIPartsModel
                {
                    BasePath = basePath,
                    PartNo = partNo,
                    Configuration = configuration,
                    TopLevelConfiguration = confName,
                    Quantity = 1
                };

                // Open the component's document to get its configuration properties
                SwDmDocumentOpenError err;
                SwDMDocument29 swDmChildDoc = (SwDMDocument29)swDmComp.GetDocument2(true, null, out err);

                if (swDmChildDoc != null)
                {
                    SwDMConfiguration18 swDmChildConf = (SwDMConfiguration18)swDmChildDoc.ConfigurationManager.GetConfigurationByName(configuration);
                    if (swDmChildConf != null)
                    {
                        object[] propNames = (object[])swDmChildConf.GetCustomPropertyNames();
                        if (propNames != null)
                        {
                            foreach (string propName in propNames)
                            {
                                string val = swDmChildConf.GetCustomProperty2(propName, out SwDmCustomInfoType type);
                                switch (propName.ToLowerInvariant())
                                {
                                    case "part no": comp.PartNo = val; break;
                                    case "description": comp.Description = val; break;
                                    case "material": comp.Material = val; break;
                                    case "stock size": comp.StockSize = val; break;
                                    case "cutlength": comp.CutLength = val; break;
                                    case "ismilled": comp.IsMilled = val == "Yes"; break;
                                    case "isturned": comp.IsTurned = val == "Yes"; break;
                                    case "machine time milling":
                                        if (int.TryParse(val, out int millingTime))
                                            comp.MillingTime = millingTime;
                                        else
                                            comp.MillingTime = 0;
                                        break;
                                    case "machine time turning":
                                        if (int.TryParse(val, out int turningTime))
                                            comp.TurningTime = turningTime;
                                        else
                                            comp.TurningTime = 0;
                                        break;
                                    case "isprofilecut": comp.IsProfileCut = val == "Yes"; break;
                                    case "thickness":
                                        if (decimal.TryParse(val, out decimal thicknessValue))
                                            comp.Thickness = thicknessValue;
                                        else
                                            comp.Thickness = 0;
                                        break;
                                    case "prefix": comp.Prefix = val; break;
                                    case "partno": comp.PartNo = val; break;
                                }
                            }
                        }
                    }
                    swDmChildDoc.CloseDoc();
                }
                componentDict[key] = comp;
            }

            // Recursively process subcomponents
            if (recursive)
            {
                SwDmDocumentOpenError err;
                SwDMDocument29 swDmChildDoc = (SwDMDocument29)swDmComp.GetDocument2(true, null, out err);

                if (swDmChildDoc != null)
                {
                    SwDMConfiguration18 swDmChildConf = (SwDMConfiguration18)swDmChildDoc.ConfigurationManager.GetConfigurationByName(configuration);
                    if (swDmChildConf != null)
                    {
                        TraverseComponents(swDmChildConf, componentDict, recursive, confName);
                    }
                    swDmChildDoc.CloseDoc();
                }
            }
        }
    }
}