PackagePackagetypeA library you install and call yourself.See every one →What this type is →independently maintainedindependently maintainedoriginPublished by one person or a small company outside SAP. Says nothing about quality; the readings say that.See every one →

abap-dynamic-assignment

A framework for maintaining runtime parameters, ranges and value mappings in ABAP instead of hard-coded values or TVARVC, checked against data elements and maintained in a RAP Fiori app.

Configuration values are often hard-coded in ABAP or wedged into the generic, rigid TVARVC table. This framework stores single values, ranges and value-to-value mappings behind a validated API, get_variant for reading and map_value for classifying an incoming value against configured rules, and ships a RAP-based Fiori elements app for maintaining them without a transport. Every value is checked against its configured data element on write, so a value that would not survive a round trip is rejected rather than corrupted silently.

Facts

Last pushLicenceMIT

Where it sits

Lives in
Provides
ConfigurationABAPConfigurationcapabilityPer-environment settings without per-environment code — profiles, layered configuration, and bindings resolved from the platform at start-up.
Flavors
Requires
abapGitabapGitartifactInstalls the repository into the ABAP system; the README's first installation step is a pull with abapGit.

Who is behind it

George DrakosGeorge DrakosPersonMaintains this
In the atlas: maintains 4, contributes to 7
@greltel
maintainer

What it declares

Every artifact

Type
Package
Origin
Independently maintained

As a package

Where it runs
Inside its host
Distributed through
abapGit

Connections2

README

quoted from greltel/abap-dynamic-assignment under MIT, read
greltel/abap-dynamic-assignment/README.mdOn GitHub

ABAP Dynamic Assignment

✅ Status: Release (3.0.0)

Open Source Contribution: This project is community-driven and Open Source! 🚀 If you spot a bug or have an idea for an enhancement, open an Issue or submit a Pull Request.

CI ABAP Cloud ABAP Version Code Statistics License

A lightweight, dynamic runtime parameter framework for ABAP Cloud. It decouples configuration values from code logic, allowing developers, functional consultants or key users to maintain variables, ranges and mappings through a Fiori Elements application or a programmatic API, bypassing hardcoded values and the rigid standard TVARVC table.

Table of contents

  1. License
  2. Contributors-Developers
  3. Key Benefits
  4. Prerequisites
  5. Installation
  6. Upgrading from 2.x
  7. Authorization
  8. Usage
  9. Architecture
  10. The configuration table
  11. Messages
  12. Running the tests
  13. Known limitations
  14. Contributing

License

This project is licensed under the MIT License.

Contributors-Developers

The repository was created by George Drakos.

Key Benefits

  • No more TVARVC: Forget the limitations, clutter and rigid structure of the standard SAP TVARVC table.
  • Zero Hardcoding: Keep your business logic clean. No more IF bukrs = '1000' or hardcoded configuration IDs.
  • Hot-Swap Parameters: Change program behaviour, inclusion/exclusion rules and value mappings in Production without a Transport Request.
  • RTTS: Builds single values, range tables (ready for SELECT ... IN) and mapping tables at runtime. Every value is converted into the type of the caller's own variable.
  • Classification, not only lookup: map_value runs the configured rules against one value and answers which bucket it falls into, comparing in the configured DDIC type rather than on strings.
  • Validated on write: A value its data element could not hold unchanged is refused when it is stored, instead of surfacing months later in whichever program reads it first. The Fiori application and the programmatic API run the same check, through the same class.
  • Zero-touch installation: Pull, activate, publish. No source code to edit, no constant to adjust.
  • ABAP Cloud: Written for ABAP for Cloud Development, released APIs only.
  • Testable by design: Every collaborator sits behind an interface and is injected through the constructor, so consumers mock the framework and the framework mocks the system. No test depends on the user, the clock, the PFCG roles or the data of the system it runs on.
  • Unit Tested: 146 ABAP Unit tests across fourteen test classes, on the OSQL Test Double Framework and cl_abap_testdouble. The same tests run off-stack on every push and pull request, transpiled to JavaScript by the abaplint transpiler against an in-memory SQLite database — no ABAP system needed for CI.
  • Fiori Elements App built with RAP: validations, defaults, draft handling, optimistic locking and authorization checks.
  • Clean: abaplint with an extended Clean ABAP rule set runs on every push and pull request. Zero findings and a green test run are the merge bar.

