Finder: Sort By Column.

Hi.

Here I wrote one script to sort contents of front Finder window by chosen column name. It works fine. The problem is that I want manage showed in Finder window columns too: remove some of them or add some of them.
The dictionary of the Finder has command make column, delete column, but I can’t understand its syntax. Here I need help.


property criteriaList : {"Date Modified", "Name", "Date Created", "Size", "Kind", "Version", "Comments", "Tags"}

set theFolder to (choose folder with prompt "SELECT A FOLDER, PLEASE.")
set theCriteria to item 1 of (choose from list criteriaList with prompt "CHOOSE A COLUMN TO SORT ITEMS, PLEASE")

-- OPEN FOLDER, WAIT WHILE FINDER WINDOW OPENS
tell application "Finder"
	activate
	tell folder theFolder
		open
		repeat until container window exists
			delay 0.1
		end repeat
	end tell
end tell

-- GET TARGET, SET BOUNDS OF WINDOW, SET VIEW TO LIST VIEW
tell application "Finder" to tell folder theFolder
	tell container window ---------------------------- window, which contains chosen folder
		set currentTarget to target --------------- save target in variable to use it later
		set theBounds to {35, 25, 1280, 805} --- save bounds to use it later
		set bounds to theBounds
		set current view to list view
	end tell
end tell

-- SET LIST VIEW OPTIONS
tell application "Finder" to tell folder theFolder
	tell container window to tell its list view options
		set calculates folder sizes to true
		set shows icon preview to false
		set icon size to small icon
		set text size to 12
		set uses relative dates to false
	end tell
end tell

-- SET SORT COLUMN	
tell application "Finder" to tell folder theFolder
	tell container window to tell its list view options
		set theColumnsList to {column id modification date column, column id name column, ¬
			column id creation date column, column id size column, column id kind column, ¬
			column id version column, column id comment column, column id label column}
		repeat with i from 1 to (count of criteriaList)
			set theItem to item i of criteriaList
			if theItem = theCriteria then ---------------------- determine which id column to use
				set sort column to (item i of theColumnsList)
				set sortColumn to sort column
				set sort direction of sortColumn to normal -- or, to reversed
				exit repeat
			end if
		end repeat
	end tell
end tell

-- CLONE FINDER WINDOW, SET BOUNDS OF NEW WINDOW TO ONES OF OLD WINDOW
tell application "Finder"
	make new Finder window to currentTarget
	tell front Finder window to set bounds to theBounds
end tell

-- CLOSE ORIGINAL FINDER WINDOW (TO SEE THE CHANGES) 
tell application "Finder" to close window 2

Update: I added sort direction.

Hi KniazidisR.

I think the columns exist all the time but are either visible or not. However, when I try to change their ‘visible’ properties by script in Mojave, the values don’t change. Moreover the exisitng ‘visible’ values don’t necessarily correspond to the visibility of the columns! Something seems to have gone wrong with Finder scripting there. :confused:

Changing a column’s ‘sort direction’ works fine, as does changing its ‘width’ — although the ‘width’ must be between the unchangeable ‘minimum width’ and ‘maximum width’ values. Changing a column’s ‘index’ also works, although this currently has no visible effect on the column order in the window.

I think your (originally posted) script above could be shortened to something like this:

property criteriaList : {"Date Modified", "Name", "Date Created", "Size", "Kind", "Version", "Comments", "Tags"}

set theFolder to (choose folder with prompt "SELECT A FOLDER, PLEASE.")
set theCriteria to item 1 of (choose from list criteriaList with prompt "CHOOSE A COLUMN TO SORT ITEMS, PLEASE")

set theBounds to {35, 25, 1280, 805} -- save the bounds to use it later
tell application "Finder"
	activate
	tell (make new Finder window to theFolder with properties {bounds:theBounds})
		set bounds to theBounds
		set current view to list view
		tell its list view options
			set calculates folder sizes to true
			set shows icon preview to false
			set icon size to small icon
			set text size to 12
			set uses relative dates to false
			set theColumnsList to {column id modification date column, column id name column, ¬
				column id creation date column, column id size column, column id kind column, ¬
				column id version column, column id comment column, column id label column}
			repeat with i from 1 to (count of criteriaList)
				set theItem to item i of criteriaList
				if theItem = theCriteria then -- determine which id column to use
					set sort column to (item i of theColumnsList)
					exit repeat
				end if
			end repeat
		end tell
		tell application "Finder" to set bounds of (make new Finder window to theFolder) to theBounds
		close
	end tell
