SAP R/3 форум ABAP консультантов
Russian ABAP Developer's Club

Home - FAQ - Search - Memberlist - Usergroups - Profile - Log in to check your private messages - Register - Log in - English
Blogs - Weblogs News

Выгрузка произвольного отчета в Excel за 15 минут



 
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> Submit a new program | Новые материалы, программы для сайта
View previous topic :: View next topic  
Author Message
Anton Sikidin
Участник
Участник



Joined: 11 Mar 2009
Posts: 18
Location: Украина

PostPosted: Thu Mar 22, 2012 1:30 am    Post subject: Выгрузка произвольного отчета в Excel за 15 минут Reply with quote

Разработка пошла в продуктив банков и предприятий, получил feedback, решено было переписать начисто красиво и правильно. Теперь это процедура на 200 строчек и никаких ручных действий.

соглашение по переменным:
-все переменные используемые в отчете должны быть определены глобально
-таблицы используемые в отчете должны быть без headerline.

соглашение по заполнению шаблона:
-если в отчете используются таблицы то первый столбец должен содержать либо текст либо 1 пробел,иначе отчет не откроется.
- одна переменная на ячейку
- переменная заключается в $# $#, например $#sy-uname$#
- строка содержащая ячейки таблицы должна содержать текст $!$Table_name$!$, где Table_name имя внутренней таблицы определенной глобально без headerline
- ячейки таблицы содержат переменные $#<wa>-field1$# $#<wa>-field2$# $#<wa>-field3$# и т.д., где field1 field2 field3 имена полей таблицы
- перед сохранением установить курсор в поле А1

шаблон сохраняем как таблица xml 2003
идем в транзакцию smw0 выбираем двоичные данные для WEB RFC приложений, F8, F8, параметры настройки->ведение MIME типов, добавить туда *.xml .

загружаем шаблон, выбираем имя.

в программе когда все переменные посчитаны вызвать форму

Code:
PERFORM export_to_excel TABLES it_source USING 'Z_TEST_EXPORT_TO_EXCEL'.


в таблице it_source находится сгенерированный xml документ, Z_TEST_EXPORT_TO_EXCE - имя шаблона.

тестовый шаблон в приложении test.xml,

рабочий легкоадоптируемый пример ниже, впримере показано как правильно выгрузить xml документ в кодировке utf-8 и избежать проблем с конвертацией.

Генерировать xml отчеты на ABAP - это как генерировать html странички на PHP: нет в этом ничего страшного и интересного.

парсер странно работает,и покорежил текст программы, прикладываю в приложении sample.rar

Code:

program xz.

types
   : tt_string TYPE STANDARD TABLE OF string
   .

TABLES
  : TADIR
  .

data
      : gt_outtab type table of TADIR
      , it_source TYPE TABLE OF string
      , code type CPCODEPAGE
      , CODEPAGE TYPE  ABAP_ENCODING

      .


*выбираем данные
select * from TADIR into table gt_outtab up to 5 rows.

* генерируем XML
PERFORM export_to_excel TABLES it_source USING 'Z_TEST_EXPORT_TO_EXCEL'.

* оперделяем кодировку
CALL FUNCTION 'SCP_CODEPAGE_BY_EXTERNAL_NAME'
  EXPORTING
    external_name = 'utf-8'
    kind          = 'H'
  IMPORTING
    sap_codepage  = code
  EXCEPTIONS
    not_found     = 1
    OTHERS        = 2.

IF sy-subrc <> 0.
 MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ELSE.
  WRITE code TO codepage.
ENDIF.

* выгружаем данные
CALL FUNCTION 'GUI_DOWNLOAD'
  EXPORTING
    filename                = 'c:\temp\123.xls'
    filetype                = 'DAT'
    codepage                = codepage
  TABLES
    data_tab                = it_source
  EXCEPTIONS
    file_write_error        = 1
    no_batch                = 2
    gui_refuse_filetransfer = 3
    invalid_type            = 4
    no_authority            = 5
    unknown_error           = 6
    header_not_allowed      = 7
    separator_not_allowed   = 8
    filesize_not_allowed    = 9
    header_too_long         = 10
    dp_error_create         = 11
    dp_error_send           = 12
    dp_error_write          = 13
    unknown_dp_error        = 14
    access_denied           = 15
    dp_out_of_memory        = 16
    disk_full               = 17
    dp_timeout              = 18
    file_not_found          = 19
    dataprovider_exception  = 20
    control_flush_error     = 21
    others                  = 22.
if sy-subrc <> 0.
  MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
          WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
endif.


form export_to_excel TABLES it_source type tt_string  using IV_OBJID TYPE  W3OBJID .

  data

        : KEY               type WWWDATATAB
        , HTML              LIKE W3HTML OCCURS 100 WITH HEADER LINE
        , MIME              LIKE W3mime OCCURS 100 WITH HEADER LINE
        , lv_tabname        type string
        , lt_bufer          TYPE TABLE OF string WITH HEADER LINE
        , wa_bufer          type string
        , lt_string         TYPE TABLE OF string
        , lv_str            TYPE string
        , lv_str2           TYPE string
        , lv_str3           TYPE string
        , lv_string         type string

        .

CONSTANTS
  : lc_lt(4) VALUE '&lt;'
  , lc_gt(4) VALUE '&gt;'
  .

FIELD-SYMBOLS
               : <field>
               , <table> TYPE ANY TABLE
               , <wa>
               .

  define process_buffer.

    LOOP AT lt_bufer INTO wa_bufer .

      find REGEX '(\$#(.*)\$#)' in wa_bufer SUBMATCHES lv_str  lv_str2.
      IF sy-subrc = 0.

        REPLACE  lc_lt in lv_str2 WITH '<'.
        REPLACE  lc_gt in lv_str2 WITH '>'.

        ASSIGN (lv_str2) to <field>.
        lv_str3 = <field>.

        REPLACE REGEX '(\$#(.*)\$#)' in wa_bufer WITH lv_str3.
        APPEND wa_bufer to it_source.

      else.

        APPEND wa_bufer to it_source.

      ENDIF.

    ENDLOOP.

  end-of-DEFINITION.

  define flush.

    " if tabname defined - loop at table
    IF  lv_tabname is not INITIAL.

      ASSIGN (lv_tabname)  to <table>.

      LOOP AT <table>  ASSIGNING <wa>.
        process_buffer.
      ENDLOOP.

    else.

       process_buffer.

    ENDIF.

    clear  lv_tabname.
    REFRESH lt_bufer.

  end-of-DEFINITION.


  " get key of object
  SELECT single * FROM WWWDATA AS F INNER JOIN TADIR AS P
                ON F~OBJID = P~OBJ_NAME
                INTO  CORRESPONDING FIELDS OF KEY
                WHERE F~SRTF2 = 0
                AND   F~RELID = 'MI'
                AND   P~PGMID    = 'R3TR'
                AND   P~OBJECT   = 'W3MI'
                AND   P~OBJ_NAME = IV_OBJID .


  " get object
  CALL FUNCTION 'WWWDATA_IMPORT'
    EXPORTING
      KEY    = KEY
    TABLES
      HTML   = HTML
      MIME   = MIME
    EXCEPTIONS
      OTHERS = 1.

  " convert raw data to string
  CALL FUNCTION 'WSI_RAW_TO_STRING'
    IMPORTING
      OUTPUT             = lv_string
    TABLES
      INPUT              = MIME
    EXCEPTIONS
      CONVERTION_FAILURE = 1
      OTHERS             = 2.
  IF SY-SUBRC <0>CR_LF INTO TABLE lt_string.


  " process template
  REFRESH it_source.

  LOOP AT lt_string INTO lv_string .

    REPLACE ALL OCCURRENCES OF '''' IN lv_string WITH ''''''.

    find regex '(ss:ExpandedRowCount="\d+")' in lv_string SUBMATCHES lv_str  lv_str2.
    IF sy-subrc = 0.
      REPLACE REGEX '(ss:ExpandedRowCount="\d+")' in lv_string WITH ''.
    ENDIF.

    " find table name
    find REGEX '(\$!\$(.*)\$!\$)' in lv_string SUBMATCHES lv_str  lv_str2.
    IF sy-subrc = 0.
      REPLACE REGEX '(\$!\$(.*)\$!\$)' in lv_string WITH ''.
      lv_tabname = lv_str2.
    ENDIF.

    " new row occured, process buffer
    find regex '(<Row)' in lv_string .
    IF sy-subrc = 0.
       flush.
    ENDIF.

    "reach end of row, add last line to buffer and process buffer
    find regex '(</Row>)' in lv_string.
    IF sy-subrc = 0.
      APPEND lv_string to lt_bufer.
       flush.
    else.
      APPEND lv_string to lt_bufer.
    ENDIF.

  ENDLOOP.

   flush.

endform.




----------------------------------------старая версия---------------------------------------------
небольшая программа и последовательность шагов как выгрузить произвольный отчет в Excel.

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

Недавно меня спросили как я делаю такие красивые отчеты, и я подумал что это будет полезно еще кому-нибудь.

работает на системах с поддержкой юникода.

Иногда нужно получить красивый отчет для бухгалтерии вроде такого


обычно образец этого отчета приходит в Excel.


открываем шаблон, и заменяем все переменные тексты переменными из программы, завернув их в $#$# например $#sy-datum$#

есть правило по одной переменной на ячейку, если нужно больше собираете заранее в 1-ну переменную и кладете ее в ячейку

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

в строке которую нужно размножить ставим $!$

играемся со шрифтами, форматом отображения и прочее.

у нас получается такой шаблон



ставим курсор в ячейку а1 и сохраняем как Таблица XML 2003 (*.xml)

полученный файл скармливаем программе Z_ASIKIDIN_TEMP, исходники в архиве, программа простая содержит только текст, запускаем выбираем файл жмем F8.

рядом с файлом появятся 2 файла: один %имя%.txt второй %имя%1.txt

нам нужен второй.

открываем копируем все в какой-нибудь инклюд.

иногда в ячейке много текста что он не помещается в одну строку редактора



в конце строки закрываем кавычку ставим точку, в начале следующей строки добавляем xml_simple '




в том месте где мы ставили $!$ будет длинный комментарий выделено красным, начало и конец строки выделено фиолетовым.

все это дело заворачиваем в loop



для ячеек содержащих дату меняем
perform to_utf CHANGING it_zaaqb-ERSDA .
на
perform date_convert CHANGING it_zaaqb-ERSDA .

в самом конце поменять

xml_download4.
на
xml_download5 'отчет.xls'.

или поменять это в генераторе.


когда нужно распечатать

вызываем инклюд

if pa_print is not INITIAL.
include z_asikidin_report.
endif.

в самом начале нужно подключить 2 инклюда с макросами и переменными, или можно их слить в один

include ZBFI_RES_DEBT_uni. " unicode convert
include ZBFI_RES_DEBT_xml. " export to excel/xml

все отчет готов!
990 строчек кода написано.

исходники и рабочие примеры в архиве

Z_ASIKIDIN_XML - демо пример

инклюды необходимые для работы
ZBFI_RES_DEBT_UNI
ZBFI_RES_DEBT_XML

Генератор отчета
Z_ASIKIDIN_TEMP

сам отчет
Z_ASIKIDIN_REPORT



sample.rar
 Description:

Download
 Filename:  sample.rar
 Filesize:  3.22 KB
 Downloaded:  1795 Time(s)


zdev_xml.rar
 Description:

Download
 Filename:  zdev_xml.rar
 Filesize:  43.62 KB
 Downloaded:  1762 Time(s)

Back to top
View user's profile Send private message
Anton Sikidin
Участник
Участник



Joined: 11 Mar 2009
Posts: 18
Location: Украина

PostPosted: Thu Apr 05, 2012 11:46 pm    Post subject: Reply with quote

хм, форум почти никто не коментит, оставлю комментарий, чтоб показать что программа обновилась
Back to top
View user's profile Send private message
mvs87
Участник
Участник



Joined: 25 Feb 2009
Posts: 34

PostPosted: Wed Oct 29, 2014 10:29 am    Post subject: Reply with quote

Приветсвую! Спасибо за программу.

Сейчас пытаюсь испробовать на документе.

Скажите, а как сделать так, чтобы при пустых ячейках рамка не копировалась?
На рисунках лишняя рамка отмечена красным.



file_2.JPG
 Description:
Результат
 Filesize:  87.9 KB
 Viewed:  36647 Time(s)

file_2.JPG



file_1.JPG
 Description:
XML файл
 Filesize:  96.03 KB
 Viewed:  36647 Time(s)

file_1.JPG



_________________
С уважением, mvs87.
Back to top
View user's profile Send private message
Anton Sikidin
Участник
Участник



Joined: 11 Mar 2009
Posts: 18
Location: Украина

PostPosted: Wed Oct 29, 2014 2:27 pm    Post subject: Reply with quote

Никак, средствами моей оазработки, можно сделать в шаблоне условное форматирование и убирать рамки если ячейка пустая
------------
А не наврал, условное флрматирование то в екселе для zwww_openform, в этой разработке быстро не получится.
------------------
Опять наврал можно сделать, для этого нужно заменить стиль ячейки. Для примера sample.rar ss:StyleID="s27" нужно поменять на ss:StyleID="Default"

Рабочий пример будеь позже
Back to top
View user's profile Send private message
mvs87
Участник
Участник



Joined: 25 Feb 2009
Posts: 34

PostPosted: Wed Oct 29, 2014 2:52 pm    Post subject: Reply with quote

Anton Sikidin wrote:
Никак, средствами моей оазработки, можно сделать в шаблоне условное форматирование и убирать рамки если ячейка пустая
------------
А не наврал, условное флрматирование то в екселе для zwww_openform, в этой разработке быстро не получится.
------------------
Опять наврал можно сделать, для этого нужно заменить стиль ячейки. Для примера sample.rar ss:StyleID="s27" нужно поменять на ss:StyleID="Default"

Рабочий пример будеь позже


в sample.rar ни в программе ни в xml-ке ненашел строки ss:StyleID="s27"


Тут получается как. Из SMW0 тянется файл, туда вставляются значения по переменным. т.е. на этапе формирования файла начит.
А не подскажете, в какую сторону копать в "form export_to_excel"

_________________
С уважением, mvs87.
Back to top
View user's profile Send private message
Anton Sikidin
Участник
Участник



Joined: 11 Mar 2009
Posts: 18
Location: Украина

PostPosted: Wed Oct 29, 2014 3:24 pm    Post subject: Reply with quote

Да ошибся. Для примера sample.rar будет s27
Открываем блокнотом и видим
Code:
<Cell ss:StyleID="s27"><Data ss:Type="String">$#&lt;wa&gt;-AUTHOR$#</Data></Cell>


S27

Для примера sample.rar нужно после строки 165
Code:
REPLACE REGEX '(\$#(.*)\$#)' in wa_bufer WITH lv_str3.


Добавить
Code:
        IF <field> is initial.
          replace 'ss:StyleID="s22"' in wa_bufer with 'ss:StyleID="Default"'.
        ENDIF.

Это хардкод, но работает, красивое решение позже. Можно дописать в шаблон свли стили.

Мне тяжело писать с телефона, интернет порезан, напишите почту объясню лусчше
Back to top
View user's profile Send private message
mvs87
Участник
Участник



Joined: 25 Feb 2009
Posts: 34

PostPosted: Wed Oct 29, 2014 3:44 pm    Post subject: Reply with quote

Code:
        REPLACE REGEX '(\$#(.*)\$#)' in wa_bufer WITH lv_str3.
          IF <field> is initial.
            BREAK-POINT.
            replace 'ss:StyleID="s22"' in wa_bufer with 'ss:StyleID="Default"'.
          ENDIF.


не прокатил.
В отладчике менял ss:StyleID="s22" на ss:StyleID="Default"
тож не получается.

может не Default нужно?

_________________
С уважением, mvs87.
Back to top
View user's profile Send private message
Anton Sikidin
Участник
Участник



Joined: 11 Mar 2009
Posts: 18
Location: Украина

PostPosted: Wed Oct 29, 2014 3:55 pm    Post subject: Reply with quote

Я отправил вам почту личным сообщением
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> Submit a new program | Новые материалы, программы для сайта All times are GMT + 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG.
SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG.
Every effort is made to ensure content integrity. Use information on this site at your own risk.