A link action script allows the user to perform a certain action when they click on a field in the Preview window. One example of a link action script is to show someone's address in Google Maps.

To open a specific address in Google Maps, all we need is the base Google Maps URL (http://maps.google.com/maps?&hl=en&q=) followed by the desired address, city, region (state, province, etc.), postal or zip code, and country. Google Maps is very forgiving so the order you add the fields to the URL is not relevant and it is pretty good at finding the address even if some fields are missing.

To create a Google Maps link action, create a new script, turn on the Link action option and fill in the Description with something like "Google Maps."

Then copy and paste the code below. The only thing you need to alter is the list of fields as indicated by the "Customization" comment.

lparameters tcFieldName, tuValue
local lcFields, laFields[1], lcLookupField, lcAddrField, lcLocation, lnI, ;
  lcField, lcValue, lcURL

* Customization: edit the table and field names in this statement. Be sure
* to put the field to look up the person by (such as their ID) as the first
* field and the other fields in a reasonable order, such as address, city,
* region, postal code, and country. Not all of these are required.

lcFields = 'Customers.CustomerID,Customers.Address,Customers.City,' + ;
  'Customers.Region,Customers.PostalCode,Customers.Country'

* If this is a "discovery" call, return the fields needed in the result set.
* The leading "*" means all of these fields are needed in the result set and
* the "action parameter" combo box should not be displayed.

if empty(tcFieldName)
  return '*,' + lcFields
else

* Get the names of the lookup and address fields.

  alines(laFields, lcFields, 1, ',')
  lcLookupField = SQApplication.GetDataSetFieldName(laFields[1])
  lcAddrField   = SQApplication.GetDataSetFieldName(laFields[2])

* tuValue contains the lookup value for the person the user clicked on. We need
* to use that to lookup the correct record since that record isn't necessarily
* the current one.

  locate for &lcLookupField = tuValue and not empty(&lcAddrField)
  lcLocation = ''
  for lnI = 2 to alen(laFields)
    lcField    = SQApplication.GetDataSetFieldName(laFields[lnI])
    lcValue    = evaluate(lcField)
    lcLocation = lcLocation + iif(empty(lcValue), '', ;
      iif(empty(lcLocation), '', ',') + trim(lcValue))
  next

* Append the location info to the base Google Maps URL and bring it up in a
* browser window.

  if not empty(lcLocation)
    lcURL = 'http://maps.google.com/maps?&hl=en&q=' + lcLocation
    SQApplication.Execute(lcURL, 'Open')
  endif
endif

Here's a more complex version that supports multiple tables with address information (in this case, two tables: Customers and Employees).

lparameters tcFieldName, tuValue
local lcCustomerFields, lcEmployeeFields, lcFields, laFields[1], ;
  lcLookupField, lcAddrField, lcLocation, lnI, lcField, lcValue, lcURL

* Customization: edit the variable, table, and field names in these
* statements. Be sure to put the field to look up the person by (such as
* their ID) as the first field and the other fields in a reasonable order,
* such as address, city, region, postal code, and country. Not all of these
* fields are required.

lcCustomerFields = 'Customers.CustomerID,Customers.Address,Customers.City,' + ;
  'Customers.Region,Customers.PostalCode,Customers.Country'
lcEmployeeFields = 'Employees.EmployeeID,Employees.Address,Employees.City,' + ;
  'Employees.Region,Employees.PostalCode,Employees.Country'

* Figure out which table we're working with. If this is a "discovery" call,
* tuValue contains the aliased field name. Otherwise, tcFieldName will have
* what we need.

if empty(tcFieldName)
  lcTable = upper(juststem(tuValue))
else
  lcTable = upper(juststem(tcFieldName))
endif

* Customization: edit these statements to use the desired table and variable
* names.

if lcTable = 'CUSTOMERS'
  lcFields = lcCustomerFields
else
  lcFields = lcEmployeeFields
endif

* If this is a "discovery" call, return the fields needed in the result set.
* The leading "*" means all of these fields are needed in the result set and
* the "action parameter" combo box should not be displayed.

if empty(tcFieldName)
  return '*,' + lcFields
else

* Get the names of the lookup and address fields.

  alines(laFields, lcFields, 1, ',')
  lcLookupField = SQApplication.GetDataSetFieldName(laFields[1])
  lcAddrField   = SQApplication.GetDataSetFieldName(laFields[2])

* tuValue contains the lookup value for the person the user clicked on. We need
* to use that to lookup the correct record since that record isn't necessarily
* the current one.

  locate for &lcLookupField = tuValue and not empty(&lcAddrField)
  lcLocation = ''
  for lnI = 2 to alen(laFields)
    lcField    = SQApplication.GetDataSetFieldName(laFields[lnI])
    lcValue    = evaluate(lcField)
    lcLocation = lcLocation + iif(empty(lcValue), '', ;
      iif(empty(lcLocation), '', ',') + trim(lcValue))
  next

* Append the location info to the base Google Maps URL and bring it up in a
* browser window.

  if not empty(lcLocation)
    lcURL = 'http://maps.google.com/maps?&hl=en&q=' + lcLocation
    SQApplication.Execute(lcURL, 'Open')
  endif
endif