How To Write A Plugin

Counting Surnames

Introduction

In this section, a new Lua structure - the table - will be used to create a list of surnames used and present the results as a result set in Family Historian.

Tables

Lua tables are very powerful.  In this first introduction, three tables are used: one to count the number of people with each surname, and two to build columns to allow the information to be output to a Result Set Window.  If you ever run a query you will be familiar with the Result Set Window.  It is the window in which the results of a query are displayed (that is, the window that is displayed when you click on the 'Results' tab in the Query Window).

To create an empty table {} (curly brackets) are used. It is also possible to put information directly into a table using the brackets, separating the values using commas.

Tables can be indexed using simple integers or by using keywords. In the example, the first table, tblSurnames, is indexed using surnames, and this allows a counter to be used for each surname.

Reading Through THE Individual RECORDs

The primary loop in the plugin is the same as for the "How many people in my file" example completed previously. The only difference is that the plugin checks for a value in the table for each surname encountered.  If the surname already exists, the plugin adds 1 to the table entry for that surname; otherwise it creates a table entry for that surname, and sets its value to 1.

Once the whole file is processed, the table will contain a list of values indexed by the surname.

Result Sets

Result sets are controlled by the fhOutputResultSet function.  This function is called once for each column of data that is to be added to the result set.  In this example, two columns are added to the result set: one for the name and one for the count. The fhOutputResultSet function takes a table as a parameter.  For the purposes of this example, the tblSurnames table is not suitable.  Tables in Lua can be indexed by numbers (e.g. tblMyTable[3] might be an expression which extracts the 3rd value from the table tblMyTable) or by other value types, such as strings.  fhOutputResultSet requires a table which is indexed by numbers, which tblSurnames is not.  However, it is quite easy to create two tables, tblSurname (note the lack of a final 's' to distinguish it from tblSurnames), and tblcount, from tblSurnames.  This is what the loop for ... in pairs ... is doing.

Finally the result set is populated by two calls to the fhOutputResultSet function, passing in the two new tables as parameters.

The Source

--[[
@Title: Surname Summary Report
@Author: Calico Pie
@LastUpdated: March 2011
@Description: Counts and Lists All Surnames in the File
]]
 
tblSurnames = {}     -- Define array for Surnames
pi = fhNewItemPtr()  -- declare pointer
pi:MoveToFirstRecord("INDI")    -- point to the first Individual record
while not pi:IsNull() do
   -- For each Person Add the Surname to the list
   strSurname = fhGetItemText(pi,'INDI.NAME:SURNAME')
   if (tblSurnames[strSurname] == nil) then
      tblSurnames[strSurname] = 1
   else
      tblSurnames[strSurname] = tblSurnames[strSurname] + 1
   end
   pi:MoveNext()
end
-- Build Tables for the result set columns for Name and Qty
tblSurname = {}
tblcount = {}
ii = 0  -- line counter for result tables
for strSurname, iQty in pairs(tblSurnames) do
   ii = ii + 1
   tblSurname[ii]  = strSurname
   tblcount[ii]    = iQty
end
fhOutputResultSetColumn('Surname', 'text',tblSurname,ii,80,'align_left',2,true)
fhOutputResultSetColumn('Count', 'integer',tblcount,ii,40,'align_right',1,false)

Note that at the top of this script is a standard script header.  It is recommended that this is included in the top of all scripts.  It should include the plugin author's name, a title and a description of what the plugin does.

To add a header to any script, simply select Insert Header from the Edit menu in the editor. The header of a plugin is displayed in the Plugin List  window when the plugin is selected.