ECMS - Using AppGetTree to replace Internet Explorer dependent learnmodes.

This document explains how to create a learnmode to replace the Internet Explorer dependent learnmodes.

[Doc 8386 is unavailable at this time.]  

DRAFT: Using AppGetTree to replace Internet Explorer dependent learnmodes. 

=======
Overview
=======

Perceptive Content 7.2.2.443 and higher and Perceptive Content 7.1.5.1899 and higher introduce a new LearnMode enhancement for capturing values from a host application. The new method involves a VBScript function called AppGetTree(). Instructions for learning these applications are available in product documentation at:

https://docs.hyland.com/ImageNow/en_US/7.2/Admin/Print/Ellucian_and_LearnMode_Integration_Getting_Started_Guide_7.1.x_7.2.x.pdf

A sample script that works with UW-Madison's HRS implementation for use with the scanning of personnel documents is included at the bottom of this kb.


===========
Prerequisites
===========

64-bit operating system – The AppGetTree() function is only supported on 64-bit workstations.

Internet browser – Hyland Technical Support recommends using Google Chrome for best results. When using AppGetTree with Google Chrome, only elements from the active tab will be pulled, while using Firefox or Internet Explorer will result in elements being pulled from all open tabs.

Temp folder – Ensure that the C:\Temp folder exists on the workstation executing the VBScript and that the user has read, write, and modify access to this location. Create the location if necessary.


========================
Creating the Application Plan
========================
In the Perceptive Content Management Console, click "Application Plans", click "Learnmode", and then click "New".

In the Plan Settings window, name the application plan accordingly, select "Window Title" in the Method list, and then enter "*Employee Information(ImageNow) - Google Chrome*"

In the Learnmode Application Plan Designer window, select "Window Walker" from the method list.

Note: Selecting Window Walker mode will reduce linking time. It is also possible to use a manual application plan for this process; however, if the plan needs to be changed in the future this may result in the need to completely re-create the manual application plan.

Do not define dictionary values in the Dictionary section.

Click the "Map" tab, and then ensure that all fields or custom properties being captured are set to "Literal" in the Application Plan Designer.

Note: If prompted to provide a default value for the field, type "To be set by script".

Under the Maps tab, double-click "Field1".

In the Field1 Attributes window, in the Script list, assign the sample VBScript (see the Sample Script section), and then click the ellipsis (…) button to open the script window.

Review the instructions in the Creating the AppGetTree VBScript section of this article to make the necessary changes to the script.


============================
Creating the AppGetTree VBScript
============================

The following instructions provide the steps necessary to customize the provided sample script for a particular environment.

Note: See the Sample Script section for a copy of the default script. 

Locate the following line: treeInfo = FindTreeGetNodes("*Host Application*") and then replace the text in quotes with the value used to identify the window title ("*Employee Information(ImageNow) - Google Chrome*").  For example: treeInfo = FindTreeGetNodes("*Employee Information(ImageNow) - Google Chrome*")

Ensure that the desired ERP window (HRS/SFS/SIS) is open and ready to link.

Uncomment the following line in the script: 'call debOut(treeInfo(0), "C:\temp\debout_0.txt")

Note: This line should only be uncommented when initially generating the element tree for the host application window. Once the tree has been successfully created, re-comment the line.

In the script window, click "Test". This will generate a file called "debout_0.txt" (located in C:\Temp), which will open and display an element tree for the window.

Within the debout file, locate the value to be captured.

In the vicinity of the desired value, locate the nearest anchor tag.

Note: An anchor tag is a value that will not change depending on the record being displayed in the host application.

          For example, a tree may look like the following:

               +row[]
                +tableCell[Employee Name: Employee ID: Position Nbr: Dept Id: Job Code: Job Title: Empl Class:]
                 +DIV[]
                  +table[]
                   +row[]
                    +tableCell[Employee Name:]
                      label[Employee Name:]
                    +tableCell[]
                      text[]->STEPHENSON,CRAIG N
                   +row[]
                    +tableCell[Employee ID:]
                      label[Employee ID:]
                    +tableCell[]
                      text[]->00123456
                   +row[]
                    +tableCell[Position Nbr:]
                      label[Position Nbr:]
                    +tableCell[]
                      text[]->02080170
                   +row[]
                    +tableCell[Dept Id:]
                      label[Dept Id:]
                    +tableCell[]
                      text[]->A067170
                   +row[]
                    +tableCell[Job Code:]
                      label[Job Code:]
                    +tableCell[]
                      text[]->13463
                   +row[]
                    +tableCell[Job Title:]
                      label[Job Title:]
                    +tableCell[]
                      text[]->IS TECH SRV SPEC
                   +row[]
                    +tableCell[Empl Class:]
                      label[Empl Class:]
                    +tableCell[]
                      text[]->CP


