Code: Alles auswählen.
LOOP AT userp.
IF userp-gltgb < sy-datum.
* FREE lt_return. "wenn nur ein Datensatz übermittelt werden soll.
MOVE userp-parid to lt_return-parid.
MOVE userp-parva to lt_return-parva.
MOVE userp-bname to lt_return-partext. "zur Kontrolle
APPEND lt_return.
ELSE.
ENDIF.
ENDLOOP.
LOOP AT lt_return.
READ TABLE userp WITH KEY bname = lt_return-partext.
MOVE 'PER' to lt_return-parid.
MOVE userp-zpernr to lt_return-parva.
APPEND lt_return. "nun ein Datensatz mehr
CLEAR lt_return.
CALL FUNCTION 'SUSR_USER_PARAMETERS_PUT'
EXPORTING
USER_NAME = userp-bname
TABLES
USER_PARAMETERS = lt_return.
CALL FUNCTION 'SUSR_USER_BUFFERS_TO_DB'
EXCEPTIONS
NO_LOGONDATA_FOR_NEW_USER = 1
NO_INIT_PASSWORD = 2
DB_INSERT_USR02_FAILED = 3
DB_UPDATE_USR02_FAILED = 4
DB_INSERT_USR01_FAILED = 5
DB_UPDATE_USR01_FAILED = 6
DB_INSERT_USR05_FAILED = 7
DB_UPDATE_USR05_FAILED = 8
DB_INSERT_USR21_FAILED = 9
DB_UPDATE_USR21_FAILED = 10
INTERNAL_ERROR = 11
OTHERS = 12.
CLEAR lt_return.
ENDLOOP.
Ich nehme mal an man muss vorher immer erst die bereits vorhandenen Parameter einlesen, den neuen Parameter dazu nehmen und dann den Fuba-Aufruf mit allen Parametern machen. Den alten sowie den dazugekommenen.Suta_K hat geschrieben:Mein nächstes Problem war aber, dass wenn ich nur den "einzelnen" Satz einlese, dass der FB dann alle meine vorhandenen Parameter im User rauschmeißt und nur den PER Parameter einträgt. Vorschläge?
Code: Alles auswählen.
REPORT ZTEST4.
DATA: BEGIN OF USERP OCCURS 0,
ZPERNR TYPE PERSNO,
GLTGB TYPE ENDDA,
BNAME TYPE UNAME,
PARID TYPE MEMORYID,
PARVA TYPE XUVALUE,
PARTEXT TYPE AS4TEXT,
END OF USERP,
LT_RETURN TYPE USTYP_T_PARAMETERS WITH HEADER LINE,
PER_IST_VORHANDEN TYPE C,
NAECHSTER_EINTRAG LIKE USERP,
ANZAHL_ZEILEN_IN_USERP TYPE I.
START-OF-SELECTION.
SORT USERP BY BNAME. " wichtig, sonst klappt mein simulierter AT END OF nicht
DESCRIBE TABLE USERP LINES ANZAHL_ZEILEN_IN_USERP.
LOOP AT USERP.
IF USERP-GLTGB < SY-DATUM.
MOVE USERP-PARID TO LT_RETURN-PARID.
MOVE USERP-BNAME TO LT_RETURN-PARTEXT. "zur Kontrolle
CASE USERP-PARID.
WHEN 'PER'.
MOVE USERP-ZPERNR TO LT_RETURN-PARVA.
PER_IST_VORHANDEN = 'X'.
WHEN OTHERS.
MOVE USERP-PARVA TO LT_RETURN-PARVA.
ENDCASE.
APPEND LT_RETURN.
* AT END OF simulieren, da ich nicht weiß, ob BNAME das erste Feld in USERP ist (nächstes Mal bitte kompletten Code oder zumindest die Typisierungen angeben!)
* Ab Release 7.40 wäre auch ein LOOP AT ... GROUP BY denkbar
IF SY-TABIX < ANZAHL_ZEILEN_IN_USERP. " oder LINES() verwenden, wenn Releasestand ausreichend hoch
READ TABLE USERP INTO NAECHSTER_EINTRAG INDEX SY-TABIX + 1.
ELSE.
CLEAR NAECHSTER_EINTRAG. " dann ist der folgende IF immer wahr
ENDIF.
IF NAECHSTER_EINTRAG-BNAME <> USERP-BNAME. " wenn aktuelle LOOP-Zeile letzten Parameter dieses Users enthält (deswegen oben der SORT vor dem LOOP)
IF PER_IST_VORHANDEN IS INITIAL. " war für diesen User ein alter Parameter PER dabei?
* Parameter PER hinzufügen, wenn er bisher noch nicht da war
MOVE 'PER' TO LT_RETURN-PARID.
MOVE USERP-ZPERNR TO LT_RETURN-PARVA.
APPEND LT_RETURN.
ENDIF.
CALL FUNCTION 'SUSR_USER_PARAMETERS_PUT'
EXPORTING USER_NAME = USERP-BNAME
TABLES USER_PARAMETERS = LT_RETURN.
CLEAR PER_IST_VORHANDEN. " leermachen für nächste Userkennung
REFRESH LT_RETURN.
ENDIF.
ENDIF.
ENDLOOP.
CALL FUNCTION 'SUSR_USER_BUFFERS_TO_DB'
EXCEPTIONS
NO_LOGONDATA_FOR_NEW_USER = 1
NO_INIT_PASSWORD = 2
DB_INSERT_USR02_FAILED = 3
DB_UPDATE_USR02_FAILED = 4
DB_INSERT_USR01_FAILED = 5
DB_UPDATE_USR01_FAILED = 6
DB_INSERT_USR05_FAILED = 7
DB_UPDATE_USR05_FAILED = 8
DB_INSERT_USR21_FAILED = 9
DB_UPDATE_USR21_FAILED = 10
INTERNAL_ERROR = 11
OTHERS = 12.
So ist es auch der richtige Weg. Die Userkennung gehört in den Infotyp 105 Subtyp 0001 der Personalnummer. Dort erwartet SAP sie auch, und dann hast Du auch beide Richtung effizient im Suchzugriff (da die PA0105 einen Sekundärindex auf USRTY/USRID hat, kannst Du mit USRTY = '0001', USRID = Benutzername effizient die Personalnummer suchen).In meiner alten Firma haben wir im aktiven Personalstamm die User ID hinterlegt (also entgegengesetzter Weg).
Kleiner Bug in meinem Coding. SY-TABIX wird vom LOOP gesetzt, vom APPEND jedoch auch (bzgl. der Tabelle LT_RETURN), so dass wir dann die Zeilennummer aus der falschen Tabelle in SY-TABIX zu stehen haben. Diesen Umstand habe ich übersehen; wie gesagt, ich hatte mein Coding nicht getestet.Trotz dessen, dass wir hier die Methode aus meiner alten Firma (User in PerNr) übernehmen, würde mich dennoch interessieren, warum der sy-tabix nach einem erfolgreichen Lauf beim 1. User, dann bei allen Folgeuser immer bei 1 anfängt.
Code: Alles auswählen.
REPORT ZTEST4.
DATA: BEGIN OF USERP OCCURS 0,
ZPERNR TYPE PERSNO,
GLTGB TYPE ENDDA,
BNAME TYPE UNAME,
PARID TYPE MEMORYID,
PARVA TYPE XUVALUE,
PARTEXT TYPE AS4TEXT,
END OF USERP,
LT_RETURN TYPE USTYP_T_PARAMETERS WITH HEADER LINE,
PER_IST_VORHANDEN TYPE C,
NAECHSTER_EINTRAG LIKE USERP,
ANZAHL_ZEILEN_IN_USERP TYPE I,
TABIX_MERKER LIKE SY-TABIX.
START-OF-SELECTION.
SORT USERP BY BNAME. " wichtig, sonst klappt mein simulierter AT END OF nicht
DESCRIBE TABLE USERP LINES ANZAHL_ZEILEN_IN_USERP.
LOOP AT USERP.
TABIX_MERKER = SY-TABIX.
IF USERP-GLTGB < SY-DATUM.
MOVE USERP-PARID TO LT_RETURN-PARID.
MOVE USERP-BNAME TO LT_RETURN-PARTEXT. "zur Kontrolle
CASE USERP-PARID.
WHEN 'PER'.
MOVE USERP-ZPERNR TO LT_RETURN-PARVA.
PER_IST_VORHANDEN = 'X'.
WHEN OTHERS.
MOVE USERP-PARVA TO LT_RETURN-PARVA.
ENDCASE.
APPEND LT_RETURN.
* AT END OF simulieren, da ich nicht weiß, ob BNAME das erste Feld in USERP ist (nächstes Mal bitte kompletten Code oder zumindest die Typisierungen angeben!)
* Ab Release 7.40 wäre auch ein LOOP AT ... GROUP BY denkbar
IF TABIX_MERKER < ANZAHL_ZEILEN_IN_USERP. " oder LINES() verwenden, wenn Releasestand ausreichend hoch
READ TABLE USERP INTO NAECHSTER_EINTRAG INDEX TABIX_MERKER + 1.
ELSE.
CLEAR NAECHSTER_EINTRAG. " dann ist der folgende IF immer wahr
ENDIF.
IF NAECHSTER_EINTRAG-BNAME <> USERP-BNAME. " wenn aktuelle LOOP-Zeile letzten Parameter dieses Users enthält (deswegen oben der SORT vor dem LOOP)
IF PER_IST_VORHANDEN IS INITIAL. " war für diesen User ein alter Parameter PER dabei?
* Parameter PER hinzufügen, wenn er bisher noch nicht da war
MOVE 'PER' TO LT_RETURN-PARID.
MOVE USERP-ZPERNR TO LT_RETURN-PARVA.
APPEND LT_RETURN.
ENDIF.
CALL FUNCTION 'SUSR_USER_PARAMETERS_PUT'
EXPORTING USER_NAME = USERP-BNAME
TABLES USER_PARAMETERS = LT_RETURN.
CLEAR PER_IST_VORHANDEN. " leermachen für nächste Userkennung
ENDIF.
ENDIF.
ENDLOOP.
CALL FUNCTION 'SUSR_USER_BUFFERS_TO_DB'
EXCEPTIONS
NO_LOGONDATA_FOR_NEW_USER = 1
NO_INIT_PASSWORD = 2
DB_INSERT_USR02_FAILED = 3
DB_UPDATE_USR02_FAILED = 4
DB_INSERT_USR01_FAILED = 5
DB_UPDATE_USR01_FAILED = 6
DB_INSERT_USR05_FAILED = 7
DB_UPDATE_USR05_FAILED = 8
DB_INSERT_USR21_FAILED = 9
DB_UPDATE_USR21_FAILED = 10
INTERNAL_ERROR = 11
OTHERS = 12.