четверг, 14 марта 2013 г.

Кнопки в Bex

Временами переставали работать кнопки в Bex. Стал разбираться... порадовал "суперкод" определения где что показывать\гасить.

Public Sub AdjustButtons()

On Error Resume Next
Dim lsheet As Worksheet
' Adjust Filter Button
If pFilterVisible Then
  For Each lsheet In ThisWorkbook.Sheets()
    If lsheet.Range("C14").Value = "Filter" Then
....
'Adjust InfoButton

If pFilterVisible Then
  For Each lsheet In ThisWorkbook.Sheets()
    If lsheet.Range("F5").Value = "Information" Then

Соответственно появление фразы Filter в ячейке C14 и Informationd F5 востанавливало работу кпопок.

Классы сообщений

Тексты в классах сообщений находяться в таблице T100. Очень удобно :)

Есть ещё таблицы

T100A Message IDs for T100
T100C Message Control by User
T100O Assignment of message to object
T100S Configurable system messages
T100SA Application Areas for Configurable Messages
T100T Table T100A text
T100U Last person to change messages
T100V Assignment of messages to tables/views
T100W Assign Messages to Workflow
T100X Error Messages: Supplements
T100ARBGB Application Area

класс R9O - сообщения похожие на Bex, но на самом деле х.з.

вторник, 5 марта 2013 г.

APPEND:

Встретил тут в коде удобный APPEND

DATA: r_typ_x TYPE RANGE OF typ_x.


APPEND:              
                'IEQ10' TO r_typ_x,  "Условие А
                'IEQ12' TO r_typ_x.  "Условие Б


append |ILE{ p_par }| to s_par[].
append |IGT{ p_par }| to k_par[].
append |IEQ00000000| to d_par[].
append |IEQ{ zcl_utils=>get_type( ) } | to lr_type.

7.4
lt_AGGA  TYPE TABLE OF abap_compname WITH EMPTY KEY. " table of  fields

  lt_AGGA  = VALUE #( ( 'Field1' ) ( 'Field2' ) ( 'Field3') ).


LOOP AT lt_AGGA ASSIGNING FIELD-SYMBOL().
              ASSIGN COMPONENT OF STRUCTURE TO .

TABLE_LINE


DATA itab TYPE RANGE OF i.
itab = VALUE #( sign = ‘I’  option = ‘BT’ ( low = 1  high = 10 )
                                          ( low = 21 high = 30 )
                                          ( low = 41 high = 50 )
                            option = ‘GE’ ( low = 61 )  ).

  lr_customer = VALUE #(
  FOR <ls_customer> IN lt_customer
  ( sign = 'I'
    option = 'EQ'
    low = )
  ).


DATA:  lr_L_Port type range of /BIC/OIZL_PORT.

    lr_L_Port = VALUE #(
      FOR <ls_t_var_range> IN i_t_var_range
        WHERE ( vnam = 'D_ZL_PORT_CEOO01' )
     ( sign   = -SIGN
       option = -OPT
       low    = -LOW
       high   = -HIGH

     ) ).

CONCATENATE LINES OF lt_sales_order INTO l_logtmp separated by ';'.

* Select fields
DATA:
    ls_view TYPE ZVTETATET,
    lo_struct TYPE REF TO cl_abap_structdescr,

    lt_fields TYPE STANDARD TABLE OF FIELDNAME.

"get list of fields
    lo_struct ?= cl_abap_typedescr=>describe_by_data( ls_view ).
    lt_fields = VALUE #(
      FOR <ls_comp> IN lo_struct->get_components( )

         ( |V~{ -name },| ) ).
...

понедельник, 4 марта 2013 г.

Тех.контект

В рамках борьбы с саботажем, активировали тех.контент. В принципе все ок, за исключение одного при первой загрузке информации по цепочкам (экстрактор 0TCT_DS21) теряли 4 часа. Переписка с SAP. Ноты. Непомогло... но при этом получили "забавный" workaround.

В таблице RSDDSTATEXTRACT по источнику храниться timestamp для выборки данных (для источника 0TCT_DS21 из таблицы RSPCPROCESSLOG). Был выяснен  интересный факт, что при загрузке данных с ограничениями в пакете, timestamp не правильно формировался. + не правильно формируется дельта при инициализации с переносом.

действия:

