Sort sub-routine not working

And by “not working” I, of course, mean that I’m not doing something right…

I have a script that goes off every morning to create an email with my morning staffing report. The below may not be elegant or ideal, but it works. What I want to do is alphabetized the lists that are generated.


display dialog "Send VisCom staffing report?" default button 2 giving up after 300

if gave up of the result is true then error number -128


set theStaff to {"Mike J.", "Josh", "Peter", "Chuck", "Ron", "Keith", "Mike M."}
set staffOut to {}
set staffSick to {}
set staffTDY to {}
set staffTelework to {}

try #allows for no one to be here
	set staffHere to choose from list theStaff with prompt "Who is here?" with multiple selections allowed and empty selection allowed
end try

if (count of staffHere) is not 0 then
	set telework to choose from list staffHere with prompt "Is anyone teleworking?" with multiple selections allowed and empty selection allowed
	set tempTDY to {}
	repeat with emplTDY in staffHere
		if emplTDY is not in telework then
			set end of tempTDY to emplTDY
		end if
	end repeat
	set tempTDY to choose from list tempTDY with prompt "Is anyone on travel?" with multiple selections allowed and empty selection allowed
end if


set tempHere to staffHere
set staffHere to {}
repeat with emplHere in tempHere
	if emplHere is in telework then
		set emplHere to emplHere & " (telework)"
		set end of staffTelework to text of emplHere
	else if emplHere is in tempTDY then
		set emplHere to emplHere & " (TDY)"
		set end of staffTDY to text of emplHere
	else
		set end of staffHere to text of emplHere
	end if
end repeat

#reset staffHere
set staffHere to staffHere & staffTelework & staffTDY



#create list of employees that are not here
repeat with emplOut in theStaff
	if emplOut is not in tempHere then
		set the end of staffOut to text of emplOut
	end if
end repeat


set allOut to staffOut
#create list of employees on sick leave
if (count of staffOut) is not 0 then
	set tempOut to staffOut
	set staffOut to {}
	set tempSick to choose from list tempOut with prompt "Is anyone sick?" with multiple selections allowed and empty selection allowed
	repeat with emplOut in tempOut
		if emplOut is not in tempSick then
			set end of staffOut to emplOut
		end if
	end repeat
	set tempOut to staffOut
	set staffOut to {}
	repeat with emplOut in allOut
		if emplOut is in tempSick then
			set emplOut to emplOut & " (SL)"
			set end of staffSick to text of emplOut
		else
			set emplOut to emplOut & " (AL)"
			set end of staffOut to text of emplOut
		end if
	end repeat
	set staffOut to staffOut & staffSick
end if


set textHere to ""
repeat with emplHere in staffHere
	set textHere to textHere & text of emplHere & "<br>"
end repeat


set textOut to ""
repeat with emplOut in staffOut
	set textOut to textOut & text of emplOut & "<br>"
end repeat


tell application "Microsoft Outlook"
	set newMessage to make new outgoing message with properties {subject:"VisCom Staffing", content:"<B><U>IN</B></U>" & textHere & "<br><br>" & "<B><U>OUT</B></U>" & "<br>" & textOut & "<br><br>"}
	make new recipient at newMessage with properties {email address:{name:"First Lastname", address:"name@company.com"}}
	open newMessage
end tell


Again, that works. But, when I incorporate the sorting sub-routine, things break down.
This does not work:


display dialog "Send VisCom staffing report?" default button 2 giving up after 300

if gave up of the result is true then error number -128


set theStaff to {"Mike J.", "Josh", "Peter", "Chuck", "Ron", "Keith", "Mike M."}
set staffOut to {}
set staffSick to {}
set staffTDY to {}
set staffTelework to {}

try #allows for no one to be here
	set staffHere to choose from list theStaff with prompt "Who is here?" with multiple selections allowed and empty selection allowed
end try

if (count of staffHere) is not 0 then
	set telework to choose from list staffHere with prompt "Is anyone teleworking?" with multiple selections allowed and empty selection allowed
	set tempTDY to {}
	repeat with emplTDY in staffHere
		if emplTDY is not in telework then
			set end of tempTDY to emplTDY
		end if
	end repeat
	set tempTDY to choose from list tempTDY with prompt "Is anyone on travel?" with multiple selections allowed and empty selection allowed
end if


set tempHere to staffHere
set staffHere to {}
repeat with emplHere in tempHere
	if emplHere is in telework then
		set emplHere to emplHere & " (telework)"
		set end of staffTelework to text of emplHere
	else if emplHere is in tempTDY then
		set emplHere to emplHere & " (TDY)"
		set end of staffTDY to text of emplHere
	else
		set end of staffHere to text of emplHere
	end if
end repeat

#reset staffHere
set staffHere to staffHere & staffTelework & staffTDY
simple_sort(staffHere)



return staffHere


#create list of employees that are not here
repeat with emplOut in theStaff
	if emplOut is not in tempHere then
		set the end of staffOut to text of emplOut
	end if
end repeat


