This is one way you could do it.
property my_progress : ""
on processHandler(my_item_count, this_item, my_ratio)
set progress_full_character_count to 20
set my_progress to ""
set my_space_progress to ""
set my_star to ASCII character 240
set my_space to ASCII character 176
tell me
activate
if (this_item / my_ratio) ≥ 1 then
repeat round (this_item / my_ratio) rounding toward zero times
set my_progress to my_progress & my_star
end repeat
end if
if (this_item / my_ratio) < 1 then
set my_progress to my_progress & my_star
end if
set my_length to length of my_progress
if this_item < my_item_count then display dialog "0% " & my_progress & (characters 1 thru (progress_full_character_count - (my_length)) of my_space_progress) & " 100%" giving up after 1 with title "In progress... processed " & this_item & " items out of " & my_item_count buttons {""}
if this_item = my_item_count then display dialog "0% " & my_progress & " 100%" giving up after 2 with title "Complete!" buttons {""}
set my_progress to ""
end tell
end processHandler
set my_ratio to 1
tell application "Adobe InDesign CS5"
activate
set my_item_count to (count every document)
if my_item_count is not 20 then
set my_ratio to (my_item_count / 20)
end if
repeat with this_item from 1 to progress_full_character_count
set my_space_progress to my_space_progress & my_space
end repeat
if my_item_count is not 20 then
set my_ratio to (my_item_count / 20)
end if
repeat with this_item from 1 to my_item_count
--do lots of stuff in InDesign
close document 1 saving no
proccessHandler(my_item_count, this_item, my_ratio)
end repeat
end tell
Let me explain.
You want the value of my_progress to be remembered across calls. In order for that to happen, it needs to be a global variable. The property makes it a global variable.
Next I took your block of code for your progress bar handler and I put in in the “on-end” block that you see. Notice the Handler takes three variables. These are set in the main part of your code, but are used in the handler code. If the values are changed in the handler, the updated values would not be passed back out.
Remember that my_progress is global variables. It can be used anywhere, with a minor exception explored below. For well written code, try to avoid global variables. It produces sloppy code and often times is harder to debug. There are some instances were some of the Applescript variables need to be defined globally though. That is were property comes in handy.
Here is that exception example I promised:
property a : 0
on doThis()
local a
set a to 4
display dialog "a is " & a
end doThis
on doThisToo()
set a to a + 8
end doThisToo
display dialog "a is " & a
doThis()
display dialog "a is " & a
doThisToo()
display dialog "a is " & a
set a to a - 4
display dialog "a is " & a
Notice the local “a” did not effect the value of the global “a”.
Okay, After a couple of sidebars, I then worked with this block of code from your code.
set progress_full_character_count to 20
set my_progress to ""
set my_space_progress to ""
set my_star to ASCII character 240
set my_space to ASCII character 176
I removed the set my_progress to “” because this is handled by the global variable. Additionally, setting this value at the beginning of the handler would clear your progress every time.
The other part of that block were stuff specifically for the handler, so I moved them to the top of the handler.
Okay, the handler is now pulled out and ready to be used. It needs to be called.
That is what this line does:
proccessHandler(my_item_count, this_item, my_ratio)
This calls the handler proccessHandler and passes the three variables my_item_count, this_item, my_ratio.
As I stated, If those values are altered in the handler, the changed values are not passed out.
For the sake of easy editing, I did not change the variable names that you used in you handler. Take a look at this block of code. This also illustrates the unchanging nature of passed variables.
on addTwoNumbers(sum, numberOne, numberTwo)
set sum to numberOne + numberTwo
end addTwoNumbers
on returnTheSum(numberOne, numberTwo)
return numberOne + numberTwo
end returnTheSum
set firstSum to 0
addTwoNumbers(firstSum, 4, 3)
set secondSum to returnTheSum(7, -3)
set a to 3
set b to 8
set thirdSum to returnTheSum(a, b)
display dialog "First sum is " & firstSum & " and second sum is " & secondSum& " and third sum is " & thirdSum
Notice how the first sum did not change its value? Additionally, variable names don’t have to line up nicely like they are in your example. In the second call to returnTheSum, the variables a and b are passed in, but the name of the variables in the handler are firstNumber and secondNumber.
Additionally, the second handler shows how results can be passed out of a handler. Notice the return on the end of the handler? the return will return the result that followed. Don’t try to return a local variable, though. It result can change as program processes.
DO NOT DO THIS
on returnTheSum(numberOne, numberTwo)
set theSum to numberOne + numberTwo
return theSum
end returnTheSum
The value theSum is a local variable and when the handler returns, it is possible the memory spot held by theSum may be overwritten by something else.
I hope this helps on getting you on your way for using handlers in your code. Sometimes they can be very handy. Additionally They can really improve the readability of your code, especially when handlers and variables are given descriptive names.