end tell

Thanks for the reply and for improving the script. I also like compact scripts, and I really liked some tricks from your script. Unfortunately, the problem with hiding and showing columns still remains. Well, I’ll try to find a way to hide/show columns, since they are persistent.

I tried to set the property visible of column with no result so I guess that the only way to rule the columns is GUI scripting.

property criteriaList : {}
tell application "Finder"
	set dateModified_loc to localized string "N169.30"
	set name_loc to localized string "N220"
	set dateCreated_loc to localized string "N169.31"
	set size_loc to localized string "N223"
	set kind_loc to localized string "N224"
	set version_loc to localized string "N226"
	set comments_loc to localized string "N227"
end tell
set criteriaList to {dateModified_loc, name_loc, dateCreated_loc, size_loc, kind_loc, version_loc, comments_loc}
log criteriaList (*Date de modification, Nom, Date de création, Taille, Type, Version, Commentaires*)


--set theFolder to ((path to desktop as text) & "des icones") as «class furl»

set theFolder to (choose folder with prompt "SELECT A FOLDER, PLEASE.")
tell application "Finder"
	activate
	tell folder theFolder
		open
		repeat until container window exists
			delay 0.1
		end repeat
	end tell
end tell
-- GET TARGET, SET BOUNDS OF WINDOW, SET VIEW TO LIST VIEW
tell application "Finder" to tell folder theFolder
	tell container window ---------------------------- window, which contains chosen folder
		set itsName to its name
		set currentTarget to target --------------- save target in variable to use it later
		set theBounds to {435, 25, 1280, 805} --- save bounds to use it later
		set bounds to theBounds
		set current view to list view
	end tell
end tell

-- SET LIST VIEW OPTIONS
tell application "Finder" to tell folder theFolder
	tell container window to tell its list view options
		set calculates folder sizes to true
		set shows icon preview to false
		set icon size to small icon
		set text size to 12
		set uses relative dates to false
	end tell
end tell

tell application "System Events" to tell process "Finder"
	set frontmost to true
	if not (exists (window 1 whose (subrole is "AXSystemFloatingWindow") and name is itsName)) then
		keystroke "j" using {command down}
		repeat 10 times
			if exists (window 1 whose (subrole is "AXSystemFloatingWindow") and name is itsName) then exit repeat
			delay 0.1
		end repeat
	end if
	tell (window 1 whose (subrole is "AXSystemFloatingWindow") and name is itsName)
		--class of UI elements --> (*checkbox, checkbox, static text, pop up button, pop up button, static text, group, button, button, static text*)
		tell group 1
			--class of UI elements (*static text, button, button, radio group, static text, pop up button, static text, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox*)
			--title of checkboxes --> {"Statut iCloud", "Date de modification", "Date de création", "Date de dernière ouverture", "Date de l’ajout", "Taille", "Type", "Version", "Commentaires", "Tags", "Utiliser les dates relatives", "Calculer toutes les tailles", "Utiliser un aperçu comme icône"}
			# As you see, there is no checkbox for "Name"
			--value of checkboxes -- 	(*0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0*)
			#  Sometimes we get a window without the wanted checkboxes
			if (count checkboxes) < 10 then error number -128
			repeat with i from 2 to 10
				if value of checkbox i is 1 then click checkbox i # uncheck the checked boxes
			end repeat
			repeat with aCheckBox in criteriaList
				if (aCheckBox as text) is not name_loc then # MUST skip the Name item for which there is no checkbox
					if value of checkbox aCheckBox is 0 then click checkbox aCheckBox # check the wanted boxes
				end if
			end repeat
		end tell
	end tell
end tell

It works … most of the times. Sometimes, I don’t know why, presssing cmd + J opens a window without the wanted checkboxes.

Of course I would be glad to read explanations about this surprising behavior.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) jeudi 12 septembre 2019 18:54:20

Thanks for localization tip. I will use it.
I think, this surprising behaviour is relayed to closing the Finder windows. Need close old executions windows to run script again.


