* Country Summary Help

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.
User avatar
ColeValleyGirl
Megastar
Posts: 5499
Joined: 28 Dec 2005 22:02
Family Historian: V7
Location: Cirencester, Gloucestershire
Contact:

Re: Country Summary Help

Post by ColeValleyGirl »

Where do you actually call main?
User avatar
tatewise
Megastar
Posts: 28410
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Country Summary Help

Post by tatewise »

Lua is very case-sensitive!

Your script is calling GetCountry but the function is getCountry

With the addition of a call of main() at the end, the script then performs as expected.

Initially, the Lua interpreter parses each function before invoking the script, which is why you see it stepping through the start and end line numbers of each function.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
avatar
British Kiwi
Famous
Posts: 106
Joined: 14 Sep 2014 09:59
Family Historian: V7

Re: Country Summary Help

Post by British Kiwi »

Yes I wasn't calling it and couldn't work out how or where to. The case sensitive I had consistent at one point and had the same result, so have fixed that.

I've now managed to get it to work. I think my confusion was that I was trying to call the function before it read the functions so I wrote:
main()

function()
end

When I had checked the code for the Surname Summary report, it didn't call the function. Is that because it is called elsewhere?

I'm giving up for the night plan on further streamlining. Thanks once again for all your help!
User avatar
tatewise
Megastar
Posts: 28410
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Country Summary Help

Post by tatewise »

The Surname Summary Report plugin calls main() on the very last line of the script.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
avatar
British Kiwi
Famous
Posts: 106
Joined: 14 Sep 2014 09:59
Family Historian: V7

Re: Country Summary Help

Post by British Kiwi »

tatewise wrote: 21 Jun 2022 12:57 The Surname Summary Report plugin calls main() on the very last line of the script.
Oops, yes now I see it. I think in VBA you didn't have to have all the functions first. Thanks :)
avatar
British Kiwi
Famous
Posts: 106
Joined: 14 Sep 2014 09:59
Family Historian: V7

Re: Country Summary Help

Post by British Kiwi »

Et voila! I'm next going to look at nested tables, or tidying up the inserting to the result tables.

Code: Select all

--[[
@Title: Country of Birth Summary Report
@Type: Standard
@Author: Melanie Marsh
@Version: 0.2
@Keywords: Country, Birth, Death
@LastUpdated: 21/06/2022
@Licence: This plugin is copyright (c) 2022 Melanie Marsh and contributors, and is licensed under the MIT License
which is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: Counts the number of births and deaths for each country used in the database.
]]


function main()

	_ = true

	local tblMasterCountries = {}		-- Definne array of master list of countries
	local tblBirthCountries = {}		-- Define array for Countries of Birth
	local tblDeathCountries = {}     -- Define array for Countries of Death

	pl = fhNewItemPtr()	-- declare pointer
	pl:MoveToFirstRecord("INDI")	-- point to the first individual record
	
	while pl:IsNotNull() do
	

		-- For each Person get the Country of Birth
		
		strBirthCountry = getCountry(fhGetItemText(pl,'%INDI.BIRT.PLAC>%'))

		-- For each Person Get the Country of Death
		strDeathCountry = getCountry(fhGetItemText(pl,'%INDI.DEAT.PLAC>%'))

		
		-- Add Birth/Death Country to the Master List
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strBirthCountry)
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strDeathCountry)
	

		-- Add the Country of Birth to the Birth List
		tblBirthCountries = addSelectedCountry(tblBirthCountries,strBirthCountry)		


		-- Add the Country of Death to the Death List
		tblDeathCountries = addSelectedCountry(tblDeathCountries,strDeathCountry)		
		

		pl:MoveNext()

	end


	-- Build Tables for the result set columns for Country and Qty
	local tblMasterCountry = {}
	local tblBirthCount={}
	local tblDeathCount = {}

	ii = 0 -- line counter for result tables

	for strMasterCountry, _ in pairs(tblMasterCountries) do

		table.insert( tblMasterCountry,strMasterCountry)
		table.insert( tblBirthCount, tblBirthCountries[strMasterCountry] or 0 )
		table.insert( tblDeathCount, tblDeathCountries[strMasterCountry] or 0 )

	end

	local ii = #tblMasterCountry
	


	fhOutputResultSetColumn('Country', 'text',tblMasterCountry,ii,80,'align_left',2,true)
	fhOutputResultSetColumn('No of Births', 'integer', tblBirthCount,ii,40,'align_right',1,false)
	fhOutputResultSetColumn('No of Deaths', 'integer', tblDeathCount,ii,40,'align_right',1,false)

