Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

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

CATIA v5r22 sp6: PartDocument problem with my first Catia macro in C# 1

Status
Not open for further replies.

Lionel35

Industrial
Feb 13, 2017
7
FR
Hello everybody, I'm a newbie here... I'm a software developper in C#, I'm not a master of c# but I know enough to code Windows desktop software in WindowsForm (and sometimes in WPF).
I use CATIA v5r22 sp6 (HD2+FS1+KT1 modules) on Windows 7 pro x64 and Microsoft Visual Studio Community 2015.

Now I try to code my first Catia macro in C# with Visual Studio because I don't know VBA very well (and I hate it... [wink]).

I have no problem to intercept COM object of my Catia session, but I don't know why I can't use the Catia.ActiveDocument ! [sad]

My (little) code:
Code:
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
// partie spécifique à CATIA
using INFITF;
using MECMOD;
using PARTITF;
using KnowledgewareTypeLib;
using ProductStructureTypeLib;

namespace MacroCatiaTest1
{
    public partial class Form1 : Form
    {
        bool CatiaRunning = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void BTtest_Click(object sender, EventArgs e)
        {
            INFITF.Application myCatia = null;
            try
            {
                myCatia = (INFITF.Application)Marshal.GetActiveObject("CATIA.Application");
                CatiaRunning = true;
            }
            catch (Exception PresenceCatia)
            {
                MessageBox.Show("CATIA n'est pas lancé!\nMacro impossible à executer!\n\n" + PresenceCatia.Message, "Erreur critique", MessageBoxButtons.OK, MessageBoxIcon.Error);
                CatiaRunning = false;
            }

            if (CatiaRunning)
            {
                myCatia.Visible = true;
                myCatia.DisplayFileAlerts = true;

                try
                {
                    [b]PartDocument myPartDocument = (PartDocument)myCatia.ActiveDocument;[/b] ==> Here is my problem...
                    Part myPart = myPartDocument.Part;

                }
                catch (Exception excep)
                {
                    MessageBox.Show(excep.Message);
                }
            }
        }
    }
}

Visual Studio explain that's an implicit cast problem between "myPartDocument" in MECMOD.PartDocument format and "myCatia" in INFITF.Application format.

If you have any idea, please I need some help... Many thanks in advance! [wink]
 
Replies continue below

Recommended for you

Try to convert following code to c#
Code:
 'GET CATIA V5
        Dim myCatia As INFITF.Application
        Try
            myCatia = GetObject(, "CATIA.application")
        Catch ex As Exception
            myCatia = CreateObject("CATIA.application")
        End Try
        'myCatia.Visible = True
        'myCatia.DisplayFileAlerts = True

        '----Get part properties----
        Dim productDocument1 As Document
        productDocument1 = myCatia.ActiveDocument
        Dim Product1 As Product
        Product1 = productDocument1.Product

Regards,
Jenia Ladkov
 
Thanks for your answer, I just tried it and I have two problems:
- Visual Studio force me to cast myCatia.ActiveDocument in INFITF.Documents but this casting operation launch an exception (HRESULT E_FAIL with a COM composant)! [mad]
- I don't have access to .Product !! But I use "using INFITF" (it's the "import" of C#), MECMOD, PARTITF, KnowledgewareTypeLib, and ProductStructureTypeLib [sad]

Code:
try
{
    Documents productDocBase;
    [b]productDocBase = (INFITF.Documents)myCatia.ActiveDocument;[/b] --> Error!
    Product productBase;
    productBase = productDocBase[b].Product[/b]; --> doesn't exist!
}
catch (Exception excep)
{
    MessageBox.Show(excep.Message);
}

Any idea? Please...
 
For information, I just successfully performed to add a new part with that code, but I always search a solution for my problem...

Code:
namespace MacroCatiaTest1
{
    public partial class Form1 : Form
    {
        bool CatiaRunning = false;
        static INFITF.Application myCatia;
        static MECMOD.PartDocument myPartDocument;
        static MECMOD.Part myPart;
        
        public Form1()
        {
            InitializeComponent();
        }

