Skip to content
Back to skills

Sap Where Used List

ASecurity

Runs SAP's Where-Used List (Verwendungsnachweis, Ctrl+Shift+F3) for any ABAP repository object across SE11, SE38, SE37, SE24, and SE91 — i.e. before deleting an object, find every program / class / FM / DDIC reference. Routes to the right initial screen by OBJECT_TYPE, fills the name, sends Ctrl+Shift+F3, ticks every scope on the popup, then branches: NOT_FOUND when SAP says no usages, FOUND_LIST when the list is rendered, or SPOOL_CREATED:<num> when called with TO_SPOOL=X (so the operator ca...

  • 7 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 27, 2026
toolsgoshellbashrefactoringgit

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned May 27, 2026

npx -y skills add sapdev-ai/sap-dev --skill sap-where-used-list --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Sap Where Used List?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Sap Where Used List
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/sapdev-ai-sap-where-used-list/badge)](https://www.skillsdirectory.com/skills/sapdev-ai-sap-where-used-list)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: sap-where-used-list
description: |
  Runs SAP's Where-Used List (Verwendungsnachweis, Ctrl+Shift+F3) for any
  ABAP repository object across SE11, SE38, SE37, SE24, and SE91 — i.e.
  before deleting an object, find every program / class / FM / DDIC
  reference. Routes to the right initial screen by OBJECT_TYPE, fills
  the name, sends Ctrl+Shift+F3, ticks every scope on the popup, then
  branches: NOT_FOUND when SAP says no usages, FOUND_LIST when the list
  is rendered, or SPOOL_CREATED:<num> when called with TO_SPOOL=X
  (so the operator can chain into /sap-sp02 to download the list).
  Pure read-only — never modifies the SAP system.
  Prerequisites: Active SAP GUI session (use /sap-login first).
argument-hint: "<OBJECT_TYPE> <OBJECT_NAME> [--to-spool]"
---

# SAP Where-Used List Skill

You run a Where-Used List against an ABAP repository object so the
operator can see every reference before deleting / refactoring it. The
skill is a thin GUI driver: it picks the right transaction by
OBJECT_TYPE, fills the name field, sends `Ctrl+Shift+F3`, ticks "Select
all" on the scope popup, and reports either NOT_FOUND, FOUND_LIST, or
SPOOL_CREATED:<num>.

Task: $ARGUMENTS

---

## Shared Resources

| File | Token | Purpose |
|---|---|---|
| `<SAP_DEV_CORE_SHARED_DIR>/rules/skill_operating_rules.md` | *(rule)* | Mandatory operating rules |
| `<SAP_DEV_CORE_SHARED_DIR>/rules/language_independence_rules.md` | *(rule)* | GUI-scripting language independence — identify by component ID + DDIC field name, status-bar checks via `MessageType` codes (S/W/E/I/A), VKey instead of menu-text, no branching on `.Text`/`.Tooltip`/window titles |
| `<SKILL_DIR>/references/sap_where_used_list.vbs` | many | Multi-txn router + scope popup + optional Print-to-spool branch |

---

## Step 0 — Resolve Work Directory

**Settings reads/writes follow `shared/rules/settings_lookup.md`** — merge `settings.local.json` over `settings.json` per-key on the `.value` field; writes always go to `settings.local.json`. Read `work_dir`.

| Setting | Default if blank |
|---|---|
| `work_dir` | `C:\sap_dev_work` |

Set `{WORK_TEMP}` = `{work_dir}\temp`. Ensure it exists:

```bash
cmd /c if not exist "{WORK_TEMP}" mkdir "{WORK_TEMP}"
```

---

## Step 0.5 — Start Logging

```bash
powershell -ExecutionPolicy Bypass -File "<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_log_helper.ps1" -Action start -StateFile "{WORK_TEMP}\sap_where_used_list_run.json" -Skill sap-where-used-list -ParamsJson "{\"object_type\":\"<TYPE>\",\"object_name\":\"<NAME>\"}"
```

Best-effort.

---

## Step 1 — Parse Arguments

| Arg | Required | Notes |
|---|---|---|
| `OBJECT_TYPE` | yes | One of: `TABLE`, `VIEW`, `DATAELEMENT`, `STRUCTURE`, `TABLETYPE`, `TYPEGROUP`, `DOMAIN`, `SEARCHHELP`, `LOCKOBJECT` (→ SE11), `PROGRAM` (→ SE38), `FM` (→ SE37), `CLASS` / `INTERFACE` (→ SE24), `MESSAGE_CLASS` (→ SE91). |
| `OBJECT_NAME` | yes | UPPERCASE repository name. |
| `--to-spool` | no | Send the rendered list to a SAP spool so a follow-up `/sap-sp02` can download it. Default: leave the list on screen and just count usages. |

**Map OBJECT_TYPE → TXN.** This determines which initial screen the
VBS opens and which name field it fills.

| OBJECT_TYPE | TXN | Name field |
|---|---|---|
| `TABLE` / `VIEW` / `DATAELEMENT` / `STRUCTURE` / `TABLETYPE` / `TYPEGROUP` / `DOMAIN` / `SEARCHHELP` / `LOCKOBJECT` | `SE11` | `ctxtRSRD1-<radio>_VAL` (radio + name field per type — same map as `/sap-se11` Step 6c) |
| `PROGRAM` | `SE38` | `ctxtRS38M-PROGRAMM` |
| `FM` | `SE37` | `ctxtRS38L-NAME` |
| `CLASS` / `INTERFACE` | `SE24` | `ctxtSEOCLASS-CLSNAME` |
| `MESSAGE_CLASS` | `SE91` | `ctxtRSDAG-ARBGB` |

**Trigger phrases:**

- "where used `<NAME>`" / "where-used list of `<NAME>`"
- "find references to `<NAME>`" / "who uses `<NAME>`"
- "check usages of `<NAME>` before delete" / "is `<NAME>` safe to delete"
- "save where-used to spool for `<NAME>`" → adds `--to-spool`

---

## Step 2 — Ensure SAP GUI Session

Run `/sap-login` if no session is active.

---

## Step 3 — Generate and Run the VBS

Map the operator's OBJECT_TYPE to the `TXN` token (see table above).
For SE11 also set `OBJECT_TYPE` so the VBS picks the right radio. For
all other transactions set `OBJECT_TYPE` empty.

Set `TO_SPOOL` to `X` if `--to-spool`, else leave empty.

Write `{WORK_TEMP}\sap_where_used_list_run.ps1`:

```powershell
$skillDir = '<SKILL_DIR>'
$content  = Get-Content "$skillDir\references\sap_where_used_list.vbs" -Raw
$content  = $content.Replace('%%TXN%%',             'THE_TXN')
$content  = $content.Replace('%%OBJECT_TYPE%%',     'THE_OBJECT_TYPE')   # empty unless TXN=SE11
$content  = $content.Replace('%%OBJECT_NAME%%',     'THE_OBJECT_NAME')
$content  = $content.Replace('%%TO_SPOOL%%',        'THE_TO_SPOOL')      # 'X' or empty
$content  = $content.Replace('%%SESSION_LOCK_VBS%%', '<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_session_lock.vbs')
# Session-attach plumbing (Phase 3.5 multi-connection aware). Resolution:
# explicit --session > SAPDEV_SESSION_PATH > sole-
# connection auto-default > refuse. See sap_attach_lib.vbs for details.
$sessionPath = ''  # set to the parsed --session value if supplied
$content  = $content.Replace('%%SESSION_PATH%%',     $sessionPath)
$content  = $content.Replace('%%ATTACH_LIB_VBS%%',   '<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_attach_lib.vbs')
. '<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_connection_lib.ps1'
$env:SAPDEV_SESSION_PATH = Get-SapCurrentSessionPath -WorkTemp '{WORK_TEMP}'
Set-Content '{WORK_TEMP}\sap_where_used_list_run.vbs' $content -Encoding Unicode
Write-Host 'Done'
```

Run via cscript:

```bash
powershell -ExecutionPolicy Bypass -File "{WORK_TEMP}\sap_where_used_list_run.ps1"
cscript //NoLogo {WORK_TEMP}\sap_where_used_list_run.vbs
```

---

## Step 4 — Interpret the Output

| Last line | Meaning |
|---|---|
| `NOT_FOUND: <TYPE> <NAME> has no usages in the selected scope.` | SAP returned the "no occurrences" popup. Object is **safe to delete** as far as the workbench knows (cross-system / Z-table-based / RTTI usages still need a manual check). |
| `FOUND_LIST: <TYPE> <NAME> has usages — list shown on screen (no spool requested).` | List is rendered but no spool was requested (operator passed no `--to-spool`). The operator can read it interactively. |
| `SPOOL_CREATED: <NUM>` | List was written to spool `<NUM>`. To download as a text file, chain into `/sap-sp02 <NUM> <PATH>`. |
| `ERROR: Could not parse spool number from sbar: '...'` | Print succeeded but the sbar message did not contain a 4+ digit spool number (unusual locale / SAP version). Open SP02 manually, take the most recent spool, then run `/sap-sp02`. |
| Other `ERROR: …` | Surface verbatim and consult Step 7. |

---

## Step 5 — Report

For NOT_FOUND, tell the user the object has no usages in the standard
ABAP-Workbench scope and is therefore (probably) safe to delete. Add
the caveat that **dynamic references** (CALL FUNCTION '...', CREATE
DATA dyn, GENERATE SUBROUTINE POOL, RFCs from external systems) are
NOT covered by where-used and must be checked separately.

For FOUND_LIST, tell the user the list is on screen and recommend
re-running with `--to-spool` if they want a saved copy.

For SPOOL_CREATED, tell the user the spool number AND the exact
follow-up command:

```text
/sap-sp02 <SPOOL_NUM> <C:\path\to\where_used_<NAME>.txt>
```

That two-step composition (where-used to spool → SP02 download) is
the documented chain.

---

## Step 6 — Clean Up

```bash
cmd /c del {WORK_TEMP}\sap_where_used_list_run.vbs & del {WORK_TEMP}\sap_where_used_list_run.ps1
```

---

## Final — Log End

```bash
powershell -ExecutionPolicy Bypass -File "<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_log_helper.ps1" -Action end -StateFile "{WORK_TEMP}\sap_where_used_list_run.json" -Status SUCCESS -ExitCode 0
```

On failure:

```bash
powershell -ExecutionPolicy Bypass -File "<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_log_helper.ps1" -Action end -StateFile "{WORK_TEMP}\sap_where_used_list_run.json" -Status FAILED -ExitCode 1 -ErrorClass <CLASS> -ErrorMsg "<short>"
```

Suggested `<CLASS>`: `WHERE_USED_FAILED`, `WHERE_USED_PRINT_FAILED`, `GUI_TIMEOUT`.

---

## Step 7 — Troubleshooting

The VBS uses two shortcuts that can shift between SAP releases:

- **`sendVKey 39`** = Ctrl+Shift+F3 = "Where-Used List" — stable across
  every ABAP Workbench transaction we drive (SE11/SE24/SE37/SE38/SE91).
- **List > Print > Print** menu path
  (`mbar/menu[0]/menu[7]/menu[0]`) — the index path is stable across
  languages but can shift one slot between SAP releases. The VBS falls
  back to `tbar[1]/btn[32]` if the menu path fails.
- **Print params dialog** (`SAPLSPRI:0600`) — the field
  `cmbPRIPAR_DYN-PRIMM2` and the commit button `btn[13]` come from the
  S/4HANA 1909 recording. Older releases used different column layouts.

When any GUI step fails with "control could not be found by id", run
`/sap-gui-diagnose full` first (visual + structural dump for the
topmost window) before guessing.

| Symptom | Diagnose | Fix |
|---|---|---|
| Scope popup never appears | The transaction may have inline scope (no popup) on this release | Surface the sbar message; the list may already be on screen |
| `Could not parse spool number from sbar` | Locale-specific message text | Open SP02 manually, look for the most recent spool by date/time; pass it to `/sap-sp02` |
| Print dialog has different field IDs | SAPLSPRI subscreen number changed | Re-record the print step on the new release; patch token positions in the VBS |

---

## Component IDs (for reference)

| Element | ID |
|---|---|
| OK code | `wnd[0]/tbar[0]/okcd` |
| SE11 sub-type radios | `wnd[0]/usr/radRSRD1-{TBMA,VIMA,DDTYPE,TYMA,DOMA,SHMA,ENQU}` |
| SE11 name fields | `wnd[0]/usr/ctxtRSRD1-{TBMA,VIMA,DDTYPE,TYMA,DOMA,SHMA,ENQU}_VAL` |
| SE38 program field | `wnd[0]/usr/ctxtRS38M-PROGRAMM` |
| SE37 FM field | `wnd[0]/usr/ctxtRS38L-NAME` |
| SE24 class field | `wnd[0]/usr/ctxtSEOCLASS-CLSNAME` |
| SE91 message-class field | `wnd[0]/usr/ctxtRSDAG-ARBGB` |
| Where-Used (Ctrl+Shift+F3) | `sendVKey 39` on `wnd[0]` |
| Scope popup: Select All | `wnd[1]/tbar[0]/btn[7]` |
| Scope popup: Continue | `wnd[1]/tbar[0]/btn[0]` |
| No-usages popup confirm | `wnd[1]/usr/btnSPOP-OPTION1` |
| List > Print > Print menu | `wnd[0]/mbar/menu[0]/menu[7]/menu[0]` |
| Print params dialog | `wnd[1]/usr/subSUBSCREEN:SAPLSPRI:0600/cmbPRIPAR_DYN-PRIMM2` |
| Print params commit | `wnd[1]/tbar[0]/btn[13]` |
| Status bar | `wnd[0]/sbar` |

---

## Composition with `/sap-sp02`

The intended chain is:

```text
/sap-where-used-list <TYPE> <NAME> --to-spool        # → SPOOL_CREATED:<NUM>
/sap-sp02 <NUM> C:\Temp\where_used_<NAME>.txt        # → local text file
```

Each skill owns one job; neither auto-invokes the other. This keeps
common "is X safe to delete?" runs cheap (no useless download when the
answer is NOT_FOUND) and makes the saved file available when the
operator wants it.

---

## Limitations

- **Standard scope only.** `tbar[0]/btn[7]` Select All ticks every
  scope SAP knows about, but **dynamic references** (`CALL FUNCTION
  '...'`, `CREATE OBJECT (cls)`, `GENERATE SUBROUTINE POOL`,
  external-system RFC calls) are not represented in the workbench
  index and won't appear in the list. A NOT_FOUND result is
  necessary-but-not-sufficient for safe deletion.
- **METHOD-level usage** is not directly supported — search the parent
  CLASS instead and grep the resulting list for the method name.
- **MESSAGE_CLASS** field-id assumption (`ctxtRSDAG-ARBGB`) is the
  default SE91 initial-screen field. If a customised SE91 layout uses
  a different field, override via the field-id table after recording
  with `/sap-gui-record`.
- **Print params dialog** field positions vary by SAP release —
  S/4HANA 1909 verified; other releases may need a one-time recording
  to confirm `PRIMM2` and `btn[13]` paths.

Files in this skill

  • README.md2.9 KB
  • SKILL.md11.6 KB
  • references/sap_where_used_list.vbs12.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.