Prerequisites

  • SAP S/4HANA 2023 FPS03 or higher (ABAP 7.58), or SAP BTP ABAP Environment
  • Authorization object ZDA_VAR — see Authorization

Installation

  1. Pull the repository with abapGit into a package with the language version ABAP for Cloud Development.
  2. Create the authorization field and object before activating — see Authorization. The behavior pool and the DCL reference ZDA_VAR.
  3. Activate everything.
  4. Publish the service binding ZUI_DA_VARIANTS_O4.
  5. Create the IAM App, Business Catalog and Launchpad tile so that the application reaches your users.

That is all. The framework instantiates without arguments on its own table ZTDA_VARIANTS.

Upgrading from 2.x

3.0.0 renames the RAP objects and the tables. There is no in-place upgrade; treat it as a fresh installation next to the old one:

2.x3.0.0
ZDA_VARIANTS, ZDA_VARIANTS_DZTDA_VARIANTS, ZTDA_VARIANTS_D
ZI_DA_VARIANTS (view, behavior definition, access control)ZR_DA_VARIANTS
ZBP_I_DA_VARIANTSZBP_R_DA_VARIANTS
ZCL_DA_VARIANTS=>check_value( ), =>data_element_exists( )ZIF_DA_VALUE_CHECK on ZCL_DA_VALUE_CHECK
NEW zcl_da_variants( table_name = … )needs packages = … as well, unless the table is the shipped one
Text symbolsMessage class ZDA

Copy the rows of ZDA_VARIANTS into ZTDA_VARIANTS (same structure), then delete the 2.x objects. Consumers that only hold ZIF_DA_VARIANTS and call get_variant, set_variant, map_value or delete_variant compile unchanged.

Authorization

The framework ships an authorization object that the RAP handlers check on every create, update and delete.

Authorization field (ADT → New → Other ABAP Repository Object → Authorization Field):

FieldData element
ZDA_PROGZDE_DA_PROGNAME

Authorization object (ADT → New → Other ABAP Repository Object → Authorization Object):

ObjectFieldsPermitted activities
ZDA_VARACTVT, ZDA_PROG01 Create, 02 Change, 03 Display, 06 Delete

Build two PFCG roles — most users only need to see what is configured:

RoleACTVTZDA_PROG
Display03* or specific programs
Maintain01, 02, 03, 06* or specific programs

03 is mandatory in the maintain role as well. The DCL grants read access through aspect pfcg_auth ( ZDA_VAR, ZDA_PROG, ACTVT = '03' ), and RAP reads the instance before every update or delete. Without 03 the user sees "record not found" while holding change authorization.

The DCL protects the Fiori application, not the programmatic API. get_variant reads the table directly, so a background job is never filtered by the authorizations of a user. That is intentional — a scheduled job must not depend on who happens to be logged on. set_variant and delete_variant write for the same reason, without an authority check. Know that before you expose them.

Usage

Reading variants programmatically
  1. Declare variables for your target data types. A single value, a range, or a table.
  2. Instantiate ZCL_DA_VARIANTS behind ZIF_DA_VARIANTS.
  3. Call get_variant. Only the targets you actually supply are computed.
  4. Use the result directly in your business logic or in Open SQL.
DATA product       TYPE i_product-product.
DATA product_range TYPE RANGE OF i_product-product.
DATA products      TYPE STANDARD TABLE OF i_product-product WITH EMPTY KEY.

TRY.
    DATA(variants) = CAST zif_da_variants( NEW zcl_da_variants( ) ).

    variants->get_variant(
      EXPORTING parameter_id = 'VALID_MATERIALS'
                program_name = 'GLOBAL'
      IMPORTING field_value  = product           " the first single value
                range        = product_range     " a real RANGE OF, ready for a WHERE clause
                values       = products ).       " one row per active variant

    SELECT FROM i_product
      FIELDS product, productgroup
      WHERE product IN @product_range
      INTO TABLE @DATA(matching_products).

  CATCH zcx_da_variants INTO DATA(error).
    " error->get_text( ) carries the reason, error->if_t100_message~t100key the message key
ENDTRY.

Range types come from the configuration. The DDIC type of the returned range is taken from the DataElement column. Leave it empty to get the native 255 character column type, which converts cleanly into any character-like range. Set it when your caller uses a numeric or date range.

Creating variants programmatically

Use set_variant for initial data loads, seed data or API integrations.

TRY.
    DATA(variants) = CAST zif_da_variants( NEW zcl_da_variants( ) ).

    variants->set_variant(
      parameter_id = 'DEFAULT_PLANTS'
      program_name = 'ZTEST'
      counter      = '00001'                      " omit to append a new row
      field_value  = '1000'
      high_value   = '2000'
      sign         = zcl_da_variants=>sign_include
      option       = zcl_da_variants=>opt_bt
      description  = 'Default Plant for Operations' ).

  CATCH zcx_da_variants INTO DATA(error).
    " validation failed, or the database rejected the row
ENDTRY.

The caller owns the LUW. set_variant does not commit. Pass commit = abap_true only from standalone scripts — never from a RAP handler, a determination or a validation.

Seed data is idempotent. Passing an existing counter replaces that row instead of appending a new one, so a load script can run twice without duplicating configuration.

set_variant rejects anything the framework would not be able to read back: a missing Parameterid or Value, an unknown or non-elementary data element, BT or NB without an upper bound, and an upper bound on any other operator. The Fiori application enforces the same rules through the same code, so both doors accept exactly the same rows.

The value has to fit its data element. 1000 configured against a one character element would come back as 1, and ABC against a NUMC element would come back as zeros. Both are refused on write. The check knows what each type loses in silence: CHAR truncates on the right, NUMC keeps only the digits, and a date field is character like, so 20240230 would be copied straight in as a day that does not exist. Leading zeros that NUMC adds by itself are not a loss and stay accepted.

Appending never overwrites. Without a counter the row is inserted, never replaced. If another LUW takes the number in between, the next one is allocated and the insert is repeated. An exhausted counter range is reported as an error, not wrapped around to 00000.

Removing variants
TRY.
    DATA(variants) = CAST zif_da_variants( NEW zcl_da_variants( ) ).

    " one row
    DATA(removed) = variants->delete_variant( parameter_id = 'DEFAULT_PLANTS'
                                              program_name = 'ZTEST'
                                              counter      = '00002' ).

    " the whole parameter
    removed = variants->delete_variant( parameter_id = 'DEFAULT_PLANTS'
                                        program_name = 'ZTEST' ).

  CATCH zcx_da_variants INTO DATA(error).
    " no parameter was named, or the database refused the delete
ENDTRY.

delete_variant returns the number of rows it removed. Removing what is not there is not an error, so a cleanup script can run twice. A blank parameter_id is refused, because without it the call would clear whatever happens to carry a blank key.

The caller owns the LUW here as well. Pass commit = abap_true only from standalone scripts.

Value mapping

Beyond filtering, the framework can translate. A mapping variant answers "what does X correspond to?" rather than "is X in scope?".

PrognameParameteridCounterSignOptValueMappingValue
ZORDER_IFORDER_TYPE_MAP1IEQCUST_STDOR
ZORDER_IFORDER_TYPE_MAP2IEQCUST_RETRE
DATA pairs_ref TYPE REF TO data.
FIELD-SYMBOLS <pairs> TYPE STANDARD TABLE.

variants->get_variant( EXPORTING parameter_id   = 'ORDER_TYPE_MAP'
                                 program_name   = 'ZORDER_IF'
                       IMPORTING mapping_values = pairs_ref ).

