Skip to main content

sap-gui-scripting

SAP GUI Scripting automation skill. Use when automating SAP GUI transactions with VBScript or Python, recording/replaying scripts, batch data entry, or screen scraping SAP screens. If the user mentions SAP GUI automation, GUI scripting, VBScript for SAP, transaction recording, or RPA with SAP GUI, use this skill.

الانتقال إلى التثبيت

معلومات المصدر

المستودع
efeumutaslan/SAP-SKILLS
آخر نشاط في المصدر
٢٤ مارس ٢٠٢٦ في ٢١:١٧
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٥
التفرعات
١

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
2 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
sap-gui-scripting
description
SAP GUI Scripting automation skill. Use when automating SAP GUI transactions with VBScript or Python, recording/replaying scripts, batch data entry, or screen scraping SAP screens. If the user mentions SAP GUI automation, GUI scripting, VBScript for SAP, transaction recording, or RPA with SAP GUI, use this skill.
disable-model-invocation
true
license
MIT
metadata
{"author":"SAP Skills Community","version":"1.1.0","last_verified":"2026-03-25"}
# SAP GUI Scripting & Automation ## Related Skills - `sap-build-process-automation` — Desktop Agent uses GUI scripting under the hood - `sap-testing-quality` — Automated GUI testing with eCATT/CBTA - `sap-s4hana-extensibility` — When to use API vs. GUI scripting ## Quick Start **Prerequisites:** 1. Enable scripting on SAP server: `RZ11` → parameter `sapgui/user_scripting` = `TRUE` 2. Enable on client: SAP GUI → Options → Accessibility & Scripting → Enable scripting 3. Disable notification popups: uncheck "Notify when script attaches" and "Notify when script opens connection" **Record your first script:** 1. Open SAP GUI → transaction you want to automate 2. Menu: Customize Local Layout (Alt+F12) → Script Recording and Playback 3. Click Record, perform actions, click Stop 4. Save as `.vbs` file — this is your starting template **Minimal VBScript — Run Transaction:** ```vbs If Not IsObject(application) Then Set SapGuiAuto = GetObject("SAPGUI") Set application = SapGuiAuto.GetScriptingEngine End If Set connection = application.Children(0) Set session = connection.Children(0) session.findById("wnd[0]/tbar[0]/okcd").text = "/nMM03" session.findById("wnd[0]").sendVKey 0 session.findById("wnd[0]/usr/ctxtRMMG1-MATNR").text = "MAT-001" session.findById("wnd[0]").sendVKey 0 ``` ## Core Concepts ### Object Hierarchy ``` GuiApplication └── GuiConnection (SAP system connection) └── GuiSession (user session / window) └── GuiFrameWindow (wnd[0], wnd[1]...) ├── GuiToolbar (tbar[0] = command, tbar[1] = app) ├── GuiUserArea (usr/) │ ├── GuiTextField, GuiCTextField │ ├── GuiComboBox, GuiCheckBox, GuiRadioButton │ ├── GuiTableControl, GuiGridView (ALV) │ ├── GuiTab, GuiTabStrip │ └── GuiTree ├── GuiStatusbar (sbar/) └── GuiTitlebar (titl/) ``` ### Element ID Pattern Format: `wnd[N]/area/type[row,col]` - `wnd[0]/tbar[0]/okcd` — Command field (OKCode) - `wnd[0]/usr/ctxtFIELD-NAME` — Context field (F4 help available) - `wnd[0]/usr/txtFIELD-NAME` — Text input field - `wnd[0]/usr/chkFIELD-NAME` — Checkbox - `wnd[0]/usr/radFIELD-NAME` — Radio button - `wnd[0]/usr/btnBUTTON-NAME` — Push button - `wnd[0]/usr/tblTABLE/ctxtFIELD[row,col]` — Table cell - `wnd[0]/usr/cntlGRID/shellcont/shell` — ALV Grid control - `wnd[0]/sbar` — Status bar (messages) ### Virtual Keys (sendVKey) | Key | Code | Description | |-----|------|-------------| | Enter | `0` | Confirm/execute | | F2 | `2` | Choose/display | | F3 | `3` | Back | | F5 | `5` | Refresh | | F8 | `8` | Execute report | | F12 | `12` | Cancel | | Shift+F4 | `16` | Save as variant | | Ctrl+S | `11` | Save | | Ctrl+Shift+F3 | `43` | Delete | ## Common Patterns ### Pattern 1: Python Automation with win32com ```python import win32com.client import time def get_sap_session(): """Connect to running SAP GUI session.""" sap_gui = win32com.client.GetObject("SAPGUI") app = sap_gui.GetScriptingEngine connection = app.Children(0) session = connection.Children(0) return session def run_transaction(session, tcode): """Navigate to transaction.""" session.findById("wnd[0]/tbar[0]/okcd").text = f"/n{tcode}" session.findById("wnd[0]").sendVKey(0) def get_status_message(session): """Read status bar message.""" sbar = session.findById("wnd[0]/sbar") return { "type": sbar.MessageType, # S=Success, E=Error, W=Warning, I=Info "text": sbar.Text } ``` ### Pattern 2: Table Data Extraction ```python def extract_alv_grid(session, grid_id="wnd[0]/usr/cntlGRID/shellcont/shell"): """Extract all data from ALV grid.""" grid = session.findById(grid_id) columns = grid.ColumnCount rows = grid.RowCount col_names = [grid.GetColumnTitles(i) for i in range(columns)] data = [] for row in range(rows): grid.SetCurrentCell(row, grid.GetColumnName(0)) record = {} for col in range(columns): col_name = grid.GetColumnName(col) record[col_name] = grid.GetCellValue(row, col_name) data.append(record) return data def extract_table_control(session, table_id): """Extract data from classic table control (scroll-aware).""" table = session.findById(table_id) all_rows = [] visible = table.VisibleRowCount total = table.RowCount for offset in range(0, total, visible): table.VerticalScrollbar.Position = offset for row in range(min(visible, total - offset)): row_data = {} for col in range(table.Columns.Count): cell = table.GetCell(row, col) row_data[table.Columns(col).Name] = cell.Text all_rows.append(row_data) return all_rows ``` ### Pattern 3: Batch Data Entry (e.g., Mass Material Change) ```python def mass_material_change(session, materials): """Change multiple materials via MM02.""" results = [] for mat in materials: run_transaction(session, "MM02") session.findById("wnd[0]/usr/ctxtRMMG1-MATNR").text = mat["matnr"] session.findById("wnd[0]").sendVKey(0) # Select views for view in session.findById("wnd[0]/usr/tabsTABSPR1").Children: if hasattr(view, "Selected"): view.Selected = view.Text in mat.get("views", ["Basic Data 1"]) session.findById("wnd[0]").sendVKey(0) # Update fields for field_id, value in mat.get("fields", {}).items(): try: session.findById(field_id).text = value except Exception as e: results.append({"matnr": mat["matnr"], "status": "ERROR", "msg": str(e)}) session.findById("wnd[0]").sendVKey(12) # Cancel continue session.findById("wnd[0]").sendVKey(11) # Ctrl+S msg = get_status_message(session) results.append({"matnr": mat["matnr"], "status": msg["type"], "msg": msg["text"]}) return results ``` ### Pattern 4: Handle Popups and Modal Dialogs ```python def handle_popup(session, action="confirm"): """Handle unexpected popup windows.""" try: popup = session.findById("wnd[1]") if action == "confirm": popup.findById("wnd[1]/usr/btnBUTTON_1").press() # Yes/OK elif action == "cancel": popup.findById("wnd[1]/usr/btnBUTTON_2").press() # No/Cancel elif action == "close": popup.Close() return True except Exception: return False # No popup present def safe_action(session, action_func, max_popups=3): """Execute action and handle any resulting popups.""" action_func() for _ in range(max_popups): time.sleep(0.3) if not handle_popup(session, "confirm"): break ``` ### Pattern 5: Login Automation ```python def login_sap(system, client, user, password, language="EN"): """Open new SAP GUI connection and login.""" import subprocess sap_logon = r"C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe" subprocess.Popen([sap_logon]) time.sleep(3) sap_gui = win32com.client.GetObject("SAPGUI") app = sap_gui.GetScriptingEngine connection = app.OpenConnection(system, True) session = connection.Children(0) session.findById("wnd[0]/usr/txtRSYST-MANDT").text = client session.findById("wnd[0]/usr/txtRSYST-BNAME").text = user session.findById("wnd[0]/usr/pwdRSYST-BCODE").text = password session.findById("wnd[0]/usr/txtRSYST-LANGU").text = language session.findById("wnd[0]").sendVKey(0) # Handle multiple logon popup handle_popup(session, "confirm") return session ``` ### Pattern 6: Error-Resilient Script Template ```python import logging logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") log = logging.getLogger("sap_script") def run_with_retry(session, func, max_retries=3, *args, **kwargs): """Run GUI action with retry on transient errors.""" for attempt in range(max_retries): try: result = func(session, *args, **kwargs) msg = get_status_message(session) if msg["type"] == "E": log.warning(f"Attempt {attempt+1}: SAP error: {msg['text']}") if attempt < max_retries - 1: session.findById("wnd[0]").sendVKey(3) # Back continue return result except Exception as e: log.error(f"Attempt {attempt+1}: Exception: {e}") if attempt == max_retries - 1: raise return None ``` ## Error Catalog | Error | Message | Root Cause | Fix | |-------|---------|------------|-----| | `Runtime error: -2147352567` | Object not found | Element ID wrong or screen changed | Use Script Recorder to get correct ID | | `Scripting disabled` | Server rejected script | `sapgui/user_scripting` = FALSE | Set via `RZ11` or profile parameter | | `No SAP GUI instance` | GetObject failed | SAP GUI not running | Start SAP GUI before script | | `Session busy` | Cannot attach | Transaction is processing | Add `time.sleep()` before action | | `Modal dialog open` | Cannot access main window | Popup blocking | Handle `wnd[1]` before `wnd[0]` | | `ALV: Invalid cell` | GetCellValue error | Row index out of range | Check `RowCount` before access | | `Multiple logon` | Popup at login | User already logged in | Handle popup or close other session | | `Authorization` | No authorization for scripting | Missing `S_SCR` auth object | Assign auth via `SU01`/role | ## Performance Tips 1. **Disable screen updates** — Not natively supported; minimize visual impact by running in background session 2. **Batch via BDC/BAPI first** — GUI scripting is last resort; prefer RFC/BAPI/OData for bulk operations 3. **Reuse sessions** — Don't login/logout per record; reuse connection for batch processing 4. **Minimize findById calls** — Cache element references: `field = session.findById(...)` then reuse `field` 5. **Handle scrolling** — For table controls, read `VisibleRowCount` and scroll incrementally 6. **Parallel sessions** — SAP allows up to 6 sessions per user; parallelize with `connection.Children(N)` 7. **Avoid hardcoded waits** — Use status bar checks instead of fixed `time.sleep()` where possible ## Gotchas - **Screen variants**: Same transaction can show different screens based on user settings — always verify screen number - **Language dependency**: Element IDs can differ by logon language for some older transactions - **ALV vs. Table Control**: `GuiGridView` (ALV) and `GuiTableControl` have completely different APIs - **SAP GUI version**: Scripting API changes between versions; test on target version - **Security policy**: Many organizations disable scripting in production — always check policy - **64-bit Python + 32-bit SAP GUI**: COM interop may fail; use matching architecture
عرض على GitHub