end



------Additional functions

--Gets the last part of the place to get the country. Assumes that the country is after the last comma.
function getCountry(strDataReference)

	-- assumes that the country is after the last comma

	strCountry = fhCallBuiltInFunction("TextPart",strDataReference,-1)

	if strCountry == "" then
		strCountry = "~Not Set~"
	end

	return strCountry


end

--Adds selected country i.e.Birth or Death etc to the Master list if it doesn't exist
 
function addSelectedCountry(tblSelectedCountries, strSelectedCountry)

	-- Add the selected Country to the selected table
	if not(tblSelectedCountries[strSelectedCountry]) then
		tblSelectedCountries[strSelectedCountry] = 1
	else
		tblSelectedCountries[strSelectedCountry] = tblSelectedCountries[strSelectedCountry] + 1
	end

	return tblSelectedCountries
	
end

-----------------Call main()
main()
I promise not to post every single modification I make, but it is making me a little excited! Nice break from the daytime job (which i love, it is just intense sometimes)
User avatar
ColeValleyGirl
Megastar
Posts: 5499
Joined: 28 Dec 2005 22:02
Family Historian: V7
Location: Cirencester, Gloucestershire
Contact:

Re: Country Summary Help

Post by ColeValleyGirl »

If you use the </> icon above your post, you can format the code as code which makes it easier to read.
avatar
British Kiwi
Famous
Posts: 106
Joined: 14 Sep 2014 09:59
Family Historian: V7

Re: Country Summary Help

Post by British Kiwi »

ColeValleyGirl wrote: 22 Jun 2022 08:19 If you use the </> icon above your post, you can format the code as code which makes it easier to read.
Great thanks. I wondered how that was happening. Thought the forum fairies were at work 😆 Much clearer, thanks 😊
User avatar
tatewise
Megastar
Posts: 28410
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Country Summary Help

Post by tatewise »

Melanie, I'm glad you are enjoying writing plugins.
I hope you don't mind me suggesting a few minor adjustments to your code?

There are several variables that would be better if they were local rather global, because they 'pollute' the global name space, which can make debugging more complex, especially when plugins are a bit more complicated.
Maybe you assumed that new variables used inside functions would automatically be local, but they are global.
e.g. This would be better
local pI
local strBirthCountry
local strDeathCountry
local strCountry

The initial statement _ = true is not needed as that global _ variable is not used.
It is not the same variable as the one in for strMasterCountry, _ in pairs(tblMasterCountries) do
Those variables strMasterCountry and _ are automatically local to the for loop.
It is conventionally popular to use _ for unused variables in for loops.

In the same way that table names start with tbl and strings start with str the equivalent for pointers is ptr.
So pI might be renamed ptrIndi.

The line ii = 0 -- line counter for result tables is not needed as that global is not used.

Consider using the fhOutputResultSetTitles(...) function otherwise the Result Set is Untitled.

Currently, the No of Births/Deaths columns are not wide enough to show the full column heading.
So, either reduce the heading text or increase the width parameter.

The function getCountry(strDataReference) parameter is not a Data Ref but the actual Place text.
i.e. function getCountry(strPlace) would be more representative.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
avatar
British Kiwi
Famous
Posts: 106
Joined: 14 Sep 2014 09:59
Family Historian: V7

Re: Country Summary Help

Post by British Kiwi »

Mike, I am always happy for suggestions, best way to learn. I just didn't want to impose on all your time! I think I managed to incorporate all the changes.

Code: Select all

--[[
@Title: Country of Birth Summary Report
@Type: Standard
@Author: Melanie Marsh
@Version: 0.2
@Keywords: Country, Birth, Death
@LastUpdated: 21/06/2022
@Licence: This plugin is copyright (c) 2022 Melanie Marsh and contributors, and is licensed under the MIT License
which is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: Counts the number of births and deaths for each country used in the database.
]]