        private void BTtest_Click(object sender, EventArgs e)
        {
            try
            {
                myCatia = (INFITF.Application)Marshal.GetActiveObject("CATIA.Application");
                CatiaRunning = true;
            }
            catch (Exception PresenceCatia)
            {
                MessageBox.Show("CATIA n'est pas lancé!\nMacro impossible à executer!\n\n" + PresenceCatia.Message, "Erreur critique", MessageBoxButtons.OK, MessageBoxIcon.Error);
                CatiaRunning = false;
            }

            if (CatiaRunning)
            {
                try
                {
                    myPartDocument = (PartDocument)myCatia.Documents.Add("Part");
                    myPart = myPartDocument.Part;
                }
                catch (Exception excep)
                {
                    MessageBox.Show(excep.Message);
                }
            }
        }
    }
}
 
@JeniaL: I succeed in doing translate in C# of your vb.net code!

This is the good code:
Code:
...

static ProductDocument productDocBase;
static Product productBase;

...

try
{
    productDocBase = (ProductDocument)myCatia.ActiveDocument;
    productBase = productDocBase.Product;
    MessageBox.Show(productBase.get_Name().ToString());
}
catch (Exception excep)
{
    MessageBox.Show(excep.Message);
}
Where "ProductDocument" and "Product" are parts of ProductStructureTypeLib reference...

I don't know if it's the better way to access of Product and Part, but it works! [wink]
 
you code works fine with a CATPart as active document. I receive Error when a CATProduct is the active doc.

Eric N.
indocti discant et ament meminisse periti
 
@itsmyjob Really? It's strange because it works on my PC (Windows 7) with a CATProduct (with or without Design Mode no problem), and now I tried on 2 other PCs (Windows 7 and 8.1) with other CATProducts and it works too...

I don't know why you receive an error... [ponder]
 
i was talking about the first code

Eric N.
indocti discant et ament meminisse periti
 
@itsmyjob It's a "basic" Documents.Add("Part") just to test if my code interacting well with Catia, I don't try more for that, sorry...

But I have always the same problem of "cast" error, when I try to use this code:
Code:
...
        static PartDocument myPartDocument = null;
        static Part myPart = null;
        static ProductDocument productDocBase = null;
        static Product productRoot = null;
...
            if (CatiaRunning)
            {
                myCatia.Visible = true;
                myCatia.DisplayFileAlerts = true;

                try
                {
                    productDocBase = (ProductDocument)myCatia.ActiveDocument;
                    productRoot = productDocBase.Product;

                    MessageBox.Show(productDocBase.get_Name() + "\n\n");

                    [b]myPartDocument = (MECMOD.PartDocument)myCatia.ActiveDocument;[/b] ==> "cast" error! But myPartDocument is a MECMOD.PArtDocuments var!!!
                    myPart = myPartDocument.Part;

                    MessageBox.Show(myPart.get_Name());
                }
                catch (Exception excep)
                {
                    MessageBox.Show(excep.Message);
                }
            }
        }
I don't understand why because I saw other examples of code on the web, and normally it's the right code... [sad]
 
ok like i said on the COE forum I think the problem come from this section

Code:
try
                {
                    [highlight #FCE94F]productDocBase = (ProductDocument)myCatia.ActiveDocument;[/highlight]
                    productRoot = productDocBase.Product;

                    MessageBox.Show(productDocBase.get_Name() + "\n\n");

                   [highlight #FCE94F] myPartDocument = (MECMOD.PartDocument)myCatia.ActiveDocument;[/highlight]
                    myPart = myPartDocument.Part;

                    MessageBox.Show(myPart.get_Name());
                }

because you're casting myCatia.ActiveDocument twice

now if you change your script to first get the type of document (as string) with

Code:
string activeDocType = myCatia.ActiveDocument.FullName.Split('.').Last();

then do a switch case to cast properly

Eric N.
indocti discant et ament meminisse periti
 
@itsmyjob: Yep, many thanks I understand better now, my new code are:

Code:
                    string[] activeDocType = myCatia.ActiveDocument.FullName.Split('.');
                    string choice = activeDocType[activeDocType.Length - 1];
                    switch (choice)
                    {
                        case "CATPart":
                            PartDocument myPartDoc = (PartDocument)myCatia.ActiveDocument;
                            myPart = myPartDoc.Part;

                            MessageBox.Show(myPart.get_Name());
                            break;
                        case "CATProduct":
                            productDocBase = (ProductDocument)myCatia.ActiveDocument;
                            productRoot = productDocBase.Product;

                            MessageBox.Show(productRoot.get_Name());
                            break;
                        default:
                            MessageBox.Show("Aucun CATProduct ni CATPart n'est accessible!");
                            break;
                    }
And it works except if there is nothing open in Catia...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top