Using tool.xml user menu with multiple selection function, I am stuck on how to find all $tool.types in folder 'tool'.
Then based on results, create individual folders (eg. BallNose, TipRad, TippedDisc....,) for found $tool.types and move each tool.type to corresponding tool.type folder created.
Solved! Go to Solution.
// Make a string expression for accessing all the tools ENTITY LIST tools = folder('tool') // Get tool type names in current language STRING LIST Tt_names = values(tools[0].Type) // Get the tool types used STRING LIST Ttypes = remove_duplicates(extract(tools,'Type')) FOREACH t IN Ttypes { // get list of all tools of given type ENTITY LIST tools_of_type = extract(filter(tools,'Type==t'),'Name') // get name of tool type in current language INT type_id = tools_of_type[0].Type STRING Type_name = Tl_names[type_id] // Create a folder if it doesn't already exist STRING Folder_name = "Tool\$Type_name" IF NOT folder_exists(fname) { CREATE FOLDER Tool $Type_name } // Move the tools to the folder FOREACH tt IN tools_of_type { EDIT FOLDER $Folder_name INSERT $tt.Name Last } }
Something like the above not tested so you may have to debug it.
Thank you @urizenYHS3W for getting me on the right path. I did a basic copy and paste...,
I'm trying to get this macro to function using "selected tools" only. Function in BLUE.
Running macro debug through tool.xml menu, errs right away on line 1 "Variable missing" . I use this same code
on all my other tool macros and works fine..., Gets through it if I run macro without debugger. Should I be modifying this Function as it seems other than string selected, the rest is redundant?
If I delete Function from Macro and allow macro to pick all tools , I get an error on line 8
Not knowing what to fix on line 8 I can't debug further. Any additional help would be greatly appreciated.
Function Main( STRING $Selected ) {
STRING LIST $ToolNames = {}
CALL Get_Tool_List($Selected, $ToolNames)
//string expression for accessing all the tools
ENTITY LIST tools = folder('tool')
// Get tool type names in current language
STRING LIST Tt_names = values(tools[0].Type)
// Get the tool types used
STRING LIST Ttypes = remove_duplicates(extract(tools,'Type'))
FOREACH tl IN $Tt_names {
// get list of all tools of given type
ENTITY LIST tools_of_type = extract(filter(tools,'Type==t'),'Name')
// get name of tool type in current language
INT type_id = tools_of_type[0].Type
STRING Type_name = Tl_names[type_id]
// Create a folder if it doesn't already exist
STRING Folder_name = "Tool\$Type_name"
IF NOT folder_exists(fname) {
CREATE FOLDER Tool $Type_name
// Move the tools to the folder
FOREACH tt IN $tools_of_type {
EDIT FOLDER $Folder_name INSERT $tt.Name Last
}
}
}
}
Function Get_Tool_List(
STRING $Selected
OUTPUT STRING LIST $Selected_Tools
)
{
If $powermill.Status.MultipleSelection.total == 0 OR $powermill.Status.MultipleSelection.First {
IF NOT member(project._keys,"Multiple_Selected_Names") {
EDIT PAR CREATE STRING "Multiple_Selected_Names"
}
$Project.Multiple_Selected_Names = ""
} ELSE {
$Project.Multiple_Selected_Names = $Project.Multiple_Selected_Names + "\"
}
$Project.Multiple_Selected_Names = $Project.Multiple_Selected_Names + $Selected
IF NOT($powermill.Status.MultipleSelection.Last or $powermill.Status.MultipleSelection.total == 0) {
MACRO ABORT
}
$Selected_Tools = TOKENS($Project.Multiple_Selected_Names, "\")
}
Needs to be split:
STRING LIST Ttypes = extract(tools,'Type')
INT num = remove_duplicates(Ttypes)
Thanks again @urizenYHS3W . Made the suggested changes ...
Populates tools list and lists all possible tool.types available to powermill then line 6 generates error.
Is there a way, on line 4, to list only the $tool.types in folder 'tool' or in the entity list 'tools' or is there not enough available information acquired at this point to give a result and I have to get past this line 6 hurtle to get there?
I find it odd that tool.type so far is represented as both
(STRING) = "End Mill" in Ttnames and as (ENUM) Type = tip_radiused in (TOOL)..., so many names!.. what to reference? Can anything be done using (ENUM)?
// Make a string expression for accessing all the tools
ENTITY LIST tools = folder('tool')
// Get tool type names in current language
STRING LIST Tt_names = values(tools[0].Type)
// Get the tool types used
STRING LIST Ttypes = extract(tools,'Type')
INT num = remove_duplicates(Ttypes)
FOREACH t IN Ttypes {
// get list of all tools of given type
ENTITY LIST tools_of_type = extract(filter(tools,'Type==t'),'Name')
// get name of tool type in current language
INT type_id = tools_of_type[0].Type
STRING Type_name = Tl_names[type_id]
// Create a folder if it doesn't already exist
STRING Folder_name = "Tool\$Type_name"
IF NOT folder_exists(fname) {
CREATE FOLDER Tool $Type_name
}
// Move the tools to the folder
FOREACH tt IN tools_of_type {
EDIT FOLDER $Folder_name INSERT $tt.Name Last
}
}
..sorry had a copy paste error there.
I find it odd that tool.type so far is represented as both
(STRING) = "End Mill" in Ttnames and as (ENUM) Type = end_mill in (TOOL)..., so many names!.. what to reference? Can anything be done using (ENUM)?
The values() method returns the data in the appropriate natural language, and in human readable terms. So you'll get the names in German, French, Chinese or whatever. If you are satisfied with the enum names then don't do the conversion.
Thank you for the clarification. I do prefer your appropriate natural language result much more than the ENUM names, was just confused why there are 2 different results for the same thing. Now that I understand why code is the way it is , I still need help getting past this line of code STRING LIST Ttypes = extract(tools,'Type').
ERROR 'Type mismatch assigning 'Type to parameter'.
No matter how much troubleshooting I try on this line, I'm getting nowhere.
I've never been successful getting tool.type to work in a macro other than the basic IF $Tool.Type == 'end_mill' or IF $Tool.Type != 'ball_nosed'.
Getting list of tool.types in folder'tool' as result is much harder than I anticipated it would be ...let alone removing duplicate entities which I hadn't even realized would need be addressed.
ENTITY LIST tools = folder('tool') OK
STRING LIST Tt_names = values(tools[0].Type) OK
STRING LIST Ttypes = extract(tools,'Type') --- At a loss --->
INT num = remove_duplicates(Ttypes) <----
STRING LIST Ttypes = apply(tools,'string(Type)')
Type checking appears to be too strict. Type is an ENUM which converts to a string but isn't. The above should work as it explicitly converts the Type to a string by applying the string function to Type.
Thanks again, again, again @urizenYHS3W , that did the trick.
But as expected, I am unable to troubleshoot the next line to get it to work.
I've tried modifying the expression to be able to get eval but not getting anywhere... all listed below.
I have very similar code I use successfully
STRING LIST $tr = extract($filter(folder('tool'), "type == '${t}' )",'tool')
but doesn't function as an ENTITY LIST.
Any additional help/guidance would be fantastic and greatly appreciated.
ENTITY LIST tools = folder('tool') OK
STRING LIST Tt_names = values(tools[0].Type) OK
STRING LIST Ttypes = apply(tools,'string(Type)') OK
INT old = remove_duplicates(Ttypes) OK
FOREACH t IN Ttypes { OK
ENTITY LIST tools_of_type = extract(filter(tools,'Type==t'),'Name') ORIGINAL PROVIDED CODE
ENTITY LIST tools_of_type = extract(filter(tools,'type==t'),'Name')
ENTITY LIST tools_of_type = extract(filter(tools,'Type == t'),'Name')
ENTITY LIST tools_of_type = extract(filter(tools,'type == t'),'Name')
ENTITY LIST tools_of_type = extract(filter('tools','Type==t'),'Name')
ENTITY LIST tools_of_type = extract(filter('tools','type==t'),'Name')
ENTITY LIST tools_of_type = extract(filter('tools','Type == t'),'Name')
ENTITY LIST tools_of_type = extract(filter('tools','type == t'),'Name')
ENTITY LIST tools_of_type = extract(filter('tools',"type == 't'"),'Name')
ENTITY LIST tools_of_type = extract(filter(folder('tool'),'Type==t'),'Name') with every variation above
FOREACH t IN Ttypes {
STRING expr = "Type=='"+string(t)+"'"
ENTITY LIST tools_of_type = extract(filter(tools,expr),'Name')
Thank you @urizenYHS3W for helping me inch my way there. What a learning curve..,
STRING expr = "Type == '"+string(t)+"'"
This Code is returning (STRING) expr = "Type == 'tip_radiused'"
Which I figure is extracted from current (STRING)t in (LIST)Ttypes.
ENTITY LIST tools_of_type = extract(filter(tools,expr),'Name')
This line is returning error "Cannot create entity using:"
I'm confused where this is going. Creating a (LIST) by extracting information by filtering a combination of
both $tools and $expr and assigning a Name?
What should the code be returning as (LIST) = ??? from the extracted/filtered .name
Figure if I know this, it could possibly help me troubleshoot it easier..., no clue
Is it trying to match current $Ttype to tools with that tool.type and add to list? Just incase if so, in $tools, (ENUM) Type = tip_radiused, not "Type == 'tip_radiused'" . Would this be affecting something? If no, any ideas would be fantastic!
ENTITY LIST tools = folder('tool')
STRING LIST Tt_names = values(tools[0].Type)
STRING LIST Ttypes = apply(tools,'string(Type)')
INT old = remove_duplicates(Ttypes)
FOREACH t IN Ttypes {
STRING expr = "Type == '"+string(t)+"'"
ENTITY LIST tools_of_type = extract(filter(tools,expr),'Name')
INT type_id = tools_of_type[0].Type
STRING Type_name = Tl_names[type_id]
// Create a folder if it doesn't already exist
STRING Folder_name = "Tool\$Type_name"
IF NOT folder_exists(fname) {
CREATE FOLDER Tool $Type_name
}
// Move the tools to the folder
FOREACH tt IN tools_of_type {
EDIT FOLDER $Folder_name INSERT $tt.Name Last
}
}
Sorry I'm not thinking
ENTITY LIST tools_of_type = filter(tools,expr)
You just want the tools of the specific type not their names.
I can see the end of the script now before erring..., thank you @urizenYHS3W .
INT type_id = tools_of_type[0].Type This code is returning (INT) type_id = 0, NEXT LINE
STRING Type_name = Tt_names[Type_id] Is returning (STRING) Type_name = "End Mill"
As per screenshot below, should it not be returning (STRING) Type_name = "Ball Nosed"
I don't know if the problem is type_id = 0 or if Type_name should be looking at something other than Tt_names since
Tt_names returns every possible powermill tool even if not in current project. Should I be referencing Ttypes since that list only has tools found in project?
Otherwise I can soldier on through the macro and it creates the folder with the wrong name due to above problem but errs trying to add tools to the folder. Guessing because there are no "end_mills" in project !? Or possibly problem with last line of code !?
ENTITY LIST $tools = folder('tool')
STRING LIST $Tt_names = values($tools[0].Type)
STRING LIST $Ttypes = apply($tools,'string(Type)')
INT old = remove_duplicates(Ttypes)
FOREACH $t IN $Ttypes {
STRING $expr = "Type == '"+string(t)+"'"
ENTITY LIST $tools_of_type = filter(tools,expr)
INT type_id = tools_of_type[0].Type
STRING Type_name = Tt_names[Type_id]
STRING Folder_name = "$Type_name"
IF NOT folder_exists($Folder_name) {
CREATE FOLDER Tool $Type_name
}
FOREACH tt IN tools_of_type {
EDIT FOLDER $Folder_name INSERT $tt.Name Last
}
}
Replace
EDIT FOLDER $Folder_name INSERT $tt.Name Last
with
STRING Cmd="EDIT FOLDER '"+$Folder_Name+"' INSERT '"+pathname($T)+"' LAST"
DoCommand $Cmd
FUNCTION MAIN { IF size(folder('tool')) == 0 { RETURN } STRING LIST FolderNames=values(folder('tool')[0].Type) STRING Cmd='' FOREACH T in folder('tool') { STRING NewFolder='Tool\'+$FolderNames[int($T.Type)] IF NOT folder_exists($NewFolder) { $Cmd="CREATE folder 'Tool' '"+$FolderNames[int($T.Type)]+"'" DoCommand $Cmd } IF dirname(pathname($T)) != $NewFolder { $Cmd="EDIT FOLDER '"+$NewFolder+"' INSERT '"+pathname($T)+"' LAST" DoCommand $Cmd } }
Thank you for helping @Anonymous .
I don't know if this solves folder naming issue or not as I silll have to address what it wrong with
INT type_id = tools_of_type[0].Type This code is returning (INT) type_id = 0, NEXT LINE
STRING Type_name = Tt_names[Type_id] Is returning (STRING) Type_name = "End Mill"
As per screenshot below, should it not be returning (STRING) Type_name = "Ball Nosed"
The script you attached works perfectly to do the same job and I will definitely hang on to that code but it's light years ahead of my current coding abilities. I'm learning as I go and finally wrapping my head around what @urizenYHS3W has been kind enough to school me on which I am finding to be very advanced . I'm aiming to finish the original script if it kills me. If you have a solution for above issue I will gladly try it!!
Thank you.
ENTITY LIST $tools = folder('tool')
STRING LIST $Tt_names = values($tools[0].Type)
STRING LIST $Ttypes = apply($tools,'string(Type)')
INT old = remove_duplicates(Ttypes)
FOREACH $t IN $Ttypes {
STRING $expr = "Type == '"+string(t)+"'"
ENTITY LIST $tools_of_type = filter(tools,expr)
INT type_id = tools_of_type[0].Type
STRING Type_name = Tt_names[Type_id]
STRING Folder_name = "$Type_name"
IF NOT folder_exists($Folder_name) {
CREATE FOLDER Tool $Type_name
}
FOREACH tt IN tools_of_type {
EDIT FOLDER $Folder_name INSERT $tt.Name Last
}
}
My macro in PM 2017 Standard working:
There is no Hungarian translation to turning tools,
will remain in English
- In
Yes @Anonymous your macro works perfectly in powermill 2020 as well.
The script you attached works perfectly to do the same job and I will definitely hang on to that code but it's light years ahead of my current coding abilities. I'm learning as I go and finally wrapping my head around what @urizenYHS3W has been kind enough to school me on which I am finding to be very advanced . I'm aiming to finish the original script if it kills me. If you have a solution for below issue I will gladly try it!!
INT type_id = tools_of_type[0].Type This code is returning (INT) type_id = 0, NEXT LINE
STRING Type_name = Tt_names[Type_id] Is returning (STRING) Type_name = "End Mill"
As per screenshot below, should it not be returning (STRING) Type_name = "Ball Nosed"
I don't know if the problem is type_id = 0 or if Type_name should be looking at something other than Tt_names since
Tt_names returns every possible powermill tool even if not in current project. Should I be referencing Ttypes since that list only has tools found in project?
ENTIRE MACRO >>>
ENTITY LIST $tools = folder('tool')
STRING LIST $Tt_names = values($tools[0].Type)
STRING LIST $Ttypes = apply($tools,'string(Type)')
INT old = remove_duplicates(Ttypes)
FOREACH $t IN $Ttypes {
STRING $expr = "Type == '"+string(t)+"'"
ENTITY LIST $tools_of_type = filter(tools,expr)
INT type_id = tools_of_type[0].Type
STRING Type_name = Tt_names[Type_id]
STRING Folder_name = "$Type_name"
IF NOT folder_exists(Folder_name) {
CREATE FOLDER Tool $Type_name
}
FOREACH tt IN tools_of_type {
EDIT FOLDER $Folder_name INSERT $tt.Name Last
}
}
Thank you for your good opinion, but I think the difference between our knowledge is much smaller than you think.
I tried to keep as much of the original code as possible, this is a working version:
ENTITY LIST $tools = folder('tool') STRING LIST $Tt_names = values($tools[0].Type) // The apply() FUNCTION not working in PM2017 //STRING LIST $Ttypes = apply($tools,'string(Type)') // Begin apply() replacement STRING LIST $Ttypes= {} FOREACH T IN folder('tool') { INT I=add_last($Ttypes,string($T.Type)) } // End apply() replacement for PM2017 INT old = remove_duplicates(Ttypes) FOREACH $t IN $Ttypes { STRING $expr = "Type == '"+ $t +"'" ENTITY LIST $tools_of_type = filter(tools,expr) INT type_id = int($tools_of_type[0].Type) STRING Type_name = $Tt_names[$Type_id] STRING Folder_name = $Type_name IF NOT folder_exists('Tool\'+Folder_name) { CREATE FOLDER Tool $Type_name } FOREACH tt IN tools_of_type { IF dirname(pathname($tt)) != 'Tool\'+Folder_name { STRING Cmd='EDIT FOLDER "Tool\'+$Folder_name+'" INSERT "'+pathname($tt)+'" Last' DoCommand $Cmd } } }
Of course, you can safely delete the replacement code by restoring the original apply () function
Made suggested changes. Had missed a change to code INT type_id = int($tools_of_type[0].Type)
Works perfect now.
This is the code I said was beyond me.... all the $cmd stuff is still new to me.
FUNCTION MAIN {
IF size(folder('tool')) == 0 {
RETURN
}
STRING LIST FolderNames=values(folder('tool')[0].Type)
STRING Cmd=''
FOREACH T in folder('tool') {
STRING NewFolder='Tool\'+$FolderNames[int($T.Type)]
IF NOT folder_exists($NewFolder) {
$Cmd="CREATE folder 'Tool' '"+$FolderNames[int($T.Type)]+"'"
DoCommand $Cmd
}
IF dirname(pathname($T)) != $NewFolder {
$Cmd="EDIT FOLDER '"+$NewFolder+"' INSERT '"+pathname($T)+"' LAST"
DoCommand $Cmd
}
}
Can't find what you're looking for? Ask the community or share your knowledge.