Table of Contents

Common Patterns

Reading a classic ABAP table

var table    = session.Table("wnd[0]/usr/tblSAPLXXX");
int total    = table.RowCount;
int pageSize = table.VisibleRowCount;

for (int start = 0; start < total; start += pageSize)
{
    table.ScrollToRow(start);
    for (int r = start; r < Math.Min(start + pageSize, total); r++)
        Console.WriteLine(table.GetCellValue(r, 0));
}

Reading an ALV grid (scroll-aware)

var grid = session.GridView("wnd[0]/usr/cntlGRID/shellcont/shell");

Log($"Total: {grid.RowCount}, visible: {grid.VisibleRowCount}, first: {grid.FirstVisibleRow}");

// Navigate focus before reading tooltips or checkboxes
grid.SetCurrentCell(3, "STATUS");
string tooltip = grid.GetCellTooltip(3, "STATUS");
bool   flagged = grid.GetCellCheckBoxValue(3, "CRITICAL");

// Get selected rows after SelectAll
grid.SelectAll();
IReadOnlyList<int> selected = grid.SelectedRows;

Bulk row read with column mapping

var rows = grid.GetRows(new[] { "MATNR", "MAKTX", "LABST" });
foreach (var row in rows)
    Console.WriteLine($"{row["MATNR"]} | {row["MAKTX"]} | {row["LABST"]}");

Handling popups

GetActivePopup() returns a unified wrapper for both GuiMessageWindow (pure dialogs) and GuiModalWindow (form dialogs):

var popup = session.GetActivePopup();
if (popup != null)
{
    Log($"[{popup.MessageType}] {popup.Title}: {popup.Text}");

    // Standard buttons
    popup.ClickOk();
    // or popup.ClickCancel()

    // Custom button by partial text match
    popup.ClickButton("Continue");

    // Inspect all buttons
    foreach (var btn in popup.GetButtons())
        Log(btn.Text);
}

Status bar — check after every navigation

session.PressExecute();
session.WaitForReadyState(timeoutMs: 15_000);

var status = session.Statusbar();
if (status.IsError)
    throw new Exception($"SAP error: {status.Text}");

Tabs, toolbars, and menus

// Select a tab by index
session.TabStrip("wnd[0]/usr/tabsTABSTRIP").SelectTab(1);

// Press a toolbar button by SAP function code
session.Toolbar().PressButtonByFunctionCode("BACK");

// Navigate a menu item
session.Menu("wnd[0]/mbar/menu[4]/menu[2]").Select();

Tree controls

var tree = session.Tree("wnd[0]/usr/cntlTREE/shellcont/shell");

tree.ExpandNode("ROOT");
foreach (var key in tree.GetChildNodeKeys("ROOT"))
    Log($"{key}: {tree.GetNodeText(key)}");

tree.SelectNode("CHILD01");
tree.DoubleClickNode("CHILD01");

// Multi-column tree cell
string cellValue = tree.GetItemText("CHILD01", "AMOUNT");

// Context menu
tree.NodeContextMenu("CHILD01");

Combo boxes

var cb = session.ComboBox("wnd[0]/usr/cmbVBAK-VKORG");

// List all available entries
foreach (var entry in cb.Entries)
    Log($"{entry.Key}: {entry.Value}");

// Set by key
cb.Key = "1000";
session.SendVKey(0); // PAI validation

Multi-session workflows

var sap = SapGuiClient.Attach();

// Get sessions by index
var session0 = sap.GetSession(connectionIndex: 0, sessionIndex: 0);
var session1 = sap.GetSession(connectionIndex: 0, sessionIndex: 1);

// Open a new parallel session on demand
session0.CreateSession();
var newSession = sap.Application
                    .GetFirstConnection()
                    .GetSessions()
                    .Last();

Connecting to a new SAP system

var app        = GuiApplication.Attach();
var connection = app.OpenConnection("PRD - Production"); // SAP Logon Pad entry name
var session    = connection.GetFirstSession();

// Or get whichever session has focus
var active = app.ActiveSession;

UserArea — relative IDs

GuiUserArea (wnd[0]/usr) lets you address children with short relative IDs instead of the full qualified path:

var usr = session.UserArea(); // defaults to "wnd[0]/usr"

var field = usr.FindById<GuiTextField>("txtMM01-MATNR");
field.Text = "MAT-0042";

Scroll containers

var sc = session.ScrollContainer("wnd[0]/usr/shellcont");
sc.VerticalScrollbar.Position = 10;
sc.ScrollToTop();

Calendar controls

var cal = session.Calendar("wnd[0]/usr/cntlCAL/shellcont/shell");
cal.SetDate(new DateTime(2026, 3, 31));
DateTime? selected = cal.GetSelectedDate();