The Omni Group
These forums are now read-only. Please visit our new forums to participate in discussion. A new account will be required to post in the new forums. For more info on the switch, see this post. Thank you!

Go Back   The Omni Group Forums > OmniFocus > OmniFocus Extras
FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
Send to Omnifocus from Merlin Thread Tools Search this Thread Display Modes
Hi RobTrew,

Both of your Merlin Scripts are wonderful. Thanks so much for posting these. i was wondering if you think that it would be possible to have resources in merlin come across as contexts and if it would be possible to get times out of merlin and entered into Omnifocus as start and due dates. I haven't ever written any apple scripts but have been thinking about learning how to recently. If this was possible it might just get me started. Also do you think it would be difficult to achieve or somethink a novice may be able to bumble through?
 
Quote:
Originally Posted by ianj View Post
i was wondering if you think that it would be possible to have resources in merlin come across as contexts and if it would be possible to get times out of merlin and entered into Omnifocus as start and due dates.
I would begin by taking a look at the parts of the code which are commented out (they contain a suggested approach to transferring dates).

For more ambitious handling of resources, it might make sense to post on the Merlin Google group.

(The issue being that an OmniFocus task can have only one context, whereas a Merlin activity can have multiple resources ...)

Last edited by RobTrew; 2010-03-11 at 07:07 AM..
 
Here is one approach to exporting from Merlin to OmniFocus in a way that translates resources assigned to Merlin activities into the contexts assigned to OmniFocus tasks.

A Merlin activity may have several resources assigned to it, whereas an OF task has only one context.

The approach adopted here is to deal with activities that have multiple 'assigned resources' by giving their corresponding tasks, in OmniFocus, a set of resource-specific sub-tasks, each of which has a different context.


Code:
(* 	Scripting with Merlin 2

	This draft code descends from ProjectWizards sample
	code, but I have made changes.	

*)

(* 	
	Name: 	Exports selected Merlin tasks to OmniFocus Folders (German: Exportiert ausgewählte Merlin Vorgänge nach OmniFocus)
	Author:	Rob Trew, based on code written for for ProjectWizards GmbH
	Info: 	Exports selected Merlin tasks to OmniFocus Folders
			Commented alternative code illustrates how to export additional fields 
			(during and completion)

			THIS VARIANT EXPORTS MERLIN RESOURCES AS OMNIFOCUS CONTEXTS
			Where Merlin activities have more than one assigned resource,
			the Omnifocus tasks acquire children corresponding to each assigned resource.
			The name of each such child consists of the task name prefixed by the resource name.
			Resource-specific child tasks are assigned to the appropriate Omnifocus context
			
			THIS VARIANT ALSO EXPORTS MERLIN DATES
			Merlin Planned Start Date and Planned End Date are used for OmniFocus Start and Due Dates

			All descendants of any selected nodes are exported.
			No need to select children if their parents or ancestors are already selected.
	Version: 1.0.2
*)


property pstrOFFolderName : "Merlin import"
property pMinsPerHour : 3600 as integer
property pNullString : "" as string

on run
	set lstActivities to MlnSelected()
	
	PlaceInOF(lstActivities)
end run

-- Get a nested list of the selected Merlin activities
on MlnSelected()
	tell application id "net.projectwizards.Merlin2"
		set oDoc to document of front window
		set oWin to main window of oDoc
		if main view of oWin is activities view then
			set lstMerlnSeld to selected objects of oWin
			if length of lstMerlnSeld > 0 then
				my Acts2NameList(lstMerlnSeld, pNullString, false)
			else
				{}
			end if
		else
			{}
		end if
	end tell
end MlnSelected

-- Translate Merlin activities to a nested list of activity properties
-- {strName, blnDone, lstSubTasks, strNote, strParent, dteStart, dteDue, dteDone, lngMins, blnFlagged}

