Просто подкаст. На подлодке. Просто один эпизод про 1C.
Рассказывает про 1С, но при случае вспоминает SAP … или не вспоминает ;-)
против Энтропии
Просто подкаст. На подлодке. Просто один эпизод про 1C.
Рассказывает про 1С, но при случае вспоминает SAP … или не вспоминает ;-)
Ну допустим, я показал ему текст некоторой программы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
REPORT y_bc001_text_search. TABLES: tadir. SELECT-OPTIONS: s_devc FOR tadir-devclass DEFAULT 'Z*' OPTION CP. SELECT-OPTIONS: s_objec FOR tadir-object. SELECT-OPTIONS: s_objnm FOR tadir-obj_name DEFAULT 'Z*' OPTION CP. PARAMETERS: p_text TYPE string. START-OF-SELECTION. SELECT tadir~pgmid, tadir~object, tadir~obj_name, trdir~subc, tadir~devclass FROM tadir LEFT OUTER JOIN trdir ON tadir~object = 'PROG' AND tadir~obj_name = trdir~name INTO TABLE @DATA(lt_objects) WHERE tadir~devclass IN @s_devc AND tadir~object IN @s_objec AND tadir~obj_name IN @s_objnm AND ( tadir~object = 'PROG' OR tadir~object = 'FUGR' OR tadir~object = 'CLAS' ). LOOP AT lt_objects ASSIGNING FIELD-SYMBOL(<object>). IF <object>-object = 'PROG' AND ( <object>-subc = '1' OR <object>-subc = 'M' ). DATA: lt_tpool TYPE STANDARD TABLE OF textpool WITH DEFAULT KEY. CALL FUNCTION 'RS_TEXTPOOL_READ' EXPORTING objectname = <object>-obj_name action = 'READ' * AUTHORITY_CHECK = ' ' language = sy-langu TABLES tpool = lt_tpool EXCEPTIONS object_not_found = 1 permission_failure = 2 invalid_program_type = 3 error_occured = 4 action_cancelled = 5 OTHERS = 6. IF sy-subrc <> 0. * Implement suitable error handling here ENDIF. LOOP AT lt_tpool ASSIGNING FIELD-SYMBOL(<tpool>). IF <tpool>-id = 'I' AND <tpool>-entry CP p_text. WRITE: <object>-obj_name, <tpool>-key, <tpool>-entry. ENDIF. ENDLOOP. ELSEIF <object>-object = 'FUGR'. DATA: lv_fugr TYPE rs38m-programm. lv_fugr = 'SAPL' && <object>-obj_name. CALL FUNCTION 'RS_TEXTPOOL_READ' EXPORTING objectname = lv_fugr action = 'READ' * AUTHORITY_CHECK = ' ' language = sy-langu TABLES tpool = lt_tpool EXCEPTIONS object_not_found = 1 permission_failure = 2 invalid_program_type = 3 error_occured = 4 action_cancelled = 5 OTHERS = 6. IF sy-subrc <> 0. * Implement suitable error handling here ENDIF. LOOP AT lt_tpool ASSIGNING <tpool>. IF <tpool>-id = 'I' AND <tpool>-entry CP p_text. WRITE: <object>-obj_name, <tpool>-key, <tpool>-entry. ENDIF. ENDLOOP. ELSEIF <object>-object = 'CLAS'. DATA: lv_clas TYPE rs38m-programm. lv_clas = <object>-obj_name. DATA(lv_eq_count) = 30 - strlen( lv_clas ). DO lv_eq_count TIMES. lv_clas = lv_clas && '='. ENDDO. lv_clas = lv_clas && 'CP'. CALL FUNCTION 'RS_TEXTPOOL_READ' EXPORTING objectname = lv_clas action = 'READ' * AUTHORITY_CHECK = ' ' language = sy-langu TABLES tpool = lt_tpool EXCEPTIONS object_not_found = 1 permission_failure = 2 invalid_program_type = 3 error_occured = 4 action_cancelled = 5 OTHERS = 6. IF sy-subrc <> 0. * Implement suitable error handling here ENDIF. LOOP AT lt_tpool ASSIGNING <tpool>. IF <tpool>-id = 'I' AND <tpool>-entry CP p_text. WRITE: <object>-obj_name, <tpool>-key, <tpool>-entry. ENDIF. ENDLOOP. ENDIF. ENDLOOP. END-OF-SELECTION. WRITE: / 'Search completed:', p_text. |
Так вот, сервис может пояснить за код, лучше чем я:
(далее…)Есть в ABAP кое-какие языковые конструкции, отсутствующие в топовых языках, по крайней мере на базовом уровне, например MOVE-CORRESPONDING.
VARYING — это одна из таких конструкций. Я изредка использовал её в базовом варианте:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
DATA: BEGIN OF ls_varstr, cod01 TYPE char20, cod02 TYPE char20, cod03 TYPE char20, cod04 TYPE char20, END OF ls_varstr. ls_varstr = VALUE #( cod01 = '001' cod02 = '002' cod03 = '003' cod04 = '004' ). DATA: lv_code TYPE char20. DO 4 TIMES VARYING lv_code FROM ls_varstr-cod01 NEXT ls_varstr-cod02. WRITE: / lv_code. ENDDO. |
Результат предсказуем:
Но как иногда оказывается, у этой конструкции есть две дополнительных глубины.
Во-первых, можно крутить два поля одновременно:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
DATA: BEGIN OF ls_varstr, cod01 TYPE char20, val01 TYPE char100, cod02 TYPE char20, val02 TYPE char100, cod03 TYPE char20, val03 TYPE char100, cod04 TYPE char20, val04 TYPE char100, END OF ls_varstr. ls_varstr = VALUE #( cod01 = '001' val01 = 'First' cod02 = '002' val02 = 'Second' cod03 = '003' val03 = 'Third' cod04 = '004' val04 = 'Fofth' ). DATA: lv_code TYPE char20. DATA: lv_value TYPE char100. DO 4 TIMES VARYING lv_code FROM ls_varstr-cod01 NEXT ls_varstr-cod02 VARYING lv_value FROM ls_varstr-val01 NEXT ls_varstr-val02. WRITE: / lv_code, '=', lv_value . ENDDO. |
И оказывается так тоже можно, результат не удивит:
А во-вторых, поля в последовательности могут называться как угодно.
Мне раньше казалось, что нумерация в поле очень важна: VAL01, VAL02. Магия! А вот нет. Так тоже можно:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
DATA: BEGIN OF ls_varstr, first TYPE char20, second TYPE char20, i-do-not-know TYPE char20, wtf TYPE char20, END OF ls_varstr. ls_varstr = VALUE #( first = '001' second = '002' i-do-not-know = '003' wtf = '004' ). DATA: lv_code TYPE char20. DO 4 TIMES VARYING lv_code FROM ls_varstr-first NEXT ls_varstr-second. WRITE: / lv_code. ENDDO. |
Если чуть подумать, то станет всё понятнее, как оно было заложено и почему. Могу проиллюстрировать на менее интуитивно понятном примере:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
DATA: BEGIN OF ls_varstr, cod01 TYPE char20, val01 TYPE char100, cod02 TYPE char20, val02 TYPE char100, cod03 TYPE char20, val03 TYPE char100, cod04 TYPE char20, val04 TYPE char100, other TYPE text60, fields TYPE text60, END OF ls_varstr. ls_varstr = VALUE #( cod01 = '001' val01 = 'First' cod02 = '002' val02 = 'Second' cod03 = '003' val03 = 'Third' cod04 = '004' val04 = 'Fofth' other = 'Other~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' fields = 'Fields~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' ). DATA: lv_code TYPE char20. DATA: lv_value TYPE char100. DO 5 TIMES VARYING lv_code FROM ls_varstr-cod01 NEXT ls_varstr-cod02 VARYING lv_value FROM ls_varstr-val01 NEXT ls_varstr-val02. WRITE: / lv_code, '=', lv_value . ENDDO. |
Обратите внимание на DO 5 TIMES. Ха-ха? Знаете что произойдёт?
(далее…)Недавно упомянули эту шутку в одном моём любимом подкасте, загуглил ответ, для меня открылись бездны смысла.
Для того, чтобы корова меньше ела и давала больше молока, (далее…)
Не все знают, но не обязательно писать Z-программы. Подсказываю: можно вместо этого писать и Y-программы во избежание чего-бы-то-ни-было.
Пробежала статья сегодня: Hello, SAP, Where Are My Global Classes?
Автор жалуется что классы как бы глобальные, а всё равно система всё больше и больше становится кладбищем велосипедов. Ничего найти нельзя, проще придумать очередной велосипед.
И тут же у меня возник резонанс: пробежал баг с неправильным расчётом и там важно было учесть количество дней между двумя датами.
В предыдущей редакции предыдущим автором использовал следующий подход:
1 2 3 4 |
CALL FUNCTION 'DAYS_BETWEEN_TWO_DATES' IMPORTING e_tage = lv_days. lv_days = v_days + 1. |
Хорошо, вот только теперь говорят, что дни надо считать только рабочие.
Вот и снова мы попадаем на кладбище велосипедов, хочешь RKE_SELECT_FACTDAYS_FOR_PERIOD, а можно и DURATION_DETERMINE, но наверняка способов ещё немало. И найти их проще через гугл, чем непосредственно в системе.
Безопасники — такие безопасники!
Есть же инструкция — надо менять пароли регулярно. Значит есть настройка — принудительная смена паролей. Сделали всё по инструкции, работа такая, думать не надо!
Ну и вот есть у меня три SAP системы, в каждой трёх-системный ландшафт, плюс домен.
Десять паролей, все разные. Вроде выполнили требования безопасности, а стало ли безопаснее?
А как внедрять Single Sign On (SSO) — так такой инструкции нет. Это сложно, думать надо, решать.
SAP пишет:
Economic sanctions against Russia are an important mechanism in the efforts to restore peace. We are in constant exchange with governments around the world, have every confidence in their guidance, and fully support the actions taken so far. We are stopping business in Russia aligned with sanctions and, in addition, pausing all sales of SAP services and products in Russia.
Вот такой ответ из коллективной Европы.
Сегодня Заказчик попросил у Подрядчика (нас) табличку:
Наименование информационной системы | Текущий уровень актуальности сведений | Общее количество записей в системе или базе данных | Перечень хранимых объектов данных |
Ну а что, очевидно же, в системе есть БД, БД измеряются в записях. Много записей — большая база, мало записей — маленькая база. Сразу всё понятно.
В общем наши сразу пошли к администратору, а он открыл Oracle SQL Developer и написал там:
select sum(NUM_ROWS) from DBA_TABLES where OWNER=’SAPR3′
И получил число (барабанная дробь)… (далее…)