четверг, 1 декабря 2016 г.

Смена типа у инфо-объекта

Коллеги поделились инструкцией:

1. SE16 -> RSDCHABAS
Фильтруем: RCHABASNM = <имя инфообъекта> (версию не фильтруем).
Меняем поле DATATP: NUMC -> CHAR. Чтобы числовые значения приходили как и раньше, добавляем в поле CONVEXIT = 'ALPHA'.
Сохраняем каждое изменение.
2. SE16 -> RSDCHA
Фильтруем: CHABASNM = <имя инфообъекта>. Копируем все значения поля CHANM в файл.
3. SE16 -> RSDIOBJ.
Фильтруем: IOBJNM = CHANM из пункта 2 (все скопированные значения). Копируем значения поля FIELDNM в файлик.

4. SE16 -> DD01L.
Фильтруем: DOMNAME = /BIC/O<имя инфообъекта>, где <имя инфообъекта> из п.2.
В найденной строке меняем поле DATATYPE = 'CHAR'.
Сохраняем каждое изменение.
5. SE16 -> DD03L.
Фильтруем: FIELDNM = FIELDNM из п.3 (все значения).
В каждой строке меняем: INTTYPE = 'C', DATATYPE = 'CHAR'.
Сохраняем каждое изменение.
Возвращаемся на экран с выводом, копируем все значения поля TABNAME в файлик.
6. SE11 -> вставляем каждое значение из предыдущего пункта -> активация.

7. RSA1 -> Инфообъект -> Изменить -> Меняем описание (любой символ), чтобы он переактивировался при активации. -> Активируем -> Меняем описание назад -> Активируем
Такую же процедуру для всех инфообъектов из п.2.
8. Через журнал использования находим все DSO, инфоисточники, кубы, в которых он присутствует -> Изменить -> Активировать
9. Для всех трансформаций из/в цели данных из предыдущего пункта -> Изменить -> Активировать. То же самое для соответствующих DTP.

Готово.

понедельник, 16 мая 2016 г.

Новый синтаксис ABAP. Читаем поле из внутренней таблицы.


    data:
lt_mat_uom type hashed table of ts_mat_uom
        with unique key /BIC/ZMATERIA



    "Находим БЕИ для материала. Заодно и проверка целостности
    lv_tmp SOURCE_FIELDS-NNOM.
    try.
      RESULT lt_mat_uom[
        key PRIMARY_KEY components /BIC/ZMATERIA lv_tmp
      ]-/BIC/ZUNIT.

      catch cx_sy_itab_line_not_found.
        "Не нашли такой материал. Целостность нарушена.
        append
          value #(
            msgid 'RSRMON'
            msgty 'E'
            msgno '000'
            msgv1 |Ошибка проверки целостности ссылок|
            msgv2 |Материал { lv_tmp }|
          )
          to MONITOR.

        "Помечаем, что есть ошибка
        lv_has_err abap_true.

    endtry.

понедельник, 11 апреля 2016 г.

Новые возможности для комментариев в переменной

     wa_method_name-low    |CHECK*{ warhtype-low }*|.


А так ещё круче:

p_text_cell |<details><summary>Script_Result</summary>|
                      && |<p>{ p_string }</p></details>|.

среда, 6 апреля 2016 г.

Ещё немного регулярок


    FIND FIRST OCCURRENCE OF REGEX `result_table\s*=\s*(.*);`
        IN l_method_src_string
        IGNORING CASE
        SUBMATCHES r_script.

    FIND FIRST OCCURRENCE OF REGEX `SCRIPT_ID\s*=\s*(\d+)`
        IN l_method_src_string
        IGNORING CASE
        SUBMATCHES r_script_id.

    FIND FIRST OCCURRENCE OF REGEX `WARH_ID\s*=\s*(\w+)`
        IN l_method_src_string
        IGNORING CASE
        SUBMATCHES r_warh_id.

    FIND ALL OCCURRENCES OF REGEX `SCRIPT_NAME\s*=\s*((.|\n)*)\*\/`
        IN l_method_src_string
        IGNORING CASE
        SUBMATCHES r_script_name.


l_method_scr_string - это текст формата:

  METHOD check_zmm_d85s_001 BY DATABASE PROCEDURE FOR HDB
  LANGUAGE SQLSCRIPT OPTIONS  READ-ONLY
  USING
      /bic/azmm_d85s00
  .
    /*
        SCRIPT_ID     = 1
        WARH_ID       = ZMM_D85S
        SCRIPT_NAME   = Проверка на заполненность ДСО.
*/
        result_table =
            select 'ERR' as result
            from "/BIC/AZMM_D85S00"
            where "/BIC/ZPER_DT" = to_char (add_days(current_date, -1), 'YYYYMM') || '01'
            having count(*) <= 100;
  ENDMETHOD.