function main()

	local tblMasterCountries = {}		-- Definne array of master list of countries
	local tblBirthCountries = {}		-- Define array for Countries of Birth
	local tblDeathCountries = {}     -- Define array for Countries of Death

	local pl
	local srBirthCountry
	local strDeathCountry
	local strCountry
	local ptrIndi

	ptrIndi = fhNewItemPtr()	-- declare pointer
	ptrIndi:MoveToFirstRecord("INDI")	-- point to the first individual record
	
	while ptrIndi:IsNotNull() do
	

		-- For each Person get the Country of Birth
		
		strBirthCountry = getCountry(fhGetItemText(ptrIndi,'%INDI.BIRT.PLAC>%'))

		-- For each Person Get the Country of Death
		strDeathCountry = getCountry(fhGetItemText(ptrIndi,'%INDI.DEAT.PLAC>%'))

		
		-- Add Birth/Death Country to the Master List
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strBirthCountry)
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strDeathCountry)
	

		-- Add the Country of Birth to the Birth List
		tblBirthCountries = addSelectedCountry(tblBirthCountries,strBirthCountry)		


		-- Add the Country of Death to the Death List
		tblDeathCountries = addSelectedCountry(tblDeathCountries,strDeathCountry)		
		

		ptrIndi:MoveNext()

	end


	-- Build Tables for the result set columns for Country and Qty
	local tblMasterCountry = {}
	local tblBirthCount = {}
	local tblDeathCount = {}


	for strMasterCountry, _ in pairs(tblMasterCountries) do

		table.insert( tblMasterCountry,strMasterCountry)
		table.insert( tblBirthCount, tblBirthCountries[strMasterCountry] or 0 )
		table.insert( tblDeathCount, tblDeathCountries[strMasterCountry] or 0 )

	end

	local ii = #tblMasterCountry
	

   local project = fhGetContextInfo('CI_PROJECT_NAME')
   fhOutputResultSetTitles("Country Summary Report","Country Summary Report for "..project, "Printed Date: %#x")

	fhOutputResultSetColumn('Country', 'text',tblMasterCountry,ii,80,'align_left',2,true)
	fhOutputResultSetColumn('No of Births', 'integer', tblBirthCount,ii,60,'align_right',1,false)
	fhOutputResultSetColumn('No of Deaths', 'integer', tblDeathCount,ii,60,'align_right',1,false)

end



------Additional functions

--Gets the last part of the place to get the country. Assumes that the country is after the last comma.

function getCountry(strPlace)

	-- assumes that the country is after the last comma

	strCountry = fhCallBuiltInFunction("TextPart",strPlace,-1)

	if strCountry == "" then
		strCountry = "~Not Set~"
	end

	return strCountry


end

--Adds selected country i.e.Birth or Death etc to the Master list if it doesn't exist
 
function addSelectedCountry(tblSelectedCountries, strSelectedCountry)

	-- Add the selected Country to the selected table
	if not(tblSelectedCountries[strSelectedCountry]) then
		tblSelectedCountries[strSelectedCountry] = 1
	else
		tblSelectedCountries[strSelectedCountry] = tblSelectedCountries[strSelectedCountry] + 1
	end

	return tblSelectedCountries
	
end

-----------------Call main()
main()
I was also thinking for adding marriages too, because...why not! So my thoughts were that I would loop through all the marriages rather than INID so that it would only be counted once, but for those who married more than once, it would be included for each time. Firstly though I am going to work on my nested tables.
User avatar
tatewise
Megastar
Posts: 28410
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Country Summary Help

Post by tatewise »

Yes, that is a great improvement but you can put local before the first use of each variable as you have done elsewhere like this:

Code: Select all

--[[
@Title: Country of Birth Summary Report
@Type: Standard
@Author: Melanie Marsh
@Version: 0.2
@Keywords: Country, Birth, Death
@LastUpdated: 21/06/2022
@Licence: This plugin is copyright (c) 2022 Melanie Marsh and contributors, and is licensed under the MIT License
which is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: Counts the number of births and deaths for each country used in the database.
]]

