I'm offering up a version of our tool change macro that we use to make tool changes easier and less code intensive in programs. Note this also makes MDI tool changes MUCH easier. This will activate the tool length offset and work offset G54 as well. This requires macros to use.
I'd appreciate any comments or suggestions for improving this.
And a disclaimer: Check the G and M codes against what your machine uses!


Usage:
T12
M98 P9006 (or just and M6 if you register the program, see below)

Yep that is all it takes to get T12 called to the spindle, with the tool length active.


You may replace the M98 P9006 with a simple M6 if you register program O9006 as M6 This may vary some for different controls, on our machine we have to set parameter 6046 = 6

parameter 6041 matches O9001
6042 matches O9002
Ect.
What ever number is assigned to the 604x is the M code that runs the 900x program


Code:
O9006 (TOOL CHANGE) 
G80
M9
G91G30Z0M5
G30X0Y0M15
IF[#[2000+#4120]LE11.0]GOTO10
#3000=97 (,YIKES, TOOL LENGTH IS TOO LONG) 
N0010
G90
T#4320M6
G53 (SUPPRESS MULTI-BUFFER)
IF[#4320EQ0]GOTO9999
POPEN
DPRNT [TIMES@#3011[80]@#3012[60]@P#120[40]@T#4120[20]]
PCLOS
IF[#[2000+#4120]GE1.0]GOTO20
#3000=98 (,YIKES, TOOL LENGTH IS TOO SHORT) 
N0020
IF[#[2200+#4120]LT1.0]GOTO30
#3000=99 (,YIKES, TOOL WEAR IS TOO LARGE) 
N0030
G90G0G43G54Z[24.99-[#[2000+#4120]+#[2200+#4120]]]H#4120
G53 (SUPPRESS MULTI-BUFFER)
IF[#4320NE#500]GOTO50
M0
M99
N0050
M1
N9999
M99

Now for the breakdown of the code

O9006 (TOOL CHANGE)
G80
M9
G91G30Z0M5
G30X0Y0M15

End previous activities and go to tool change position. Make sure automatic cycles are canceled and coolant is off, stop and orient the spindle.

IF[#[2000+#4120]LE11.0]GOTO10
#3000=97 (,YIKES, TOOL LENGTH IS TOO LONG)
N0010

This is a quick check that the tool isn't too long for the machine/tool change, and will stop with error 97 and ",YIKES, TOOL LENGTH IS TOO LONG" as the message.

G90
T#4320M6

The actual tool change. this machine uses the T# on the same line as the M6 not all will. #4320 recalls the last T# used previously

G53 (SUPPRESS MULTI-BUFFER)
IF[#4320EQ0]GOTO9999

If T0 is called exit without activating any tool length ect.


POPEN
DPRNT [TIMES@#3011[80]@#3012[60]@P#120[40]@T#4120[20]]
PCLOS

Outputs on the com port a line with the date and time, program number, and tool number separated by the @ symbol. I couldn't figure out how to output a comma or tab...

IF[#[2000+#4120]GE1.0]GOTO20
#3000=98 (,YIKES, TOOL LENGTH IS TOO SHORT)
N0020
IF[#[2200+#4120]LT1.0]GOTO30
#3000=99 (,YIKES, TOOL WEAR IS TOO LARGE)

More tool length and length wear checks to make sure something stupid wasn't put in the offset table. This will also catch a missing offset


N0030
G90 G0 G43 G54 Z[24.99-[#[2000+#4120]+#[2200+#4120]]]H#4120

Here we activate the tool offset. Home position is at Z25.0 This calculates the tool length and moves to Z24.99 (0.010 move) The move is required to activate the tool offset.


G53 (SUPPRESS MULTI-BUFFER)
IF[#4320NE#500]GOTO50
M0
M99

A number in macro variable 500 will cause the program to pause after changing to that tool number. cycle start will continue normal operation.


N0050
M1
N9999
M99

And finally turning on optional stop stops after any/all tool changes.

Here is a simple version with very little of the fancy stuff
Code:
O9006 (TOOL CHANGE) 
G80
M9
G91G30Z0M5
G30X0Y0M15
T#4320M6
G53 (SUPPRESS MULTI-BUFFER)
G90G0G43G54Z[24.99-[#[2000+#4120]+#[2200+#4120]]]H#4120
G53 (SUPPRESS MULTI-BUFFER)
M99