четверг, 31 марта 2016 г.

Regex. Пример

Исходный текст:
*        SCRIPT_ID     = '1'.
*        WARH_ID       = 'ZMM_D85S'.
*        SCRIPT_NAME   = 'Проверка на заполненность ДСО'.

    result_table =
        select 'ERR' as result
        from "/BIC/AZMM_D85S00"
        where "/BIC/ZPER_DT" = to_char (add_days(current_date, -1), 'YYYYMM') || '01'
        having count(*) <= 100;
    

FIND FIRST OCCURRENCE OF REGEX `result_table\s*=\s*(.*);`
        IN l_string
        IGNORING CASE
        SUBMATCHES r_script. " Весь текст селекта

    FIND FIRST OCCURRENCE OF REGEX `SCRIPT_ID\s*=\s*'([^']*)`
        IN l_string
        IGNORING CASE
        SUBMATCHES r_script_id. " ZMM_D85S

вторник, 22 марта 2016 г.

Как вытащить список методов у любого класса?

CL_OO_OBJECT=>GET_INSTANCE( <имя класса> )->GET_METHODS( PUBLIC_METHODS_ONLY = 'X' )


Динамически получаем тип выходной таблицы метода:
  TRY.
      pcl_oo_object cl_oo_object=>get_instance(
        p_class_name
        ).

      p_result_table_type_name pcl_oo_object->get_parameter_type(
          cpdname p_cpdname
          sconame 'RESULT_TABLE'
        )-type.

      p_result_table_type |{ class_name }=>{ p_result_table_type_name }|.

    CATCH cx_root INTO px_exc.
      pv_str px_exc->get_text).
      MESSAGE pv_str TYPE 'I'.
  ENDTRY.

четверг, 10 марта 2016 г.

Exception condition "DP_OUT_OF_MEMORY" triggered

Дамп при загрузке файлов через GUI_UPLOAD.

GUI 7.40 sp5, но дамп всё равно ловится.

Помогло полностью перезапустить SAP Logon.




Категория              Программная ошибка ABAP
ДинамОшибка            RAISE_EXCEPTION
АВАР-прогр.            ZNN_LOGISTIC_CENTER_XML_PARSER
Прикладной компонент   Не присвоено
Дата и время           09.03.2016 16:45:46


 Краткий текст
     Exception condition "DP_OUT_OF_MEMORY" triggered

 Что произошло?
     The current ABAP program has encountered an unexpected situation.

 Что Вы можете сделать?
     Note down which actions and inputs caused the error.

     To process the problem further, contact you SAP system
     administrator.

     Using Transaction ST22 for ABAP Dump Analysis, you can look
     at and manage termination messages, and you can also
     keep them for a long time.

 Анализ ошибки
     A RAISE statement in program "CL_GUI_FRONTEND_SERVICES======CP" has raised
      exception condition "DP_OUT_OF_MEMORY".
     Since the exception was not caught by a program higher up in the call
     hierarchy, processing was terminated.

     Short text for exception condition:
     You can find detailed documentation about the exception condition in
     transaction SE37 (Function Library). You can find the name of the
     function module called from the display of active calls.

пятница, 4 марта 2016 г.

Нарезаем string на строки определённой длины

DATA:
    lo_conv TYPE REF TO cl_abap_conv_in_ce,
lt_xml_result TYPE STANDARD TABLE OF char2048,
l_string      TYPE string,
l_data        TYPE xstring.

  lo_conv cl_abap_conv_in_ce=>create(
    EXPORTING encoding 'UTF-8'
      input l_data
      ).

  WHILE lo_conv->is_at_end EQ abap_false.
    CALL METHOD lo_conv->read
      EXPORTING
        n    2048
      IMPORTING
        data l_string.

    APPEND l_string TO lt_xml_result.
  ENDWHILE.

среда, 2 марта 2016 г.

Вывод содержимого любой таблицы в xml


report ZTST.

types:
  begin of ts_output,
    id type i,
    tab type string,
    descr type string,
    data type ref to data,
  end of ts_output,
  tt_output type table of ts_output
.

data:
  gv_tabname type tabname,
  gt_output type tt_output,
  gv_result_html type string.

select-options:
  so_tabnm for gv_tabname no intervals
.