In this example, an anchor tag for Employee ID is label[Employee ID:], where three rows below it is the value for the specific record in the window (00123456). While the value of Employee ID will change depending on the record being viewed, the anchor tag will always be named the same.

It may be necessary to try several different anchor tags in order to find the one that works best.

After identifying an anchor tag, count the number of rows up or down to reach the value to be captured.

For example, using the label[Employee ID:] anchor tag, the value to be captured (00123456) is three rows below the anchor tag, hence the count will be +2.

As an additional example, if the value to be capture was two rows above the anchor tag, the count would be -2.

In the VBScript, locate the following line: ‘capturedValue = GetValueFromAnchor(treeInfo(1), "YOUR ANCHOR TAG HERE", <+/- number of lines to desired value>)

Copy this example, and then paste a copy underneath it. In the copy, uncomment the line, and then replace the placeholders with the anchor tag and row count previously identified. Additionally, rename the capturedValue variable to an accurate identifier.

For example: Employee ID = GetValueFromAnchor(treeInfo(1), "Employee ID", +2)

For each additional value that needs to be captured, repeat steps 5 through 7 to identify the anchor tags and row counts, and then insert a new GetValueFromAnchor function for each, assigning them to their own variables.

          For example:

               employee ID = GetValueFromAnchor(treeInfo(1), "Employee ID", +2)
               employee name = GetValueFromAnchor(treeInfo(1), "Employee Name", -3)
               Dept Id = GetValueFromAnchor(treeInfo(1), "Dept Id", +12)

Assign the captured value(s) to the required fields or custom properties for the Content document. To do this, go to the following commented line: ‘This assigns the values to the Fields

Underneath the comments, add the operations to map the captured values to the applicable fields or custom properties. 

For example:

                ‘This assigns the values to the Fields
                ‘Folder = Field1
                ‘Tab = Field2
                ‘Field3 = Field3
                ‘DocProperty(“<CP NAME HERE>”) = variable
                Folder = EmplID
Tab = EmployeeName
Field3 = PositionNumber
Field4 = UDDS
DocProperty("A_OHR_Pfile_Appt Title") = A_OHR_Pfile_ApptTitle
DocProperty("A_OHR_Pfile_Appt Title Code") = A_OHR_Pfile_ApptTitleCode
DocProperty("A_OHR_Pfile_Job Code") = A_OHR_Pfile_JobCode


==================
Sample Script
==================

' Written By: Riley Flinn
' Version: 2.6
' Date Updated: 03/05/2019
' Last Updated by: Riley Flinn & Andrew Langford
' Modified by: Craig Stephenson
' Date Modified: 06/11/2019
' target URL description:  https://www.hrs.wisconsin.edu 
' Workforce Administration > Employee Information(ImageNow)

' Get values using AppGetTree(). This script uses AppGetTree to pull linking information from a browser window and maps it to the document keys.

' this function passes the name of the screen and returns the tree and the tree nodes. treeInfo(0) contains the tree, and treeInfo(1) contains the nodes.
' Replace "*Host Application*" with the window title of your host application
treeInfo = FindTreeGetNodes("*Employee Information(ImageNow) - Google Chrome*")

If treeInfo(0) <> "" Then

' FOR TESTING ONLY, write the tree to a text file and open it.
' for generating a tree ensure the following directory exists: "C:\temp\debout_0.txt"
' if this directory does not exist, then replace the string with a directory that does exist within the quotes.
' call debOut(treeInfo(0), "C:\temp\debout_0.txt")


' this uses "YOUR ANCHOR TAG HERE" as the anchor and indexes the capturedValue off this anchor tag.
'capturedValue = GetValueFromAnchor(treeInfo(1), "label[Employee Name:]", <+/- number of lines to desired value>)