on Acts2NameList(lstSeln, strParent, blnPeerRes)
	set lstNames to {}
	using terms from application "Merlin"
		repeat with oItem in lstSeln
			tell oItem
				-- 				set dblCompletion to given actual completion
				-- 				set blnDone to (dblCompletion is not missing value) and not (dblCompletion < 1)
				set blnFlagged to (priority is very high priority)
				-- 				
				-- 				set recDurn to planned duration
				-- 				tell recDurn
				-- 					set dblAmount to amount
				-- 					set eUnit to unit
				-- 				end tell
				-- 				if dblAmount > 0 then
				-- 					if eUnit = hours then
				-- 						set lngMins to dblAmount * pMinsPerHour
				-- 					else if eUnit = minutes then
				-- 						set lngMins to dblAmount
				-- 					else if eUnit = seconds then
				-- 						set lngMins to dblAmount / 60
				-- 					else
				-- 						set lngMins to 0
				-- 					end if
				-- 				end if				
				-- 				set end of lstNames to {name, blnDone, lstChiln, description, pNullString, planned start date, planned end date, actual end date, lngMins, blnFlagged}
				set lstRes to assigned resources of oItem as list
				set lngRes to count of lstRes
				set blnManyRes to lngRes > 1
				set strName to name
				set lstActs to activities
				if length of lstActs > 0 then
					set lstChiln to my Acts2NameList(lstActs, strName, blnManyRes)
				else
					set lstChiln to {}
				end if
				
				if assigned resources string is missing value then
					if blnPeerRes then
						set blnWrite to true
						set strContext to strName
						set strName to strName & ": " & strParent
						--set end of lstNames to {strName, false, lstChiln, description, strContext, planned start date, planned end date, missing value, 0, blnFlagged}
					else
						set blnWrite to false
					end if
				else
					set blnWrite to true
					if lngRes = 1 then
						set strContext to assigned resources string of oItem
					else
						set strContext to ""
					end if
				end if
				
				if blnWrite then
					set end of lstNames to {strName, false, lstChiln, description, strContext, planned start date, planned end date, missing value, 0, blnFlagged}
				end if
				
				-- 				set end of lstNames to {strName, false, lstChiln, description, strContext, missing value, missing value, missing value, 0, false}
				
			end tell
		end repeat
	end using terms from
	return lstNames
end Acts2NameList

-- Place nested list of activity names in a new OF project
on PlaceInOF(lstActivities)
	if length of lstActivities > 0 then
		tell application "OmniFocus"
			tell default document
				set oFolder to make new folder with properties {name:pstrOFFolderName & " " & (current date)}
				my FillOFFolder(oFolder, lstActivities)
			end tell
		end tell
	end if
end PlaceInOF

-- Transfer activities to the specified OF folder
on FillOFFolder(oFolder, lstActivities)
	using terms from application "OmniFocus"
		tell oFolder
			repeat with oAct in lstActivities
				set {strName, blnDone, lstChiln, strNote, strParent, dteStart, dteDue, dteDone, lngMins, blnFlagged} to oAct
				if (strNote is not missing value) and (length of strNote > 0) then
					
					set oProject to make new project with properties {name:strName, note:strNote}
				else
					set oProject to make new project with properties {name:strName}
				end if
				
				if length of lstChiln > 0 then
					my FillOFProj(oProject, lstChiln)
				end if
			end repeat
		end tell
	end using terms from
end FillOFFolder

-- Transfer activities to the specified project (or parent task)
on FillOFProj(oProj, lstActivities)
	using terms from application "OmniFocus"
		tell oProj
			repeat with oAct in lstActivities
				set {strName, blnDone, lstChiln, strNote, strParent, dteStart, dteDue, dteDone, lngMins, blnFlagged} to oAct
				if (strNote is not missing value) and (length of strNote > 0) then
					set oTask to make new task with properties {name:strName, note:strNote}
				else
					set oTask to make new task with properties {name:strName}
				end if
				tell oTask
					-- 					if blnDone then set completed to true
					if not dteStart is missing value then set start date to dteStart
					if not dteDue is missing value then set due date to dteDue
					-- 					if not dteDone is missing value then set date completed to dteDone
					-- 					if lngMins > 0 then set estimated minutes to lngMins
					if blnFlagged then set flagged to true
					if strParent is not missing value then
						if length of strParent > 0 then
							set oContext to my GetContext(strParent)
							set context of oTask to oContext
						end if
					end if
				end tell
				if length of lstChiln > 0 then
					my FillOFProj(oTask, lstChiln)
				end if
			end repeat
		end tell
	end using terms from
end FillOFProj

on GetContext(strName)
	if strName ≠ "" then
		tell application "OmniFocus"
			tell default document
				set lstMatches to flattened contexts where name = strName
				if length of lstMatches > 0 then
					return first item of lstMatches
				else
					return (make new context with properties {name:strName})
				end if
			end tell
		end tell
	else
		return missing value
	end if
