Closed ozserhatt closed 5 months ago
Look at the error messsage, look at the method you're calling and see what it expects. relations
You need to pass a Parameter
not a str
.
I would expect
part_name = bom_parameter_set.direct_parameters.item("PART-NAME").value
relations.create_formula("formula1", "", part_num, f"{part_name}")
to be more like
param_part_name = bom_parameter_set.direct_parameters.item("PART-NAME")
relations.create_formula("formula1", "", param_part_name, param_part_name.value)
But, this will generate an error. I'm not sure how to solve this as I don't understand what your end goal here is. The relation itself doesn't make much sense.
There are examples of using relations in:
https://github.com/evereux/pycatia/blob/master/user_scripts/create_bounding_box.py
https://github.com/evereux/pycatia/blob/master/user_scripts/wing_surface_from_naca_profile.py
Also, record a macro mimicking what it is you're trying to do and read the generated code. Should give you some pointers.
I want to relation, parameter of Part Number with my local parameter PART-NAME. If i write on parameter PART-NAME : "xxxx" , it will be change my Part Number to "xxxx" I sent macro for you
Sub CATMain()
Dim partDocument1 As PartDocument
Set partDocument1 = CATIA.ActiveDocument
Dim part1 As Part
Set part1 = partDocument1.Part
Dim relations1 As Relations
Set relations1 = part1.Relations
Dim parameters1 As Parameters
Set parameters1 = part1.Parameters
Dim parameter1 As Parameter
Set parameter1 = parameters1.Item("Part2\Part Number")
Dim formula1 As Formula
Set formula1 = relations1.CreateFormula("Formula.1", "", parameter1, "`BOM\POS-NO` +" & """" & "_" & """" & "+`BOM\PART-NAME` ")
formula1.Rename "Formula.1"
End Sub
OK I understand now.
You need to get the Part Number
Parameter
from the Part
. The essential line being root_part_number = parameters.item(f'{product.part_number}\Part Number')
from pycatia import catia
from pycatia.product_structure_interfaces.product_document import ProductDocument
from pycatia.mec_mod_interfaces.part_document import PartDocument
caa = catia()
application = caa.application
documents = application.documents
product_document: ProductDocument = application.active_document
product = product_document.product
part_document = PartDocument(documents.item(product.reference_product.file_name).com_object)
part = part_document.part
parameters = part.parameters
relations = part.relations
root_part_number = parameters.item(f'{product.part_number}\Part Number')
root_parameter_set = parameters.root_parameter_set
parameter_sets = root_parameter_set.parameter_sets
bom_parameter_set = parameter_sets.item("BOM")
param_part_name = bom_parameter_set.direct_parameters.item("PART-NAME")
relations.create_formula("formula1", "", param_part_name, f"`{root_part_number.name}`")
Actually, I try to say it will be reverse so, if i write in param_part_name , I want see on my PartNumber automatically. I try it but it does not run..
from pycatia import catia
from pycatia.product_structure_interfaces.product_document import ProductDocument
from pycatia.mec_mod_interfaces.part_document import PartDocument
caa = catia()
application = caa.application
documents = application.documents
product_document: ProductDocument = application.active_document
product = product_document.product
part_document = PartDocument(documents.item(product.reference_product.file_name).com_object)
part = part_document.part
parameters = part.parameters
relations = part.relations
root_part_number = parameters.item(f'{product.part_number}\Part Number')
root_parameter_set = parameters.root_parameter_set
parameter_sets = root_parameter_set.parameter_sets
bom_parameter_set = parameter_sets.item("BOM")
param_part_name = bom_parameter_set.direct_parameters.item("PART-NAME")
relations.create_formula("formula1", "", root_part_number, f"`{param_part_name.value}`")
SyntaxWarning: invalid escape sequence '\P'
root_part_number = parameters.item(f'{product.part_number}\Part Number')
You need to use the param_part_name.name
as I did above but you need to drop the root part number.
Explore the output of param_part_name.name to understand the need of the split.
Replace the last line with this:
param_part_name_without_parent = param_part_name.name.split('\\', 1)[1]
relations.create_formula("formula1", "", root_part_number, f"`{param_part_name_without_parent}`")
Reading your macro above you should have been able to debug this yourself. 😄
Aff, man, i can not do it
from pycatia import catia
from pycatia.product_structure_interfaces.product_document import ProductDocument
from pycatia.mec_mod_interfaces.part_document import PartDocument
caa = catia()
application = caa.application
documents = application.documents
product_document: ProductDocument = application.active_document
product = product_document.product
part_document = PartDocument(documents.item(product.reference_product.file_name).com_object)
part = part_document.part
parameters = part.parameters
relations = part.relations
root_part_number = parameters.item(f'{product.part_number}\Part Number')
root_parameter_set = parameters.root_parameter_set
parameter_sets = root_parameter_set.parameter_sets
part_num = parameters.item("part_number")
bom_parameter_set = parameter_sets.item("BOM")
param_part_name = bom_parameter_set.direct_parameters.item("PART-NAME")
param_part_name_without_parent = param_part_name.name.split('\\', 1)[1]
relations.create_formula("formula1", "", root_part_number, f"`{param_part_name_without_parent}`")
raise CATIAApplicationException(f'Could not find parameter name "{index}".')
pycatia.exception_handling.exceptions.CATIAApplicationException: Could not find parameter name "part_number".
I can't tell what line it's failing on from your error log. If it's root_part_number = parameters.item(f'{product.part_number}\Part Number')
you need to ask yourself why?
Is there a parameter in the parameters collection called Part Number
? Print out the contents of the parameters collection.
I suspect this is a locale issue where your installation of CATIA V5 uses your locality translation of Part Number
.
Again, simple to debug, no?
Try removing this, it's not relevant to what we're doing here as far as I can see:
part_num = parameters.item("part_number")
I can't help anymore unless I see the script error output regarding where the failure was.
I've written this stand alone script that should work for anyone. It'll fail for those not using an English locale for Catia V5 but will get a warning message related to that.
Also, note the use of Parameters.get_name_to_use_in_relation
. Just discovered that, very useful!
"""
Creates the string parameter `part_number`. The `Document`s `Part Number`
(for english locales) is then linked to the output of `part_number` using
relations / formula.
Changing the parameter `part_number` will then update the `Document`s
`Part Number`.
Requirements: The active document must be a CATPart.
"""
```python
from pycatia import catia
from pycatia.exception_handling.exceptions import CATIAApplicationException
from pycatia.mec_mod_interfaces.part_document import PartDocument
caa = catia()
application = caa.application
documents = application.documents
part_document: PartDocument = application.active_document
part = part_document.part
product = part_document.product
parameters = part.parameters
relations = part.relations
# first check to see if the parameter already exists, if not then create it
try:
param_part_number = parameters.item('part_number')
except CATIAApplicationException:
param_part_number = parameters.create_string('part_number', 'TempName')
try:
param_root_part_number = parameters.item(f'{product.part_number}\Part Number')
except CATIAApplicationException:
raise CATIAApplicationException('Change "Part Number" to the correct translation for your locale')
relations.create_formula('Formula.1', '', param_root_part_number, f'`{parameters.get_name_to_use_in_relation(param_part_number)}`')
That was good stuff man, but still I can not for sub-parameters. 1- I have a sub-parameterset called BOM 2-I have a sub-parameter inside BOM called PART-NAME 3- Not give a raise or error, but it does not work. 4-Can you try this code ? And you can see from +Relations on Catia. We have a warning icon.
from pycatia import catia
from pycatia.exception_handling.exceptions import CATIAApplicationException
from pycatia.mec_mod_interfaces.part_document import PartDocument
caa = catia()
application = caa.application
documents = application.documents
part_document: PartDocument = application.active_document
part = part_document.part
product = part_document.product
parameters = part.parameters
relations = part.relations
root_parameter_set = parameters.root_parameter_set
parameter_sets = root_parameter_set.parameter_sets
bom_set = parameter_sets.item("BOM")
# first check to see if the parameter already exists, if not then create it
try:
param_part_number = bom_set.direct_parameters.item("PART-NAME")
except CATIAApplicationException:
param_part_number = parameters.create_string('part_number', 'TempName')
try:
param_root_part_number = parameters.item(f'{product.part_number}\Part Number')
except CATIAApplicationException:
raise CATIAApplicationException('Change "Part Number" to the correct translation for your locale')
relations.create_formula('Formula.1', '', param_root_part_number, f'`{bom_set.direct_parameters.get_name_to_use_in_relation(param_part_number)}`')
If you want the parameter to be created under the set "BOM", do like this.
bom_set.direct_parameters.create_string('part_number', 'TempName'). And there was an error with the fstring for the relation.
from pycatia import catia
from pycatia.exception_handling.exceptions import CATIAApplicationException
from pycatia.mec_mod_interfaces.part_document import PartDocument
caa = catia()
application = caa.application
documents = application.documents
part_document: PartDocument = application.active_document
part = part_document.part
product = part_document.product
parameters = part.parameters
relations = part.relations
root_parameter_set = parameters.root_parameter_set
parameter_sets = root_parameter_set.parameter_sets
bom_set = parameter_sets.item("BOM")
# first check to see if the parameter already exists, if not then create it
try:
param_part_number = bom_set.direct_parameters.item("PART-NAME")
except CATIAApplicationException:
param_part_number = bom_set.direct_parameters.create_string('part_number', 'TempName')
try:
param_root_part_number = parameters.item(f'{product.part_number}\Part Number')
except CATIAApplicationException:
raise CATIAApplicationException('Change "Part Number" to the correct translation for your locale')
relations.create_formula('Formula.1', '', param_root_part_number, f'{bom_set.direct_parameters.get_name_to_use_in_relation(param_part_number)}')
Well done ! Thank you dear Mithro. Problem solved :)
Bro! If it is active document Product so, you have a tree with part in product document. This is not working.
raise CATIAApplicationException(f'Could not find parameter name "{index}".')
pycatia.exception_handling.exceptions.CATIAApplicationException: Could not find parameter name "Product2\Part Number".
I have a loop to add formula all parts.
I have edited my script above to include a description to explicitly state that's it's designed for use in a CATPart
.
If you want it to work for a CATProduct
you'll need to implement some of the logic already seen in this topic, written by you.
If you want to get this to work when looping through a product you'll need to implement some of the logic in #213 which was started by you.
Yeah, I know that but it does not work. When in loop , it is trying to find a parameter of Part Number for product. But my loop , if it is product, run again loop and if it is part, create formula I have recursive loop.
Another question is : How can i relation with two parameters ? I try it but i can not find really. There is an yellow warning error on formula.
from pycatia import catia
from pycatia.exception_handling.exceptions import CATIAApplicationException
from pycatia.mec_mod_interfaces.part_document import PartDocument
caa = catia()
application = caa.application
documents = application.documents
part_document: PartDocument = application.active_document
part = part_document.part
product = part_document.product
parameters = part.parameters
relations = part.relations
root_parameter_set = parameters.root_parameter_set
parameter_sets = root_parameter_set.parameter_sets
bom_set = parameter_sets.item("BOM")
# first check to see if the parameter already exists, if not then create it
try:
param_part_number = bom_set.direct_parameters.item("PART-NAME")
param_pos_no = bom_set.direct_parameters.item("POS-NO")
except CATIAApplicationException:
param_part_number = bom_set.direct_parameters.create_string('PART-NAME', 'TempName')
param_pos_no = bom_set.direct_parameters.create_string('POS-NO', '00_000')
try:
param_root_part_number = parameters.item(f'{product.part_number}\Part Number')
except CATIAApplicationException:
raise CATIAApplicationException(
'Change "Part Number" to the correct translation for your locale')
param1 = bom_set.direct_parameters.get_name_to_use_in_relation(param_part_number)
param2 = bom_set.direct_parameters.get_name_to_use_in_relation(param_pos_no)
relations.create_formula('PART-NUMBER', '', param_root_part_number,
f"'{param1}_{param2}'")
relations.create_formula('PART-NUMBER', '', param_root_part_number, f'{param1}+"_"+{param2}')
Thank you really, dear brother !!!
Thankyou for the help @Mithro86 . 👍
If you select a part on tree, that's OK! But ; When you select a product if you want to loop it inside parts, it is an error :
I think it try to find a Part Number parameter for product.
raise CATIAApplicationException(f'Could not find parameter name "{index}".')
pycatia.exception_handling.exceptions.CATIAApplicationException: Could not find parameter name "Product3\Part Number".
param_root_part_number = parameters.item(f'{product.part_number}\Part Number')
I need to " f'(part.part_number}\Part Number) " But the class of Part does not exist PART NUMBER function
I don't understand. param_root_part_number = parameters.item(f'{product.part_number}\Part Number')
is correct and works in the context of the examples so far.
Why this isn't working for you I don't know. I'm guessing it's to do with the way you're looping through a Product. You haven't provided any code and my crystal ball is currently broken.
I think it is something like this you are looking for? It goes trough the Product and adds "BOM"-set and creates the relation for renaming. Added some logic for the renaming based on position and parent product.
from pycatia import catia
from pycatia.in_interfaces.documents import Documents
from pycatia.product_structure_interfaces.product_document import ProductDocument
from pycatia.product_structure_interfaces.product import Product
from pycatia.mec_mod_interfaces.part import Part
from pycatia.mec_mod_interfaces.part_document import PartDocument
from pycatia.exception_handling.exceptions import CATIAApplicationException
caa = catia()
application = caa.application
documents = application.documents
active_document = ProductDocument(application.active_document.com_object)
product = active_document.product
def work_in_part(part_document, i, sub_product_id):
part = part_document.part
part = Part(part.com_object)
parameters = part.parameters
relations = part.relations
root_set = parameters.root_parameter_set
# check for subset otherwise create subset
try:
bom_set = root_set.parameter_sets.item("BOM")
except:
bom_set = root_set.parameter_sets.create_set("BOM")
try:
param_part_number = bom_set.direct_parameters.item("PART-NAME")
param_pos_no = bom_set.direct_parameters.item("POS-NO")
except CATIAApplicationException:
param_part_number = bom_set.direct_parameters.create_string('PART-NAME', 'TempName')
pos_no = str(i).zfill(3)
sub_product_id = str(sub_product_id).zfill(2)
param_pos_no = bom_set.direct_parameters.create_string('POS-NO', f'{sub_product_id}_{pos_no}')
part_product = Product(part_document.get_item(part.name).com_object)
try:
param_root_part_number = parameters.item(f'{part_product.part_number}\\Part Number')
param1 = bom_set.direct_parameters.get_name_to_use_in_relation(param_part_number)
param2 = bom_set.direct_parameters.get_name_to_use_in_relation(param_pos_no)
relations.create_formula('PART-NUMBER', '', param_root_part_number, f'{param1}+"_"+{param2}')
part.update()
except CATIAApplicationException:
raise CATIAApplicationException(
'Change "Part Number" to the correct translation for your locale')
def traverse_product_structure(product, documents, sub_product_id_counter=[0], parent_sub_product_id=0):
children = product.get_children()
for i, child in enumerate(children):
if child.reference_product.type == "CATProduct":
sub_product_id_counter[0] += 1
current_sub_product_id = sub_product_id_counter[0]
traverse_product_structure(child, documents, sub_product_id_counter, current_sub_product_id)
elif child.reference_product.type == "CATPart":
part_document = PartDocument(documents.item(child.reference_product.file_name).com_object)
work_in_part(part_document, i, parent_sub_product_id)
traverse_product_structure(product, documents)
Edited to handle deeper level sub-products.
Thanks for taking the time to do this. Appreciated.
Closing as original issue is resolved.
Can you help me dear friends ? I can not create a relation with parameter value on Part Number
ERROR :