вторник, 9 ноября 2021 г.

Query Builder. how to check email

 

For publications:

Select SI_ID, SI_NAME, SI_KIND, SI_PARENT_FOLDER  ,

SI_SCHEDULEINFO.SI_DESTINATIONS, SI_INSTANCE, SI_SCHEDULE_STATUS

from CI_INFOOBJECTS where SI_KIND = 'Publication'

and SI_INSTANCE = 0

and SI_SCHEDULEINFO.SI_DESTINATIONS.SI_TOTAL > 0

and "si_scheduleinfo.si_destinations.1.si_progid" = 'CrystalEnterprise.Smtp'

and

( "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_SENDER_NAME" like '%email%'

or ( "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_MAIL_ADDRESSES.SI_TOTAL" > 0

       and "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_MAIL_ADDRESSES" like '%emailh%')

or ( "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_MAIL_BCC.SI_TOTAL" > 0

       and "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_MAIL_BCC" like '%email%')

or ( "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_MAIL_CC.SI_TOTAL" > 0

       and "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_MAIL_CC" like '%email%')

)



For schedule of publications:

Select SI_ID, SI_NAME, SI_KIND, SI_PARENT_FOLDER  ,

SI_SCHEDULEINFO.SI_DESTINATIONS, SI_INSTANCE, SI_SCHEDULE_STATUS

from CI_INFOOBJECTS where SI_KIND = 'Publication'

and SI_INSTANCE = 1

and SI_SCHEDULE_STATUS = 9

and SI_SCHEDULEINFO.SI_DESTINATIONS.SI_TOTAL > 0

and "si_scheduleinfo.si_destinations.1.si_progid" = 'CrystalEnterprise.Smtp'

and

( "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_SENDER_NAME" like '%email%'

or ( "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_MAIL_ADDRESSES.SI_TOTAL" > 0

       and "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_MAIL_ADDRESSES" like '%email%')

or ( "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_MAIL_BCC.SI_TOTAL" > 0

       and "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_MAIL_BCC" like '%email%')

or ( "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_MAIL_CC.SI_TOTAL" > 0

       and "si_scheduleinfo.si_destinations.1.SI_DEST_SCHEDULEOPTIONS.SI_MAIL_CC" like '%email%')

)


четверг, 18 февраля 2021 г.

Custom hierarchies ( SET )

https://blogs.sap.com/2013/10/21/custom-hierarchies/

https://blogs.sap.com/2012/05/02/custom-hierarchy-extraction-in-sap-bw-73-part1/

https://blogs.sap.com/2012/08/09/custom-hierarchy-extraction-in-sap-bw-73-part2/

https://blogs.sap.com/2012/08/10/custom-hierarchy-extraction-in-sap-bw-73-part3/

понедельник, 7 сентября 2020 г.

среда, 8 июля 2020 г.

Run DTP, run!

Надо перегрузить данные из А в B
Но сделать надо это по некому признаку, в данном случае по дате.
Да, можно было через TVARV, но как то хотелось реализовать по другому.

В общем, идея простая...
Запускается DTP, находит последний загруженный пакет в B, смещает дату и аглы.



DATA: l_date type d.

"get target
DATA(l_target) = i_r_request->get_tgt( ).

"type of target
"DATA(l_target_type) = i_r_request->get_tgttp( ).

"ref to target
DATA(lo_request_list) = cl_rsdso_data_request_list=>create(
                          i_adsonm = l_target(30) ).
"refresh list
lo_request_list->refresh( ).

"get list of all requests in XREF format
DATA(lt_request_xref) = lo_request_list->get_t_request_xref( ).

