×
INTELLIGENT WORK FORUMS
FOR ENGINEERING PROFESSIONALS

Log In

Come Join Us!

Are you an
Engineering professional?
Join Eng-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Eng-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

How to know if user selected a Part or a Product ?

How to know if user selected a Part or a Product ?

How to know if user selected a Part or a Product ?

(OP)

Hello,

I would like to know if the user selected the Part or the Product.
To go around the problem, I cast the object into a Part and if it’s fail I suppose I’m on the Product and I cast to the Product.

I would prefer to find what object I’m on before casting it.
Thank you,

Vincent;


CODE --> VB.net

Imports INFITF
Imports ProductStructureTypeLib
Imports MECMOD
Imports Microsoft.VisualBasic


Module Module1
    Public CATIA As INFITF.Application
    Public Doc As Document
    Public Prod As ProductDocument
    Public Part As Part
    Public Prods As Products
    Public pSel As Selection
    Const iName As String = "Cleaning Harness"

    Sub Main()
        CATIA = CType(GetObject(, "CATIA.Application"), INFITF.Application)

        Try
            'Retrieve the Selection object 
            pSel = CATIA.ActiveDocument.Selection

            'Get the object in the selection 
            Part = pSel.Item(1).Value

            'Display message 
            MsgBox("Selected element: " & Part.Name)
        Catch
            MsgBox("Not a  part.")
        End Try

    End Sub

End Module 

RE: How to know if user selected a Part or a Product ?

You can use this simple function:

CODE --> VB.NET

Public Function IsCatiaPart(product As Object) As Boolean
  Dim refParent As Object = product.ReferenceProduct.Parent
  
  If TypeName(refParent) = "PartDocument" Then
    Return True
  End If
  
  Return False
End Function 

In your code, call it this way:

CODE --> VB.NET

Dim isPart As Boolean = IsCatiaPart(pSel.Item(1).Value) 

Tesak
https://scripts4all.eu/play-tetris-in-catia-v5-dra... - Play Tetris in CATIA V5 drawing

RE: How to know if user selected a Part or a Product ?

(OP)
Hello tesak,

tks again for helping.

I'm getting the following error when I run the code:

An unhandled exception of type 'System.MissingMemberException' occurred in Microsoft.VisualBasic.dll
Additional information: Public member 'ReferenceProduct' on type 'Part' not found.

on the line:
Dim refParent As Object = product.ReferenceProduct.Parent

any ideas?

Talou;

RE: How to know if user selected a Part or a Product ?

How do you call it? I am afraid that you passed a Part as a parameter, but the function expects a Product. I need to see the whole code.

Tesak
https://scripts4all.eu/play-tetris-in-catia-v5-dra... - Play Tetris in CATIA V5 drawing

RE: How to know if user selected a Part or a Product ?

(OP)
There is something weird with my object...

If I do File, New Product and New Part and use the code on those. Then the code works.

But if I use it on the object on which I need to work on. It's doing that error.

On these, it's works:


On these, it's not working:


Some_Part_3 seem standard...

The other are particular. Harness and contextual obj...



Here is the code:

CODE --> vb.net

Imports INFITF
Imports ProductStructureTypeLib
Imports MECMOD
Imports Microsoft.VisualBasic


Module Module1
    Public CATIA As INFITF.Application
    Public pDoc As Document
    Public pProdD As ProductDocument
    Public pProd As Product
    Public pPart As Part
    Public pProds As Products
    Public pSel As Selection
    Const iName As String = "Cleaning Harness"

    Sub Main()
        CATIA = CType(GetObject(, "CATIA.Application"), INFITF.Application)

        'Retrieve the Selection object 
        pSel = CATIA.ActiveDocument.Selection

        Dim isPart As Boolean = IsCatiaPart(pSel.Item(1).Value)

        MsgBox("Is Part:" + isPart.ToString)
    End Sub


    Public Function IsCatiaPart(product As Object) As Boolean
        Dim refParent As Object = product.ReferenceProduct.Parent

        If TypeName(refParent) = "PartDocument" Then
            Return True
        End If

        Return False
    End Function

End Module 

RE: How to know if user selected a Part or a Product ?

(OP)
By the way Tesak, I LOVED the post you provide for Product reordering in CATIA V5 VBA.

https://www.eng-tips.com/viewthread.cfm?qid=445034

That what made me start writing in VB.net.

I think it would be better for me to go with CSharp. I have code example on other framework that I will probably need to use.

If you happen to have an example with "Catia.Application" in CSharp, That will help me to get some speed up.

Regards,

Talou;

RE: How to know if user selected a Part or a Product ?

Hi Talou,
function I have provided I use only in standard CATIA V5 products to distinguish CATIA parts from products. If you use it in other workbenches than classic Assembly design, it is likely that it will fail.

C# is a powerfull language, maybe a bit better than VB.NET, however it is not that straightforward to port existing VBS, VBA code to C#. In combination with CATIA, VB.NET has some advantages, but generally go ahead with C#. It is probably better investment for the future :).

Tesak
https://scripts4all.eu/play-tetris-in-catia-v5-dra... - Play Tetris in CATIA V5 drawing

RE: How to know if user selected a Part or a Product ?

(OP)
Hello Tesak,

I need your help again.

In the following simple assembly. If the user select the Document, the workbench "Assembly" is still active as the user didn't double click on the document.
Therefore it failed when I try to launch the command "Delete Useless Elements" which belong to the Part workbench.

Would you know how I can change workbench?

Thank you!

Here is the code I have in CSharp, which is your code that you provided in VBA for the “Product Reordering”. It’s now working fine. I still need to figure out how to handle the Catia objects. But there is progress.

CODE --> CSharp

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using INFITF;
using ProductStructureTypeLib;
using MECMOD;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Windows.Automation;
using log4net;
using log4net.Config;


//using System.Windows.Forms.Application

namespace CleanHarness
{

    class Program
    {
        static private string CATIAV5APPNAME = "CATIA V5";
        static private string DELUSELESSELEMENT = "Delete Useless Elements";
        static private string OK = "OK";

        private static readonly log4net.ILog log = log4net.LogManager.GetLogger
        (System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);


        static void Main(string[] args)
        {
            //TODO:Can't get my logger to work
            log.Info("This is a Info message");

            INFITF.Application CATIA = (INFITF.Application)Marshal.GetActiveObject("Catia.Application");

            // Set references to Catia
            Document pActiveDoc = CATIA.ActiveDocument;

            //Retrieve the Selection object 
            Selection pSel = CATIA.ActiveDocument.Selection;

            //Dim isPart As Boolean = IsCatiaPart(pSel.Item(1).Value)

            // Selection test: 
            //    The Harness doc success the cast in Part
            //    The Harness part fail the cast in Part and success for Prod
            //    The split harness product success cast in Prod

            // Did the user select the document?
            try
            {
                //Get the object in the selection 
                Part pPart = (Part)pSel.Item2(1).Value;

                //Display message 
                Console.WriteLine("Selected element: " + pPart.get_Name());

                pSel.Clear();
                pSel.Add(pPart);

                DeleteUselessElements(CATIA);
            }
            catch
            {
                try
                {
                    Console.WriteLine("Selection is not the document.");

                    //Did the user select the product?
                    //Can//t cast in ProductDocument need to be cast in Product.
                    Product pProd = (Product)pSel.Item(1).Value;

                    Console.WriteLine("Success cast to product.");

                    //Can//t do that directl, need to get the part document!
                    //DeleteUselessElements(CATIA)

                    //Dim isPart As Boolean = IsCatiaPart(pSel.Item(1).Value)

                    //Console.WriteLine("Is this a part:" + isPart)
                }
                catch
                {
                    Console.WriteLine("Not a product.");
                }
            }
            //Console.WriteLine("Is Part:" + isPart.ToString)

            Console.ReadLine();
        }



