* Automatic update of a field based on another field

For users to report plugin bugs and request plugin enhancements; and for authors to test new/new versions of plugins, and to discuss plugin development (in the Programming Technicalities sub-forum). If you want advice on choosing or using a plugin, please ask in General Usage or an appropriate sub-forum.
Post Reply
User avatar
dewilkinson
Superstar
Posts: 280
Joined: 04 Nov 2016 19:05
Family Historian: V7
Location: Oundle, Northamptonshire, England
Contact:

Automatic update of a field based on another field

Post by dewilkinson » 18 Aug 2017 12:42

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.
David Wilkinson researching Bowtle, Butcher, Edwards, Gillingham, Overett, Ransome, Simpson, and Wilkinson in East Anglia

Deterioration is contagious, and places are destroyed or renovated by the spirit of the people who go to them

User avatar
Valkrider
Megastar
Posts: 1534
Joined: 04 Jun 2012 19:03
Family Historian: V7
Location: Lincolnshire
Contact:

Re: Automatic update of a field based on another field

Post by Valkrider » 18 Aug 2017 12:51

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.

User avatar
Jane
Site Admin
Posts: 8441
Joined: 01 Nov 2002 15:00
Family Historian: V7
Location: Somerset, England
Contact:

Re: Automatic update of a field based on another field

Post by Jane » 18 Aug 2017 13:32

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.
Jane
My Family History : My Photography "Knowledge is knowing that a tomato is a fruit. Wisdom is not putting it in a fruit salad."

User avatar
tatewise
Megastar
Posts: 27083
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Automatic update of a field based on another field

Post by tatewise » 18 Aug 2017 13:37

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.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry

User avatar
dewilkinson
Superstar
Posts: 280
Joined: 04 Nov 2016 19:05
Family Historian: V7
Location: Oundle, Northamptonshire, England
Contact:

Re: Automatic update of a field based on another field

Post by dewilkinson » 18 Aug 2017 20:01

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!!)
David Wilkinson researching Bowtle, Butcher, Edwards, Gillingham, Overett, Ransome, Simpson, and Wilkinson in East Anglia

Deterioration is contagious, and places are destroyed or renovated by the spirit of the people who go to them

User avatar
tatewise
Megastar
Posts: 27083
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Automatic update of a field based on another field

Post by tatewise » 19 Aug 2017 10:44

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.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry

User avatar
dewilkinson
Superstar
Posts: 280
Joined: 04 Nov 2016 19:05
Family Historian: V7
Location: Oundle, Northamptonshire, England
Contact:

Re: Automatic update of a field based on another field

Post by dewilkinson » 19 Aug 2017 11:15

Mike,

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

David
David Wilkinson researching Bowtle, Butcher, Edwards, Gillingham, Overett, Ransome, Simpson, and Wilkinson in East Anglia

Deterioration is contagious, and places are destroyed or renovated by the spirit of the people who go to them

Post Reply