1. Снять ограничения с пакетов (мы не хотели грузить старые).
2. Прогрузить инициализацию без переноса
3. Прогрузить дельту - и вот тут в 1й дельте приходят все данные
4. Дальнейшие дельты идут корректно

пятница, 22 февраля 2013 г.

Активация DSO

Медитировал на тему активации DSO... точнее какой % активации DSO, и идти мне спать, или маленько посидеть, чтобы пнуть процесс дальше.

Если зайти в лог активации, то можно увидеть что основное время тратиться на записи типа :
BIBCTL_DEPEQUQGFT5PS7P03XM99IHON with ID 23311900

  Вопрос, и сколько этих ID может быть? В общем формула почти простая  

Кол-во записей ID = (Кол-во Записей которые будут вставлены) / (размер пакета активации = 20000 by default) + Random(0|1|2)  

Таким образом зная общее кол-во записей, можно посчитать сколько уже сформировалось в логе, т.е. можно посчитать % активации...  

Формула была проверена на 23 больших активациях, поэтому и появился коэффициент Random.
Удачных активаций!

Для изменения размера пакета активации DSO используется транзакция  RSODSO_SETTINGS.

среда, 30 января 2013 г.

Global query variant

Оказалось, что не все знают, что можно создавать глобальные варианты для запуска отчета.
Делается это достаточно просто, при создании варианта надо убрать галку Save as User Variant, задать тех.имя и сохранить.


Объект авторизации - S_RS_PARAM (необходим в случае глобальных вариантов)

Таблицы - RSRPARAMETRIZA (вариант и параметры) и RSRPARAMETRIZAT (тексты)

Интересные поля:

PARENTCOMPONENT - тип объекта
1 Query
2 Workbook
3 Web Application
4 Planning Sequence
5 Planning Function
6 Enterprise Report

ELTUID - тех.имя запроса
PERSONAL - локальный (X) и глобальный (SPACE) вариант
OWNER - user id создателя
CONTENT - содержание варианта в XML формате

Перенос - стандартного (по одной кнопке) способа переноса не существует. Но есть варианты.

Руками в транспорт
PgmID Obj     Object name

R3TR  TABU RSRPARAMETRIZA
R3TR  TABU RSRPARAMETRIZAT

С помощью ведения таблицы *

- SE16
- ‘RSRPARAMETRIZA’
- Нажать кнопку ‘table Contents’ (or F7)
- Провалится в контент (‘F8′)
- Выделить записи для траспортировки
- В меню выбрать ‘table Entry’ -> ‘Transport Entries’
- Выбрать запрос на перенос

* но много на формах сообщений, что способ не работает, закрыт пункт ‘Transport Entries’








понедельник, 28 января 2013 г.

Float

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

Почитал ещё курс BC402, порадовала фраза...
Внимание: Для вычислений в арифметике с плавающей запятой используются операции с плавающей запятой соответствующих процессоров. Поскольку алгоритмы выполняются над двоичными числами, могут возникать погрешности. Степень и эффект таких погрешностей не поддаются оценке.

Теперь, на примере...

DATA:

l_value1 TYPE p DECIMALS 5 value '1.755',
l_value2 TYPE f value '1.755',

l_result1 TYPE p DECIMALS 1,
l_result2 TYPE p DECIMALS 2,
l_result3 TYPE p DECIMALS 3,
l_result4 TYPE p DECIMALS 4.

l_result1 = l_value1. write / l_result1.
l_result2 = l_value1. write / l_result2.
l_result3 = l_value1. write / l_result3.
l_result4 = l_value1. write / l_result4.

l_result1 = l_value2. write / l_result1.
l_result2 = l_value2. write / l_result2.
l_result3 = l_value2. write / l_result3.
l_result4 = l_value2. write / l_result4.

Результат:
[b]l_value1 TYPE p DECIMALS 5 value '1.755'[/b]

0.0 1.8
0.00 1.76
0.000 1.755
0.0000 1.7550

[b]l_value2 TYPE f value '1.755'[/b]
0.0 1.8
0.00 1.75
0.000 1.755
0.0000 1.7550
Получается, что при float округление, делается с учетом размерности приемника + 1.
Т.е. 1,755 которая во представляется внутри как 0.7549999999999999E+00 при преобразовании к 0.00 преобразуют по факту 1.754, а не 1.755

Срочно выкидываем float отовсюду во избежании...