tell application "Finder"
	set dateModified_loc to localized string "N169.30"
	set name_loc to localized string "N220"
	set dateCreated_loc to localized string "N169.31"
	set size_loc to localized string "N223"
	set kind_loc to localized string "N224"
	set version_loc to localized string "N226"
	set comments_loc to localized string "N227"
end tell
set criteriaList to {dateModified_loc, name_loc, dateCreated_loc, size_loc, kind_loc, version_loc, comments_loc}

set theFolder to (choose folder with prompt "SELECT A FOLDER, PLEASE.")
set theCriteria to item 1 of (choose from list criteriaList with prompt "CHOOSE A COLUMN TO SORT ITEMS, PLEASE")
set theBounds to {35, 25, 1280, 805}

tell application "Finder"
	
	-- GET CONTAINER WINDOW NAME
	set windowName to displayed name of folder theFolder
	
	-- GET TARGET, SET BOUNDS OF WINDOW, SET VIEW TO LIST VIEW
	tell (make new Finder window to theFolder with properties {bounds:theBounds})
		
		set theBounds to bounds
		set current view to list view
		
		-- SET LIST VIEW OPTIONS
		tell its list view options
			set calculates folder sizes to true
			set shows icon preview to false
			set icon size to small icon
			set text size to 12
			set uses relative dates to false
			
			-- SET SORT COLUMN, SET ITS VIEW OPTIONS	
			set theColumnsList to {column id modification date column, column id name column, ¬
				column id creation date column, column id size column, column id kind column, ¬
				column id version column, column id comment column, column id label column}
			repeat with i from 1 to (count of criteriaList)
				set theItem to item i of criteriaList
				if theItem = theCriteria then
					set sort column to (item i of theColumnsList)
					set sortColumn to sort column
					set sort direction of sortColumn to normal
					set width of sortColumn to 80
					exit repeat
				end if
			end repeat
		end tell
		
		-- CLONE FINDER WINDOW, SET BOUNDS OF NEW WINDOW TO ONES OF OLD WINDOW
		tell application "Finder" to set bounds of (make new Finder window to theFolder) to theBounds
		close
	end tell
end tell

tell application "System Events" to tell process "Finder"
	set frontmost to true
	keystroke "j" using {command down}
	
	repeat until (exists (window 1 whose (subrole is "AXSystemFloatingWindow") and (name is windowName)))
		delay 0.1
	end repeat
	set theWindow to window 1 whose (subrole is "AXSystemFloatingWindow") and (name is windowName)
	
	tell theWindow to tell group 1
		repeat with i from 2 to 10
			if value of checkbox i is 1 then click checkbox i
		end repeat
		repeat with aCheckBox in criteriaList
			if (aCheckBox as text) is not name_loc then ¬
				if value of checkbox aCheckBox is 0 then click checkbox aCheckBox
		end repeat
	end tell
end tell

The visible property hasn’t worked for a very-long time. I posted about this 7 months ago and I found posts from 2010 raising this same issue.

https://macscripter.net/viewtopic.php?id=46755

BTW, changing a column’s sort direction with a script only works if the Finder thinks the column is visible, regardless of whether or not the column is actually visible. The error message that results is:

“Finder got an error: A column must be visible to make it the sort column.”

As I see, the visible property works, but it does not mean visibility on the screen, but the availability of the Finder to change column’s properties. Just for this reason, I noticed the make and delete (column) commands. In principle, they can work as showing/hiding a column in the Finder window. First, I have to find the proper delete command syntax, as I think it is easier.

Thanks for the feedback but I’m not convinced.

I ran the script this morning before any other task (just after boot).
I tried to apply to one of the folder which failed yesterdays and it failed again.

Your script fails before attempting to execute the GUI scripting code.
It’s the instruction : set sort column to (item i of theColumnsList) which issue : error “Erreur dans Finder : La colonne que vous souhaitez utiliser comme colonne de tri doit être visible.” number -10000 because one of the column to which you try to grab the sort setting.

The GUI scripting code must be executed before triggering the sort settings.

Even executing the code this way, the offending instruction strikes.
It’s because you try to rule the label column which is not in your list of criteria.

Here is a code which does the job.