function main()

	local tblMasterCountries = {}		-- Definne array of master list of countries
	local tblBirthCountries = {}		-- Define array for Countries of Birth
	local tblDeathCountries = {}     -- Define array for Countries of Death

	local ptrIndi = fhNewItemPtr()	-- declare pointer
	ptrIndi:MoveToFirstRecord("INDI")	-- point to the first individual record
	
	while ptrIndi:IsNotNull() do

		-- For each Person get the Country of Birth
		
		local strBirthCountry = getCountry(fhGetItemText(ptrIndi,'%INDI.BIRT.PLAC>%'))

		-- For each Person Get the Country of Death
		local strDeathCountry = getCountry(fhGetItemText(ptrIndi,'%INDI.DEAT.PLAC>%'))

		
		-- Add Birth/Death Country to the Master List
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strBirthCountry)
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strDeathCountry)
	

		-- Add the Country of Birth to the Birth List
		tblBirthCountries = addSelectedCountry(tblBirthCountries,strBirthCountry)		


		-- Add the Country of Death to the Death List
		tblDeathCountries = addSelectedCountry(tblDeathCountries,strDeathCountry)		
		

		ptrIndi:MoveNext()

	end


	-- Build Tables for the result set columns for Country and Qty
	local tblMasterCountry = {}
	local tblBirthCount = {}
	local tblDeathCount = {}


	for strMasterCountry, _ in pairs(tblMasterCountries) do

		table.insert( tblMasterCountry,strMasterCountry)
		table.insert( tblBirthCount, tblBirthCountries[strMasterCountry] or 0 )
		table.insert( tblDeathCount, tblDeathCountries[strMasterCountry] or 0 )

	end

	local ii = #tblMasterCountry
	

   local project = fhGetContextInfo('CI_PROJECT_NAME')
   fhOutputResultSetTitles("Country Summary Report","Country Summary Report for "..project, "Printed Date: %#x")

	fhOutputResultSetColumn('Country', 'text',tblMasterCountry,ii,80,'align_left',2,true)
	fhOutputResultSetColumn('No of Births', 'integer', tblBirthCount,ii,60,'align_right',1,false)
	fhOutputResultSetColumn('No of Deaths', 'integer', tblDeathCount,ii,60,'align_right',1,false)

end



------Additional functions

--Gets the last part of the place to get the country. Assumes that the country is after the last comma.

function getCountry(strPlace)

	-- assumes that the country is after the last comma

	local strCountry = fhCallBuiltInFunction("TextPart",strPlace,-1)

	if strCountry == "" then
		strCountry = "~Not Set~"
	end

	return strCountry


end

--Adds selected country i.e.Birth or Death etc to the Master list if it doesn't exist
 
function addSelectedCountry(tblSelectedCountries, strSelectedCountry)

	-- Add the selected Country to the selected table
	if not(tblSelectedCountries[strSelectedCountry]) then
		tblSelectedCountries[strSelectedCountry] = 1
	else
		tblSelectedCountries[strSelectedCountry] = tblSelectedCountries[strSelectedCountry] + 1
	end

	return tblSelectedCountries
	
end

-----------------Call main()
main()
In case you had not realised you cannot use '%INDI.MARR.PLAC>%' because Marriage events are not held in the Individual records but in Family records linked to the Individual records.

So to find all Marriage events only once, loop through Family (FAM) records instead of Individual (INDI) records.
i.e. Use ptrFam:MoveToFirstRecord("FAM") and '%FAM.MARR.PLAC>%'

You might also want to consider Baptisms, Christenings, Burials, and Cremations.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
avatar
British Kiwi
Famous
Posts: 106
Joined: 14 Sep 2014 09:59
Family Historian: V7

Re: Country Summary Help

Post by British Kiwi »

tatewise wrote: 22 Jun 2022 12:21 Yes, that is a great improvement but you can put local before the first use of each variable as you have done elsewhere like this:

Code: Select all

--[[
@Title: Country of Birth Summary Report
@Type: Standard
@Author: Melanie Marsh
@Version: 0.2
@Keywords: Country, Birth, Death
@LastUpdated: 21/06/2022
@Licence: This plugin is copyright (c) 2022 Melanie Marsh and contributors, and is licensed under the MIT License
which is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: Counts the number of births and deaths for each country used in the database.
]]