end GetContext

Last edited by RobTrew; 2012-05-09 at 09:17 PM.. Reason: Ver 1.0.2
 
Quote:
Originally Posted by RobTrew View Post
Here is an illustrative first draft, which transfers any activities selected in Merlin (with their sub-activities) to a new date-stamped Folder in OF.

I am not aware of any way of adding this to the Send To menu, but if you save the script with a suitable name and place it in

/Users/[Your User Name]/Library/Scripts/Applications/Merlin

then it will appear in Merlin's script menu.

Code:
-- ver 0.5  Exports tasks selected in Merlin to OF Folder 
-- Commented alternative code would allow for export of some additional fields 
------(dates, duration, very high priority, completion etc)
-- Copyright ©2010 Robin Trew, UK. All rights reserved.


-- Note that all descendants of any selected nodes are exported.
-- (There is no need to select children if their parents or ancestors are already selected)

property pstrOFFolderName : "Merlin import"
property pMinsPerHour : 3600 as integer
property pNullString : "" as string

on run
	set lstActivities to MlnSelected()
	
	PlaceInOF(lstActivities)
end run

-- Get a nested list of the selected Merlin activities
on MlnSelected()
	tell application id "net.projectwizards.Merlin2"
		set oDoc to document of front window
		set oMerlnSeld to selected objects of main window of oDoc
		if length of oMerlnSeld > 0 then
			my Acts2NameList(oMerlnSeld, {})
		else
			{}
		end if
	end tell
end MlnSelected

-- Translate Merlin activities to a nested list of activity properties
-- {strName, blnDone, lstSubTasks, strNote, strParent, dteStart, dteDue, dteDone, lngMins, blnFlagged}

on Acts2NameList(lstSeln, lstParent)
	using terms from application "Merlin"
		repeat with oItem in lstSeln
			set lstChiln to {}
			set lstActs to activities of oItem
			if length of lstActs > 0 then
				set lstChiln to my Acts2NameList(lstActs, {})
			end if
			tell oItem
				-- 				set dblCompletion to given actual completion
				-- 				set blnDone to (dblCompletion is not missing value) and not (dblCompletion < 1)
				-- 				set blnFlagged to (priority is very high priority)
				-- 				
				-- 				set recDurn to planned duration
				-- 				tell recDurn
				-- 					set dblAmount to amount
				-- 					set eUnit to unit
				-- 				end tell
				-- 				if dblAmount > 0 then
				-- 					if eUnit = hours then
				-- 						set lngMins to dblAmount * pMinsPerHour
				-- 					else if eUnit = minutes then
				-- 						set lngMins to dblAmount
				-- 					else if eUnit = seconds then
				-- 						set lngMins to dblAmount / 60
				-- 					else
				-- 						set lngMins to 0
				-- 					end if
				-- 				end if				
				-- 				set end of lstParent to {name, blnDone, lstChiln, description, pNullString, planned start date, planned end date, actual end date, lngMins, blnFlagged}
				
				set end of lstParent to {name, false, lstChiln, description, pNullString, missing value, missing value, missing value, 0, false}
			end tell
		end repeat
	end using terms from
	return lstParent
end Acts2NameList

-- Place nested list of activity names in a new OF project
on PlaceInOF(lstActivities)
	if length of lstActivities > 0 then
		tell application "OmniFocus"
			tell default document
				set oFolder to make new folder with properties {name:pstrOFFolderName & " " & (current date)}
				my FillOFFolder(oFolder, lstActivities)
			end tell
		end tell
	end if
end PlaceInOF

-- Transfer activities to the specified OF folder
on FillOFFolder(oFolder, lstActivities)
	using terms from application "OmniFocus"
		tell oFolder
			repeat with oAct in lstActivities
				set {strName, blnDone, lstChiln, strNote, strParent, dteStart, dteDue, dteDone, lngMins, blnFlagged} to oAct
				if (strNote is not missing value) and (length of strNote > 0) then
					
					set oProject to make new project with properties {name:strName, note:strNote}
				else
					set oProject to make new project with properties {name:strName}
				end if
				
				if length of lstChiln > 0 then
					my FillOFProj(oProject, lstChiln)
				end if
			end repeat
		end tell
	end using terms from
end FillOFFolder

