rplantiko

Grouping a string in blocks

Mar 26th, 2020
1,102
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. *&---------------------------------------------------------------------*
  2. *& Report ZZ_DIGIT_GROUPS
  3. *&---------------------------------------------------------------------*
  4. *& Zeichenfolge von rechts in Fünferblöcke gruppieren
  5. *& (wie in ESR-Einzahlungsscheinen die Referenznummern)
  6. *&---------------------------------------------------------------------*
  7. *& Es ist gut, sich in Übungsaufgaben dieser Art zu erproben,
  8. *& nicht weil es eine konkrete Arbeitsaufgabe wäre,
  9. *& sondern um sich an ihr zu fragen:
  10. *&  • Was hat man für Möglichkeiten (Ideen für Algorithmen finden)?
  11. *&  • Wird es besser unter Zuhilfenahme neuerer ABAP-Funktionen?
  12. *&  • Wie lesbar wird der Code?
  13. *&  • Wie lesbar bekommt man ihn überhaupt hin?
  14. *&  • Und was für Vor- und Nachteile haben die Alternativen?
  15. *&---------------------------------------------------------------------*
  16. *& Ideen für Algorithmen
  17. *&---------------------------------------------------------------------*
  18. *& CONVERT_WITH_OFFSET :
  19. *& Offset-Zeiger wandert von rechts in Fünferschritten durch den String
  20. *& CONVERT_WITH_SHIFT  :
  21. *& Die Funktion shift_right( ) schiebt Fünferblöcke nach rechts
  22. *& CONVERT_WITH_REGEX  :
  23. *& Globaler Replace des Ausdrucks `(.{5})` durch `$1 `
  24. *&---------------------------------------------------------------------*
  25. report zz_digit_groups.
  26.  
  27.  
  28. field-symbols: <p_digits> type c.
  29.    " Nur für Algorithmen, die ein Typ-C-Feld benötigen
  30.    " Unterprogramm to_char generiert ein C-Feld dynamischer Länge
  31.  
  32. parameters: p_digits type string
  33.               default '212190109010077040007'
  34.               lower case. "(Es dürfte auch alles mit Buchstaben funktionieren)
  35.  
  36. selection-screen comment /35(82) result.
  37.  
  38.  
  39. selection-screen skip.
  40. parameters: p_width type n length 3 default 0.
  41.  
  42. selection-screen skip.
  43. parameters:
  44.   p_shift  radiobutton group 001 default 'X',
  45.   p_regex  radiobutton group 001,
  46.   p_offset radiobutton group 001.
  47.  
  48. at selection-screen output.
  49.   perform convert.
  50.  
  51. at selection-screen on p_width.
  52.   p_digits = |{ p_digits alpha = in width = p_width }|.
  53.  
  54. at selection-screen.
  55.   condense p_digits no-gaps.
  56.  
  57. form convert.
  58.   if p_shift eq 'X'.
  59.     perform convert_with_shift.
  60.   elseif p_regex eq 'X'.
  61.     perform convert_with_regex.
  62.   elseif p_offset eq 'X'.
  63.     perform convert_with_offset.
  64.   endif.
  65. endform.
  66.  
  67. form convert_with_shift.
  68.  
  69.   clear result.
  70.  
  71. * Idee: iterativ mit SHIFT 5 Stellen nach rechts schieben
  72. * Dieser Algorithmus konsumiert den Input
  73.  
  74.   data(lv_input) = p_digits.
  75.   while count_any_not_of( val = lv_input sub = ` ` ) >= 5.
  76.     result = substring_before(
  77.                val = lv_input
  78.                regex = `$`
  79.                len = 5 )
  80.            && ` ` && result.
  81.     lv_input = shift_right( val = lv_input places = 5 ).
  82.   endwhile.
  83.  
  84.   result = condense( lv_input && ` ` && result ).
  85.  
  86. endform.
  87.  
  88. form convert_with_regex.
  89.  
  90. * Idee: Fünfergruppen mit dem Muster (.{5}) finden und durch `$1 ` ersetzen
  91. * Damit das funktioniert, muß man anfangs den String
  92. * durch führende Leerzeichen auf eine durch 5 teilbare Länge bringen.
  93.  
  94. * Zahl der benötigten Stellen, um p_digits zu Fünferblöcken aufzustocken
  95.   data(lv_diff)  = 5 * ( ( strlen( p_digits ) + 4 ) div 5 ) - strlen( p_digits ).
  96.  
  97. * Leerzeichen vorne anfügen
  98.   data(lv_digits) = repeat( val = ` ` occ = lv_diff ) && p_digits.
  99.  
  100.   data(lv_result) = replace(
  101.       val = lv_digits
  102. * Fünferblöcke finden und in der ersten Capture Group einfangen
  103.       regex = `(.{5})`
  104. * OCC = 0 heißt: alle Treffer ersetzen
  105.       occ = 0
  106. * Jeweils ein Leerzeichen anfügen
  107.       with = `$1 `  ).
  108.  
  109. * Das eine schließende Leerzeichen entfernen
  110.   result = condense( lv_result ).
  111.  
  112. endform.
  113.  
  114.  
  115. form convert_with_offset.
  116.  
  117.   clear result.
  118.  
  119. * Idee: ein Zeiger wandert den String rückwärts in Fünferschritten
  120.  
  121.   data(lv_offset) = strlen( p_digits ) - 5.
  122.   while lv_offset >= 0.
  123.     result = p_digits+lv_offset(5) && ` ` && result.
  124.     subtract 5 from lv_offset.
  125.   endwhile.
  126.  
  127.   result = condense(
  128.     substring( val = p_digits off = 0 len = 5 + lv_offset )
  129.     && ` ` && result
  130.   ).
  131.  
  132. endform.
  133.  
  134. * Falls für einen Algorithmus nötig, die eingegebene Ziffernfolge in ein Typ C-Feld der nötigen Länge verwandeln
  135. * War in den drei hier vorgestellten Lösungen nicht nötig
  136. form to_char.
  137.   data: lv_char type ref to data,
  138.         lv_len  type i.
  139.   lv_len = strlen( p_digits ).
  140.   create data lv_char type c length lv_len.
  141.   assign lv_char->* to <p_digits>.
  142.   <p_digits> = p_digits.
  143. endform.
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×