Whereas OmniOutliner 3 rows and other objects benefit from a has subtopics property, OmniFocus scripting suffers from the lack of a has subtasks property.
This is a pity, as efficient (and fast-running) applescripts need to push as much of their logic as possible into WHERE/WHOSE queries, to minimize the volume of slow and costly Apple Event traffic.
It is of course possible to branch on (count of tasks) > 0, but there is no idiom that I can find which enables us to use a WHERE query to select only those OF tasks which have children. (In OmniOutliner the has subtopics property makes it easy to do this for rows).
I have given an example below of where I feel the lack of a queryable has subtopics property, to avoid looping through every task, fetching a list of its potential children, and testing whether the length of the list is more than 0, before going into an attempt at recursive descent. Much more efficient, and cleaner, to delegate this to a lower level through a simple WHERE query.
I have filed a request for the addition of a has subtasks property through OF Help > Send Feedback (If you prefer applescripts which run fast, and are simple to write, please feel encouraged to do the same :-)
(This would be particularly helpful, incidentally, for simplifying and speeding up the writing and performance of custom data export scripts, which have to recursively walk the entire data tree).
This is a pity, as efficient (and fast-running) applescripts need to push as much of their logic as possible into WHERE/WHOSE queries, to minimize the volume of slow and costly Apple Event traffic.
It is of course possible to branch on (count of tasks) > 0, but there is no idiom that I can find which enables us to use a WHERE query to select only those OF tasks which have children. (In OmniOutliner the has subtopics property makes it easy to do this for rows).
I have given an example below of where I feel the lack of a queryable has subtopics property, to avoid looping through every task, fetching a list of its potential children, and testing whether the length of the list is more than 0, before going into an attempt at recursive descent. Much more efficient, and cleaner, to delegate this to a lower level through a simple WHERE query.
I have filed a request for the addition of a has subtasks property through OF Help > Send Feedback (If you prefer applescripts which run fast, and are simple to write, please feel encouraged to do the same :-)
(This would be particularly helpful, incidentally, for simplifying and speeding up the writing and performance of custom data export scripts, which have to recursively walk the entire data tree).
Code:
-- RETURN A FLATTENED LIST OF ANY (UNCOMPLETED) FLAGGED TASKS -- OR SUB-TASKS IN A PROJECT on FlatFlaggedTaskList(oParent) using terms from application "OmniFocus" tell oParent -- ADJUST THE WHERE QUERIES TO MATCH THE PURPOSE set lstTasks to tasks where (flagged is true) and (completed is false) -- A HAS SUBTASKS PROPERTY (like HAS SUBTOPIC in OO3 rows) WOULD BE USEFUL: -- THE FOLLOWING QUERY COULD IMPROVE PERFORMANCE set lstParentTasks to tasks (**** WHERE HAS SUBTASKS IS TRUE ****) end tell -- SOME WASTED ITERATION AND TESTING HERE repeat with oTask in lstParentTasks set lstSubTasks to tasks of oTask if (count of lstSubTasks) > 0 then ¬ set lstTasks to lstTasks & my FlatFlaggedTaskList(oTask) end repeat return lstTasks end using terms from end FlatFlaggedTaskList on ProjectList(oParent) using terms from application "OmniFocus" tell oParent -- ADJUST THE WHERE QUERIES TO MATCH THE PURPOSE set lstProjects to projects where (status is active) set lstFolders to folders where hidden is false end tell repeat with oFolder in lstFolders set lstProjects to lstProjects & my ProjectList(oFolder) end repeat return lstProjects end using terms from end ProjectList on run tell application id "com.omnigroup.OmniFocus" set oDoc to default document set lstProjects to my ProjectList(oDoc) set lstFlagged to {} repeat with oProj in lstProjects set lstFlagged to lstFlagged & my FlatFlaggedTaskList(oProj) end repeat set strFlagged to "" repeat with oTask in lstFlagged set strFlagged to strFlagged & "-" & tab & name of oTask & return end repeat set strMsg to ((count of lstFlagged) as string) & ¬ " flagged tasks in active projects not done:" & return & return & strFlagged display dialog strMsg with title "Count (uncompleted) flagged tasks in projects" end tell tell application "Finder" set the clipboard to strMsg end tell end run
Last edited by RobTrew; 2010-06-09 at 04:56 AM..