-- Transfer activities to the specified project (or parent task)
on FillOFProj(oProj, lstActivities)
	using terms from application "OmniFocus"
		tell oProj
			repeat with oAct in lstActivities
				set {strName, blnDone, lstChiln, strNote, strParent, dteStart, dteDue, dteDone, lngMins, blnFlagged} to oAct
				if (strNote is not missing value) and (length of strNote > 0) then
					set oTask to make new task with properties {name:strName, note:strNote}
				else
					set oTask to make new task with properties {name:strName}
				end if
				-- 				tell oTask
				-- 					if blnDone then set completed to true
				-- 					if not dteStart is missing value then set start date to dteStart
				-- 					if not dteDue is missing value then set due date to dteDue
				-- 					if not dteDone is missing value then set date completed to dteDone
				-- 					if lngMins > 0 then set estimated minutes to lngMins
				-- 					if blnFlagged then set flagged to blnFlagged
				-- 				end tell
				if length of lstChiln > 0 then
					my FillOFProj(oTask, lstChiln)
				end if
			end repeat
		end tell
	end using terms from
end FillOFProj
Dear Rob
Please can you or anyone else help with a script that will import the dates. I cannot fathom how to do this. Programming is not my thing at all. I f anyone can help I'd be grateful. I would just like to export activities from Merlin to Omnifocus, but obviously need the dates to act on them appropriately.
Thanks
 
Quote:
Originally Posted by Matt View Post
a script that will import the dates.
You may need to expand a little on what you mean by the dates.

The current script (above) exports the planned start date, and planned end date, of each Merlin activity, and places them in the start date and due date of the exported activity in OmniFocus.

Are you looking for a different mapping ?

(Merlin activities have a number of other date fields)


--
 
Dear Rob

Sorry for delay. I didn't get notification.

For some reason the script is not giving me dates, any dates.
the start and due dates would be fine.

Can you help with getting the script working properly?

What do I do with it?

I've been copying and pasting it into Script Editor and then 'saving as' with a new file name and placing this in the 'send to' menu folder of Merlin. I can see it there and it does export, but - NO dates!

Hope you can help

Many thanks

Matt
 
It's hard to know exactly what issue you are stumbling on without looking at your Merlin data, which is a bit beyond the scope of this forum.

Merlin do distribute this script on their site, and I think you might get quicker and fuller help from merlin2users@googlegroups.com
 
Quote:
Originally Posted by RobTrew View Post
Here is one approach to exporting from Merlin to OmniFocus in a way that translates resources assigned to Merlin activities into the contexts assigned to OmniFocus tasks.

A Merlin activity may have several resources assigned to it, whereas an OF task has only one context.

The approach adopted here is to deal with activities that have multiple 'assigned resources' by giving their corresponding tasks, in OmniFocus, a set of resource-specific sub-tasks, each of which has a different context.
This is even better than your first scripts and a really good help in setting your review agenda for projects using OFs forecast once activities are imported, thanks a lot.

I wonder, though, is there a way for the script to identify resources as contexts when they already exist in Omnifocus under a context group? I group mine under "Contact" and "Waiting for" simply to avoid a long context list. Contexts at top level are recognised by the script, but once "hidden" under a group they are not.
 
Thank you for spotting that. The updated GetContext() function in the code above (1.0.2) now finds nested contexts.

It should now read:
Code:
on GetContext(strName)
	if strName ≠ "" then
		tell application "OmniFocus"
			tell default document
				set lstMatches to flattened contexts where name = strName
				if length of lstMatches > 0 then
					return first item of lstMatches
				else
					return (make new context with properties {name:strName})
				end if
			end tell
		end tell
	else
		return missing value
	end if
end GetContext
 
Thanks for that! And again: thank you for your tireless efforts and brilliant scripts.
 
 


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Last Post
Exporting to Merlin 2 FROM Omnifocus RobTrew OmniFocus Extras 2 2013-03-12 11:37 PM
Update Merlin 2 tasks using OmniFocus JamieStarr OmniFocus Extras 4 2011-12-14 12:41 AM
Send to Omnifocus mcortina OmniFocus Extras 0 2011-07-11 10:04 AM
New to Omnifocus: How to send an email from omnifocus iain.c.devine Applying OmniFocus 2 2011-01-31 10:30 PM
Send to Omnifocus? bcalloway OmniFocus for iPhone 2 2010-01-23 07:24 PM


All times are GMT -8. The time now is 01:16 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.