Variables left empty with application Notes and AppleScript

Hello,

I just created part 1 of a script, which is to transfer Data from application Notes into a FileMaker Pro database.
The script runs without any error, but the variables which should contain the data to transfer are left empty as shown with the inserted dialogs.


tell application "Notes"
	activate
	set DocNum to (the count of notes of folder "Notes" of account "iCloud")
	set folderList to (get the (id of every note of folder "Notes" of account "iCloud") as list)
	repeat with i from 1 to DocNum
		set selectedNote to item i of folderList
		display dialog (selectedNote)  --the id is correctly shown in the dialog
		set Datum to (the creation date of note of folder "Notes" of account "iCloud" whose id = selectedNote)
		display dialog (Datum as string)
		set Headline to (the name of note of folder "Notes" of account "iCloud" whose id = selectedNote)
		display dialog (Headline as string)
		set Bodytext to (the body of note of folder "Notes" of account "iCloud" whose id = selectedNote)
	end repeat
end tell

I can’t see any mistake with this script, since ist runs without any error message. Do I have to use more brackets?

note of folder “Notes” of account “iCloud” whose id = selectedNote
returns an empty list while
first note of folder “Notes” of account “iCloud” whose id = selectedNote
return a note descriptor.

You may use the code :

tell application "Notes"
	activate
	set DocNum to (the count of notes of folder "Notes" of account "iCloud")
	set folderList to (get the (id of every note of folder "Notes" of account "iCloud") as list)
	repeat with i from 1 to DocNum
		set selectedNote to item i of folderList
		display dialog (selectedNote) --the id is correctly shown in the dialog
		
		set Datum to (the creation date of first note of folder "Notes" of account "iCloud" whose id = selectedNote)
		display dialog (Datum as string)
		set Headline to (the name of first note of folder "Notes" of account "iCloud" whose id = selectedNote)
		display dialog (Headline as string)
		set Bodytext to (the body of first note of folder "Notes" of account "iCloud" whose id = selectedNote)
		
	end repeat
end tell

but my own choice would be :

tell application "Notes"
	activate
	set folderList to (get the (id of every note of folder "Notes" of account "iCloud")) # no need to coerce as list, it's already a list
	repeat with selectedNote in folderList # no need to use an index in the loop
		display dialog (selectedNote) --the id is correctly shown in the dialog
		tell (first note of folder "Notes" of account "iCloud" whose id = selectedNote) # get access to the note only once
			set Datum to its creation date
			display dialog (Datum as string)
			set Headline to its name
			display dialog (Headline as string)
			set Bodytext to its body
			display dialog Bodytext
		end tell
	end repeat
end tell

I had a little doubt upon my change to the instruction setting folderList, so I deleted my existing notes minus one and the result was a list. I deleted the last note and the result was a list too.

Yvan KOENIG running El Capitan 10.11.3 in French (VALLAURIS, France) mardi 16 février 2016 16:52:53

Hello,