ASSIGN pairs_ref->* TO <pairs>.

LOOP AT <pairs> ASSIGNING FIELD-SYMBOL(<pair>).
  ASSIGN COMPONENT 'VALUE'         OF STRUCTURE <pair> TO FIELD-SYMBOL(<from>).
  ASSIGN COMPONENT 'MAPPING_VALUE' OF STRUCTURE <pair> TO FIELD-SYMBOL(<to>).
  " <from> is the incoming code, <to> is the value to post with
ENDLOOP.

The table is returned as a data reference because the type of the MAPPING_VALUE column is only known at runtime, from the configured MappingDataElement. If a parameter holds a single row, use mapping_field_value instead and skip the table entirely.

Two ways to read the same rows. A mapping table built with mapping_values pairs Value with MappingValue and ignores the range fields. map_value uses them as the rule that decides which pair applies. Rows written for the first style work in the second: an EQ row simply matches its own value.

Classifying a value

get_variant answers "which values are in scope". map_value reads the same rows the other way round and answers "which bucket does this one value fall into". Every active row is a rule, evaluated in counter order, with the operator and the bounds it carries.

PrognameParameteridCounterSignOptValueHighValueMappingValue
ZPLANTSPLANT_REGION1EEQ1500
ZPLANTSPLANT_REGION2IBT10001999NORTH
ZPLANTSPLANT_REGION3IBT20002999SOUTH
DATA region TYPE c LENGTH 10.

variants->map_value( EXPORTING parameter_id  = 'PLANT_REGION'
                               program_name  = 'ZPLANTS'
                               input         = '1200'
                     IMPORTING mapping_value = region       " NORTH
                               matched       = DATA(matched) ).

The first rule that answers decides. Row 1 carries sign_exclude, so plant 1500 stops the search and comes back unmatched even though row 2 would otherwise have covered it. That is how a hole is punched into a range that maps as a whole.

The comparison runs in the configured DDIC type. A BT 9 AND 100 on a numeric element matches 50. On the stored 255 character strings the same rule would reject it, because '50' sorts below '9'. Set DataElement whenever the values are numeric or dates. Patterns (CP, NP) always compare character wise, wildcards included.

A value that no rule covers is not an error. matched comes back abap_false and mapping_value stays initial. Only an unknown parameter raises.

Injecting your own configuration table
DATA(variants) = CAST zif_da_variants(
                     NEW zcl_da_variants( table_name = 'ZMY_OWN_VARIANTS'
                                          packages   = 'ZMY_PACKAGE' ) ).

The injected table must be structurally identical to ZTDA_VARIANTS. You name the packages it may live in; the constructor validates the name with cl_abap_dyn_prg=>check_table_name_str and raises ZCX_DA_VARIANTS when the table is unknown, lives elsewhere, or when no package list is given. The shipped table needs no list.

Testing a consumer

Consumers hold ZIF_DA_VARIANTS, so a consumer's unit test never needs the configuration table:

DATA(variants) = CAST zif_da_variants( cl_abap_testdouble=>create( 'ZIF_DA_VARIANTS' ) ).

cl_abap_testdouble=>configure_call( variants )->set_parameter( name  = 'field_value'
                                                               value = '1000' ).
variants->get_variant( EXPORTING parameter_id = 'DEFAULT_PLANT' IMPORTING field_value = DATA(plant) ).

DATA(cut) = NEW zcl_my_consumer( variants ).

Architecture

ZIF_DA_VARIANTS ──── ZCL_DA_VARIANTS (facade)
                        │
                        ├── ZIF_DA_REPOSITORY ──── ZCL_DA_REPOSITORY      every database access
                        ├── ZIF_DA_VALUE_CHECK ─── ZCL_DA_VALUE_CHECK     RTTS type checks
                        ├── ZIF_DA_RULE_MATCHER ── ZCL_DA_RULE_MATCHER    sign / option / bounds
                        └── ZIF_DA_SYSTEM_CONTEXT  ZCL_DA_SYSTEM_CONTEXT  user and clock

