BuildDataRef builds a full data reference with instance indices from an item pointer, and provides the record id and type tag for the associated record. If the pointer is invalid it returns empty strings and 0 record id. This function is a compatible evolution of the previous BuildDR function.
GetDataRefPtr reverses the process and supplies an item pointer for a data reference, record id, and record type tag. The data reference may be relative to the record root tag, e.g. “~.NAME”, providing the record type tag is supplied. If the record type tag is omitted, it is extracted from the full data reference. If any parameters are invalid it returns a NULL pointer.
Requires: None
Code
-
--[[ @function: BuildDataRef @description: Get Full Data Reference for Pointer @parameters: Item Pointer @returns: Data Reference String, Record Id Integer, Record Type Tag String @requires: None ]] function BuildDataRef(ptrRef) local strDataRef = "" -- Data Reference with instance indices e.g. INDI.RESI[2].ADDR local intRecId = 0 -- Record Id for associated Record local strRecTag = "" -- Record Tag of associated Record type i.e. INDI, FAM, NOTE, SOUR, etc -- getDataRef() is called recursively per level of the Data Ref -- ptrRef points to the upper Data Ref levels yet to be analysed -- strRef compiles the lower Data Ref levels including instances local function getDataRef(ptrRef,strRef) local ptrTag = ptrRef:Clone() local strTag = fhGetTag(ptrTag) -- Current level Tag ptrTag:MoveToParentItem(ptrTag) if ptrTag:IsNotNull() then -- Parent level exists local intSib = 1 local ptrSib = ptrRef:Clone() -- Pointer to siblings with same Tag ptrSib:MovePrev("SAME_TAG") while ptrSib:IsNotNull() do -- Count previous siblings with same Tag intSib = intSib + 1 ptrSib:MovePrev("SAME_TAG") end if intSib > 1 then strTag = strTag.."["..intSib.."]" end getDataRef(ptrTag,"."..strTag..strRef) -- Now analyse the parent level else strDataRef = strTag..strRef -- Record level reached, so set return values intRecId = fhGetRecordId(ptrRef) strRecTag = strTag if not fhIsValidDataRef(strDataRef) then print(strDataRef.." is Invalid") end end end -- local function getDataRef if type(ptrRef) == "userdata" then getDataRef(ptrRef,"") end return strDataRef, intRecId, strRecTag end -- function BuildDataRef --[[ @function: GetDataRefPtr @description: Get Pointer for Full Data Reference @parameters: Data Reference String, Record Id Integer, Record Type Tag String (optional) @returns: Item Pointer which IsNull() if any parameters are invalid @requires: None ]] function GetDataRefPtr(strDataRef,intRecId,strRecTag) strDataRef = strDataRef or "" if not strRecTag then strRecTag = strDataRef:gsub("^(%u+).*$","%1") -- Extract Record Tag from Data Ref end local ptrRef = fhNewItemPtr() ptrRef:MoveToRecordById(strRecTag,intRecId or 0) -- Lookup the Record by Id ptrRef:MoveTo(ptrRef,strDataRef) -- Move to the Data Ref return ptrRef end -- function GetDataRefPtr
Usage
-
local ptrRef = fhNewItemPtr() ptrRef:MoveToFirstRecord("FAM") ptrRef:MoveToFirstChildItem(ptrRef) print( BuildDataRef(ptrRef) ) -->> FAM.MARR 1 FAM ptrRef = GetDataRefPtr("~.NAME",2,"INDI") print(fhGetDisplayText(ptrRef)) -->> Name: Julia Amanda FISH ptrRef = GetDataRefPtr("INDI.NAME",2) print(fhGetDisplayText(ptrRef)) -->> Name: Julia Amanda FISH ptrRef:MoveToFirstRecord("INDI") while ptrRef:IsNotNull() do local strRef, intId, strTag = BuildDataRef(ptrRef) print(strRef, intId, strTag) -->> INDI.NAME 1 INDI ptrRef = GetDataRefPtr(strRef,intId) print(fhGetDisplayText(ptrRef)) -->> Name: Anthony Edward MUNRO ptrRef:MoveNextSpecial() if intId > 1000 then break end end
Previous Code
-
--[[ @function: BuildDR @description: Get Data Reference for Tag @parameters: Item Pointer @returns: Data reference String (excluding index) @requires: none ]] function BuildDR(ptr) local ptrTemp = fhNewItemPtr() ptrTemp:MoveTo(ptr) strDR = fhGetTag(ptrTemp) while fhHasParentItem(ptrTemp) do ptrTemp:MoveToParentItem(ptrTemp) strDR = fhGetTag(ptrTemp)..'.'..strDR end return strDR end