Unique Identifier

Good morning,

Is there a way to set a custom metadata identifier (or any other type of custom metadata) to only accept a value that does not appear elsewhere in that field?

I’m using a custom metadata identifier field to save a unique ID that identifies a given record (it’s used outside Devonthink as well, as part of a larger project, so using an internal DT-generated unique
file identifier won’t work), and at the moment, I have to search each time before entering a new person to make sure I’m at the right number. Not the worst thing, but I was wondering if I couldn’t improve it.

Screenshot attached for context.

Sorry but currently there’s no built-in function for validating an identifier.

1 Like

No worries. It’s a minor thing – upgrading these records into Devonthink is still the best thing I’ve ever done. :smiley:

1 Like

Are you using a full alphabetic nomenclature, e.g., I’d be listed as N-… ?

In your screenshot all IDs start with B except the one of the currently selected record which starts with J (the one whose ID is shown in the inspector).

Are you only interested in incrementing the number, no matter with what character the ID starts?

1 Like

The identifiers are the first letter of the last name of the individual in the record, plus a numerical sequence.

So, the first individual entered into the record set (long before Devonthink got involved) with a last name starting with S was S-001, the first with a B was B-001, the seventeenth with an S was S-017,

Let’s say that the current records have individuals whose last name started with S, up to S-097. I find a new individual and start a new record. S-… . At that point at the moment, I have to look up what the last S was, and hope I don’t make a mistake and duplicate. I’d like a way where, if I were to type in S-090 (since there is already someone with that in their ID field), it will kick back an error, but if I type in S-098, it won’t.

Does that make sense?

Yes, exactly.

This script increments the highest custom meta data ID and sets it for the selected record.

If it doesn’t find an ID for a given last name it starts with “001”.

-- Increment Custom Meta Data "ID"

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

tell application id "DNtp"
	try
		set theRecords to selected records
		if (count of theRecords) = 0 or (count of theRecords) > 1 then error "Please select one record."
		set theRecord to item 1 of theRecords
		
		set theRecord_CMD_ID to get custom meta data for "id" from theRecord
		
		if theRecord_CMD_ID = missing value then
			set theRecord_Name to name of theRecord
			set theID_Character to character 1 of theRecord_Name
			
			set theDatabase to database of theRecord
			set theCustomMetaData_all to custom meta data of contents of theDatabase whose location does not start with ("/" & (name of trash group of theDatabase))
			
			set theNewID to my incrementID(theID_Character, theCustomMetaData_all)
			add custom meta data theNewID for "id" to theRecord
		else
			error "This record already got an ID."
		end if
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
		return
	end try
end tell

on incrementID(theID_Character, theCustomMetaData_all)
	try
		set theArray to current application's NSMutableArray's arrayWithArray:theCustomMetaData_all
		set thePredicate to "!self = " & (current application's NSNull's |null|()) & " AND " & "self.mdid BEGINSWITH " & quoted form of theID_Character
		set theArray_filtered to (theArray's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:thePredicate))
		
		if theArray_filtered's |count|() ≠ 0 then
			set theIDs to theArray_filtered's valueForKey:"mdid"
			set theIDs_sorted to theIDs's sortedArrayUsingSelector:"localizedStandardCompare:"
			set theLastID_string to (theIDs_sorted's lastObject()) as string
			set theLastIDNumber to ((characters ((offset of "-" in theLastID_string) + 1) thru -1 in theLastID_string) as string) as integer
		else
			set theLastIDNumber to 0
		end if
		
		-- https://stackoverflow.com/questions/6390706/how-can-i-pad-an-integer-on-the-left-with-zeros/6390835#6390835
		set theNumberFormatter to current application's NSNumberFormatter's new()
		theNumberFormatter's setPaddingPosition:(current application's NSNumberFormatterPadBeforePrefix)
		theNumberFormatter's setPaddingCharacter:"0"
		theNumberFormatter's setMinimumIntegerDigits:3
		set theNewIDNumber_String to theNumberFormatter's stringFromNumber:(current application's NSNumber's numberWithInteger:(theLastIDNumber + 1))
		
		return theID_Character & "-" & (theNewIDNumber_String as string)
		
	on error error_message number error_number
		activate
		if the error_number is not -128 then display alert "Error: Handler \"incrementID\"" message error_message as warning
		error number -128
	end try
end incrementID

2 Likes

Thanks, @pete31

1 Like