IF lt_request_xref IS NOT INITIAL.
  "get last request
  SORT lt_request_xref BY SRC_POS DESCENDING.
  ASSIGN lt_request_xref[ 1 ]-SRC_TSN TO FIELD-SYMBOL(<SRC_TSN>).

  TRY.
    "ref to request object (DTP)
    DATA(lo_request) = cl_rsbk_request=>create_from_db(
                        i_process_tsn = <SRC_TSN>
                        i_request_tsn = <SRC_TSN> ).

    "get filters in table view
    DATA(lt_filter) = lo_request->get_th_range( ).
  CATCH cx_rs_not_found.
    p_subrc = 1.
    EXIT.
  ENDTRY.

  "get value for i_fieldnm
  READ TABLE lt_filter
    WITH KEY FIELDNM = i_fieldnm
    ASSIGNING FIELD-SYMBOL(<ls_filter>).

  IF sy-subrc = 0.
    "increment date
    l_date = <ls_filter>-LOW.
    l_date = l_date + 1.

    "set restriction in DTP
    READ TABLE l_t_range
      WITH KEY fieldname = i_fieldnm.

    IF sy-subrc = 0.
      l_t_range-low = l_date.
      modify l_t_range index sy-tabix.
    ELSE.
      l_t_range-FIELDNAME = i_fieldnm.
      l_t_range-SIGN = 'I'.
      l_t_range-OPTION = 'EQ'.
      l_t_range-LOW = l_date.
      append l_t_range.
    ENDIF.
  ENDIF.
ENDIF.

p_subrc = 0.


7.5
DATA: l_date type d.
DATA: l_fiscper type /BI0/OIFISCPER.
DATA: ls_tlogo       TYPE rstran_s_tlogo.

"fill TLOGO structure
ls_tlogo-tlogo = i_r_request->get_tgttp( ).
ls_tlogo-objnm = i_r_request->get_tgt( ).

"ref to target
DATA(lo_request_list) = cl_rsdso_data_request_list=>create(
                          i_s_tlogo   = ls_tlogo ).
"refresh list
lo_request_list->refresh( ).

"get list of all requests in XREF format
DATA(lt_request_xref) = lo_request_list->get_t_request_xref( ).

IF lt_request_xref IS NOT INITIAL.
  "get last request
  SORT lt_request_xref BY SRC_POS DESCENDING.
  ASSIGN lt_request_xref[ 1 ]-SRC_TSN TO FIELD-SYMBOL(<SRC_TSN>).

  TRY.
    "ref to request object (DTP)
    DATA(lo_request) = cl_rsbk_request=>create_from_db(
                        i_process_tsn = <SRC_TSN>
                        i_request_tsn = <SRC_TSN> ).

    "get filters in table view
    DATA(lt_filter) = lo_request->get_th_range( ).
  CATCH cx_rs_not_found.
    p_subrc = 1.
    EXIT.
  ENDTRY.

  "get value for i_fieldnm
  READ TABLE lt_filter
    WITH KEY FIELDNM = i_fieldnm
    ASSIGNING FIELD-SYMBOL(<ls_filter>).

  IF sy-subrc = 0.
    "increment date
    l_fiscper = <ls_filter>-LOW.
    l_date = |{ l_fiscper(4) }{ l_fiscper+5(2) }01|.
    l_date = l_date + 33.
    l_fiscper = |{ l_date(4) }0{ l_date+4(2) }|.

    "set restriction in DTP
    READ TABLE l_t_range
      WITH KEY fieldname = i_fieldnm.

    IF sy-subrc = 0.
      l_t_range-low = l_fiscper.
      l_t_range-sign = 'I'.
      l_t_range-option = 'EQ'.
      modify l_t_range index sy-tabix.
    ELSE.
      l_t_range-FIELDNAME = i_fieldnm.
      l_t_range-SIGN = 'I'.
      l_t_range-OPTION = 'EQ'.
      l_t_range-LOW = l_fiscper.
      append l_t_range.
    ENDIF.
  ENDIF.
ENDIF.

p_subrc = 0.

Вызов цепочки из отчета

ABAP функция на FOX

В общем надо запускать RSPC_API_CHAIN_START с параметром I_NOPLAN = 'X'

Иначе, странная хрень с теи какой статус завершения у цепочки может возникать.

понедельник, 18 ноября 2019 г.

Hierarchy 3.x >> 7.х

Давно не делал эту операцию, в общем даже как то подзабыл что надо подправить чтобы заработало нормально.