        //Call Catia command: Delete Useless Elements and click "ok" button
        static public void DeleteUselessElements(INFITF.Application CATIA)
        {
            Console.WriteLine("Deleting Useless Elements on selected document.");

            CATIA.StartCommand("Delete Useless Elements");

            AutomationElementCollection childs =
            AutomationElement.RootElement.FindAll(
            TreeScope.Children, Condition.TrueCondition);

            AutomationElement catiaWindow = null;

            foreach (AutomationElement child in childs)
            {
                //Debug
                Console.WriteLine(child.Current.Name);

                string appName = child.Current.Name;
                if (appName.Contains(CATIAV5APPNAME))
                {
                    catiaWindow = child;
                }
            }

            if(catiaWindow == null)
            {
                Console.WriteLine("Could not found application named:" + CATIAV5APPNAME);
                return;
            }

            Condition graphWinCond =
            new PropertyCondition(AutomationElement.NameProperty, DELUSELESSELEMENT);

            AutomationElement graphWin;
            //wait for Graph window to open and get it
            do
            {
                graphWin = catiaWindow.FindFirst(TreeScope.Children, graphWinCond);
                System.Windows.Forms.Application.DoEvents();
            } while (graphWin == null);

            Condition btnOKCondition =
            new PropertyCondition(AutomationElement.NameProperty, OK);

            AutomationElement btnOk =
            graphWin.FindFirst(TreeScope.Children, btnOKCondition);

            //control pattern definition (button click)
            InvokePattern patOK = null; 
            btnOk.GetCurrentPattern(InvokePattern.Pattern);
            try
            {
                patOK = btnOk.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(ex.Message);  // Most likely "Pattern not supported."
                return;
            }
            //Click Ok button
            patOK.Invoke();
        }
    }
} 

RE: How to know if user selected a Part or a Product ?

(OP)
LWolf helped me.

Here is the solution.

CODE --> CSharp

Selection pSel = CATIA.ActiveDocument.Selection;
Product pProd = pSel.Item2(1).Value as Product;
CATBaseDispatch pObj = pProd.ReferenceProduct.Parent;
PartDocument pPart = pObj as PartDocument;
pSel.Clear();
pSel.Add(pPart.Part); // <-- The missing link...

CATIA.StartWorkbench("PrtCfg"); 

Thank you for the help Tesak! Really appreciate!

Talou;

RE: How to know if user selected a Part or a Product ?

(OP)
And now, here is the answer of the question I had for that thread:

The real question was how to know if the user selected the Part itself or the Document under the part.
The following function will return an object on the Document, whatever the selection made by the user.

Thanks Tesak, the key that I was missing was → Prod.ReferenceProduct.Parent;

CODE --> CSharp

static public PartDocument RetreivePartDocument(CATBaseDispatch pObj)
        {
            try
            {
                PartDocument pPartDoc = (PartDocument) pObj;
                return pPartDoc;
            }
            catch
            {
                Console.WriteLine("Fail to cast to PartDocument.");
                Console.WriteLine("Retreiving PartDocument from Product interface.");
                try
                {
                    Product pProd = (Product) pObj;

                    Console.WriteLine("Success cast to Product interface.");

                    //Going up in the class architechture. (still the same obj)
                    CATBaseDispatch pCBDObj = pProd.ReferenceProduct.Parent;

                    // Must be on "PartDocument" object!
                    // CSharp will allow a cast to Part but it's not right.
                    // a direct cast to Part fail in VB.
                    PartDocument pPart = (PartDocument) pCBDObj;

                    Console.WriteLine("Success to get to the part.");
                    return pPart;
                }
                catch
                {
                    Console.WriteLine("Fail retreive the PartDocument object.");
                    return null;
                }
            }
        } 

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Eng-Tips Forums free from inappropriate posts.
The Eng-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Eng-Tips forums is a member-only feature.

Click Here to join Eng-Tips and talk with other members!


Resources

eBook – How to Choose the Correct Corrosion Testing Method
When designing a metal component, engineers have to consider how susceptible certain alloys are to corrosion in the final product’s operating environment. In a recent study by NACE (National Association of Corrosion Engineers), it was estimated that the direct and indirect costs of corrosion in the United States is approximately 6.2% of the GDP. In 2016, that cost exceeded $1 trillion dollars for the first time. Download Now

Close Box

Join Eng-Tips® Today!

Join your peers on the Internet's largest technical engineering professional community.
It's easy to join and it's free.

Here's Why Members Love Eng-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close