That's not exactly what you asked for, but I hope you can make it based on that.
Export:
FUNCTION Main() {
// Tool export example macro
// The $ToolProperties freely expandable with valid members, and special handling elements.
// The separator character '"' is beacuse it cannot be a valid PowerMill name, unlike the comma character.
// The Map record separator is '|', Map field separator is ':'.
// The 1st member always 'Type', 2nd member always 'Name', the other members can be in any order.
// In the example the 'ShankData' and 'HolderData' special elemets. - The valid member names 'ShankSetValues' and 'HolderSetValues'.
STRING LIST ToolProperties={'Type','Name','Diameter','Length','TipRadius','Overhang','DrillAngle','ShankData','HolderData','HolderName'}
STRING ExportFilename = ''
$ExportFilename = FILESELECT "Please select tool export file"
// Handling of a previously interrupted macro run
DIALOGS MESSAGE OFF
FILE CLOSE export
DIALOGS MESSAGE ON
//
FILE OPEN $ExportFilename FOR WRITE AS export
STRING Header=''
FOREACH S IN $ToolProperties {
$Header=$Header+$S+'"'
}
// Write field names
FILE WRITE $Header TO export
FOREACH T IN folder('tool') {
STRING ToolData=''
FOREACH P IN $ToolProperties {
IF member($T._keys,$P) {
STRING Cmd='$'+'PropValue ='+'$'+'T.'+$P
STRING PropValue=''
DoCommand $Cmd
// The empty fields replace with ' '
$PropValue=select($PropValue=='',' ',$PropValue)
$ToolData=$ToolData+$PropValue+'"'
} ELSE {
SWITCH $P {
CASE 'Name'
// Special case: the member($T._keys,'Name') return with false (PowerMill 2017)
$ToolData=$ToolData+$T.Name+'"'
BREAK
CASE 'ShankData'
// Shank data
IF size($T.ShankSetValues) == 0 {
$ToolData=$ToolData+' "'
} ELSE {
STRING Shank=''
FOREACH MapData IN $T.ShankSetValues {
$Shank=$Shank+$MapData.LowerDiameter+':'+$MapData.UpperDiameter+':'+$MapData.Length+'|'
}
$ToolData=$ToolData+$Shank+'"'
}
BREAK
CASE 'HolderData'
// Holder data
IF size($T.HolderSetValues) == 0 {
$ToolData=$ToolData+' "'
} ELSE {
STRING Holder=''
FOREACH MapData IN $T.HolderSetValues {
$Holder=$Holder+$MapData.LowerDiameter+':'+$MapData.UpperDiameter+':'+$MapData.Length+':'+$MapData.Ignore+'|'
}
$ToolData=$ToolData+$Holder+'"'
}
BREAK
DEFAULT
// Missing members, misspelling field names
$ToolData=$ToolData+' "'
}
}
}
FILE WRITE $ToolData TO export
}
FILE CLOSE export
}
Import:
FUNCTION Main() {
// Tool import example macro.
// The separator character '"' is beacuse it cannot be a valid PowerMill name, unlike the comma character.
// The Map record separator is '|', Map field separator is ':'.
// The 1st member always 'Type', 2nd member always 'Name', the other members can be in any order.
// Supported tool types: Ballnosed,Tip radiused and Drill. The dictionary expandable.
DICTIONARY ToolTypes={'tip_radiused','TIPRADIUSED','ball_nosed','BALLNOSED','drill','DRILL'}
STRING ImportFilename = ''
$ImportFilename = FILESELECT "Please select tool import file"
IF NOT file_exists( $ImportFilename) {
RETURN
}
// Handling of a previously interrupted macro run
DIALOGS MESSAGE OFF
FILE CLOSE import
DIALOGS MESSAGE ON
//
FILE OPEN $ImportFilename FOR READ AS import
STRING Header=''
FILE READ $Header FROM import
STRING LIST ToolProperties=tokens($Header,'"')
IF (size(ToolProperties) < 2) OR (ucase($ToolProperties[0]) != 'TYPE') OR (ucase($ToolProperties[1]) != 'NAME') {
FILE CLOSE import
MESSAGE INFO 'Wrong file -missing header'
RETURN
}
STRING LIST ImportData={}
FILE READ $ImportData FROM import
FILE CLOSE import
INT Count=1
FOREACH $Record IN $ImportData {
STRING LIST ToolData=tokens($Record,'"')
IF size($ToolData) != $size(ToolProperties) {
MESSAGE INFO 'Wrong record Nr.'+$Count+' -different size '+size($ToolData)+' != ' + $size(ToolProperties)
RETURN
}
STRING ToolType=remove_first($ToolData)
IF member($ToolTypes,ToolType) {
STRING ToolName=remove_first($ToolData)
IF entity_exists('tool',$ToolName) {
$ToolName=new_entity_name('tool',$ToolName)
}
STRING Cmd='CREATE TOOL "'+$ToolName+'" $ToolTypes[$ToolType]'
DoCommand $Cmd
ENTITY T=entity('tool',$ToolName)
INT Field=2
FOREACH P IN $ToolData {
STRING FieldName=$ToolProperties[$Field]
IF member($T._keys,$FieldName) {
STRING Cmd='$'+'T.'+$FieldName+'="'+$P+'"'
DoCommand $Cmd
} ELSE {
SWITCH $FieldName {
CASE 'ShankData'
// Shank data
IF trim($P) != '' {
STRING LIST Maps=tokens($P,'|')
FOREACH item IN $Maps {
STRING LIST Values=tokens($item,':')
IF size($Values) != 3 {
MESSAGE INFO MESSAGE INFO 'Wrong Shank data in Nr.'+$Count+'record. '+ $size(Values)+' != 3'
RETURN
}
EDIT TOOL ; SHANK_COMPONENT ADD
REAL V=real($Values[0])
EDIT TOOL ; SHANK_COMPONENT LOWERDIA $V
$V=real($Values[1])
EDIT TOOL ; SHANK_COMPONENT UPPERDIA $V
$V=real($Values[2])
EDIT TOOL ; SHANK_COMPONENT LENGTH $V
}
}
BREAK
CASE 'HolderData'
// Holder data
IF trim($P) != '' {
STRING LIST Maps=tokens($P,'|')
FOREACH item IN $Maps {
STRING LIST Values=tokens($item,':')
IF size($Values) != 4 {
MESSAGE INFO MESSAGE INFO 'Wrong Holder data in Nr.'+$Count+'record. '+ $size(Values)+' != 4'
RETURN
}
EDIT TOOL ; HOLDER_COMPONENT ADD
REAL V=real($Values[0])
EDIT TOOL ; HOLDER_COMPONENT LOWERDIA $V
$V=real($Values[1])
EDIT TOOL ; HOLDER_COMPONENT UPPERDIA $V
$V=real($Values[2])
EDIT TOOL ; HOLDER_COMPONENT LENGTH $V
IF $Values[3]==0 {
EDIT TOOL ; HOLDER_COMPONENT IGNORE NO
} ELSE {
EDIT TOOL ; HOLDER_COMPONENT IGNORE YES
}
}
}
BREAK
DEFAULT
// Missing members, misspelling field names
}
}
$Field=$Field+1
}
}
}
}