function main()

	local tblMasterCountries = {}		-- Definne array of master list of countries
	local tblBirthCountries = {}		-- Define array for Countries of Birth
	local tblDeathCountries = {}     -- Define array for Countries of Death

	local ptrIndi = fhNewItemPtr()	-- declare pointer
	ptrIndi:MoveToFirstRecord("INDI")	-- point to the first individual record
	
	while ptrIndi:IsNotNull() do

		-- For each Person get the Country of Birth
		
		local strBirthCountry = getCountry(fhGetItemText(ptrIndi,'%INDI.BIRT.PLAC>%'))

		-- For each Person Get the Country of Death
		local strDeathCountry = getCountry(fhGetItemText(ptrIndi,'%INDI.DEAT.PLAC>%'))

		
		-- Add Birth/Death Country to the Master List
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strBirthCountry)
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strDeathCountry)
	

		-- Add the Country of Birth to the Birth List
		tblBirthCountries = addSelectedCountry(tblBirthCountries,strBirthCountry)		


		-- Add the Country of Death to the Death List
		tblDeathCountries = addSelectedCountry(tblDeathCountries,strDeathCountry)		
		

		ptrIndi:MoveNext()

	end


	-- Build Tables for the result set columns for Country and Qty
	local tblMasterCountry = {}
	local tblBirthCount = {}
	local tblDeathCount = {}


	for strMasterCountry, _ in pairs(tblMasterCountries) do

		table.insert( tblMasterCountry,strMasterCountry)
		table.insert( tblBirthCount, tblBirthCountries[strMasterCountry] or 0 )
		table.insert( tblDeathCount, tblDeathCountries[strMasterCountry] or 0 )

	end

	local ii = #tblMasterCountry
	

   local project = fhGetContextInfo('CI_PROJECT_NAME')
   fhOutputResultSetTitles("Country Summary Report","Country Summary Report for "..project, "Printed Date: %#x")

	fhOutputResultSetColumn('Country', 'text',tblMasterCountry,ii,80,'align_left',2,true)
	fhOutputResultSetColumn('No of Births', 'integer', tblBirthCount,ii,60,'align_right',1,false)
	fhOutputResultSetColumn('No of Deaths', 'integer', tblDeathCount,ii,60,'align_right',1,false)

end



------Additional functions

--Gets the last part of the place to get the country. Assumes that the country is after the last comma.

function getCountry(strPlace)

	-- assumes that the country is after the last comma

	local strCountry = fhCallBuiltInFunction("TextPart",strPlace,-1)

	if strCountry == "" then
		strCountry = "~Not Set~"
	end

	return strCountry


end

--Adds selected country i.e.Birth or Death etc to the Master list if it doesn't exist
 
function addSelectedCountry(tblSelectedCountries, strSelectedCountry)

	-- Add the selected Country to the selected table
	if not(tblSelectedCountries[strSelectedCountry]) then
		tblSelectedCountries[strSelectedCountry] = 1
	else
		tblSelectedCountries[strSelectedCountry] = tblSelectedCountries[strSelectedCountry] + 1
	end

	return tblSelectedCountries
	
end

-----------------Call main()
main()
In case you had not realised you cannot use '%INDI.MARR.PLAC>%' because Marriage events are not held in the Individual records but in Family records linked to the Individual records.

So to find all Marriage events only once, loop through Family (FAM) records instead of Individual (INDI) records.
i.e. Use ptrFam:MoveToFirstRecord("FAM") and '%FAM.MARR.PLAC>%'

You might also want to consider Baptisms, Christenings, Burials, and Cremations.
That looks much more streamlined, I will do that.

Yes I knew that I couldn't loop through INDI, but you have saved me time working out where marriages were, so thank you. And yes I am likely to look at other events, if there is a place, it is likely going to be added :)
avatar
British Kiwi
Famous
Posts: 106
Joined: 14 Sep 2014 09:59
Family Historian: V7

Re: Country Summary Help

Post by British Kiwi »

Evening, me again! So I have managed to finish my plugin which includes burials, christenings, marriages etc. I need to fully test, but seems to work fine. After having a break (school holidays!) I decided to try using nested tables (if that is the right term). I think I have finally cracked it, kind of. However, I am now a little stuck on how to output it. I tried to use the fhOutputResultsSetColumn, but I don't think I am using it correctly with the structure. Can anyone point me in the right direction? Here is my code:

Code: Select all

--[[
@Title: Country of Birth Summary Report
@Type: Standard
@Author: Melanie Marsh
@Version: 0.3
@Keywords: Country, Birth, Baptism, Christening, Marriage, Death, Burial
@LastUpdated: 21/06/2022
@Licence: This plugin is copyright (c) 2022 Melanie Marsh and contributors, and is licensed under the MIT License
which is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: Counts the number of births and deaths for each country used in the database.
]]