start-of-selection.
perform f_get_data
  using so_tabnm[]
  changing gt_output
.

perform f_format_table_html
  using gt_output "it_tab
  changing gv_result_html "cv_html
.


gv_result_html |<meta charset="utf-8"><body>{ gv_result_html }</body>|.

data:
  lt_export type table of string.

append gv_result_html to lt_export.

call method cl_gui_frontend_services=>gui_download
  exporting
*    bin_filesize              =
    filename                  'C:\Temp\Demo.html'
    filetype                  'ASC'
    codepage                  '1504'
    write_bom                 ''
  changing
    data_tab                  lt_export
  .

if sy-subrc <> 0.
* Implement suitable error handling here
endif.



**********************************************************************
form f_get_data
  using i_tabname type any table
  changing ct_output type tt_output

.

  data:
    lo_result type ref to cl_sql_result_set,
    lo_tab_handler type ref to cl_abap_tabledescr,
    lo_res type ref to data,
    lv_sql type string
  .

  field-symbols:
    <lfs_tabname_range> type any,
    <lfs_tabname> type any
  .


  loop at i_tabname
    assigning <lfs_tabname_range>.

    assign component 'LOW'
      of structure <lfs_tabname_range>
      to <lfs_tabname>
    .

    lv_sql |select * from "{ <lfs_tabname> }"|.

    lo_result cl_sql_connection=>get_connection(
    )->create_statement(
    )->execute_query(
      lv_sql
    ).


    lo_tab_handler cl_abap_tabledescr=>get(
      p_line_type cast cl_abap_datadescr(
        cl_abap_structdescr=>describe_by_data_ref(
          lo_result->get_struct_ref(
            lo_result->get_metadata)
          )
        )
      )
    )
    .

    create data lo_res type handle lo_tab_handler.

    lo_result->set_param_table(
      lo_res
    ).

    lo_result->next_package).
    lo_result->close).

    append value #(
      id sy-tabix
      tab <lfs_tabname>
      descr |Содержимое таблицы { <lfs_tabname> }|
      data lo_res
    to ct_output.

  endloop.


endform.
**********************************************************************

**********************************************************************
form f_format_table_html
  using it_tab type any table
  changing cv_html type string
.

  data:
    lt_fields type cl_abap_structdescr=>component_table,
    lv_class_name type string
  .

  data:
    lv_cell_val type string,
    lv_row_val type string
  .

  field-symbols:
    <lfs_field> like line of lt_fields,
    <lfs_table_row> type any,
    <lfs_data> type any,
    <lfs_data_as_tab> type any table
  .


  lt_fields cast cl_abap_structdescr(
    cast cl_abap_tabledescr(
      cl_abap_tabledescr=>describe_by_data(
        it_tab
      )
    )->get_table_line_type)
  )->get_components(
  ).


  cv_html '<table border="1px">'.

  loop at it_tab
    assigning <lfs_table_row>.

    lv_row_val '<tr>'.

    loop at lt_fields
      assigning <lfs_field>.

      assign component <lfs_field>-name
        of structure <lfs_table_row>
        to <lfs_data>
      .

      if <lfs_field>-name 'DATA'.

        assign <lfs_data>->to <lfs_data_as_tab>.

        perform f_format_table_html
          using <lfs_data_as_tab>
          changing lv_cell_val
        .

        lv_cell_val |<details><summary>Table data</summary>|
          && |<p>{ lv_cell_val }</p></details>|.

        else.
          lv_cell_val <lfs_data>.

      endif.

      lv_row_val lv_row_val
        && |<td>{ lv_cell_val }</td>|.

    endloop.

    lv_row_val |{ lv_row_val }</tr>|.
    cv_html cv_html
      && cl_abap_char_utilities=>newline
      && lv_row_val
    .

  endloop.

  cv_html |{ cv_html }</table>|.

*  cl_demo_output=>display_html( cv_html ).
endform.
**********************************************************************

пятница, 19 февраля 2016 г.

Формирование CSV из экселя

' Выгрузка в .CSV
Sub Export()
Dim l_sheet As String
Dim l_rowval As String
Dim l_file As String
Dim l_out As Object
Dim l_fout As Variant
Dim l_tmp

Dim l_regex As New RegExp
Dim l_matches

l_regex.Pattern = "\(([\S]+)\)"
With l_regex
.Global = True
.IgnoreCase = True
End With

l_sheet = "Test"
If l_regex.Test(ActiveSheet.Name) Then
Set matches = l_regex.Execute(ActiveSheet.Name)
l_sheet = matches(0).SubMatches(0)
'Else
' MsgBox "Specify filename in parentheses (e.g. ""Listname (FILE_NAME)"")"
End If

