Update file data card value using Solidworks PDM API

Hi Team,

I’m trying to update file data card values like below… API is working fine but the value is not updating in the card…

   var vault = iPDMFile.Vault as IEdmVault7;

        if (!iPDMFile.IsLocked)
        {
            iPDMFile.LockFile(vault.RootFolderID, 0, (int)EdmLockFlag.EdmLock_Simple);

            bool isLocked = iPDMFile.IsLocked;

            IEdmEnumeratorVariable5 varEnum = default(IEdmEnumeratorVariable5);
            varEnum = iPDMFile.GetEnumeratorVariable();

            Array valueList = null;
            varEnum.GetUpdateVars(iPDMFile.LockedInFolderID, out valueList);

            int idx = 0;
            idx = Information.LBound(valueList);
            int upper = 0;
            upper = Information.UBound(valueList);

            string msg = null;  

            IEdmVariableMgr5 varMgr = default(IEdmVariableMgr5);
            varMgr = (IEdmVariableMgr5)iPDMFile.Vault;            
            IEdmVariable5 var = default(IEdmVariable5);
            IEdmVariableValue6 value = default(IEdmVariableValue6);        
            while (idx <= upper)
            {
                value = (IEdmVariableValue6)valueList.GetValue(idx);
                idx = idx + 1;
                var = varMgr.GetVariable(value.VariableID);
                string strValName = value.VariableName;
                string strValValue = value.GetValue("@").ToString();
           
            }             

            
          //Updating Description value in Data card....

//Tried with uitlity

        IEdmVault5 valut5 = (IEdmVault5)iPDMFile.Vault;

        IEdmVault7 valut7 = (IEdmVault7)valut5;
        IEdmBatchUpdate2 Update = default(IEdmBatchUpdate2);
        Update = (IEdmBatchUpdate2)valut7.CreateUtility(EdmUtility.EdmUtil_BatchUpdate);

        IEdmSearch5 Search = default(IEdmSearch5);
        Search = (IEdmSearch5)valut7.CreateUtility(EdmUtility.EdmUtil_Search);


        int RevisionID = 0;           
        IEdmVariableMgr5 VariableMgr = default(IEdmVariableMgr5);
        VariableMgr = (IEdmVariableMgr5)valut5;
        RevisionID = VariableMgr.GetVariable("Descrption").ID;


        Search.FileName = iPDMFile.Name;
        Search.FindLockedFiles = true;
        Search.FindUnlockedFiles = false;


        IEdmSearchResult5 Result = default(IEdmSearchResult5);
        Result = Search.GetFirstResult();

        while ((Result != null))
        {
            Update.SetVar(Result.ID, RevisionID, "P", "", (int)EdmBatchFlags.EdmBatch_Nothing);             
            Result = Search.GetNextResult();
        }

        //Write all the card variable values to the database
        Array Errors = null;
        int errorSize = 0;
        errorSize = Update.CommitUpdate(out Errors, null);

//Second way uisng

        IEdmEnumeratorVariable5 vars = (IEdmEnumeratorVariable5)iPDMFile.GetEnumeratorVariable();
        object DescName = "Descprtion";
        string DescVal = "Sample Test";          
         vars.SetVar(strNewVal, "", DescVal );
           vars.flush()
       
            
        }


      //Update END
           
            iPDMFile.UndoLockFile(0);       

            
        }

Try this:

    /// <summary>
    /// Sets the variable value.
    /// </summary>
    /// <param name="file">The file.</param>
    /// <param name="variableName">Name of the variable.</param>
    /// <param name="value">The value.</param>
    /// <param name="configurationName">Name of the configuration.</param>
    /// <exception cref="ArgumentNullException">
    /// file
    /// or
    /// Configuration cannot be empty
    /// </exception>
    /// <exception cref="Exception">Failed to set variable.</exception>
    public static void SetVariableValue(this IEdmFile5 file, string variableName, object value, string configurationName = "@")
    {
        if (file == null)
            throw new ArgumentNullException(nameof(file));

        // generic file
        if (file.IsAssembly() ==false && file.IsDrawing() == false && file.IsPart() == false)
            configurationName = string.Empty;
        else
        {
            if (string.IsNullOrWhiteSpace(configurationName))
                throw new ArgumentNullException("Configuration cannot be empty");
        }

            try
        {
            IEdmEnumeratorVariable8 fileEnumerator = file.GetEnumeratorVariable() as IEdmEnumeratorVariable8;
            fileEnumerator.SetVar(variableName, configurationName, value);
            fileEnumerator.CloseFile(true);
        }
        catch (Exception ex)
        {
            throw new Exception("Failed to set variable.", ex);
        }
    }

    /// <summary>
    /// Returns whether the document is a SOLIDWORKS drawing or not.
    /// </summary>
    /// <param name="file">File.</param>
    /// <returns>File</returns>
    public static bool IsDrawing(this IEdmFile5 file)
    {
        return file.Name.ToLower().EndsWith(".slddrw");
    }

    /// <summary>
    /// Returns whether the document is a SOLIDWORKS part or not.
    /// </summary>
    /// <param name="file">File.</param>
    /// <returns>File</returns>
    public static bool IsPart(this IEdmFile5 file)
    {
        return file.Name.ToLower().EndsWith(".sldprt");
    }
