Aber wie genau muss der beschaffen sein, damit er genutzt wird? Beim READ TABLE ist es ja so, dass dieser sich an der Tabelleneigenschaft SORTED oder HASHED orientiert, sofern der angegebene Schlüssel zum entsprechenden Tabellenschlüssel passt. Bei STANDARD TABLEs kann man BINARY SEARCH angeben, so wie Du es bei Deinem Beispiel gemacht hast.Man braucht aber dafür einen passenden Index auf der Tabelle, sonst kann das schneckig werden. Aber dafür sind Indizes ja da.
Code: Alles auswählen.
*&---------------------------------------------------------------------*
*& Report ZTEST_TABLE_SEARCH
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZTEST_TABLE_SEARCH.
DATA: T_STANDARD TYPE STANDARD TABLE OF PERSNO WITH HEADER LINE,
T_SORTED TYPE SORTED TABLE OF PERSNO WITH UNIQUE DEFAULT KEY WITH HEADER LINE,
T_HASHED TYPE HASHED TABLE OF PERSNO WITH UNIQUE DEFAULT KEY WITH HEADER LINE,
I TYPE I,
J TYPE I,
RUNTIME TYPE I.
PARAMETERS: ENTRIES TYPE I OBLIGATORY.
*** START-OF-SELECTION ***
START-OF-SELECTION.
* Fill standard table
GET RUN TIME FIELD I.
DO ENTRIES TIMES.
T_STANDARD = SY-INDEX.
INSERT TABLE T_STANDARD.
ENDDO.
GET RUN TIME FIELD J.
RUNTIME = J - I.
WRITE: / 'Fill Standard table:', RUNTIME.
* Fill sorted table
GET RUN TIME FIELD I.
DO ENTRIES TIMES.
T_SORTED = SY-INDEX.
INSERT TABLE T_SORTED.
ENDDO.
GET RUN TIME FIELD J.
RUNTIME = J - I.
WRITE: / 'Fill Sorted table:', RUNTIME.
* Fill hashed table
GET RUN TIME FIELD I.
DO ENTRIES TIMES.
T_HASHED = SY-INDEX.
INSERT TABLE T_HASHED.
ENDDO.
GET RUN TIME FIELD J.
RUNTIME = J - I.
WRITE: / 'Fill Hashed table:', RUNTIME.
* Search standard table
GET RUN TIME FIELD I.
READ TABLE T_STANDARD WITH KEY TABLE_LINE = T_STANDARD.
GET RUN TIME FIELD J.
RUNTIME = J - I.
WRITE: / 'Search last entry of Standard table:', RUNTIME.
* Search sorted table
GET RUN TIME FIELD I.
READ TABLE T_SORTED WITH KEY TABLE_LINE = T_STANDARD.
GET RUN TIME FIELD J.
RUNTIME = J - I.
WRITE: / 'Search last entry of Sorted table:', RUNTIME.
* Search hashed table
GET RUN TIME FIELD I.
READ TABLE T_HASHED WITH KEY TABLE_LINE = T_STANDARD.
GET RUN TIME FIELD J.
RUNTIME = J - I.
WRITE: / 'Search last entry of Hashed table:', RUNTIME.
SKIP.
WRITE 'Results are in micro seconds.'.
Das ist auch so eine Verwendung, die ich kapsele..... Wenn es sich lohnt, in eine SORTED kopieren und damit arbeiten.zzcpak hat geschrieben:chic!
Bei mir erübrigt sich die Frage nach dem Tabellen-Typ. Der RFC-Fuba liefert die interne Tabelle als TABLES Parameter und da meckert er, wenn ich ihm was anderes als STANDARD TABLE serviere.
Mit guter Performance wird das aber in vielen Fällen nichts zu tun haben, Schlüssel oder nicht. Wenn Du mein obiges Testprogramm mal ausprobiert hast, dann siehst Du, dass selbst im ungünstigsten Fall (letzter Eintrag ist der richtige) bei satten 10.000 Tabelleneinträgen die Arbeit mit einer sequentiell durchsuchten Standardtabelle schneller ist als mit einer SORTED TABLE. Natürlich hängt das immer von den Umständen ab. Wenn Du die Tabelle nur einmal im Programm befüllst, aber danach häufig durchsuchst, wird es sicherlich anders aussehen.Der Standard bei mir ist SORTED TABLE, STANDARD TABLE verwende ich nur für bestimmte Zwecke, die ich kapsele. Beispiel: Eine Datentabelle soll in einem ALV dargestellt werden, die Datentabelle ist vom Typ SORTED. Die Methode, die den ALV darstellt, nimmt die SORTED TABLE entgegen und kopiert die für Darstellungszwecke in ein STANDARD TABLE. *Arbeiten* werde ich nur mit der SORTED TABLE, eben weil ich da die Schlüssel habe.
Was bedeutet das? Dass ich die Syntax in ein TRY-ENDTRY-CATCH-Konstrukt verpacken muss, da sie mir sonst gnadenlos wegdumpt, wenn es die Zeile nicht gibt? Dann ist der Schönheitsvorteil aber schon wieder dahin. Mit diesem Block drumrum sieht das auch nicht mehr viel hübscher aus als mit IF SY-SUBRC...Bei der neuen Syntax muss man halt beachten, dass sie keinen sy-subrc wirft, sondern eine Ausnahme auslöst!
Wir können uns ja darauf einigen, bis zur Bereitstellung einer besseren Lösung ersatzweise geschweifte Klammern { } zu verwenden.PS: Irgendwas sollten die Admins sich überlegen, wie man hier eckige Klammern in code-Tags darstellen kann - du hast recht, das funktioniert auch mit den Tipps nicht.
Folgende Benutzer bedankten sich beim Autor DeathAndPain für den Beitrag:
Daniel
du dort gar keine Schlüssel verwendest. Weiter hab ich da gar nicht mehr geguckt.DeathAndPain hat geschrieben:Wenn Du mein obiges Testprogramm mal ausprobiert hast, dann siehst Du, dass
Natürlich, alles hängt immer vom Kontext ab.DeathAndPain hat geschrieben:Außerdem hängt es vom Kontext ab, ob eine Sortierung überhaupt Sinn macht.
Das führt dann aber dazu, dass man das Coding nicht mehr kopieren kann. Ich wäre gegen diese Einigung.DeathAndPain hat geschrieben:Wir können uns ja darauf einigen, bis zur Bereitstellung einer besseren Lösung ersatzweise geschweifte Klammern { } zu verwenden.PS: Irgendwas sollten die Admins sich überlegen, wie man hier eckige Klammern in code-Tags darstellen kann - du hast recht, das funktioniert auch mit den Tipps nicht.
Kommt auf den Kontext an *wiederholzzcpak hat geschrieben:Frisst die Kopieraktion den Geschwindigkeitsvorteil nicht wieder auf?
Gesteigerte Lesbarkeit, ja. Finde ich sehr wichtig.zzcpak hat geschrieben:Immerhin sieht "itab[ bedingung ]" deutlich chicer aus als die READ TABLE Arie.
Was ein Fehler ist, denn ich benutze sehr wohl Schlüssel. Alles andere würde der ABAP-Compiler bei SORTED und HASHED auch gar nicht zulassen.du dort gar keine Schlüssel verwendest. Weiter hab ich da gar nicht mehr geguckt.
Man kann ja hinterher ein Search&Replace machen. Damit wäre der Code im Forum gut lesbar, und wenn der Code es Dir wert ist, ihn in die SE38/Eclipse reinzukopieren, dann wird es an dem einen Arbeitsschritt ja hoffentlich nicht scheitern.Das führt dann aber dazu, dass man das Coding nicht mehr kopieren kann. Ich wäre gegen diese Einigung.
Nur leider geht sie weitgehend den Bach runter, wenn ich dafür dann ein fettes TRY-ENDTRY-CATCH-Konstrukt drumrumbauen muss.Gesteigerte Lesbarkeit, ja. Finde ich sehr wichtig.
Was ist gegen TRY einzuwenden? Einen TRY - ENDTRY Block gegenüber 10 und mehr SY-SUBRC Abfragen finde ich dann doch deutlich übersichtlicher.DeathAndPain hat geschrieben: Was bedeutet das? Dass ich die Syntax in ein TRY-ENDTRY-CATCH-Konstrukt verpacken muss, da sie mir sonst gnadenlos wegdumpt, wenn es die Zeile nicht gibt? Dann ist der Schönheitsvorteil aber schon wieder dahin. Mit diesem Block drumrum sieht das auch nicht mehr viel hübscher aus als mit IF SY-SUBRC...
Code: Alles auswählen.
rs_system_info-instance = iv_server_name.
READ TABLE it_bdi_log INTO ls_log
WITH KEY step = iv_server_name
tcode = 'HOSTNAME'.
IF sy-subrc = 0.
rs_system_info-shost = ls_log-comm.
ENDIF.
READ TABLE it_bdi_log INTO ls_log
WITH KEY tcode = 'SYSID'.
IF sy-subrc = 0.
rs_system_info-sysid = ls_log-comm.
ENDIF.
READ TABLE it_bdi_log INTO ls_log
WITH KEY tcode = 'SYS RELEASE'.
IF sy-subrc = 0.
rs_system_info-sys_release = ls_log-comm.
ENDIF.
READ TABLE it_bdi_log INTO ls_log
WITH KEY tcode = 'COMPONENT VERSION'.
IF sy-subrc = 0.
rs_system_info-comp_version = ls_log-comm.
ENDIF.
Code: Alles auswählen.
TRY.
rs_system_info-instance = iv_server_name.
rs_system_info-shost = it_bdi_log[ step = iv_server_name
tcode = 'HOSTNAME' ]-comm.
rs_system_info-sysid = it_bdi_log[ tcode = 'SYSID' ]-comm.
rs_system_info-sys_release = it_bdi_log[ tcode = 'SYS RELEASE' ]-comm.
rs_system_info-comp_version = it_bdi_log[ tcode = 'COMPONENT VERSION' ]-comm.
CATCH cx_sy_itab_line_not_found.
RETURN.
ENDTRY.
Folgende Benutzer bedankten sich beim Autor zzcpak für den Beitrag:
ralf.wenzel
Das sollte im Ausnahmeobjekt stehen.DeathAndPain hat geschrieben:Ja, wenn Du damit zufrieden bist, am Ende zu erfahren, dass Du mit irgendeiner Deiner Zuweisungen aufs Maul gefallen bist, ohne zu wissen mit welcher, dann gebe ich Dir recht.
Im Regelfall werde ich aber wissen wollen, welcher der Tabelleneinträge, auf die ich zugreife, gefehlt hat, um darauf individuell reagieren zu können (etwa mit einer aussagekräftigen Fehlermeldung statt eines allgemeinen "Fehler: Eine Zuweisung hat nicht hingehauen"). Damit aber brauchst Du um jede einzelne Deiner Zuweisungen einen TRY-ENDTRY-CATCH-Block! Und damit wird der Code echt hässlich.
Du kannst mit Ausnahmeklassen total viel machen. Bei Folgefehlern immer die alte Ausnahme als PREVIOUS übergeben, dann kannst du das Ganze am Ende auspacken und ein komplettes Fehlerprotokoll sehr detailliert ins Anwenderlog schreiben. Im Grunde genommen brauchst du vom User gar keine Fehlermeldung mehr (die sind eh meist nix wert), der User sagt "geht nicht" und alle Infos kriegst du aus dem Log. Geile Sache, das.DeathAndPain hat geschrieben:Ok, wenn das so ist, dann wird die Sache interessant. Ich bin davon ausgegangen, dass ich nur den Ausnahmetyp bekomme und das war es dann.
zzcpak hat geschrieben:Bei mir erübrigt sich die Frage nach dem Tabellen-Typ. Der RFC-Fuba liefert die interne Tabelle als TABLES Parameter und da meckert er, wenn ich ihm was anderes als STANDARD TABLE serviere.
Probiert mal eine Tabelle vom Typ "Standard Table" (damit der RFC-Fuba nicht meckert bzw. der ALV nicht dumpt wenn man die angezeigte Tabelle umsortiert ) mit einem sekundären sorted- oder hash-Schlüssel über den man nachher tatsächlich zugreift. Dann hat man "best of both worlds" mit dem Nachteil das SAP halt 2 Schlüssel verwalten muss bzw. man bei Zugriffen halt den Alternativschlüssel angeben muss.ralf.wenzel hat geschrieben:... Der Standard bei mir ist SORTED TABLE, STANDARD TABLE verwende ich nur für bestimmte Zwecke, die ich kapsele. Beispiel: Eine Datentabelle soll in einem ALV dargestellt werden, die Datentabelle ist vom Typ SORTED. Die Methode, die den ALV darstellt, nimmt die SORTED TABLE entgegen und kopiert die für Darstellungszwecke in ein STANDARD TABLE. *Arbeiten* werde ich nur mit der SORTED TABLE, eben weil ich da die Schlüssel habe.
ich denke mal dass es billiger ist 2 Indices zu verwalten als 2 identische Tabellen im Speicher vorhalten zu müssen?black_adept hat geschrieben:zzcpak hat geschrieben:Bei mir erübrigt sich die Frage nach dem Tabellen-Typ. Der RFC-Fuba liefert die interne Tabelle als TABLES Parameter und da meckert er, wenn ich ihm was anderes als STANDARD TABLE serviere.Probiert mal eine Tabelle vom Typ "Standard Table" (damit der RFC-Fuba nicht meckert bzw. der ALV nicht dumpt wenn man die angezeigte Tabelle umsortiert ) mit einem sekundären sorted- oder hash-Schlüssel über den man nachher tatsächlich zugreift. Dann hat man "best of both worlds" mit dem Nachteil das SAP halt 2 Schlüssel verwalten muss bzw. man bei Zugriffen halt den Alternativschlüssel angeben muss.ralf.wenzel hat geschrieben:... Der Standard bei mir ist SORTED TABLE, STANDARD TABLE verwende ich nur für bestimmte Zwecke, die ich kapsele. Beispiel: Eine Datentabelle soll in einem ALV dargestellt werden, die Datentabelle ist vom Typ SORTED. Die Methode, die den ALV darstellt, nimmt die SORTED TABLE entgegen und kopiert die für Darstellungszwecke in ein STANDARD TABLE. *Arbeiten* werde ich nur mit der SORTED TABLE, eben weil ich da die Schlüssel habe.