Page 1 of 1

Automatic update of a field based on another field

Posted: 18 Aug 2017 12:42
by dewilkinson
I am in the process of tidying up historical data entry errors. When our records began we were not as diligent with citations as we should have been, and I am hoping to automate some updating as manually it would take a long time.

An example is, for a specified source "Email 14/5/2003" was entered in the Where within Source field (it was actually entered in TMG and transferred as that). What I wish to do is automatically update the Entry Date field with "14/5/2003" and change the Where within Source to "email" when Where within Source = "Email 14/5/2003" en bloc.

The very useful Search and Replace plugin does not allow that type of conditional function as far as I can see. Before I embark on trying to create a Plugin to do this, does one already exist? (I cannot find one in the Plugin Store) or is there a simpler way? In my computing past a quick SQL query would do the job, but I don't think that is possible with FH although it was possible in TMG.

All thoughts most welcome.

Re: Automatic update of a field based on another field

Posted: 18 Aug 2017 12:51
by Valkrider
If @Mike Tate or someone else doesn't come up with a way to do this natively it would be easy enough to do in Notepad++ (free download) as it allows regex etc for finding what you want and then splitting. Don't forget to experiment on a copy of your gedcom.

Re: Automatic update of a field based on another field

Posted: 18 Aug 2017 13:32
by Jane
It's an easy enough plugin if you have a programming background.

Use plugins:code_snippets:loop_all_items|> Loop All Items (code snippet) as a base. Then you can find the where within source tags and split the strings and create/update the data and entry date field for the parent item.

Re: Automatic update of a field based on another field

Posted: 18 Aug 2017 13:37
by tatewise
The difficult step is not so much finding and splitting the Where within Source value, but creating and setting the Entry Date field, which may not even exist in the GEDCOM file for that Citation.

There is no general purpose Plugin for that kind of operation, and to create one would be extremely difficult to cater for all input and output fields and all possible manipulations of the data.

The easiest solution is to write custom Plugins to perform just the operations you need.
Since these are one-off manipulations it is not worth creating a sophisticated user interface.
For the given example write a Plugin to detect that particular Where within Source value, split it into two, and save the results in the Where within Source field and Entry Date field.
Once that has worked, edit the Plugin script to detect a different value, and so on.
Remember that Date fields are not plain text and must use Date functions to create the correct format.
See plugins:index#developer_guide|> Family Historian Plugins > Developer Guide for general advice.

Re: Automatic update of a field based on another field

Posted: 18 Aug 2017 20:01
by dewilkinson
Thank you very much for your replies. I agree this is a 'one off' plugin so doesn't need to be topped and tailed. I have had a day of learning LuA (never used it before) and have got what I need working other than writing a date to the Entry Date field. I cannot be creating the Entry Date field as ptrDate shows as Null.

This is the simple code I have created so far and tested on a back up copy of my Gedcom file

Code: Select all


-- Extract date from Where within Source PlugIn

--		Author  Dr. David E Wilkinson
--		v 0.1 18th August 2017

--    Purpose
--		This code snippet is designed to split the contents of the Where within Source field into its
--		correct entry and transfer the date to the Entry Date field as specified by the user. Note that if
--		the Entry date field is not Null no update will occur.

--		The user is required to complete the three parameters below.

-- Enter your change parameters here
local strWhere = "GEDCOM File Aug. 2002"			-- The text to find in the Where within Source field
local strWhereNew = "GedCom file"					-- The text to leave behind in the Where within Source Field
local datDate = fhNewDate(2002, 8, 0)				-- The date to insert into the source Entry Date field (use 0 if month or date unknown)

local ptrItem = fhNewItemPtr()			-- Pointer to data item scan to find SOUR Citations
local ptrPage = fhNewItemPtr()			-- Pointer to PAGE tag: Where Within Source
local ptrDate = fhNewItemPtr()			-- Pointer to DATA.DATE tag: Entry Date

local i = 0							-- Counter

local strPage = ""					--	variable for storing page (Where within Source) field content




-- Main code begins here --

for intType, strType in ipairs({"INDI","FAM"}) do	-- Scan both Family and Individual Record Types

	ptrItem:MoveToFirstRecord(strType)									-- set pointer to start of database

	while ptrItem:IsNotNull() do											-- loop through entire database
		if fhGetTag(ptrItem) == "SOUR" then								-- only process Source records

			ptrPage:MoveTo(ptrItem,"~.PAGE")							-- get pointer to Where within Source field

			strPage = fhGetValueAsText(ptrPage)							-- extract Where within Source field content

			if (strPage == strWhere) then								-- test to see if change needed
	
				ptrDate = fhCreateItem("~.DATA.DATE", ptrItem)		-- create Entry Date field

				fhSetValueAsText(ptrPage, strWhereNew)					-- update the Where within Source field
				fhSetValueAsDate(ptrDate, datDate)						-- update the Entry date Field

				i = i + 1														-- increment update counter
			end
		end

		ptrItem:MoveNextSpecial()											-- move to next item in database
	end
end

print (os.date('!%a, %d %b %Y %H:%M:%S GMT'))
fhMessageBox(i .. ' records updated')									-- Eureka (or not!!)

Re: Automatic update of a field based on another field

Posted: 19 Aug 2017 10:44
by tatewise
David, I have moved this thread to the Plugin Discussions Forum.

That is a great start for one day of learning.

Creating FH Gedcom data structures is quite tricky, so here is some guidance.

fhCreateItem("DATA", ptrItem) needs a single Tag without the ~. prefix as it knows it must be a subsidiary Tag.
Each nested Tag must be created as a separate step. fhCreateItem("DATA.DATE", ptrItem) is not allowed.

You must test if a Tag already exists, as if it does then either fhCreateItem(...) will fail or create a second [2] instance.
e.g.
ptrDate:MoveTo(ptrItem,"~.DATA")
if ptrDate:IsNull() then ptrDate = fhCreateItem("DATA", ptrItem) end
ptrDate = fhCreateItem("DATE", ptrDate)

Strictly speaking you should test if the DATE tag exists too, but for these one off cases it is not necessary.

BTW: The reason the DATA tag may already exist is that ~.SOUR.DATA.TEXT may exist for the Text From Source field.

FYI: If you need to deal with similar Where within Source text, but with various dates, then it may be possible to convert each date to a valid Date format using the The Family Historian API > Objects > Date methods.

Re: Automatic update of a field based on another field

Posted: 19 Aug 2017 11:15
by dewilkinson
Mike,

Thank you, that did the trick. I thought I might just missing a step.

David