Delighted to hear it works for you, Craig. 
Just to be clear on this, unless a variable is declared as global, or defined as a script property, it usually needs to be either passed to a handler as a parameter - or defined within the subroutine itself. However, I think the question of where the variable is defined may be confused slightly by the presence of the using terms from block. This is really only required to allow the perform mail action with messages handler to compile. So the reason you don’t need to qualify the CheckOrMakeFolder call with my, is that it’s not actually in a tell block. (I may have added to the confusion, by using an incorrect reference to the subroutine - something which I’ve now corrected above.)
Your question about using item 1, rather than a repeat loop, is a good one. Much of the time, Mail certainly seems to process incoming messages individually. However, since I have come across instances where more than one message has been processed at a time, I’d say it’s generally safer to stick to the repeat method.
Finally, there are several ways in which you could approach the question of printing. You might, for example, create a stay-open script application to carry out the batch printing - something like this:
property printPath : missing value
property printNow : false
to setPrintPath(dp)
set printPath to dp
end setPrintPath
to printFiles()
(* your print statements here *)
end printFiles
on idle
if printNow then
set printNow to false
printFiles()
return quit
else
set printNow to true
15 * minutes
end if
end idle
For this example, I’ve called the saved application “Paystubs Print Idler”. Your Mail script would then need to be modified something like this:
using terms from application "Mail"
on perform mail action with messages The_Messages
set today_folder to CheckOrMakeFolder((current date)'s short date string)
tell application "Mail" to repeat with This_Message in The_Messages
set PDF_name to text from word 2 to word 3 of (get This_Message's content)
save first mail attachment of This_Message in (today_folder & PDF_name & ".pdf")
end repeat
end perform mail action with messages
end using terms from
----------------------------------------------------------------------
on CheckOrMakeFolder(date_string)
set dp to (path to documents folder as Unicode text) & "Cathouse:Payroll:Paystubs:" & date_string & ":"
tell application "Finder" to set newFolder to not (exists folder dp)
if newFolder then
do shell script "mkdir -p " & quoted form of POSIX path of dp
launch application "Paystubs Print Idler"
tell application "Paystubs Print Idler" to setPrintPath(dp)
end if
dp
end CheckOrMakeFolder
Another (possibly simpler) method might be to incorporate a print handler within the mail script itself, so that an individual print command is issued for each message processed:
to printFile(PDF_file)
(* your individual print PDF_file statements here *)
end printFile
using terms from application "Mail"
on perform mail action with messages The_Messages
set today_folder to CheckOrMakeFolder((current date)'s short date string)
tell application "Mail" to repeat with This_Message in The_Messages
set PDF_name to text from word 2 to word 3 of (get This_Message's content)
set PDF_file to today_folder & PDF_name & ".pdf"
save first mail attachment of This_Message in PDF_file
my printFile(PDF_file)
end repeat
end perform mail action with messages
end using terms from
----------------------------------------------------------------------
on CheckOrMakeFolder(date_string)
set dp to (path to documents folder as Unicode text) & "Cathouse:Payroll:Paystubs:" & date_string & ":"
tell application "Finder" to if not (exists folder dp) then do shell script "mkdir -p " & quoted form of POSIX path of dp
dp
end CheckOrMakeFolder
The variable PDF_file may need to coerced from a path to an alias (or whatever) for your printing subroutine - but that should give you the general idea… 