function main()

	local tblCountry = {} --Define master list of countries and events
	local strBirthCountry
	local strBaptismCountry
	local strChristeningCountry
	local strDeathCountry
	local strBurialCountry

	local ptrIndi = fhNewItemPtr()	-- declare pointer
	ptrIndi:MoveToFirstRecord("INDI")	-- point to the first individual record
	
	while ptrIndi:IsNotNull() do

		-- For each Person get the Country of Birth, add to tblCountry and add a Birth event if needed
		
		strBirthCountry = getCountry(fhGetItemText(ptrIndi,'%INDI.BIRT.PLAC>%'))
		tblCountry = addCountryEvent(tblCountry,strBirthCountry,"Birth")

		-- For each Person get the Country of Baptism, add to tblCountry and add a Baptism event if needed
		strBaptismCountry = getCountry(fhGetItemText(ptrIndi, '%INDI.BAPM.PLAC>%'))
		tblCountry = addCountryEvent(tblCountry,strBaptismCountry,"Baptism")		

		-- For each Person get the Country of Christening, add to tblCountry and add a Christening event if needed
		strChristeningCountry = getCountry(fhGetItemText(ptrIndi, '%INDI.CHR.PLAC>%'))
		tblCountry = addCountryEvent(tblCountry,strChristeningCountry,"Christening")				

		-- For each Person get the Country of Death, add to tblCountry and add a Death event if needed
		strDeathCountry = getCountry(fhGetItemText(ptrIndi,'%INDI.DEAT.PLAC>%'))
		tblCountry = addCountryEvent(tblCountry,strDeathCountry,"Death")						

		-- For each Person get the Country of Burial, add to tblCountry and add a Burial event if needed
		strBurialCountry = getCountry(fhGetItemText(ptrIndi,'%INDI.BURI%'))
		tblCountry = addCountryEvent(tblCountry,strBurialCountry,"Burial")								

		ptrIndi:MoveNext()

	end

	--Get marriage countries

	local strMarriageCountry
	local ptrFam = fhNewItemPtr()	-- declare family pointer
	ptrFam:MoveToFirstRecord("FAM")	-- point to the first family record
	
	while ptrFam:IsNotNull() do

		--For each 'family' get the country of marriage add to tblCountry and add a marriage event if needed
		strMarriageCountry = getCountry(fhGetItemText(ptrFam,'%FAM.MARR.PLAC>%'))
		tblCountry = addCountryEvent(tblCountry,strMarriageCountry,"Marriage")								
		
		ptrFam:MoveNext()
	
	end

-- output to table

	local ii = #tblCountry

	ii = 11
   local project = fhGetContextInfo('CI_PROJECT_NAME')
   fhOutputResultSetTitles("Country Summary Report","Country Summary Report for "..project, "Printed Date: %#x")
	fhOutputResultSetColumn('Country', 'text',tblCountry,ii,80,'align_left',2,true)
--	fhOutputResultSetColumn('No of Births', 'integer', tblCountry.Births,ii,60,'align_right',1,false)
	


end

------Additional functions

--Gets the last part of the place to get the country. Assumes that the country is after the last comma.

function getCountry(strPlace)

	-- assumes that the country is after the last comma

	local strCountry = fhCallBuiltInFunction("TextPart",strPlace,-1)

	if strCountry == "" then
		strCountry = "~Not Set~"
	end

	return strCountry

end


-------------------------------------------------------------------------------------------
--Checks if country exists, if not adds a row for country. 
--Checks if country has the event i.e. birth already and if so, increases by one otherwise
--adds event with an amount of 1
-------------------------------------------------------------------------------------------

function addCountryEvent(tblCountry, strCountry,strEvent)

	if not(tblCountry[strCountry]) then
		tblCountry[strCountry]={}
		tblCountry[strCountry][strEvent] = 1
	else
		if not(tblCountry[strCountry][strEvent])then
			tblCountry[strCountry][strEvent] = 1
		else
			tblCountry[strCountry][strEvent] = tblCountry[strCountry][strEvent]+1
		end
	end

	return tblCountry

end

-----------------Call main()
main()
Hope it all makes sense. Thanks in advance :)
User avatar
Jane
Site Admin
Posts: 8514
Joined: 01 Nov 2002 15:00
Family Historian: V7
Location: Somerset, England
Contact:

Re: Country Summary Help

Post by Jane »

The result set column needs a simple flat table for each column.

Personally I tend to require fhUtils and using the included createResultSet function.
That way you can simply loop through your result table and push it over into an output set.

The instructions for use are here: http://pluginstore.family-historian.co. ... ltSet.html
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: 28410
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Country Summary Help

