Get all datacard variable names from a file?

I’m trying to get all the variable names that exists on the datacard of a specific file in PDM Professional? Any pointers? My only pre-condition is that I only have access to the IEdmFile5 interface.

IEdmEnumeratorVariable5 has a GetUpdateVars method that gives you a list of all variables you can update for that file.

1 Like

@slohmann This is not entirely true. If the file is checked-in, this method returns nothing.

That’s good to know. Wasn’t there a data card interface? I thought I saw you mention that somewhere.

I think so. I’m going to end up doing it that way. Will post code here.

If you only care about one version of the file, you can use IEdmFile5.GetEnumeratorVariable and then use GetVersionVars and pass the version number that you care about into it.

If you want to check the current value in the data card, use IEdmEnumeratorVariable6.GetVarFromDb().

Disclaimer: I don’t know how GetVarFromDb functions when the file isn’t checked in, but I assume it gets the database variable regardless of check-in state.

GetVarFromDb don’t care whether the file is checked out or not. It doesn’t even care if the variable is part of the datacard of the file. It will always get the latest version value though.

Another way to go about it would be IEdmVault#.CreateUtility(EdmUtility.EdmUtil_VariableMgr)

Then use the IEdmVariableMgr5 interface to get the first variable and iterate through them.

IEdmPos varPos = VarMgr.GetFirstVariablePosition();
IEdmVariable5 variable = VarMgr.GetNextVariable(varPos);

Source: 2017 SOLIDWORKS API Help - Find Data Cards with Description Variable Example (C#)

@BigCrazyAl @slohmann If you are interested. I found a way to do this but this approach that uses the card interface is ridiculous slow.

  public static string[] GetVariablesNames(IEdmFile5 file)
        {
            var l = new List<string>();
            var vault = file.Vault;
            var card = (file.GetNextFolder(file.GetFirstFolderPosition()).GetCard(System.IO.Path.GetExtension(file.Name).Replace(".","")));
            var pos = card.GetFirstControlPosition();
            while (pos.IsNull == false)
            {
                var control = card.GetNextControl(pos);
                var variableId = control.VariableID; 

                if (variableId != 0)
                {
                    var variable = vault.GetObject(EdmObjectType.EdmObject_Variable, variableId) as IEdmVariable5;

                    if (l.Contains(variable.Name) == false)
                        l.Add(variable.Name);
                }

            }

            return l.ToArray();
        }

        [STAThread]
        private static void Main(string[] args)
        {

            var vault = new EdmVault5Class();
            vault.Login("ajlili", "ajlili", "Bluebyte");
            var folder = default(IEdmFolder5);
            var file = vault.GetFileFromPath($@"C:\SOLIDWORKS PDM\BLUEBYTESYSTEMS\Bluebyte\api\200-123000-001.SLDASM", out folder);

            var timer = new Stopwatch();
            timer.Start();
            var variables = GetVariablesNames(file);
            timer.Stop();
            Console.WriteLine($"Done in {timer.Elapsed.ToString()}");
            Console.WriteLine(string.Join(System.Environment.NewLine, variables));

            Console.ReadLine();
        }

1 Like

I got curious and tested your code out on my end @AmenJlili . I added your function to a debug add-in and ran it on a part file. Perhaps your connection to the DB is slow vs. the data card interface itself.

1 Like

Probably is true. My db is on the cloud.

@AmenJlili
I use @artem 's function to add all the variables into the combobox with some modification.

IEdmVault5 vault5 = new EdmVault5();
vault5 = mVault;
if (!vault5.IsLoggedIn)
{
	vault5.LoginAuto(vault5.Name, 0);
}
IEdmVariableMgr5 swPdmVarsMgr = (IEdmVariableMgr5)vault5;
IEdmPos5 swVarPost = swPdmVarsMgr.GetFirstVariablePosition();
List<string> variable_list = new List<string>();

while (!swVarPost.IsNull)
{
	IEdmVariable5 swPdmVar;
	try
	{
		swPdmVar = swPdmVarsMgr.GetNextVariable(swVarPost);
	}
	catch (Exception)
	{
		break;
	}
	if (!string.IsNullOrEmpty(swPdmVar.Name))
	{
		variable_list.Add(swPdmVar.Name);
	}
}

ComboBox_1.Items.AddRange(variable_list.Distinct().ToArray());
1 Like

Thanks for sharing your code! That returns all the variables from the vault. I’m only interested in variables that in the datacard.

Hi Amen, and via Sql as readonly?

SELECT TOP (1000) [ControlID]
,[CardID]
,[X]
,[Y]
,[Width]
,[Height]
,[Tag]
,[Type]
,[Parent]
,[Page]
,[VariableID]
,[Preview]
,[DefaultValueType]
,[DefaultValue]
,[SpecialDefaultValue]
,[SerialNumberID]
,[FolderCardVariableID]
,[FontData]
,[ButtonCmd]
,[WritesAllCfgs]
,[InputFormula]
,[CheckFlag]
,[Resizing]
,[CardListID]
FROM [PDMDB].[dbo].[CardControls]

regards
Massimo

1 Like