(* KBB_HltDB_upd
--------------------------------------------------
Function
1. Designed specifically to update a FMP Health Tracking Database
2. Input is from 1 of 3 .csv Files downloade with health data
Health Data - Apple HealthKit data (BP, Weight, BodyFat%
MyFitnessPal - Nutrition data and exercise data
--------------------------------------------------
This Work
--
-- Created by: Karl Browning
-- Created on: 12/01/18
--
-- Copyright (c) 2018
-- All Rights Reserved
--
Change log is maintained at the end of this script listing.
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
-----------------------------------------------------
- V A R I A B L E S
-----------------------------------------------------
*)
property V_DB : "Health Data Tracking.fmp12" --
property V_startDate : 1 / 1 / 2000
property v_this_name : ""
property dataCells : {}
(*
-----------------------------------------------------
- T A B L E S
-----------------------------------------------------
*)
property type_list : {} -- eg: {"CSV"}
property extension_list : {"csv"} -- eg: {"csv""}, NOT: {".txt", ".text", ".jpg", ".jpeg"}
property typeIDs_list : {"public.comma-separated-values-text"} -- eg: {"public.csv"}
property exerciseHeading : "ÔªøDate,Exercise,Type,Exercise Calories,Exercise Minutes,Sets,Reps Per Set,Pounds,Steps,Note"
-- property exerciseHeading : "Date,Exercise,Type,Exercise Calories,Exercise Minutes,Sets,Reps Per Set,Pounds,Steps,Note"
property nutritionHeading : "ÔªøDate,Meal,Calories,Fat (g),Saturated Fat,Polyunsaturated Fat,Monounsaturated Fat,Trans Fat,Cholesterol,Sodium (mg),Potassium,Carbohydrates (g),Fiber,Sugar,Protein (g),Vitamin A,Vitamin C,Calcium,Iron,Note"
property bodymeasuresHeading : "Start,Finish,Body Fat Percentage (%),Steps (count),Weight (lb)"
property columnHeadings : {}
(*
-----------------------------------------------------
- C O U N T E R S
-----------------------------------------------------
*)
property rowCount : 0
(*
-----------------------------------------------------
- K O N S T A N T S
-----------------------------------------------------
*)
property K_scriptName : "KBB_HltDB_upd"
property K_pFile_Path : (path to desktop as alias) as string -- location of log file
property K_Filemaker : "Filemaker Pro Advanced" --
property K_Filemaker_Version : "" -- Version Name of Filemaker in use
property K_sourceFilePath : ((path to documents folder from user domain as string) & "Databases") -- location of Music Library Database
property K_Activity_Table : "H Activity"
property K_Activity_T_Layout : "T Activity"
property K_Activity_cmn_Layout : "Activity_cmn"
property K_Nutrition_Table : "H Nutrition"
property K_Nutrition_T_Layout : "T Nutrition"
property K_Nutrition_cmn_Layout : "Nutrition_cmn"
property K_BP_Table : "H Blood Pressure"
property K_BP_cmn_Layout : "BP_cmn"
property K_BodyMeasures_Table : "H BodyMeasures"
property K_BodyMeasures_T_Layout : "T BodyMeasures"
property K_BodyMeasures_cmn_Layout : "BodyMeasures_cmn"
(*
__________________________ Test File characteristics to assure validity _________________________________
1. Valid name extension (see extension_List)
2. Valid file type (see type_List)
3. Valid typeID
*)
on open theDroppedFiles
repeat with i from 1 to the count of theDroppedFiles
set this_item to item i of theDroppedFiles
set the item_info to info for this_item
tell application "System Events"
try
set v_this_name to the name of this_item
on error
set v_this_name to "No Name"
end try
try
set this_extension to the name extension of this_item
on error
set this_extension to ""
end try
try
set this_filetype to the file type of this_item
on error
set this_filetype to ""
end try
try
set this_typeID to the type identifier of this_item
on error
set this_typeID to ""
end try
end tell
if (this_filetype is in the type_list) or ¬
(this_extension is in the extension_list) or ¬
(this_typeID is in typeIDs_list) then
-- Request the Starting Date to filter the dropped file records
repeat
if V_startDate = 1 / 1 / 2000 then -- If multiple files, only do this once
try
display dialog ¬
"Enter the begining selection date in MM/DD/YY form:" default answer ""
set inputReturned to text returned of result
on error number -128
finalAlert(("Cancel Request Accepted (1)"), "")
return
end try
try
set V_startDate to date inputReturned
if the V_startDate comes after (current date) then
display dialog ¬
"Re-enter the date. Can't be later than today." buttons {"OK", "CANCEL"} ¬
default button 1 with icon caution
else
exit repeat
end if -- Test for valid start date
on error number -30720 -- invalid date entered
try
display dialog ¬
"Re-enter the date. It isn't correct. You entered: " & inputReturned ¬
buttons {"OK", "QUIT"} ¬
default button 2 ¬
cancel button "QUIT" with icon stop
on error number -128
finalAlert(("Cancel Request Accepted (2)"), "")
return
end try -- 2nd error trap for valid date
end try -- Error trap for valid date
end if -- date test for already taken
end repeat
validateFileColumns(this_item)
end if
end repeat
end open
(*
____________ validate_table_format - Input Table must conform to column requirements ________________
*)
on validateFileColumns(this_csvFile)
set theRows to paragraphs of (read this_csvFile)
set AppleScript's text item delimiters to ","
set columnHeadings to every text item of item 1 of theRows -- get column headings
set AppleScript's text item delimiters to ""
if item 1 of theRows = exerciseHeading or ¬
item 1 of theRows = nutritionHeading or ¬
item 1 of theRows = bodymeasuresHeading then
-- process_aDroppedFile
else
finalAlert((v_this_name & " has no valid headings"), "")
return
end if
-- Initialize the FMP Health Data Tracking
tell application "FileMaker Pro Advanced"
if it is not running then
launch application K_Filemaker
end if
if not (exists database V_DB) then
try
tell me to set V_sourceFilePath to alias (K_sourceFilePath & ":" & V_DB)
set V_myDBLocation to ¬
(choose file with prompt ¬
"Which Filemaker data base?")
open V_myDBLocation
on error number -128
finalAlert(("Cancel Request Accepted (3)"), "")
return
end try
end if
end tell
(* ***********************************************************************************************
____________ process_Activity_Data - Get individual lines from csv file _________________________
*)
-- Select which table is to be updated based on the column headings
-- (They are unique for each csv that was downloaded)
if item 2 of columnHeadings = "Exercise" then -- handle as the exercise table data
process_Activity_Data(theRows)
tell application "FileMaker Pro Advanced" to go to layout K_Activity_cmn_Layout
finalAlert(("Activity Data Updated"), "Processed " & (count of theRows) & " Rows.")
else if item 2 of columnHeadings = "Meal" then -- handle as the nutrition table data
process_Nutrition_Data(theRows)
tell application "FileMaker Pro Advanced" to go to layout K_Nutrition_cmn_Layout
finalAlert(("Nutrition Data Updated"), "Processed " & (count of theRows) & " Rows.")
else -- must be the body measures table data
process_BodyMeasures_Data(theRows)
tell application "FileMaker Pro Advanced" to go to layout K_BodyMeasures_cmn_Layout
finalAlert(("Body Measures Data Updated"), "Processed " & (count of theRows) & " Rows.")
end if
return
end validateFileColumns
(* ***********************************************************************************************
____________ process_Activity_Data - Get individual lines from csv file _________________________
*)
on process_Activity_Data(tableRows)
try -- Trap any errors
set rowCounter to 1
repeat with l from 2 to count of tableRows
if item l of tableRows = "" then -- Should mean EOF
exit repeat
end if
set AppleScript's text item delimiters to "\""
set dataCells to text items of item l of tableRows -- get starting row after column headings
set AppleScript's text item delimiters to ""
if (count of dataCells) = 1 then
set AppleScript's text item delimiters to ","
set dataCells to text items of item l of tableRows -- get starting row after column headings
set AppleScript's text item delimiters to ""
else if (count of dataCells) = 3 then
set exerciseText to replaceCommas(item 2 of dataCells)
set fullLine to item 1 of dataCells & exerciseText & item 3 of dataCells
set AppleScript's text item delimiters to ","
set dataCells to text items of fullLine -- get starting row after column headings
set AppleScript's text item delimiters to ""
end if
set theDate to item 1 of dataCells
set c_ExDate to word 2 of theDate & "/" & word 3 of theDate & "/" & word 1 of theDate
set theDate to date c_ExDate -- coerce to Apple date format
if theDate is not less than V_startDate then -- ignore records that are before the requested start date
set textDate to getTextDate(theDate) as string
set reqLayout to K_Activity_T_Layout
set reqTable to K_Activity_Table
tell application "FileMaker Pro Advanced"
go to layout K_Activity_T_Layout
set reqCell to name of cell "Ex_Date"
end tell -- applicaiton
-- Find any record for this date in the Body Measures Table
tell me to findFMPRecords(K_Activity_T_Layout, K_Activity_Table, reqCell, textDate)
set updflag to false -- Initialize
tell application "FileMaker Pro Advanced"
if (count of every record in current layout) = 0 then -- Create a new Entry
tell me to addActivityRecord(reqLayout, reqTable, dataCells, textDate)
set updflag to true -- Completed handling the incoming record
else -- if more than 1 enter the steps only in the 1st
go to layout K_Activity_T_Layout
repeat with r from 1 to count of every record in current layout
tell record (r) of current layout
if cell "Ex_Exercise" = item 2 of dataCells then -- Update matched date & Exercise
set cell "Ex_Type" to item 3 of dataCells
set cell "Ex_Calories" to item 4 of dataCells as number
set cell "Ex_Time" to item 5 of dataCells as number
set updflag to true -- Completed handling the incoming record
exit repeat -- Quit Looking
end if -- Text for existing exercise
end tell -- Current Record address
end repeat -- checking multiple Activity Table records
end if -- Either add new Activity Table record or update existing one
if updflag is false then -- Means that I've not processed this incoming record
tell me to addActivityRecord(reqLayout, reqTable, dataCells, textDate)
end if -- test for if already updated for the incoming record
end tell -- application
end if -- date test - excluding incomming data that is earlier than requested start
set rowCounter to rowCounter + 1
end repeat -- each row in the dropped csv file
on error errMsg number errNum
set topMsg to (errNum & " : " & errMsg) as string
set subMsg to ("Row " & rowCounter & " of " & (count of tableRows))
finalAlert(topMsg, subMsg)
return
end try
end process_Activity_Data
(* ***********************************************************************************************
____________ process_Nutrition_Data - Get individual lines from csv file _________________________
*)
on process_Nutrition_Data(tableRows)
try -- Trap any errors
set rowCounter to 1
repeat with l from 2 to count of tableRows
if item l of tableRows = "" then
exit repeat
end if
set AppleScript's text item delimiters to ","
set dataCells to text items of item l of tableRows -- get starting row after column headings
set AppleScript's text item delimiters to ""
set theDate to item 1 of dataCells
set c_ExDate to word 2 of theDate & "/" & word 3 of theDate & "/" & word 1 of theDate
set theDate to date c_ExDate -- coerce to Apple date format
if theDate is not less than V_startDate then -- ignore records that are before the requested start date
set textDate to getTextDate(theDate) as string
set reqLayout to K_Nutrition_T_Layout
set reqTable to K_Nutrition_Table
tell application "FileMaker Pro Advanced"
go to layout K_Nutrition_T_Layout
set reqCell to name of cell "Date"
end tell -- applicaiton
-- Find any record for this date in the Body Measures Table
tell me to findFMPRecords(K_Nutrition_T_Layout, K_Nutrition_Table, reqCell, textDate)
set updflag to false -- Initialize
tell application "FileMaker Pro Advanced"
if (count of every record in current layout) = 0 then -- Create a new Entry
tell me to addNutritionRecord(reqLayout, reqTable, dataCells, textDate)
set updflag to true -- Completed handling the incoming record
else -- if more than 1 enter the steps only in the 1st
go to layout K_Nutrition_T_Layout
repeat with r from 1 to count of every record in current layout
tell record (r) of current layout
if cell "Meal" = item 2 of dataCells then -- Update matched date & Exercise
set cell "Calories Consumed" to item 3 of dataCells as number
set cell "Fat" to item 4 of dataCells as number
set cell "FatSaturated" to item 5 of dataCells as number
set cell "FatPol" to item 6 of dataCells as number
set cell "FatMono" to item 7 of dataCells as number
set cell "Cholesterol" to item 9 of dataCells as number
set cell "Sodium" to item 10 of dataCells as number
set cell "Potassium_mg_" to item 11 of dataCells as number
set cell "Carbs" to item 12 of dataCells as number
set cell "Fiber" to item 13 of dataCells as number
set cell "Sugar" to item 14 of dataCells as number
set cell "Protein" to item 15 of dataCells as number
set cell "VitaminA_IU_" to item 16 of dataCells as number
set cell "VitaminC_IU_" to item 17 of dataCells as number
set cell "Calcium" to item 18 of dataCells as number
set cell "Iron_mg_" to item 19 of dataCells as number
set cell "Note" to item 20 of dataCells
set updflag to true -- Completed handling the incoming record
exit repeat -- Quit Looking
end if -- Text for existing exercise
end tell -- Current Record address
end repeat -- checking multiple Activity Table records
end if -- Either add new Activity Table record or update existing one
if updflag is false then -- Means that I've not processed this incoming record
tell me to addNutritionRecord(reqLayout, reqTable, dataCells, textDate)
end if -- test for if already updated for the incoming record
end tell
end if
set rowCounter to rowCounter + 1
end repeat
on error errMsg number errNum
set topMsg to (errNum & " : " & errMsg) as string
set subMsg to ("Row " & rowCounter & " of " & (count of tableRows))
finalAlert(topMsg, subMsg)
return
end try
end process_Nutrition_Data
(* ***********************************************************************************************
_________________ process_BodyMeasures_Data - Get individual lines from csv file _________________________
Only update BodyFat % & Weight in Body Measure Table
update steps (count) in the Activity Table
*)
on process_BodyMeasures_Data(tableRows)
try -- Trap any errors
set rowCounter to 1
repeat with l from 2 to count of tableRows
if item l of tableRows = "" then
exit repeat
end if
set AppleScript's text item delimiters to ","
set dataCells to text items of item l of tableRows -- get starting row after column headings
set AppleScript's text item delimiters to ""
set theDate to item 1 of dataCells
set c_ExDate to word 2 of theDate & "/" & word 1 of theDate & "/" & word 3 of theDate
set theDate to date c_ExDate -- coerce to Apple date format
set textDate to ""
if theDate is not less than V_startDate then -- ignore records that are before the requested start date
set textDate to getTextDate(theDate) as string
set reqLayout to K_BodyMeasures_T_Layout
set reqTable to K_BodyMeasures_Table
tell application "FileMaker Pro Advanced"
go to layout K_BodyMeasures_T_Layout
set reqCell to name of cell "bmDate"
end tell -- applicaiton
-- Find any record for this date in the Body Measures Table
tell me to findFMPRecords(K_BodyMeasures_T_Layout, K_BodyMeasures_Table, reqCell, textDate)
-- Update the found record. Body Measures Table requires only 1 record per date
tell application "FileMaker Pro Advanced"
go to layout K_BodyMeasures_T_Layout
if (count of every record in current layout) > 0 then
go to record 1
if item 5 of dataCells is not equal to "0.0" then
set cell "Weight" to item 5 of dataCells as number
end if -- is there weight to update
if item 3 of dataCells is not equal to "0.0" then
set cell "BodyFat%" to item 3 of dataCells as number
end if -- is there body fat pctg to update
else -- No matching records for this date
-- add a new record - but not if incoming BodyFat and Weight are zero (don't need a record with zeros)
if item 3 of dataCells is equal to "0.0" and ¬
item 5 of dataCells is equal to "0.0" then
-- No need for update
else
go to layout K_BodyMeasures_T_Layout
set newBMRecord to (create new record at table K_BodyMeasures_Table) -- get the record id for future reference
tell record ID newBMRecord
set cell "Weight" of newBMRecord to item 5 of dataCells as number
set cell "BodyFat%" of newBMRecord to item 3 of dataCells as number
set cell "bmDate" of newBMRecord to textDate
end tell -- new record ID
end if -- are there values in weight and body fat pctg
end if -- is there a record for the new data date
-- clean up the layout - back to all records
tell application "FileMaker Pro Advanced"
show layout K_BodyMeasures_T_Layout
tell table K_BodyMeasures_Table
show every record
end tell -- table
end tell -- application
end tell -- application
-- If there is incoming data for steps - update the Activity Table with steps
if item 4 of dataCells is not equal to "0.0" then
tell application "FileMaker Pro Advanced"
go to layout K_Activity_T_Layout
set reqLayout to K_Activity_T_Layout
set reqTable to K_Activity_Table
tell application "FileMaker Pro Advanced"
go to layout K_Activity_T_Layout
set reqCell to name of cell "Ex_Date"
end tell
-- Find any record for this date in the Activity Table
tell me to findFMPRecords(K_Activity_T_Layout, K_Activity_Table, reqCell, textDate)
if (count of every record in current layout) = 1 then -- just update the steps count
set cell "Ex_Steps" to item 4 of dataCells
else if (count of every record in current layout) > 1 then -- if more than 1 enter the steps only in the 1st
-- and Clear subsequent records
repeat with r from 1 to count of every record in current layout
tell record (r) of current layout
if r = 1 then
set cell "Ex_Steps" to item 4 of dataCells
else
set cell "Ex_Steps" to "0"
end if
end tell
end repeat
-- No existing Activity records for this date
-- add a new record
else -- There are no existing Activity records - add this one
go to layout K_Activity_T_Layout
set newExRecord to (create new record at table K_Activity_Table) -- get the record id for future reference
tell record ID newExRecord
set cell "Ex_Date" of newExRecord to textDate
set cell "Ex_Exercise" of newExRecord to "AppleWatch Step Count"
set cell "Ex_Type" of newExRecord to "Steps"
set cell "Ex_Steps" of newExRecord to item 4 of dataCells
end tell
end if
-- clean up the Activity layout - back to all records
tell application "FileMaker Pro Advanced"
show layout K_Activity_T_Layout
tell table K_Activity_Table
show every record
end tell -- table
end tell -- application
end tell -- application
end if
end if -- date test -
set rowCounter to rowCounter + 1
end repeat
on error errMsg number errNum
set topMsg to (errNum & " : " & errMsg) as string
set subMsg to ("Row " & rowCounter & " of " & (count of tableRows))
finalAlert(topMsg, subMsg)
return
end try
end process_BodyMeasures_Data
(* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
---- E N D O F S C R I P T M A I N L I N E ----
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
*)
(* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
-- HANDLERS
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
*)
(*
__________________________ on getTextDate (return MM/DD/YYYY _________________________________
*)
on getTextDate(theDate)
set {year:y, month:m, day:d} to theDate -- get today for the processed date
set y to y as string -- convert year to string
set yy to characters 3 thru 4 of y as string -- just use 10s years of the full year
set mm to (m * 1 as string) -- coerce the month into string integers
if length of mm = 1 then -- if it is a single digit month, put a zero infront of it
set mm to "0" & mm
end if
set dd to (d * 1 as string) -- coerce the month into string integers
if length of dd = 1 then -- if it is a single digit month, put a zero infront of it
set dd to "0" & dd
end if
set textDate to (mm & "/" & dd & "/" & yy)
return {textDate}
end getTextDate
(*
__________________________ on findFMPRecords (perform find on requested table for date) _________________________________
*)
on findFMPRecords(reqLayout, reqTable, reqCell, textDate)
tell application "FileMaker Pro Advanced"
activate
show layout reqLayout
tell table reqTable
show every record
end tell
try -- If there are older requests, delete them - FMP remembers them forever
delete every request
end try
create request -- == forces exact find
set xcellID1 to ID of cell reqCell
set xcellID to item 2 of xcellID1
set cell ID xcellID of request 1 to textDate
find
end tell
end findFMPRecords
(*
__________________________ on addActivityRecord _________________________________
*)
on addActivityRecord(reqLayout, reqTable, dataCells, textDate)
tell application "FileMaker Pro Advanced"
activate
show layout reqLayout
tell table reqTable
show every record
end tell
set newExRecord to (create new record at table reqTable) -- get the record id for future reference
tell record ID newExRecord
set cell "Ex_Date" of newExRecord to textDate
set cell "Ex_Exercise" of newExRecord to item 2 of dataCells
set cell "Ex_Type" of newExRecord to item 3 of dataCells
set cell "Ex_Calories" of newExRecord to item 4 of dataCells as number
set cell "Ex_Time" of newExRecord to item 5 of dataCells as number
set cell "Ex_Note" of newExRecord to item 10 of dataCells
end tell
end tell
end addActivityRecord
(*
__________________________ on addNutritionRecord _________________________________
*)
on addNutritionRecord(reqLayout, reqTable, dataCells, textDate)
tell application "FileMaker Pro Advanced"
activate
show layout reqLayout
tell table reqTable
show every record
end tell
set newNutRecord to (create new record at table reqTable) -- get the record id for future reference
tell record ID newNutRecord
set cell "Date" of newNutRecord to textDate
set cell "Meal" of newNutRecord to item 2 of dataCells
set cell "Calories Consumed" of newNutRecord to item 3 of dataCells as number
set cell "Fat" of newNutRecord to item 4 of dataCells as number
set cell "FatSaturated" of newNutRecord to item 5 of dataCells as number
set cell "FatPol" of newNutRecord to item 6 of dataCells as number
set cell "FatMono" of newNutRecord to item 7 of dataCells as number
set cell "Cholesterol" of newNutRecord to item 9 of dataCells as number
set cell "Sodium" of newNutRecord to item 10 of dataCells as number
set cell "Potassium_mg_" of newNutRecord to item 11 of dataCells as number
set cell "Carbs" of newNutRecord to item 12 of dataCells as number
set cell "Fiber" of newNutRecord to item 13 of dataCells as number
set cell "Sugar" of newNutRecord to item 14 of dataCells as number
set cell "Protein" of newNutRecord to item 15 of dataCells as number
set cell "VitaminA_IU_" of newNutRecord to item 16 of dataCells as number
set cell "VitaminC_IU_" of newNutRecord to item 17 of dataCells as number
set cell "Calcium" of newNutRecord to item 18 of dataCells as number
set cell "Iron_mg_" of newNutRecord to item 19 of dataCells as number
set cell "Note" of newNutRecord to item 20 of dataCells
end tell
end tell
end addNutritionRecord
(*
__________________________ replaceCommas _________________________________
-- Replace Comma with semi-colon
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
*)
property punctuationMarks : {","}
on replaceCommas(replText)
set replCharList to characters of replText -- parse the text into a list with the individual characters
repeat with i from 1 to count of items of replCharList
set replCharacter to replCharList's item i as string
if replCharacter is in punctuationMarks then
set replCharList's item i to (";")
end if
end repeat
set replText to replCharList as string
return replText as string
end replaceCommas
(*
__________________________ on Run (when launched vs dropped) _________________________________
*)
on run
open {choose file}
end run
(*
__________________________ finalAlert _________________________________
D_Msg - Primary Message
D_subMsg - Sub title
*)
on finalAlert(D_Msg, D_subMsg)
display notification D_Msg subtitle D_subMsg ¬
with title K_scriptName
delay 2
end finalAlert
(*
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Change Log
Reverse Chronological order
---------------------------------------
2018.12.30 V1.2 - Moved request for date range so it only occurs once - no matter how many files
2018.12.23 V1.1 - At end of update return to FM Display Layout and Notify of completion.
2018.12.01 V1.0 - Initial Release
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
*)
'''