tell application "Finder"
	set name_loc to localized string "N220"
	set dateModified_loc to localized string "N169.30"
	set dateCreated_loc to localized string "N169.31"
	set dateLastOpened_loc to localized string "N169.32" # not used here
	set size_loc to localized string "N169.33"
	set version_loc to localized string "N169.34"
	set kind_loc to localized string "N169.35"
	set comments_loc to localized string "N169.36"
	set tags_loc to localized string "N169.37"
	set dateAdded_loc to localized string "N169.38" # not used here
end tell
# CAUTION, don't change the variables ordering !
set criteriaList to {dateModified_loc, name_loc, dateCreated_loc, size_loc, kind_loc, version_loc, comments_loc, tags_loc}

set theFolder to (choose folder with prompt "SELECT A FOLDER, PLEASE.")
set theCriteria to item 1 of (choose from list criteriaList with prompt "CHOOSE A COLUMN TO SORT ITEMS, PLEASE")
set theBounds to {35, 25, 1280, 805}

tell application "Finder"
	
	-- GET CONTAINER WINDOW NAME
	set windowName to displayed name of folder theFolder
	
	-- GET TARGET, SET BOUNDS OF WINDOW, SET VIEW TO LIST VIEW
	tell (make new Finder window to theFolder with properties {bounds:theBounds})
		
		set theBounds to bounds
		set current view to list view
		
		-- SET LIST VIEW OPTIONS
		tell its list view options
			set calculates folder sizes to true
			set shows icon preview to false
			set icon size to small icon
			set text size to 12
			set uses relative dates to false
			# Make visible the listed columns.
			my ruleColumns(windowName, criteriaList, name_loc)
			#Now we may sort the wanted column 
			-- SET SORT COLUMN, SET ITS VIEW OPTIONS	
			set theColumnsList to {column id modification date column, column id name column, ¬
				column id creation date column, column id size column, column id kind column, ¬
				column id version column, column id comment column, column id label column}
			repeat with i from 1 to (count of criteriaList)
				set theItem to item i of criteriaList
				if theItem = theCriteria then
					set sort column to (item i of theColumnsList)
					set sortColumn to sort column
					set sort direction of sortColumn to normal
					set width of sortColumn to 80
					exit repeat
				end if
			end repeat
		end tell
		
		-- CLONE FINDER WINDOW, SET BOUNDS OF NEW WINDOW TO ONES OF OLD WINDOW
		tell application "Finder" to set bounds of (make new Finder window to theFolder) to theBounds
		close
	end tell
end tell

on ruleColumns(windowName, criteriaList, name_loc)
	
	tell application "System Events" to tell process "Finder"
		set frontmost to true
		# CAUTION: if the floating window already exists, keystroking would close it !
		if not (exists (window 1 whose (subrole is "AXSystemFloatingWindow") and name is windowName)) then
			keystroke "j" using {command down}
			repeat 10 times # I never use while here because it's annoying if for some reason the window doesn't appear
				if exists (window 1 whose (subrole is "AXSystemFloatingWindow") and name is windowName) then exit repeat
				delay 0.1
			end repeat
		end if
		set theWindow to window 1 whose (subrole is "AXSystemFloatingWindow") and (name is windowName)
		tell theWindow
			--class of UI elements --> (*checkbox, checkbox, static text, pop up button, pop up button, static text, group, button, button, static text*)
			--subrole of button -1 --> "AXCloseButton"
			tell group 1
				--class of UI elements (*static text, button, button, radio group, static text, pop up button, static text, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, checkbox*)
				--title of checkboxes --> {"Statut iCloud", "Date de modification", "Date de création", "Date de dernière ouverture", "Date de l’ajout", "Taille", "Type", "Version", "Commentaires", "Tags", "Utiliser les dates relatives", "Calculer toutes les tailles", "Utiliser un aperçu comme icône"}
				repeat with i from 2 to 10
					if value of checkbox i is 1 then click checkbox i # Uncheck the columns boxes
				end repeat
				repeat with aCheckBox in criteriaList
					# No need to check the checkbox value, we have set all of them to 0
					if (aCheckBox as text) is not name_loc then click checkbox aCheckBox
				end repeat
			end tell
			click button -1 # Close the window
		end tell
	end tell
end ruleColumns

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 13 septembre 2019 11:55:19

Completed the list of localized columns titles using a better set of resources.

OK, thanks Yvan.
I think, the GUI scripting solution now works fine. I will use it until appears something better.

I edited message #9 with an enhanced list of localized columns titles.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 13 septembre 2019 14:33:52