Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Solution] Exporting BOM with AssemblyConvertor #110

Closed
deloarts opened this issue Mar 25, 2022 · 3 comments
Closed

[Solution] Exporting BOM with AssemblyConvertor #110

deloarts opened this issue Mar 25, 2022 · 3 comments
Assignees

Comments

@deloarts
Copy link
Contributor

Problem

I tried exporting the bill of material as Excel using the get_item method:

bom = product.get_item("BillOfMaterial")
bom.set_current_format(format)
bom.print("XLS", path, product)

This is failing with AttributeError: 'AnyObject' object has no attribute 'SetCurrentFormat' since the get_item method doesn't return AssemblyConvertor.

Solution

I made changes to the any_object.py file by adding the following import

from pycatia.system_interfaces.cat_base_dispatch import CATBaseDispatch

and by adding the following method to the AnyObject class:

def get_item_dispatch(self, id_name: str) -> CATBaseDispatch:
    return self.com_object.GetItem(id_name)

I was following the typehints of the V5automation.chm:

AnyObject (method)
...
Methods
  GetItem(CATBSTR IDName) As CATBaseDispatch

This way i was able to get the AssemblyConvertor object and thus the bill of material as Excel:

from pycatia.product_structure_interfaces.product import Product
from pycatia.product_structure_interfaces.assembly_convertor import AssemblyConvertor

def export_bom(product: Product, path: str, format: tuple):
    bom = AssemblyConvertor(product.get_item_dispatch("BillOfMaterial"))
    bom.set_current_format(format)
    bom.set_secondary_format(format)
    bom.print("XLS", path, product)

with the format being a tuple containing the keywords of the products properties ("PartNumber", "Revision", ...) or the names of user_ref_properties and the path is using windows style seperators \\.

Note

Sometimes the export failes with an error (-2147467259). I haven't figured out what this error is, because I only encountered it once. After restarting my computer I wasn't able to reproduce the error again. But I don't think this error is related to the pywin32 dispatch, because I also got this error by running the equivalent catvbs:

Sub CATMain()
    CATIA.StatusBar = "Running BOM Export"
    Dim Path: Path = "C:\Users\i030\Desktop\bom.xls"
    Dim Product
    Dim BOM
    Dim BOMFormat(4)
    
    BOMFormat(0) = "Typ"
    BOMFormat(1) = "Menge"
    BOMFormat(2) = "Teilenummer"
    BOMFormat(3) = "Definition"

    Set Product = CATIA.ActiveDocument.Product
    Set BOM = Product.GetItem("BillOfMaterial")

    BOM.SetCurrentFormat BOMFormat
    BOM.SetSecondaryFormat BOMFormat
    BOM.Print "XLS", Path, Product
End Sub

Discussion

I havent't tested it yet, but it should be possible, that this way (returning the get_item method as CATBaseDispatch) may work for all other objects that you try to get with the get_item method. Do you think this could be added or may this break something else?

evereux added a commit that referenced this issue Apr 12, 2022
method appears to require the use of system_service.avaluate
@evereux
Copy link
Owner

evereux commented Apr 12, 2022

Thanks for the question @deloarts!

I've submitted a patch to the development branch for which you can see the link above. This change only affects the assembly_convertor.print method so there's no worry of it affecting anything else.

My quick and dirty code that worked:

from pycatia import catia
from pycatia.product_structure_interfaces.product import Product
from pycatia.product_structure_interfaces.assembly_convertor import AssemblyConvertor
caa = catia()
document = caa.active_document
product = document.product
product = Product(product.com_object)

bom = product.get_item("BillOfMaterial")
assembly_convertor = AssemblyConvertor(bom.com_object)

details_top = ("Quantity", "Part Number", "Type", "Nomenclature", "Revision")
details_recap = ("Quantity", "Part Number")
assembly_convertor.set_current_format(details_top)
assembly_convertor.set_secondary_format(details_recap)

assembly_convertor.print("XLS", "C:\\Users\\evereux\\Documents\\lalala.xls", product)

Thanks for reporting this and going to the effort you have. It's appreciated.

I think this is something worth adding to the examples too.

@evereux
Copy link
Owner

evereux commented Apr 12, 2022

Sometimes the export failes with an error (-2147467259). I haven't figured out what this error is, because I only encountered it once. After restarting my computer I wasn't able to reproduce the error again. But I don't think this error is related to the pywin32 dispatch, because I also got this error by running the equivalent catvbs:

Just been playing a bit with this and I can reproduce:

  • run script to generate xls.
  • press No when asked to overwrite file (this will throw a similar error).
  • run script again (error is thrown, file is still created).

I will continue to get the error until I restart CATIA. This isn't a bug in pycatia as far as I know. Whether the bug is in pywin32 or CATIA itself I don't know.

error message:

pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, 'ExecuteScript(Evaluate, MemoryMacro, print)\nExecution error\n(The scripting engine for CATScript has reported the following error:\n\nSource: CATIAAssemblyConvertor\nDescription: The method Print failed\nLine: 3\nColumn: 12\n)\n', None, 0, -2147467259), None)

@deloarts
Copy link
Contributor Author

deloarts commented Apr 12, 2022

I updated my local assembly_converter.py print method according to your changes and got the print method working using your way (by passing the com_object).

bom = product.get_item("BillOfMaterial")
assembly_convertor = AssemblyConvertor(bom.com_object)

Many thanks for pointing me in the right direction, I think I can solve some other issues in my code this way ...

For the error: I was able to reproduce the error message -2147467259 by using linux style separtors C:/Users/... instead of windows style C:\\Users\\.. when passing the path. You then have to kill CATIA and Excel in the task-manager, otherwise the error will pop up everytime, even when you use the correct separator afterwards. Steps to reproduce:

  1. Use wrong separator / and export the bom using the print method and wait for the error to happen
  2. No Excel file will be created
  3. Use correct separator \\ and export the bom again and wait for the error (a file will be created)
  4. Open the excel file: It's empty
  5. Kill CATIA and Excel using the task-manager
  6. Delete the empty excel file
  7. Restart CATIA and export the bom using the print method and the correct sep
  8. Find the excel file being exported correct

If you're planning on adding this to the examples you may consider adding a warning for using the correct separator, because the error message just says unknown error:

>>> import win32api
>>> win32api.FormatMessage(-2147467259)
'Unbekannter Fehler\r\n'

Closing the issue with this.

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants