Purpose
Read all tree nodes

Solution
Use the predefined VB function
   guinet.TreeControl.CopyText

It copies the whole tree into a GuiXT text variable, one line for each tree node. Each line contains the node key, node level and one or more values for the tree columns.


Example

In transaction VA03 the header texts are shown via a tree control. The user clicks on a tree node to see the corresponding text, or an empty area if no header text of this type exists
:


VA03 Standard header text display      Click to enlarge


Instead, we want to present all existing texts immediately:


Our new text display      Click to enlarge

 

Video


Show video in full screen

 

The implementation is a little bit more complex than one would expect, since the SAP tree structure is somewhat complicated: The tree node content is different depending on whether no text, one text or more than one text - in different languages - exists for a particular text type.

To display the texts we embed an HTML control into SAP GUI. This allows us to design a user friendly layout using CSS options in HTML. Enhancements such as choosing  different background colors for different text types can easily be added if required.

  • Alternatively we can use pure GuiXT means, namely dynamically generated text boxes. This requires more GuiXT coding and restricts the layout possibilities to standard SAP GUI.
  • Instead of reading the various texts via the VA03 sceens we can read them with a BAPI Call, e.g. "BAPISDORDER_GETDETAILEDLIST". This is faster but requires extra  programming effort to convert the SAP text format into a displayable format and to read the text name for each text type. 

GuiXT Script  "sapmv45a.e4002.txt"

// clear all transaction specific GuiXT variables
// if new transaction or order number changed
if not V[tc.transactionid=&V[_transactionid]] or not V[tc.vbeln=&F[VBAK-VBELN]]
 
Clear V[tc.*]
 
Clear text[tc.*]
 
Set V[tc.transactionid] "&V[_transactionid]"
  Set V[tc.vbeln] "&F[VBAK-VBELN]"
endif

if Q[Transaction=VA03] and Q[Page=Texts]

 // read all header texts if not yet done
  if not V[tc.header_texts_read]
    Set V[tc.header_texts_read] "X"
    Enter process="read_header_texts.txt"
    Stop script
  endif

  // delete SAP splitter container, with tree and text controls
  del X[SPLITTER_CONTAINER]

  // delete all buttons below the text control, starting with the "Create" button
  del P[Create] P[Create]+(0,200)

 // now display the texts using an HTML control
 Box (5,2) (30,147) "Header texts"
 Control (5.7,3) (29.8,147.3) _
     
progid="about:blank" _
    
 name="va03.control.headertexts"

 // call up a VB function which generates the HTML document
 CallVB utilities.VA03.DisplayTexts "&V[va03.control.headertexts]"

endif

 

InputScript  "read_header_texts.txt" 

// Init text display in VB class
CallVBAsync utilities.VA03.InitTextDisplay

// Intialize text index and reset language variable
Set V[k] 0
Clear V[textlanguage]

// SAP header text display
Screen sapmv45a.4002

  // read whole text tree into a GuiXT text variable
  CallVBAsync guinet.treecontrol.copytext textname:="tc.headertexts" delimiter:=";"

  Enter

// Repeat the next screen for each existing text
label read_text
Screen sapmv45a.4002

  // Display a title, since this can last a few seconds if many texts exist
  Title "Reading header texts..."

 // text language set? then add the text in VB class
  if V[textlanguage]
      // add text
     CallVBAsync utilities.VA03.AddText
               "&V[nodekey]"
"&V[texttitle]"
"&V[textlanguage]"
  endif

  // identify all text ids for which a text exists
  label check_next_text

  // next index in tree
  Set V[k] &V[k] + 1

  // copy line from GuiXT variable that represents the tree
  CopyText fromText="tc.headertexts" tostring="wa" line="&V[k]"

  if Q[ok]

    // the various parts that describe the tree node
    // are separated by ";"
    // we use copytext to split the line into these parts
    CopyText fromString="wa" toText="watext"
   
CopyText fromText="watext" toString="nodekey" line=1 delimiter=";"
    CopyText fromText="watext" toString="nodelevel" line=2 delimiter=";"
    CopyText fromText="watext" toString="colA" line=4 delimiter=";"
    CopyText fromText="watext" toString="colB" line=5 delimiter=";"

    // depending on node level the content is different
    if V[nodelevel=0]
      // no text or, if language is set, one text
      Set V[texttitle] "&V[colA]"
      Set V[textlanguage] "&V[colB]"
   else
      // more than one language
      Set V[textlanguage] "&V[colA]"
  endif

  // text exists?
 
if V[textlanguage]
    // select this tree node to display the text
    CallVBAsync guinet.TreeControl.SelectNodeByKey key:="&V[nodekey]"
    Enter

    // repeat this Screen block to read the text from screen and process
    // the next tree node
    goto read_text

  else
    // no text of this type, try next tree node
    goto check_next_text
  endif

 endif

 // we are done and can display the texts n the HTML control
 Enter

 

VB.NET 

Public Class va03

    ' list of VA03 header texts
    Private headertexts As New List(Of Longtext)

    ' initialize
    Public Function InitTextDisplay()
        headertexts.Clear()

        Return "X"
    End Function

    ' add one header text
    Public Function AddText(ByVal id As String, _
                     ByVal title As String, ByVal language As String)

        ' new longtext object
        Dim lt As New Longtext
        lt.id = id
        lt.title = title
        lt.language = language

        ' read text from text control
        Dim tc As New guinet.TextControl
        lt.text = tc.GetText("")

        ' add text
        headertexts.Add(lt)

        ' done
        Return "X"

    End Function

    Public Function DisplayTexts(wb As SHDocVw.WebBrowser)


        ' set suitable CSS style for whole area
        Dim s As String = "<div style='font-family:Arial;
                     font-size:10pt; height:100%;  overflow-y: auto;'>"

        ' add HTML for all texts
        For Each lt As Longtext In headertexts
            s &= lt.ToHtml
        Next

        ' no text at all? then display message
        If headertexts.Count = 0 Then
            s &= "<br><br>No texts available"
        End If

        ' ending DIV
        s &= "</div>"

        ' now load the HTML into the web browser control
         Dim doc As mshtml.HTMLDocumentClass = wb.Document
        doc.body.innerHTML = s
        ' done
        Return "X"

    End Function

End Class

' VA03 long text
Public Class Longtext

    Public id As String
    Public language As String
    Public title As String
    Public text As String

    '  longtext as HTML box 
    Public Function ToHtml() As String

        ' encode in HTML format and replace carriage-return with <br>
        Dim htmltext As String = _
           System.Net.WebUtility.HtmlEncode(text).Replace(vbCr, "<br>")
        Dim htmltitle As String = 
           System.Net.WebUtility.HtmlEncode(title)

        ' choose suitable CSS style to display the text box
        Dim s As String
        s = "<div style='width:290px; height:160px; 
                         float:left; overflow-y: auto; margin:10px; "
        s &= "padding:4px; border-width: 1px; border-style: solid;
                     border-color: #404040; background-color:#f8f8f8';>"
        s &= "<b>" & htmltitle & " (" & language & ")</b><br>" _
                                      & htmltext & "</div>"

        Return s
    End Function

End Class
In order to build the VB project in MS Visual Studio, you need references to

  • Microsoft Internet Controls  COM  Interop.SHDOCVw.dll
  • Microsoft.mshtml .NET Microsoft.shtml.dll  (do not embed interop types)
     

 

Components
InputAssistant + Controls