/// <summary>
    /// Returns whether the document is a SOLIDWORKS assembly or not.
    /// </summary>
    /// <param name="file">File.</param>
    /// <returns>File</returns>
    public static bool IsAssembly(this IEdmFile5 file)
    {
        return file.Name.ToLower().EndsWith(".sldasm");
    }

@AmenJlili , thanks for your reply.

I tried the same code as you suggested but the new value is not updated in data card.

Checkout
Call the your code
Checkin

Any help ?

There are a lot of things that can go wrong.

Check if the file is checked out.
Check if the variable is on a datacard.
Check if the option Prefer 32 bits is turned off in the project’s properties under the build tab or the application tab if you are using VB.NET

@AmenJlili ,

  • to update card value , first I’m checkout the file like below iPDMFile.LockFile(vault.RootFolderID, 0, (int)EdmLockFlag.EdmLock_Simple);
  • Yes, variable (Revision) is on datacard, which is driving from file custom property
  • I’m using C#, x64

Please show a screenshot of your exception. I can’t tell what’s going on with your code…

@Prasad290 Did you manage to solve this problem? I think I have a similar issue…

@Frans : Thanks for signing up to CADoverflow. Can you post your code here so I can help you.

@AmenJlili: Thanks for looking into this. I think it is a vault issue. After my code failed (that I made according to your lessons on CADSharp) I went back to the example code form the PDM API help: Batch Update Card Variables Example (VB.NET). I run that code as is and the variables in the datacard of the .txt file and folder are changed as planned. I changed it to work with .sldprt files and @ configuration and the variables are not written any longer. I do see the new variable values showing up in the sql table VariableValues so the setvar function seems to be ok. But the values don’t show up in the datacard. A get latest version doesn’t help. Checking in the file sets the values in de sql table back to the values as they were and always had been on the datacard. So something goes wrong with writing the variables for a Solidworks and Office file. It does work for txt and jpg files. For debugging I use the PDMVaultBrowser that Artem (CodeStack) made. I tried with Notepad as well and that showed the same behaviour. I don’t get any errors using the batchUpdate2 function. Just that the variables don’t update.

Have you set up your variable mapping to point data card variables to .sldprt and other solidworks files?

Here’s an example mapped to the custom properties of solidworks files. Each variable on your data card should be mapped to your file type in some way.

Hi all,

Yes, the custom properties are set with the variables and linked to the file extensions. Our problem does seem to have to do with them though. But then not the custom property in the variable setting but in the Solidworks file.

I went back to the basis with a new clean Vault based on the Solidworks Default vault and added 1 folder, a clean .sldprt without custom properties and a txt file. I run the BatchUpdatcecardVars from the helpfile with some tweaking to make it suitable for Solidworks files and have more variables changed. (Batch Update Card Variables Example (VB.NET) - 2021 - SOLIDWORKS API Help)
The txt file works flawlessly again. Data card in explorer shows all the new variables.
The sldprt file has 2 variables that are not updated on the explorer data card.
It turned out that those are passed from the Folder to the data card of the sldprt file and are also part of the custom properties in the sldprt file.
As soon as the variable of the data card is set as a custom property in the part file it is no longer updated by the API.
Data card variables that are not linked to a custom property in the part are not shown in the data card opened by Solidworks.
Data card variables are only pushed to a custom property in the part when the value is changed by hand.
New custom properties are only made when the value on the data card is changed by hand and not by the API.
The part has been checked in and out several times. Get latest version. That makes no difference.

Here is a picture of the datacard in explorer to show what I mean:

My (variable) 9 is set by the API and is empty on the data card in Solidworks nor is it (variable and value) in the custom property of the part file
Description is set by hand and not changeable by the API. It is visible in Solidworks data card and as a variable and value in custom property
Project Name and Number are from the parent folder. Not changeable by the API. it is visible in Solidworks data card and custom property

We have PDM for more than 10 years and have quite a number of Dispatch scripts in the production vault that monitor and change variables. We use the custom properties of the model to push variables to the drawing.

Sometimes the Dispatch scripts fail so I thought I dive into the API stuff to replace the Dispatch scripts and make PDM more robust…

Is the above mentioned interaction of the API with the data card and custom properties normal/as expected?

If your application is a standalone (console application, winforms and or wpf) then make sure to uncheck prefer 32 bits from the project properties.

1 Like

Thanks! That did the trick for this test environment.

1 Like

You’re welcome. Make sure to tick the answer as the right one and come in the future with more questions!