Post by tatewise »

As the Help for fhOutputResultSetColumn(...) says for the tblData parameter: "The table must be a simple indexed table."

Your tblCountry now is a nested structure with country name keys, so it is not a simple table indexed by integer keys.
It may be convenient to manage the data in such a structure but it must be transformed into a set of simple indexed tables for output in the Result Set.

BTW: Line 45 has %INDI.BURI% that should be %INDI.BURI.PLAC%
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
avatar
British Kiwi
Famous
Posts: 106
Joined: 14 Sep 2014 09:59
Family Historian: V7

Re: Country Summary Help

Post by British Kiwi »

Jane wrote: 07 Jul 2022 13:40 The result set column needs a simple flat table for each column.

Personally I tend to require fhUtils and using the included createResultSet function.
That way you can simply loop through your result table and push it over into an output set.

The instructions for use are here: http://pluginstore.family-historian.co. ... ltSet.html
Thanks Jane, I will go through this and have a look :)
avatar
British Kiwi
Famous
Posts: 106
Joined: 14 Sep 2014 09:59
Family Historian: V7

Re: Country Summary Help

Post by British Kiwi »

tatewise wrote: 07 Jul 2022 13:45 As the Help for fhOutputResultSetColumn(...) says for the tblData parameter: "The table must be a simple indexed table."

Your tblCountry now is a nested structure with country name keys, so it is not a simple table indexed by integer keys.
It may be convenient to manage the data in such a structure but it must be transformed into a set of simple indexed tables for output in the Result Set.

BTW: Line 45 has %INDI.BURI% that should be %INDI.BURI.PLAC%
Thanks for picking up the %INDI.BURI.PLAC% bit, I've corrected it.

So would you say that it in this case it is better to keep it in a series of tables? This is my other code that I produced which uses the series of tables.

Code: Select all

--[[
@Title: Country of Birth Summary Report
@Type: Standard
@Author: Melanie Marsh
@Version: 0.4
@Keywords: Country, Birth, Baptism, Christening, Marriage, Death, Burial
@LastUpdated: 08/07/2022
@Licence: This plugin is copyright (c) 2022 Melanie Marsh and contributors, and is licensed under the MIT License
which is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: Counts the number of births, christenings, marriages, deaths and burials for each country used in the database.
]]


