Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations waross on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

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

Status
Not open for further replies.

Talou

Computer
May 14, 2019
17
0
0
SE

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:
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
 
Replies continue below

Recommended for you

You can use this simple function:

Code:
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:
Dim isPart As Boolean = IsCatiaPart(pSel.Item(1).Value)

Tesak
- Play Tetris in CATIA V5 drawing
 
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;
 
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:
StandardObj_bby5gb.png


On these, it's not working:
HarnessObj_i4h4rw.png


Some_Part_3 seem standard...

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



Here is the code:
Code:
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
 
By the way Tesak, I LOVED the post you provide for Product reordering in CATIA V5 VBA.


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;
 
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
- Play Tetris in CATIA V5 drawing
 
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.
simpleAssembly_uvfr04.png

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.

C#:
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();
        }
    }
}
 
LWolf helped me.

Here is the solution.

C#:
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;
 
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;

C#:
        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;
                }
            }
        }
 
Status
Not open for further replies.
Back
Top