EmplID = GetValueFromAnchor(treeInfo(1), "label[Employee Name:]", +7)
EmployeeName = GetValueFromAnchor(treeInfo(1), "label[Employee Name:]", +2)
PositionNumber = GetValueFromAnchor(treeInfo(1), "label[Employee Name:]", +12)
UDDS = GetValueFromAnchor(treeInfo(1), "label[Employee Name:]", +17)
A_OHR_Pfile_ApptTitle = GetValueFromAnchor(treeInfo(1), "label[Employee Name:]", +27)
A_OHR_Pfile_ApptTitleCode = GetValueFromAnchor(treeInfo(1), "label[Employee Name:]", +32)  
A_OHR_Pfile_JobCode = GetValueFromAnchor(treeInfo(1), "label[Employee Name:]", +22)
'This assigns the values to the Fields
'Folder = Field1
'Tab = Field2
'Field3 = Field3
'DocProperty("CP NAME HERE") = variable
'Folder = capturedValue

Folder = EmplID
Tab = EmployeeName
Field3 = PositionNumber
Field4 = UDDS
DocProperty("A_OHR_Pfile_Appt Title") = A_OHR_Pfile_ApptTitle
DocProperty("A_OHR_Pfile_Appt Title Code") = A_OHR_Pfile_ApptTitleCode
DocProperty("A_OHR_Pfile_Job Code") = A_OHR_Pfile_JobCode


End If


' DO NOT EDIT FUNCTIONS BELOW
function GetValueFromAnchor(nodes, anchor, position)
     anchor_position = -1
     cursor = 0
     for ln = LBound(nodes) to UBound(nodes)
          If InStr(nodes(ln), anchor) > 0 Then
               ' Found our anchor.
               anchor_position = cursor
               Exit For
          End If
          cursor = cursor + 1
     next
     If anchor_position = -1 Then
          MsgBox("Could not find " & anchor & ".")
     Else
          GetValueFromAnchor = GetValue(nodes(anchor_position + position))
     End If
end function

' Function to write tree to a text file
function debOut(tree, tempDirectory)

    Set objFSO = CreateObject("Scripting.FileSystemObject")
    fcount = 0
    exists = objFSO.FileExists(tempDirectory)
    while exists and fcount < 10
        fcount = fcount + 1
        s = "_" + CStr(fcount)
        tempDirectory = Replace(tempDirectory, "_" + CStr(fcount - 1), "_" + CStr(fcount))
        exists = objFSO.FileExists(tempDirectory)
    wend
    Set objFile = objFSO.CreateTextFile(tempDirectory, True, true)
    objFile.Write(tree)
    objFile.Close
    CreateObject("WScript.Shell").Run(tempDirectory)
end function

' Function get the value of the node within the tree.
function GetValue(text)
    st = Split(text, "->")
    if UBound(st) > 0 then
        GetValue = Trim(st(1))
    else
        'This gets the value within the "[]"
        if instr(text, "[") > 0 AND instr(text, "]") > 0 Then
            GetValue = Trim(Mid(text, instr(text, "[") + 1, instr(text, "]") - instr(text, "[") - 1))
        else
            GetValue = Trim(text)
        end if
    end if
end function

'this function returns the tree
function FindTree(screenName)
'this will loop up to 10 times trying to get the tree.
attemptEnd = 0
h = FindWindow(screenName)
While treeChunks <= 0 OR attemptEnd = 9
treeChunks = AppGetTree(h, "", treeNodes)
attemptEnd = attemptEnd + 1
Wend
If treeChunks > 0 Then
for c = 0 to treeChunks - 1
tree = tree + treeNodes(c)
next
Else
MsgBox Replace(screenName, "*", "") + " browser window was not found after ten attempts!",0,"Notice"
tree = ""
End If
findTree = tree
end function

'this function handles getting the nodes.
function FindTreeGetNodes(screenName)

' This section handles if there is a shortened tree that is returned by the FindTree function
h = FindWindow(screenName)
If h = 0 Then
MsgBox "A window with the title, " + Replace(screenName, "*", "") + ", was not found.",0,"Notice"
FindTreeGetNodes = Array("","")
Else
'this loop will attempt to bring back a tree up to 45 times, but will stop if it cannot
for i = 0 to 45
tree = FindTree(screenName)
if i = 45 then
MsgBox "Your linking window may not have loaded. Please attempt again, or contact your ImageNow administrator.",0,"Notice"
tree = ""
exit for
elseif tree = "" then
exit for
elseif length > 60 then
exit for
else
' Get nodes within the tree.
nodes = Split(tree, vbCrLf)
length = ubound(nodes) + 1
end if

next
FindTreeGetNodes = Array(tree, nodes)
End If
end function