function main()

	local tblMasterCountries = {}		-- Definne array of master list of countries
	local tblBirthCountries = {}		-- Define array for Countries of Birth
	local tblBaptismCountries = {}	-- Define array for Countries of Baptism
	local tblChristeningCountries = {}	-- Define array for Countries of Christenings
	local tblDeathCountries = {}     -- Define array for Countries of Death
	local tblBurialCountries = {}	-- Define array for Countries of Burial
	local tblMarriageCountries = {}	-- 	Define array for Countries of Marriage


	local ptrIndi = fhNewItemPtr()	-- declare pointer
	ptrIndi:MoveToFirstRecord("INDI")	-- point to the first individual record
	
	while ptrIndi:IsNotNull() do
	

		-- For each Person get the Country of Birth, add to Master and Birth List
		
		local strBirthCountry = getCountry(fhGetItemText(ptrIndi,'%INDI.BIRT.PLAC>%'))
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strBirthCountry)
		tblBirthCountries = addSelectedCountry(tblBirthCountries,strBirthCountry)		

		-- For each Person get the Country of Baptism, add to Master and Baptism List
		local strBaptismCountry = getCountry(fhGetItemText(ptrIndi, '%INDI.BAPM.PLAC>%'))
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strBaptismCountry)
		tblBaptismCountries = addSelectedCountry(tblBaptismCountries,strBaptismCountry)		

		-- For each Person get the Country of Christening, add to Master and Christening List
		local strChristeningCountry = getCountry(fhGetItemText(ptrIndi, '%INDI.CHR.PLAC>%'))
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strChristeningCountry)
		tblChristeningCountries = addSelectedCountry(tblChristeningCountries,strChristeningCountry)		

		-- For each Person get the Country of Death, add to Master and Death List		
		local strDeathCountry = getCountry(fhGetItemText(ptrIndi,'%INDI.DEAT.PLAC>%'))
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strDeathCountry)
		tblDeathCountries = addSelectedCountry(tblDeathCountries,strDeathCountry)		
		
		-- For each Person get the Country of Burial, add to Master and Burial List		
		local strBurialCountry = getCountry(fhGetItemText(ptrIndi,'%INDI.BURI.PLAC%'))
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strBurialCountry)
		tblBurialCountries = addSelectedCountry(tblBurialCountries,strBurialCountry)		


		ptrIndi:MoveNext()

	end


	--Get marriage countries

	local ptrFam = fhNewItemPtr()	-- declare family pointer
	ptrFam:MoveToFirstRecord("FAM")	-- point to the first family record
	
	while ptrFam:IsNotNull() do

		--For each 'family' get the country of marriage and add to master and marriage list
		local strMarriageCountry = getCountry(fhGetItemText(ptrFam,'%FAM.MARR.PLAC>%'))
		tblMasterCountries = addSelectedCountry(tblMasterCountries, strMarriageCountry)	
		tblMarriageCountries = addSelectedCountry(tblMarriageCountries,strMarriageCountry)		

		
		ptrFam:MoveNext()
	
	end


	-- Build Tables for the result set columns for Country and Qty
	local tblMasterCountry = {}
	local tblBirthCount = {}
	local tblBaptismCount = {}
	local tblChristeningCount = {}
	local tblDeathCount = {}
	local tblBurialCount = {}
	local tblMarriageCount = {}


	for strMasterCountry, _ in pairs(tblMasterCountries) do

		table.insert( tblMasterCountry,strMasterCountry)
		table.insert( tblBirthCount, tblBirthCountries[strMasterCountry] or 0 )
		table.insert( tblBaptismCount, tblBaptismCountries[strMasterCountry] or 0 )		
		table.insert( tblChristeningCount, tblChristeningCountries[strMasterCountry] or 0 )
		table.insert( tblDeathCount, tblDeathCountries[strMasterCountry] or 0 )
		table.insert( tblBurialCount, tblBurialCountries[strMasterCountry] or 0 )
		table.insert( tblMarriageCount, tblMarriageCountries[strMasterCountry] or 0 )

	end

	local ii = #tblMasterCountry
	

   local project = fhGetContextInfo('CI_PROJECT_NAME')
   fhOutputResultSetTitles("Country Summary Report","Country Summary Report for "..project, "Printed Date: %#x")

	fhOutputResultSetColumn('Country', 'text',tblMasterCountry,ii,80,'align_left',2,true)
	fhOutputResultSetColumn('No of Births', 'integer', tblBirthCount,ii,60,'align_right',1,false)
	fhOutputResultSetColumn('No of Baptisms', 'integer', tblBaptismCount,ii,60,'align_right',1,false)
	fhOutputResultSetColumn('No of Christenings', 'integer', tblChristeningCount,ii,70,'align_right',1,false)
	fhOutputResultSetColumn('No of Marriages', 'integer', tblMarriageCount,ii,60,'align_right',1,false)	
	fhOutputResultSetColumn('No of Deaths', 'integer', tblDeathCount,ii,60,'align_right',1,false)
	fhOutputResultSetColumn('No of Burials', 'integer', tblBurialCount,ii,60,'align_right',1,false)


end



------Additional functions

--Gets the last part of the place to get the country. Assumes that the country is after the last comma.

function getCountry(strPlace)

	-- assumes that the country is after the last comma

	local strCountry = fhCallBuiltInFunction("TextPart",strPlace,-1)

	if strCountry == "" then
		strCountry = "~Not Set~"
	end

	return strCountry


end

--Adds selected country i.e.Birth or Death etc to the Master list if it doesn't exist
 
function addSelectedCountry(tblSelectedCountries, strSelectedCountry)

	-- Add the selected Country to the selected table
	if not(tblSelectedCountries[strSelectedCountry]) then
		tblSelectedCountries[strSelectedCountry] = 1
	else
		tblSelectedCountries[strSelectedCountry] = tblSelectedCountries[strSelectedCountry] + 1
	end

	return tblSelectedCountries
	
end

-----------------Call main()
main()
My next question is about error trapping. In my VBA days I used to have a lot of On Error etc type code. Is that used in Lua?
User avatar
tatewise
Megastar
Posts: 28410
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Country Summary Help

Post by tatewise »

Yes, that series of tables is the solution.

Regarding error handling, see the http://www.lua.org/manual/5.3/manual.html#2.3 Error Handling section.
However, in my experience, most error handling involves identifying FH Project data 'errors' and user interface 'errors' rather than trapping programming errors.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
Post Reply