it is a pity, that AppleScript syntax of most applications (particularly those of Apples own) is so poorly documented, that even advanced AS programmers hardly will find the correct syntax at once. I experienced that with nearly 90% of the applications it needs a lot of “try and error” to succeed at end. The AppleScript functions lists are not very helpful in this case, since there a no samples for complete instructions. There are only few exceptions, like with FileMaker Pro, where you can get a perfect documentation with al lot of instruction samples or with RagTime, which is completely recordable, so you can look at the results to get the right feeling for the syntax. “ I wonder why Apples applications are not recordable :-((

Since your hint was somewhat late and I had to proceed, totally dispaired, I tried the following and, great miracle, it works:


tell application "Notes"
	activate
	set DocNum to (the count of every note of folder "Notes" of account "iCloud")
	set dateList to (get the (creation date of every note of folder "Notes" of account "iCloud") as list)
	set nameList to (get the (name of every note of folder "Notes" of account "iCloud") as list)
	set textList to (get the (body ofevery note of folder "Notes" of account "iCloud") as list)
	
	repeat with i from 1 to DocNum
		set Datum to ((item i of dateList) as string)
		set Headline to ((item i of nameList) as string)
		set Inhalt to ((item i of textList) as string)
		my transfer(Datum, Headline, Inhalt)
	end repeat
end tell

on transfer(Datum, Headline, Inhalt)
	tell application "FileMaker Pro Advanced"
		create new record at end
		go to last record
		set cell "Datum" of current record to Datum
		set cell "Headline" of current record to Headline
		set cell "Bodytext" of current record to Inhalt
	end tell
end transfer

I run this under MacOS El Capitan and it was rather fast. I was afraid, that this possibly won’t run, since there were about 650 notes, most of them rather large (more than 2000 characters), what, I thought, could be to much for the variable “textList” - but no problem :wink:

As I practice AppleScript for many years, I don’t remember where I learnt that specifying first was required.

As I am lazy I would edit your code as :

tell application "Notes"
	activate
	
	set {dateList, namelist, textlist} to ({creation date, name, body} of every note of folder "Notes" of account "iCloud") --as list # no need to coerce as list because it IS agroup of 3 lists
	set DocNum to count dateList
	
	repeat with i from 1 to DocNum
		set Datum to ((item i of dateList) as string)
		set Headline to ((item i of namelist) as string)
		set Inhalt to ((item i of textlist) as string)
		my transfer(Datum, Headline, Inhalt)
	end repeat
end tell

on transfer(Datum, Headline, Inhalt)
tell application "FileMaker Pro Advanced"
		create new record at end
		go to last record
		tell current record # I don't own FileMaker so I can't test this syntax
			set cell "Datum" to Datum
			set cell "Headline" to Headline
			set cell "Bodytext" to Inhalt
		end tell
end tell
end transfer

About the FileMaker code, maybe it may reduced to

tell application "FileMaker Pro Advanced"
		create new record at end
		tell last record 
			set cell "Datum" to Datum
			set cell "Headline" to Headline
			set cell "Bodytext" to Inhalt
		end tell
end tell

Yvan KOENIG running El Capitan 10.11.3 in French (VALLAURIS, France) mercredi 17 février 2016 19:44:47

Keep in mind that higher level programming languages will increase efficiency but hardly decrease difficulty. It’s the inevitable failure of higher programming languages because they were designed to make programming easier while they only increase efficiency as they grow. The trivial aspects of programming can only be automated in higher level programming languages but the essence and complex parts of programming remains for the programmer.

But you example shows an different problem which is described in the ASLG:

note of folder "Notes" of account "iCloud" whose id = selectedNote

This is an object specifier with a whose clause. That means an filter will be applied to an range of objects. note doesn’t indicate object but a class while it’s plural form notes is shorthand for the range every note. I’m even surprised that FileMaker doesn’t throw an error on that line but simply returns an empty list (which is wrong if you ask me). This is something that is well described in ASGL. Here another example look at the last line that will throw an error, it doesn’t indicate a range:

tell application "System Events"
	name of processes whose frontmost = true -- Result: {"AppleScript Editor"}
	name of every process whose frontmost = true -- Result: {"AppleScript Editor"}
	name of first process whose frontmost = true -- Result: "AppleScript Editor"
	name of last process whose frontmost = true -- Result: "AppleScript Editor"
	name of process 1 whose frontmost = true -- Result: "AppleScript Editor"
	name of processes 1 thru 1 whose frontmost = true -- Result: {"AppleScript Editor"}
	name of some process whose frontmost = true -- Result: "AppleScript Editor"
	name of middle process whose frontmost = true -- Result: "AppleScript Editor"
	name of process whose frontmost = true -- Result: error
end tell

Many thanks for your excellence guidance and code. All very helpful.

Could you please help me understand what you mean by “specifying first”?

Thanks.

It was about a preceding message in which I wrote :

note of folder “Notes” of account “iCloud” whose id = selectedNote
returns an empty list while
first note of folder “Notes” of account “iCloud” whose id = selectedNote
return a note descriptor.

Yvan KOENIG running El Capitan 10.11.3 in French (VALLAURIS, France) vendredi 19 février 2016 10:26:33

I think Yvan means that when referring to an element (a ‘note’ is an element in Notes), the correct syntax is to specify which element is meant, even if only one is expected to be at the given location in the situation being scripted. The OP’s script in post #1 omits to do this in some lines:

-- OP:
set Datum to (the creation date of note of folder "Notes" of account "iCloud" whose id = selectedNote)

-- Yvan's correction in post #2:
set Datum to (the creation date of first note of folder "Notes" of account "iCloud" whose id = selectedNote)

It’s customary to use ‘first’ in such cases, although ‘last’, ‘middle’, and ‘some’ usually work as well (if possibly not as efficiently).

However, since the notes are identified here by their ‘id’ property, it may be possible to use an ID reference rather than a filter reference (although I’m not in a position to test it myself):

set Datum to (the creation date of note id selectedNote of folder "Notes" of account "iCloud")

If the whose clause will return a single element in a list you still need to specify the element from that list. Code like item of {true} will throw an error as well. So to get the only item from the list you can use first, last, middle, some or n (where n = 1 or -1) as in my example code in the previous post. You don’t need to use first per se, any range mentioned is fine.

Yvan Koenig, Nigel Garvey, and DJ Bazzie Wazzie:

Many thanks to each of you for responding to my question, and making this very clear.
I learned a lot from this, and I know that others who read it in the future will as well.

Could a moderator take these three posts, and put them in a thread pinned to the top so it would be easy for others to find?

I have clipped it to my Evernote account for future reference.

Not the every (or plural) or range references, since these would still return single item lists.

My mistake