'l_file = InputBox("Введите имя файла", "Сохранить лист", l_sheet & ".CSV")
l_file = UCase(l_sheet)

l_fout = Application.GetSaveAsFilename( _
FileFilter:="Файл с разделителем ; (*.csv), *.csv", _
InitialFileName:=l_file, _
Title:="Сохранить содержимое в файл" _
)

If l_fout = False Then
l_tmp = MsgBox(Prompt:="Отменено пользователем", _
Buttons:=vbInformation Or vbOKOnly, _
Title:="Не сохранено" _
)
Exit Sub
End If

Set l_out = CreateObject("ADODB.Stream")
l_out.Charset = "utf-8"
l_out.Open
'Open l_file For Output As #1


For l_rnum = 6 To ActiveSheet.UsedRange.Rows.Count
l_rowval = ""
For l_cnum = 1 To ActiveSheet.UsedRange.Rows(6).Columns.End(xlToRight).Column
l_rowval = l_rowval & Cells(l_rnum, l_cnum).Value & ";"
Next l_cnum
l_rowval = l_rowval & vbCrLf
'Print #1, l_rowval
l_out.Writetext l_rowval
Next l_rnum

l_out.SaveToFile l_fout, 2
'Close #1

MsgBox "Лист сохранен в файл " & l_fout

End Sub
' Преобразует в текст
Sub Format_Data_As_Text()
Dim l_val As String
Dim l_cell As Object


For Each l_cell In Selection.SpecialCells(xlCellTypeVisible)
l_val = l_cell.Value
l_cell.Value = l_val
Next l_cell

End Sub
' Добавляем слева нули до определнной длины
Sub Selection_Lpad_Zeroes()
Dim l_val As String
Dim l_regex As New RegExp
Dim l_len As Integer
Dim l_cell As Object

l_regex.Pattern = "^[0-9]+$"
With l_regex
.Global = True
.IgnoreCase = True
End With

l_len = InputBox("Длина поля для дополнения нулями", "Дополнить нулями до длины...", 4)
For Each l_cell In Selection.SpecialCells(xlCellTypeVisible)
l_val = l_cell.Value
If l_regex.Test(l_val) Then
l_val = Right(String(l_len, "0") & l_val, l_len)
l_cell.Value = l_val
End If
Next l_cell

End Sub
' Преобразует все кавычки к одному типу ""
Sub Format_Quotes()
Dim l_regex As New RegExp
Dim l_val As String
Dim l_cell As Object

l_regex.Pattern = "«|»"
With l_regex
.Global = True
.IgnoreCase = True
End With

For Each l_cell In Selection.SpecialCells(xlCellTypeVisible)
l_val = l_cell
If l_regex.Test(l_val) Then
l_val = l_regex.Replace(l_val, """")
l_cell.Value = l_val
End If
Next l_cell

End Sub

Sub ZF()
Dim l_regex As New RegExp
Dim l_val As String
Dim l_cell As Object

l_regex.Pattern = "«|»"
With l_regex
.Global = True
.IgnoreCase = True
End With

For Each l_cell In Selection.SpecialCells(xlCellTypeVisible)
l_cell.Value = "ЗФ"
Next l_cell

End Sub

' Удаляем пробелы
Sub Trim()
Dim l_regex As New RegExp
Dim l_val As String
Dim l_cell As Object

l_regex.Pattern = "^ +| +$"
With l_regex
.Global = True
.IgnoreCase = True
End With

For Each l_cell In Selection.SpecialCells(xlCellTypeVisible)
l_val = l_cell
If l_regex.Test(l_val) Then
l_val = l_regex.Replace(l_val, "")
l_cell.Value = l_val
End If
Next l_cell
End Sub

среда, 10 февраля 2016 г.

Получить список полей любой таблицы

По имени таблицы:

data:
gt_fields type ddfields.

  gt_fields CAST cl_abap_structdescr(
    cl_abap_structdescr=>describe_by_nametabname )
  )->get_ddic_field_list(
    EXPORTING
      p_langu sy-langu
      p_including_substructres abap_true
  ).


По указателю на область памяти, где лежит таблица:

data:
 result_table      TYPE REF TO data,
  gt_fields         TYPE CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE.

  gt_fields cast cl_abap_structdescr(
      cast cl_abap_tabledescr(
          cl_abap_tabledescr=>describe_by_data_refresult_table )
      )->get_table_line_type(
      )
  )->get_components(
  ).