+ start routine:

    CALL METHOD cl_rstran_gen_step_hier_split=>reset_interval_nodes
      EXPORTING
        i_iobjnm      = '0COSTELMNT'
        i_t_intervals = SOURCE_PACKAGE_5
      CHANGING
        c_t_nodes     = SOURCE_PACKAGE_3.

То что DTP пакет внутри желтый - это в общем терпимо.

вторник, 11 декабря 2018 г.

Экстратор, виртуальник на трансформации

BI

Inverse routine:

  C_TH_FIELDS_INBOUND = I_TH_FIELDS_OUTBOUND.
  C_R_SELSET_INBOUND = I_R_SELSET_OUTBOUND.
  C_EXACT = RS_C_TRUE.

https://archive.sap.com/kmuuid2/f05d0b81-076a-2c10-44ab-f00b0b90ce38/Writing%20Inverse%20Routine%20with%20Expert%20Routine.pdf

http://www.denisreis.com/how-to-sap-bi-inverse-routinen-invertierungsroutinen-in-sap-bw/ - тут попонятней, хоть и на немецком...


Но не помогло, где то до start inverse рутине терялись переданные параметры.
Сделал передачу параметров через глобальные переменные класса.

ERP:

Все поля могут быть переданны как параметры в источник, галки не важны, от слова совсем.

Полей было много... было лень перечислять их, поэтому

* Select ranges
 DATA:
    lt_where    TYPE STANDARD TABLE OF char200,
    lt_condtab  TYPE TABLE OF hrcond,
    ls_condtab  LIKE LINE OF lt_condtab.

"collect values of restrictions
    clear ls_condtab.
    LOOP AT s_s_if-t_select
      ASSIGNING FIELD-SYMBOL()
      WHERE sign   = 'I'.

      ls_condtab-field =  -fieldnm.
      ls_condtab-opera = -option.
      ls_condtab-high  = -high.
      ls_condtab-low   = -low.
      APPEND ls_condtab TO lt_condtab.
    ENDLOOP.

    "create WHERE clause
    CALL FUNCTION 'RH_DYNAMIC_WHERE_BUILD'
      EXPORTING
        dbtable         = SPACE
      TABLES
        condtab         = lt_condtab
        where_clause    = lt_where
      EXCEPTIONS
        empty_condtab   = 1
        no_db_field     = 2
        unknown_db      = 3
        wrong_condition = 4
        OTHERS          = 5.

      OPEN CURSOR WITH HOLD @s_cursor FOR
      SELECT *
      FROM ZVTETATET
        WHERE (lt_where).

The elements in the "SELECT LIST" list must be separated using commas.

Нужен был left outer join на курсоре

Пока было условие на 1й таблице всё было хорошо

OPEN CURSOR s_cursor FOR
      SELECT V~FORM V~ID D~DAT
      FROM Table1 as V
        LEFT OUTER JOIN Table2 as D
        ON  V~docnum = D~docnum
        WHERE V~FORM EQ 'LC'.

Но после добавления условия на 2й таблице, возникла ошибка

The elements in the "SELECT LIST" list must be separated using commas.

Вариант решения

OPEN CURSOR @s_cursor FOR
      SELECT V~FORM, V~ID, D~DAT
      FROM Table1 as V
        LEFT OUTER JOIN Table2 as D
        ON  V~docnum = D~docnum
        WHERE V~FORM EQ 'LC'
             AND  D~DAT GT '20180101'.

воскресенье, 9 декабря 2018 г.

MDX

SELECT
NON EMPTY
  { [00O2TOGA0GQMBY3GPSFLP5TIR].Members }
ON COLUMNS,
NON EMPTY
  {
    {FILTER([0COMP_CODE].MEMBERS,   "All" <> [0COMP_CODE].[20COMP_CODE])}
   *{FILTER([0CALYEAR].MEMBERS,"All" <> [0CALYEAR].[20CALYEAR])}
  }
DIMENSION PROPERTIES
   [0COMP_CODE].[20COMP_CODE]
  ,[0CALYEAR].[20CALYEAR]

ON ROWS
FROM
  [cube/query]

 SAP VARIABLES