ZR_DA_VARIANTS (RAP root) ── ZBP_R_DA_VARIANTS
                                │  lcl_variants_factory (composition root, inject_* hooks)
                                ├── ZIF_DA_AUTHORIZATION ── ZCL_DA_AUTHORIZATION   AUTHORITY-CHECK ZDA_VAR
                                ├── ZIF_DA_REPOSITORY                             early numbering
                                └── ZIF_DA_VALUE_CHECK                            validations

ZC_DA_VARIANTS (projection) ── ZUI_DA_VARIANTS ── ZUI_DA_VARIANTS_O4 (OData V4, UI)
ZCX_DA_VARIANTS ── if_t100_dyn_msg + if_abap_behv_message, message class ZDA

Every collaborator of ZCL_DA_VARIANTS is an optional constructor parameter with a production default. The behavior pool resolves its collaborators through a local factory, which is what lets the RAP tests inject an authorization double instead of depending on the PFCG roles of whoever runs them.

ZCX_DA_VARIANTS implements IF_ABAP_BEHV_MESSAGE, so one exception object carries a message from the value check straight into reported-%msg of the Fiori application, with the same number and the same variables the API caller would see.

The configuration table

ColumnMeaning
PROGNAMEProgram scope. Use GLOBAL for parameters shared across programs
PARAMETERIDThe parameter being configured
COUNTERSequence inside one program and parameter, assigned automatically
IS_ACTIVEOnly active rows are returned. Defaults to set on creation
SIGN / OPTRange semantics, I/E and EQ, BT, CP, …
VALUE / HIGH_VALUEThe value, and the upper bound for BT and NB
DATA_ELEMENTDDIC type of the value. Empty means the native column type
MAPPING_VALUEThe value this row translates to
MAPPING_DATA_ELDDIC type of the mapping value
DESCRIPTIONFree text. set_variant generates one when it is left empty

ZTDA_VARIANTS has delivery class C and restricted data maintenance. Administrative fields are filled by the RAP framework and by set_variant.

Messages

All messages come from the message class ZDA and are translatable as one unit. The constants of ZCX_DA_VARIANTS name them, so a caller can react to a specific cause:

CATCH zcx_da_variants INTO DATA(error).
  IF error->if_t100_message~t100key = zcx_da_variants=>no_active_variant.
    " nothing configured yet, fall back to the default
  ENDIF.
NumberConstantRaised when
003no_active_variantNo active row exists for the parameter
005 / 006invalid_data_element / invalid_mapping_elementA configured type does not exist or is not elementary
011 / 024table_not_allowed / packages_missingThe injected table is refused
012 / 014inconsistent_elements / inconsistent_mapping_elementsRows of one parameter disagree on their type
013 / 019high_value_missing / high_value_not_allowedThe upper bound does not match the operator
015 / 016counter_exhausted / counter_not_securedNo free counter
017 / 018parameter_missing / value_missingA mandatory field is blank
020 – 023value_not_convertible, value_does_not_fit, invalid_date, invalid_timeThe value would not survive its type
001 / 002 / 004 / 009 / 010conversion, RTTS, database and write errorsThe cause is chained in previous

Running the tests

ADT: right click the package -> Run As -> ABAP Unit Test   (Ctrl+Shift+F10)

146 tests across fourteen test classes. None of them touches real data, the real user, the real clock or the real authorizations:

Test classCovers
ltc_variantsRanges, value tables, mapping tables, normalisation, validation, stamping, the constructor
ltc_defectsRegressions for the defects closed in 2.1.0
ltc_value_typesThe type check that runs before a value is written
ltc_mappingmap_value, every operator, exclusion and rule order
ltc_deletedelete_variant, single rows and whole parameters
ltc_exceptionT100 text, severity, chaining and variable length of ZCX_DA_VARIANTS
ltc_repositoryActive rows, draft counters, bulk counter reads, taken keys, delete counts
ltc_rule_matcherTyped comparison, patterns, NB, unknown operators, overflowing input
ltc_numberingEarly numbering, pending drafts and the exhausted key range
ltc_defaultsThe determination that fills IsActive, Sign and Opt
ltc_validationsAll three save-time validations, triggered through a real save
ltc_authorizationsGlobal and instance authorization through an injected double
ltc_option_vhThe options query provider, including the paging contract
ltc_sign_vhThe sign query provider, including the paging contract