set allOut to staffOut
#create list of employees on sick leave
if (count of staffOut) is not 0 then
	set tempOut to staffOut
	set staffOut to {}
	set tempSick to choose from list tempOut with prompt "Is anyone sick?" with multiple selections allowed and empty selection allowed
	repeat with emplOut in tempOut
		if emplOut is not in tempSick then
			set end of staffOut to emplOut
		end if
	end repeat
	set tempOut to staffOut
	set staffOut to {}
	repeat with emplOut in allOut
		if emplOut is in tempSick then
			set emplOut to emplOut & " (SL)"
			set end of staffSick to text of emplOut
		else
			set emplOut to emplOut & " (AL)"
			set end of staffOut to text of emplOut
		end if
	end repeat
	set staffOut to staffOut & staffSick
end if


set textHere to ""
repeat with emplHere in staffHere
	set textHere to textHere & text of emplHere & "<br>"
end repeat


set textOut to ""
repeat with emplOut in staffOut
	set textOut to textOut & text of emplOut & "<br>"
end repeat


tell application "Microsoft Outlook"
	set newMessage to make new outgoing message with properties {subject:"VisCom Staffing", content:"<B><U>IN</B></U>" & textHere & "<br><br>" & "<B><U>OUT</B></U>" & "<br>" & textOut & "<br><br>"}
	make new recipient at newMessage with properties {email address:{name:"First Lastname", address:"name@company.com"}}
	open newMessage
end tell



on simple_sort(my_list)
	set the index_list to {}
	set the sorted_list to {}
	repeat (the number of items in my_list) times
		set the low_item to ""
		repeat with i from 1 to (number of items in my_list)
			if i is not in the index_list then
				set this_item to item i of my_list as text
				if the low_item is "" then
					set the low_item to this_item
					set the low_item_index to i
				else if this_item comes before the low_item then
					set the low_item to this_item
					set the low_item_index to i
				end if
			end if
		end repeat
		set the end of sorted_list to the low_item
		set the end of the index_list to the low_item_index
	end repeat
	return the sorted_list
end simple_sort

So, I started breaking out bits of the script, but I still can’t figure out what is going on. In as much as the result displays a correctly sorted list, this portion will work:



set theStaff to {"Mike J.", "Josh", "Peter", "Chuck", "Ron", "Keith", "Mike M."}
set staffOut to {}
set staffSick to {}
set staffTDY to {}
set staffTelework to {}




try #allows for no one to be here
	set staffHere to choose from list theStaff with prompt "Who is here?" with multiple selections allowed and empty selection allowed
end try

if (count of staffHere) is not 0 then
	set telework to choose from list staffHere with prompt "Is anyone teleworking?" with multiple selections allowed and empty selection allowed
	set tempTDY to {}
	repeat with emplTDY in staffHere
		if emplTDY is not in telework then
			set end of tempTDY to emplTDY
		end if
	end repeat
	set tempTDY to choose from list tempTDY with prompt "Is anyone on travel?" with multiple selections allowed and empty selection allowed
end if


set tempHere to staffHere
set staffHere to {}
repeat with emplHere in tempHere
	if emplHere is in telework then
		set emplHere to emplHere & " (telework)"
		set end of staffTelework to text of emplHere
	else if emplHere is in tempTDY then
		set emplHere to emplHere & " (TDY)"
		set end of staffTDY to text of emplHere
	else
		set end of staffHere to text of emplHere
	end if
end repeat


set staffHere to staffHere & staffTelework & staffTDY
simple_sort(staffHere)



on simple_sort(my_list)
	set the index_list to {}
	set the sorted_list to {}
	repeat (the number of items in my_list) times
		set the low_item to ""
		repeat with i from 1 to (number of items in my_list)
			if i is not in the index_list then
				set this_item to item i of my_list as text
				if the low_item is "" then
					set the low_item to this_item
					set the low_item_index to i
				else if this_item comes before the low_item then
					set the low_item to this_item
					set the low_item_index to i
				end if
			end if
		end repeat
		set the end of sorted_list to the low_item
		set the end of the index_list to the low_item_index
	end repeat
	return the sorted_list
end simple_sort


What is it about the rest of the script that is making the sort not work correctly?

Thanks!

What if you replace :

simple_sort(staffHere)

by

set staffHere to my simple_sort(staffHere)

Yvan KOENIG running Sierra 10.12.3 in French (VALLAURIS, France) jeudi 16 février 2017 18:01:14

That works!

Until I put it into Automator. Once there, it gives “expected end” where the “on simple_sort” line is.

I’ll do some more playing next week.

Thanks!

It sounds as if you may have pasted the entire script inside the ‘run’ handler. ‘simple_sort’ is a handler in its own right and has to be outside:

on run {input, parameters}
	
	(* All the script code here except for the simple_sort handler. *)
	
	return input
end run

on simple_sort(my_list)
	set the index_list to {}
	set the sorted_list to {}
	repeat (the number of items in my_list) times
		set the low_item to ""
		repeat with i from 1 to (number of items in my_list)
			if i is not in the index_list then
				set this_item to item i of my_list --as text
				if the low_item is "" then
					set the low_item to this_item
					set the low_item_index to i
				else if this_item comes before the low_item then
					set the low_item to this_item
					set the low_item_index to i
				end if
			end if
		end repeat
		set the end of sorted_list to the low_item
		set the end of the index_list to the low_item_index
	end repeat
	return the sorted_list
end simple_sort

That’s it! Thanks for that; I was unclear on how AS worked within Automator.