[!V000001] INCLUDING [0CALDAY].[20180505]
[0CMPCODE] INCLUDING [0COMP_CODE].[0001]
[!V000003] INCLUDING [0CALYEAR].[2018]

Нашел более производительный вариант, использовать c Level01.Member

SELECT
  {[Measures].[00O2TOGA0GQMBWHEA5HWM60RN]}
ON COLUMNS,
NON EMPTY {
  {[ZDIM1].[LEVEL01].Members}
 *{[ZDIM2].[LEVEL01].Members}
 *{[ZDIM5].[LEVEL01].Members}
}
DIMENSION PROPERTIES
  [ZDIM1].[2ZATT1]
 ,[ZDIM1].[2ZATT2]
 ,[ZDIM1].[1ZATT3]
 ,[ZDIM5].[5ZITEM]
 ,[ZDIM5].[20CALDAY]
 ,[ZDIM5].[10COMP_CODE]

ON ROWS
FROM
  [cube/query]]

WHERE {
  {[ZDIM1__ZATTR1].[valA],[ZDIM1__ZATTR1].[valB],[ZDIM1__ZATTR1].[valG]}
 *{[0INFOPROV].[cubeA],[0INFOPROV].[cubeB],[0INFOPROV].[cubeC]}
 *{[ZDIM2__ZATTR1].[#]}
}

SAP VARIABLES
  [!V000001] INCLUDING [ZDIM2__ZATTR1].[D]
 ,[!V000002] INCLUDING [ZDIM2].[USD]
 ,[!V000012] INCLUDING [0CALDAY].[20200101] : [0CALDAY].[20200421]


воскресенье, 20 мая 2018 г.

Hierarchy

После обновления ERP, часть иерархий из наборов перестала грузится. Система просто не видет части иерархий в ERP, а часть видит.

Есть немного пространственная нота на эту тему - 2162245
Но суть в следующем...

В функции GSBH_HIERARCHY_CATALOG_SETS происходит исключение наборов входящих в другой набор, если родительский набор(супернабор) имеет тип S - Одномерный набор

В качестве решения загружаю "отброшенные" иерархии уже из родительской иерархии. Т.е. сделал трансформацию самого объекта на себя. В принцинципе все работает четко, есть только пару ньюансов...

1. В фильтре DTP надо обязательно указывать тип объекта - там так устроен поиск.


2. Было лениво делать для каждой иерархии свою трансформацию.
Сделал одну, а имя иерархии беру из ограничений DTP

DATAlt_filter TYPE RSBK_TH_RANGE.
DATAl_HIENM   TYPE RSHIENM.
FIELD-SYMBOLS LIKE LINE OF lt_filter.
"get DTP filter

p_r_request
->GET_TH_RANGERECEIVING R_TH_RANGE lt_filter ).
"get node name
READ TABLE lt_filter
  
WITH KEY FIELDNM 'NODENAME'
  
ASSIGNING .
IF sy-subrc 0.

  l_HIENM 
-LOW.
  
TRANSLATE l_HIENM TO UPPER CASE.

  
"dummy hier - Don't let the word make your hard
  
IF l_HIENM SPACE.

    l_HIENM 
'ZTEST1'.
  
ENDIF.

  
LOOP AT SOURCE_PACKAGE_1
    
ASSIGNING .

    
-H_HIENM l_HIENM.
  
ENDLOOP.
ENDIF.

воскресенье, 14 января 2018 г.

Afe macroses

in ThisWorkbook

Public Sub Workbook_SAP_Initialize()

' register callbacks
Call Application.Run("SAPExecuteCommand", "RegisterCallback", "AfterRedisplay", "Callback_AfterRedisplay")
'Call Application.Run("SAPExecuteCommand", "RegisterCallback", "BeforePlanDataSave", "Callback_BeforePlanDataSave")
'Call Application.Run("SAPExecuteCommand", "RegisterCallback", "BeforePlanDataReset", "Callback_BeforePlanDataReset")
'Call Application.Run("SAPExecuteCommand", "RegisterCallback", "BeforeMessageDisplay", "Callback_BeforeMessageDisplay")
'Call Application.Run("SAPExecuteCommand", "RegisterCallback", "BeforeFirstPromptsDisplay", "Callback_BeforeFirstPromptsDisplay")

End Sub


Sub Callback_AfterRedisplay()

 'just do it sometning :)
End Sub


Bex 7

Sub CallBack(ParamArray varname())

  Application.Interactive = False
  Application.EnableEvents = False
  Application.DisplayAlerts = False
  Application.ScreenUpdating = False

On Error Resume Next: Err

Dim lData_Provider As String
lData_Provider = Right(varname(2), 11)
Set lRange = varname(1)

....

Err:
  Application.Interactive = True
  Application.EnableEvents = True
  Application.DisplayAlerts = True
  Application.ScreenUpdating = True
End Sub


User function (should be defined in module)

'Join dimension
Function JoinDim(DimName As String, Optional delimiter As String = ";")
    JoinDim = ""
 
    'SAPListOfMembers returns unique list values of dimension
    'But result depends of characteristic setting
    'so you can receive one-dimensional or multi-dimensional array as result
    Dim Dimension As Variant
    Dimension = Application.Run("SAPListOfMembers", "DS_1", "FILTER", DimName)
 
    Dim l As Integer
    m = UBound(Dimension)

    For Each a In Dimension
 
    i = i + 1
    If i = m + 1 Then        'take only 2nd values
      'Exit For              'if you would like to take 1ts values
      JoinDim = ""
    ElseIf i = m + m + 1 Then
      Exit For
    End If
 
    If a <> "#" And a <> "#/#" Then
   
      If InStr(1, JoinDim, a, vbTextCompare) = 0 Then
     
        If Len(JoinDim) > 0 Then
        JoinDim = JoinDim & delimiter
        End If
     
        JoinDim = JoinDim & a
      End If
    End If
    Next a
End Function
'ZL_PORT

https://www.reyemsaibot.com/2016/07/25/analysis-office-infofields-formulas-dashboard-functions/


RIBBON
https://www.reyemsaibot.com/2016/12/01/analysis-office-2-4-customize-user-interface/
https://answers.sap.com/questions/223594/sap-analysis-25-custom-ribbon-macro.html
https://help.sap.com/viewer/5dd171bef6df457d9172164f7fd7dd7c/2.5.2.0/en-US/a4dcdbabddad45c085c8179f3fe28f0b.html
https://www.youtube.com/watch?v=X1jXGF8NiFs


Sub Button1_Click()
  Dim lResult As Long
  lResult = Application.Run("SAPExecuteCommand", "PlanDataSave")
End Sub

четверг, 22 июня 2017 г.

User check

RSUSR100N - суперская программа для просмотра изменения пользователя... не забудте только галок наставить

RSUSR200 - обзор по всем пользователям

пятница, 26 мая 2017 г.

среда, 23 ноября 2016 г.

суббота, 5 ноября 2016 г.

BO всячина

Формулы:
=1=0 - формула возвращает NULL, иногда очень удобно использовать при дальнейшей обработке... например условия
FormatDate
=ToDate(UserResponse("P_0CALDAY_CEIO01");"INPUT_DATE_TIME")
=FormatDate(ToDate(Right([var.Period];19);"INPUT_DATE_TIME");"dd.MM.yyyy")

Сортировки:

Chart

Variable & Scheduling
Вариантов несколько:
1. Два отчета, с скрытой переменной и переменной для ввода
2. Один отчет, с 2мя связанными переменными. Работаем по 2й скрытой... если 1я пустая, то 2ю вычисляем, иначе 2= 1. Типа так.

Или есть самый приличный вариант, правда надо уровень системы и патча - https://archive.sap.com/documents/docs/DOC-62160

Date&Time
https://blogs.sap.com/2013/11/21/how-to-use-formulae-to-change-date-and-time-formats-in-webintelligence/
https://bobjblog.wordpress.com/tag/formatdate/
https://bobjblog.wordpress.com/2012/03/05/web-intelligence-date-formats/

Формат числа
http://www8.senado.gov.br/BOE/OpenDocument/1809120828/AnalyticalReporting/help/en/frameset.htm?4721c57e6e041014910aba7db0e91070.html
https://sapbwinfo.wordpress.com/2016/11/07/custom-number-format-with-decimal/


Blog

="<a href=\"https://BWSERVER/sap/bw/analysis?APPLICATION=EXCEL&OBJECT_TYPE=QUERY_VIEW&OBJECT_ID=ZZ_QUERY_VIEW_NAME"
+ "&var" + URLEncode("0DATE_var") + "="+URLEncode(""+[variable Date])
+ "\" title=\"\" target=\"_blank\" nav=\"web\">LINK</a>"


="<a href=\"https://BWSERVER/sap/bw/analysis?APPLICATION=EXCEL&OBJECT_TYPE=QUERY&OBJECT_ID=ZZ_QUERY_NAME"
+ "&var" + URLEncode("0DATE_var") + "="+URLEncode(""+[variable Date])
+ "\" title=\"\" target=\"_blank\" nav=\"web\">LINK</a>"

Адрес BWSERVER - fm RSBB_URL_PREFIX_GET

="<a href=\"../../opendoc/openDocument.jsp?iDocID=" 
+ "xxxxxxxxxxxxxxx_XXXXXX"
+ "&sIDType=CUID&sType=wid"
+ "&lsS" + URLEncode("0DATE_var") + "="+URLEncode(""+[variable Date])
+ "\" title=\"\" target=\"_blank\" nav=\"doc\">LINK</a>"

Подробнее
https://help.sap.com/doc/225672d1fdbb4a4aac19ae794349ec26/4.2.6/en-US/sbo42sp6_opendocument_en.pdf

Значения измерения в одной строке
https://blogs.sap.com/2016/05/12/group-dimension-values-in-a-single-cell/


Администрирование

https://help.sap.com/docs/SAP_BUSINESSOBJECTS_BUSINESS_INTELLIGENCE_PLATFORM/987ff4008e2d47fb9f92f7b085a204cd/b35f19f0-8f1d-48e5-bc0d-480ada93fc4b.html?version=4.2.4&locale=ru-RU

четверг, 27 октября 2016 г.

Transport BADI

Список:
CTS_EXPORT_FEEDBACK -> feedback after export of a transport request.
CTS_IMPORT_FEEDBACK -> feedback after import of a transport request.
CTS_INT_REQUEST_CHCK -> internal: request checks.
CTS_REQUEST_CHECK -> request checks.
CTS_TASKDOC_TEMPLATE -> determine template for the task documentation.

Пример:
https://blogs.sap.com/2013/09/19/how-to-trigger-atc-or-code-inspector-checks-during-the-release-of-a-transport-task/
https://wiki.scn.sap.com/wiki/display/Snippets/Email+Feedback+for+Transports

Идеи:
CTS_REQUEST_CHECK-CHECK_BEFORE_CREATION – можно сделать проверку name convention для транспортов

CTS_REQUEST_CHECK-CHECK_BEFORE_RELEASE – перед релизом проверить в что там нет пакетов и DTP или что параметры в пакете и DTP идентичны параметрам в продуктивной системе

CTS_REQUEST_CHECK-CHECK_BEFORE_RELEASE_SLIN – можно натравить проверку по name convention из SLIN’a для проверки ABAP’a

CTS_REQUEST_CHECK-CHECK_BEFORE_CHANGING_OWNER – можно настроить уведомление владельца о этом действии

CTS_INT_REQUEST_CHCK- CHECK_BEFORE_RELEASE – не совсем понял чем он отличается от CTS_REQUEST_CHECK-CHECK_BEFORE_RELEASE

CTS_EXPORT_FEEDBACK или CTS_IMPORT_FEEDBACK
- тут можно устроить проверку на момент загрузки данных и переноса… чтобы не мудрить, проверка на активные цепочки
- ну и уведомление BW группы в случае переноса в продуктив , cебе же спокойней будет
- кстати и запрет на перенос в продуктив тоже настроить можно попробовать