Static checks and the transpiled unit tests, locally or in CI (Node 22, see .nvmrc):

npm ci          # pinned @abaplint toolchain from package-lock.json
npm run lint    # abaplint, zero findings expected
npm test        # transpile src/ to JavaScript and run the ABAP Unit tests off-stack
npm run check   # both

The same two jobs run on every push and pull request through .github/workflows/ci.yml. A handful of tests need the real system (package check, CONV # into a generic parameter) and run only in ADT; they are listed with a reason under options.skip in abap_transpile.json.

Known limitations

  • The API does not check authorizations. ZDA_VAR protects the Fiori application through the behaviour definition and the DCL. set_variant and delete_variant write directly, so anything that can call the class can change configuration.
  • Direct table access bypasses every validation. Data maintenance on ZTDA_VARIANTS is restricted, but a report writing the table directly still gets past every check.
  • Message variables hold 50 characters. A cause text longer than that is cut in the message; the full text stays available in error->previous.

Contributing

See CONTRIBUTING.md. Every pull request must pass the CI workflow (abaplint and the transpiled unit tests) and ship its ABAP Unit tests.

MIT, read

History

Latest

v3.0.0

Features 6, Changed 6, Fixes 5

Notes

Breaking release. See Upgrading from 2.x in the README before upgrading.

Added
  • GitHub Actions workflow running abaplint on every push and pull request, with an extended Clean ABAP rule set.
  • CONTRIBUTING.md, issue and pull request templates, .editorconfig, .gitattributes.
  • ZIF_DA_REPOSITORY, ZIF_DA_VALUE_CHECK, ZIF_DA_RULE_MATCHER, ZIF_DA_SYSTEM_CONTEXT and ZIF_DA_AUTHORIZATION, each with a production implementation, injected through the constructor of ZCL_DA_VARIANTS or the local factory of the behavior pool.
  • Message class ZDA; ZCX_DA_VARIANTS names every message as a constant and implements IF_ABAP_BEHV_MESSAGE, so the same object serves API and RAP.
  • use etag on the projection behavior definition.
  • 23 new unit tests (146 in total): authorizations, stamping, exception contract, repository, rule matcher, constructor.
Changed
  • Objects renamed to the project naming convention: ZDA_VARIANTS → ZTDA_VARIANTS, ZDA_VARIANTS_D → ZTDA_VARIANTS_D, ZI_DA_VARIANTS → ZR_DA_VARIANTS (view entity, behavior definition, access control), ZBP_I_DA_VARIANTS → ZBP_R_DA_VARIANTS. Existing configuration rows must be copied to the new table.
  • Delivery class of the configuration table is now C (customizing).
  • zcl_da_variants split into a repository, a value checker and a rule matcher; the public API behind ZIF_DA_VARIANTS is unchanged. check_value and data_element_exists moved to ZIF_DA_VALUE_CHECK.
  • Installation no longer requires editing default_packages: the shipped table needs no package list, an injected table takes the caller's list.
  • The numbering handler reads the stored counters through the repository in one round trip instead of one SELECT per entity.
  • matches renamed to avoid shadowing the built-in function.
Fixed
  • RAP unit tests no longer depend on the PFCG authorizations, the user or the clock of the system they run on.
  • Obsolete IS REQUESTED replaced by IS SUPPLIED.
  • An unknown data element was reported twice in the Fiori application.
  • The instance authorization handler ignored requested_authorizations.
  • Two sided mapping assertions in the tests were split so that a failure names the concept that broke.
  1. v2.1.0

    Features 5, Fixes 4

    Notes
    Added
    • map_value: classifies one value against the configured rules, comparing in the configured DDIC type, with exclude semantics and first-rule-wins ordering.
    • delete_variant: idempotent removal of one row or a whole parameter, returning the number of rows removed.
    • check_value as a public class method, shared by the API and the RAP validation checkValueTypes, rejecting values their data element could not hold unchanged (CHAR truncation, NUMC filtering, impossible dates and times).
    • Unit tests for both RAP value help query providers, including a regression test for the paging contract.
    • README sections for map_value, delete_variant, What's New and Known Limitations.
    Fixed
    • Six defects found while extending the test suite, covered by ltc_defects.
    • Message truncation in the Fiori application: RAP message texts longer than the message variable were cut silently.
    • Early numbering could wrap the counter to 00000 when the key range was exhausted; it is now reported as an error.
    • Values with trailing blanks in CHAR30 fields were compared incorrectly.
  2. v2.0.0dated in the atlas

    Removed 1, Features 7, Changed 2

    Notes
    Added
    • ZIF_DA_VARIANTS interface in front of ZCL_DA_VARIANTS, with enumerated types for sign and option.
    • set_variant: programmatic creation and replacement of variants with the same validations the Fiori application applies.
    • Authorization object ZDA_VAR (fields ACTVT, ZDA_PROG), authorization class ZDA, DCL role on the root view entity, global and instance authorization handlers in the behavior pool.
    • RAP validations checkDataElements and checkRangeConsistency, determination setDefaults, early numbering of the counter.
    • Own domains and data elements (ZDO_DA_*, ZDE_DA_*) for every column of the configuration table.
    • Value help query providers ZCL_DA_SIGN_VH and ZCL_DA_OPTION_VH reading domain fixed values; ZCX_DA_QUERY.
    • Unit tests for the behavior pool.
    Changed
    • ZCL_DA_VARIANTS rewritten with modern syntax, class-based error handling and RTTS based type conversion.
    • Lock master uses LastChangedAt as total etag.
    Removed
    • ZI_DA_DATAELEMENT_VH.
  3. v1.0.0

    Features 4

    Notes
    Added
    • Runtime parameter framework replacing hardcoded values and TVARVC: configuration table ZDA_VARIANTS, ZCL_DA_VARIANTS with get_variant building single values, ranges and mapping tables at runtime.
    • RAP managed, draft-enabled Fiori Elements application (ZI_DA_VARIANTS, ZC_DA_VARIANTS, ZUI_DA_VARIANTS, ZUI_DA_VARIANTS_O4).
    • ABAP Unit tests on the OSQL Test Double Framework.
    • abaplint configuration for ABAP for Cloud Development.
Configuration
  1. config-managementTheme, CSS and CSP settings of abap2UI5 pages kept in tables
  2. abaKLibrary for managing ABAP constants from registered sources
  3. aqoABAP application options as a structure with a generated editor
  4. abap-gencustGeneric customizing table and reader for ad hoc ABAP parameters
  5. abap-tvarvcHelper class for reading TVARVC parameters and select-options

Details

Sources3
dotabapdiscovered herechecked
github.com/greltel/abap-dynamic-assignmenttree, pushes, contributors, CIchecked
README.mdquoted, and what the entry declareschecked

Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.

Compatibility and provenance
discovered viadotabap
first seen in the atlas
ecosystem and domainabap, operations-and-runtime
abaplint
issues under its own abaplint configuration0
lines7,099
statements3,729
objects52
files41
analysed, main
abaplint version2.120.84
Flavors1
ABAP Cloud
“Written for ABAP for Cloud Development.” — greltel/abap-dynamic-assignment — README, Key Benefitschecked
History in the atlas1
  1. First seen.
For your agent
Ref
artifact:greltel-abap-dynamic-assignment
JSON
/artifacts/greltel-abap-dynamic-assignment.json
MCP
Connecting an agent