gifts2017

Интеграция SAP и 1С8

Опубликовал Женька Ture (ture) в раздел Обмен - Обмен с другими системами

Интеграция SAP и 1С8 может быть осуществлена через многочисленные технологии, предлагаемые SAP. Но все они в конечном счете делятся на две группы:
1) обращение из SAP к 1С
2) обращение 1С к SAP
Я расскажу о каждой из этих групп.

Обращение из SAP к 1С.

К этой группе следует отнести непосредственное подключение из SAP к базе 1С, расположенной на SQL сервере. Я нашел единственно простое решение - непосредственно на сервере SAP работать с наполнением базы 1С минуя всяких посредников (включая платформу 1С). Вот пример загрузки справочника "Банки" из 1С в таблицу базы данных SAP:

REPORT  YTURE2.

"открываем соединение
EXEC SQL.
    CONNECT TO 'NSI' AS 'V'
ENDEXEC.

IF sy-subrc = 0.
    "ставим текущее соединение
    EXEC SQL.
      SET CONNECTION 'V'
    ENDEXEC.

    TABLES YBANK.
    "объявляем запись, которая будет принимать значения из курсора
    data: line like YBANK,
          bank like YBANK.

    "открываем курсор
    EXEC SQL.
       OPEN dbcur FOR SELECT
                          t.ссылка,
                          t.версия,
                          t.ПометкаУдаления,
                          t.код,
                          t.Наименование,
                          t.ГоловнойБанк,
                          t.КоррСчет
                      FROM RБанкиID as t
    ENDEXEC.


    DO.
       "извлекаем из курсора очередной набор
       EXEC SQL.
         FETCH NEXT dbcur INTO :line
       ENDEXEC.

       "убеждаемся, что получили из курсора данные
       IF sy-subrc <> 0.
         EXIT.
       ELSE.
         "найдем банк
         select SINGLE * into bank from YBANK where ref = line-ref.
         if sy-SUBRC = 0 and bank-VER = line-ver.
           CONTINUE. "пропускаем, т.к. не изменилось
         elseif sy-SUBRC = 0.
            UPDATE YBANK from LINE. "обновляем
         else.
            INSERT YBANK from LINE. "добавляем
         endif.

         "просто печатаем полученные данные
         select SINGLE * into bank from YBANK where ref = line-ref.
         if sy-SUBRC = 0.
           WRITE: / BANK-ref, BANK-ver, BANK-mark, BANK-code, BANK-DESCR, BANK-MAJOR_BANK, BANK-COR_ACCOUNT.
         ENDIF.

       ENDIF.
    ENDDO.

    "закрываем курсор
     EXEC SQL.
       CLOSE dbcur
     ENDEXEC.

     "закрываем соединение
      EXEC SQL.
        DISCONNECT 'V'
      ENDEXEC.
ENDIF.

В комментариях я отметил основные моменты (кто-то приятно ужаснется, впервые увидев этот процедурный язык). Не печальтесь, если что-то останется непонятно сразу. Здесь просто имитация работы с курсором sql. Код отдаленно напомнит Вам все, с чем Вы когда-то сталкивались и t-sql, и foxpro, и дельфи. Это просто букет воспоминаний.

Чтобы на SQL сервере было возможно так легко разобраться с наполнением бызы (запрос в тексте весьма недвусмысленно говорит о простоте), Вам понадобится создать представления к таблицам 1С (это отдельная тема, она есть и среди моих публикаций). Имея некий курсор, Вы можете прочитать последовательно весь справочник 1С, обрабатывая на каждом шаге его элементы. Я не стал приводить сложной реализации с делением на фрагменты обмена и ограничился линейным перебором с проверкой версии элемента справочника 1С перед загрузкой.

Самих настроек подключения Вы не видите, потому что они собраны в отдельном месте. Оно называется DBCO. Это имя некого мастера или формы, которые принято называть транзакцией. Не удивляйтесь искажению терминологии, т.к. SAP имеет глубокие исторические корни, и в каждый поворотный момент истории нужно было принимать решения о выборе пути и названий (SAP вообще редко везло с выбором). Ниже скрин настройки:

 

Здесь следует обратить внимание на тип подключаемой базы (DBMS) и строку соединения. Из-за путаницы терминов и подходов со строкой соединения с первого раза справляются не многие. Обратите внимание, что инстанс (экземпляр) сервера SQL указан через обратный слеш, а не тире. Проверить проблемы соединения можно в транзакции ST22, где будет детально описаны все проблемы (увы, здесь не всплывает окно сообщений, как в 1С). Файл библиотеки dbmssslib.dll можно скачать с маркета (http://scn.sap.com/thread/1345635) или извлечь из архива (пач ядра, для MSSQL). Архив с расширением sar или car можно открыть программой SAPCAR.EXE с параметрами -xvf После извлечения нужной библиотеки, ее можно просто скопировать по пути, указанном в ST22.

Я не нашел другого более простого и быстро реализуемого способа. Но из SAP можно работать и с веб-сервисами 1С. На первом итапе перед Вами будет стоять "дикая" потребность быстрого обмена, а веб-сервисы вообще не обеспечат требуемую скорость.

Обращение 1С к SAP.

Этот раздел сложен скорее своим многообразием выбора. Перед Вами и прямое обращение к базе данных SAP (как мы это сделали с 1С), и шина SAP PI (интеграционная шина), и Web AS (собственный web-сервер), и пр. Выбор велик, а времени во всем этом разбираться нет. По правде говоря, обидно будет затратить усилия и разочароваться в результате.

Давайте проведем аналогию с 1С. 1С умеет выгружать файлики и загружать их. SAP не может не уметь делать так же. Но разве это современно? 1С умеет отправлять почтовые сообщения, SAP и здесь не отстает. Но разве это быстро? 1С умеет работать с web-сервисами! О да! А как же SAP? 

SAP предлагает что-то большое и с первого взгляда невразумительно в теме web-сервисов. Когда Вы затратите свое дорогое время, внимательно и осторожно изучите этот вопрос, то вместе с чувством огромной проделанной работы и сорванных сроков в вашей душе поселится разочарование. Впрочем, если Вы сеньор программист с/с++/java и набрались в жизни много знаний о популярных и современных технологиях, то сможете рассуждать за одним столом с консультантами SAP о программировании, культуре бизнеса, политике и, конечно, симпатичных девушках. 

В основе всех известных мне сегодня технологиях доступа из 1С к SAP лежит абревиатура RFC. RFC - это удаленный вызов функций. Это чем-то напоминает web-сервисы 1С, только нет посредника и клиент непосредственно вызывает функциональные модули. Это работает непосредственно через сокеты (3300 tcp порт на сервере). Формат обмена спрятан в коммерческой библиотеке, которая предлагает API-интерфейс (смотрите детали в SDK RFC). Реализация предложена на языке C. Взгляните на простой пример. 

Это строка соединения:

Это подключение:

Это вызов удаленной функции по имени:

И закрываем соединение:

Просто и понятно, если Вы ежедневно пишете программы на с/с++. А если нет? Для таких случаев открывается целый спектор готовых решений, который я немного и упомянул выше. В первую очередь опытные консультанты обступят Вас вокруг с уже готовыми ценами за услуги. Смутное чувство нереальности происходящего не оставит Вас, пока они не уйдут. Но с их уходом останется только пустота (станное чувство, которое не возникает после разговора со специалистами). Нет, у Вас, конечно, останется понимание о размере счетов, которые нужно оплатить, но вот с пониманием и знанием следующих направлений развития все плачевно (помните продавцов в магазине?)

Я скажу Вам прямо без утайки. Если Вы овладеете RFC, то весь довесок или букет интеграционных решений станет Вам не нужен. Взгляните на простой алгоритм вызова из 1С удаленной функции SAP:

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	res=ПодключитьВнешнююКомпоненту("C:\Users\etyurin\Documents\Visual Studio 2013\ProjectsCPP\sap-rfc\Release\sap-rfc.dll", "VK", ТипВнешнейКомпоненты.Native);
	ДемоКомп = Новый("AddIn.VK.SapRfc");
	ДемоКомп.СтрокаСоединения="TYPE=3 CLIENT=1 USER=***** PASSWD=**** LANG=E ASHOST=***** SYSNR=00 USE_SAPGUI=0";
	Если не ДемоКомп.УстановитьСоединение() тогда
		Сообщить(ДемоКомп.ПоследняяОшибка());
	иначе		
		ДемоКомп.ИмяФункции="YTURE_FM";
		
		Строка1="WERRwqedqwdeqwd 1123123 ывапыРОРОР";
		ДемоКомп.ДобавитьПараметр("exporting","REQUTEXT","TYPC",Строка1,СтрДлина(Строка1));
		ДемоКомп.ДобавитьПараметр("importing","ECHOTEXT","TYPC","",1024);
		ДемоКомп.ДобавитьПараметр("importing","RESPTEXT","TYPC","",1024);
		
		//ДемоКомп.УдалитьПараметр("ECHOTEXT");
		//ДемоКомп.ДобавитьПараметр("importing","ECHOTEXT","TYPC","",1024);
		//res=ДемоКомп.КоличествоПараметров("importing");
		
		Если не ДемоКомп.Вызвать() тогда
			Сообщить(ДемоКомп.ПоследняяОшибка());
		Иначе
			res1=ДемоКомп.ПолучитьПараметр("ECHOTEXT");
			res2=ДемоКомп.ПолучитьПараметр("RESPTEXT");
			ДемоКомп.ОчиститьВсеПараметры();
		КонецЕсли;
		ДемоКомп.ЗакрытьСоединение();
	КонецЕсли;	
	
КонецПроцедуры

Удаленная функция представляет из себя функциональный модуль (в примере это YTURE_FM). Функция принимает один строковый параметр с именем REQUTEXT и возвращает два строковых параметра ECHOTEXT и RESPTEXT (это как передать в функцию три параметра, два из которых она изменит).

Функциональный модуль можно создать в транзакции SE37. Обратите внимание на отметку удаленного вызова:

 Входящие параметры:

Возвращаемые параметры:

А вот и обработка на сервере SAP переданных параметров:

Здесь в коде нет заморочек. Это просто ЭХО, т.е. возвращается то, что передали (параметр с именем RESPTEXT дополнительно заполняется сведениями о подключении).

Имея возможность подключиться из 1С непосредственно к серверу SAP, минуя многочисленных посредников, Вы бережете время и получаете максимальную скорость. Чтобы описание не выглядело голословно, я приложил релиз компоненты для 1С. Однако надеюсь, что я убедил Вас в правильности использовать и изучать сразу RFC и не разбрасывать своё время и усилия на зоопарк вокруг интеграции. В конечном счете Вы сбережете и фонд оплаты труда, т.к. зверинец весьма прожорлив.  

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Компjнента
.7z 67,48Kb
15.04.16
5
.7z 67,48Kb 5 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. aspirator 23 (aspirator23) 15.04.16 17:51
Тоже использовал RFC. Правда сами функции писали программисты sap. Только согласовывал с ними передаваемые параметры.
2. Two World (Prometeus2011) 18.04.16 17:34
Тема, несомненно, интересная. Однако, SAP достаточно редкая птица на российских просторах учетных систем. Думаю, если-бы были задачи, то нашлись-бы и исполнители. Я, например. И ВК написать для обмена - не сильно большая проблема, в общем-то. Но в целях самопознания это мутить - полный эксгибиционизм. Короче, нужна конкретная задача.
3. Олег Филиппов (comol) 19.04.16 11:15
Как-то всё-таки не православно забить на XI/PI и "пилить" интеграцию "дедовским способом"....
4. Женька Ture (ture) 19.04.16 18:41
(3) comol, в начале внедрения остро стоит вопрос перемещения большого количества данных в SAP (поэтому прямое обращение к вьюхам 1С). А вот безнаказанно ходить к данным в сап как в 1С еще нельзя (поэтому rfc). Прочие интеграционные продукты (к примеру, которые Вы упомянули) работают через rfc, но вводят дополнительное звено - продукт написанный на java. Пока остро стоит потребность в движение большого количества информации, java будет слабым звеном (очень медленно и много ресурсов отнимает).
5. Максим Кузнецов (Makushimo) 20.04.16 07:36
а мне понравился настрой автора.
ничего не понятно, конечно с наскоку, но настроение как ни странно не испортилось )))
плюсую
корум; Saint13; +2 Ответить
6. Максим Пащенко (maksip) 04.05.16 16:27
Мне кажется не совсем уместным данными из таблиц БД 1с делать напрямую загрузку в БД SAP и наоборот. При обновлении платформы 1с может измениться структура хранения таблиц. И если со справочником банков это ещё и может пройдет, то с регистрами или даже документами возможно вся загрузка возможно сломается. Плюс ко всему нет возможности использовать бизнес логику 1с,а она при обновлении конфигурации также может меняться. К тому же встает вопрос о блокировках, как себя поведет сервер БД и сервер приложений 1с при одновременном использовании таблиц и 1с и обработкой БД.
7. Женька Ture (ture) 04.05.16 16:44
(6) maksip,
При обновлении платформы 1с может измениться структура хранения таблиц.
так и будет, если удалять реквизиты, к примеру.
Плюс ко всему нет возможности использовать бизнес логику 1с
и это верно(что меня радует однозначно)
К тому же встает вопрос о блокировках
еще как может встать.

Вьюхи переделываем после обновлений конфигурации, сломанные загрузки чиним (иногда даже заранее), логика 1С не пашет и "владельцы" базы ноят, что их не спросили, а им хотелось бы подмазаться, ну и конечно блокировок нет, потому что грязное чтение во вьюхах (это как грязные танцы). Загрузка периодическая (10 мин), т..е. данные выправляются по версии (можно добавлять задержку в 1-2 мин, чтоб танцев не было, но так уже не зажигает).
8. Максим Пащенко (maksip) 04.05.16 17:14
(7) ture, (7) ture, Тогда согласен. В этом случае решение вполне подходит
9. Трактор Трактор (Трактор) 05.05.16 12:13
Хорошее решение для тех у кого и сап и 1С под рукой. Возможно даже лучшее. Ибо мой опыт работы с сапёрами говорит о море непонимания при обсуждении интерфейсов. Я несколько раз делал обмен с САПом. Всегда это был обмен файлами. А файлы у САПа сильно замусорены. На три значащих поля двадцать не имеющих к обмену отношения.
10. Женька Ture (ture) 23.06.16 11:11
Если кто изощренный никрофил, то ему понравится пара примеров от мастера.
Здесь процедурная модель:
REPORT  zfirst_program03.


TABLES sflight.

"внутренняя таблица
DATA: gt_sflight TYPE TABLE OF sflight.

"объявление параметров отбора
SELECT-OPTIONS: so_car FOR sflight-carrid,
                so_con FOR sflight-connid,
                so_fld FOR sflight-fldate.

START-OF-SELECTION.

  SELECT
    *
  INTO TABLE gt_sflight
  FROM
    sflight
  WHERE
    carrid  IN so_car
    AND  connid  IN so_con
    AND  fldate  IN so_fld.

  IF sy-subrc <> 0.
    "сообщение в строке состояния
    MESSAGE 'Нету' TYPE 'S'.
    RETURN. "выход из программного модуля
  ENDIF.

  IF LINES( gt_sflight ) = 8. "количество строк в таблице
    DATA n TYPE i.
    n = LINES( gt_sflight ).
    WRITE: / n.
  ENDIF.

  DATA: lt_fcat TYPE lvc_t_fcat.
  CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
   EXPORTING
*     I_BUFFER_ACTIVE              =
     i_structure_name             = 'SFLIGHT' "считываем метаданные именно этой таблицы
*     I_CLIENT_NEVER_DISPLAY       = 'X'
*     I_BYPASSING_BUFFER           =
*     I_INTERNAL_TABNAME           =
   CHANGING
      ct_fieldcat                  = lt_fcat  "и сохраняем МЕТАДАННЫЕ в эту внутреннюю таблицу
   EXCEPTIONS
     inconsistent_interface       = 1
     program_error                = 2
     OTHERS                       = 3.

  IF sy-subrc <> 0.
    CASE sy-subrc.
      WHEN 1.
      WHEN 2.
        MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
      WHEN OTHERS.
    ENDCASE.
  ENDIF.

  DATA: ls_fcat LIKE LINE OF lt_fcat.
  ls_fcat-do_sum = 'X'.

  MODIFY lt_fcat FROM ls_fcat
  TRANSPORTING do_sum  "меняем только одно поле во внутренней таблице на основе структуры
  WHERE fieldname = 'PAYMENTSUM' OR fieldname = 'PRICE'.

  DATA: ls_layout TYPE lvc_s_layo.
  "делаем зебру в списке
  ls_layout-zebra = 'X'.
  "минимальная ширина колонок
  ls_layout-cwidth_opt = 'X'.

  "ls_layout-edit = 'X'.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
   EXPORTING
*     I_INTERFACE_CHECK                 = ' '
*     I_BYPASSING_BUFFER                =
*     I_BUFFER_ACTIVE                   =
     i_callback_program                = sy-repid
*     I_CALLBACK_PF_STATUS_SET          = ' '
     i_callback_user_command           = 'ZNYP'
*     I_CALLBACK_TOP_OF_PAGE            = ' '
*     I_CALLBACK_HTML_TOP_OF_PAGE       = ' '
*     I_CALLBACK_HTML_END_OF_LIST       = ' '
*     I_STRUCTURE_NAME                  =
*     I_BACKGROUND_ID                   = ' '
*     I_GRID_TITLE                      =
*     I_GRID_SETTINGS                   =
     is_layout_lvc                     = ls_layout
     it_fieldcat_lvc                   = lt_fcat "передаем метаданные
*     IT_EXCLUDING                      =
*     IT_SPECIAL_GROUPS_LVC             =
*     IT_SORT_LVC                       =
*     IT_FILTER_LVC                     =
*     IT_HYPERLINK                      =
*     IS_SEL_HIDE                       =
*     I_DEFAULT                         = 'X'
*     I_SAVE                            = ' '
*     IS_VARIANT                        =
*     IT_EVENTS                         =
*     IT_EVENT_EXIT                     =
*     IS_PRINT_LVC                      =
*     IS_REPREP_ID_LVC                  =
*     I_SCREEN_START_COLUMN             = 0
*     I_SCREEN_START_LINE               = 0
*     I_SCREEN_END_COLUMN               = 0
*     I_SCREEN_END_LINE                 = 0
*     I_HTML_HEIGHT_TOP                 =
*     I_HTML_HEIGHT_END                 =
*     IT_ALV_GRAPHICS                   =
*     IT_EXCEPT_QINFO_LVC               =
*     IR_SALV_FULLSCREEN_ADAPTER        =
*   IMPORTING
*     E_EXIT_CAUSED_BY_CALLER           =
*     ES_EXIT_CAUSED_BY_USER            =
    TABLES
      t_outtab                          = gt_sflight "передаем сами данные
*   EXCEPTIONS
*     PROGRAM_ERROR                     = 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.
  ENDIF.

*&---------------------------------------------------------------------*
*&      Form  my_CALLBACK_PROGRAM
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
  TYPE-POOLS slis.
*&---------------------------------------------------------------------*
*&      Form  zmy_callback
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->R_UCOMM      text
*      -->LS_SELFIELD  text
*----------------------------------------------------------------------*
FORM ZNYP USING r_ucomm LIKE sy-ucomm
                        ls_selfield TYPE slis_selfield.
  CASE r_ucomm.
    WHEN '&IC1'. "double clik
      MESSAGE 'Пупс' TYPE 'S'.
  ENDCASE.

ENDFORM.                    "my_callback_program
...Показать Скрыть


А здесь объектная:
REPORT  zthrid_program_v3.

*----------------------------------------------------------------------*
*       CLASS lcl_handle_events DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS my_handle_events DEFINITION.
  PUBLIC SECTION.
    METHODS:
      on_double_click FOR EVENT double_click OF cl_salv_events_table
        IMPORTING row column.
ENDCLASS.                    "lcl_handle_events DEFINITION

TABLES sflight.
DATA: lt_sflight TYPE TABLE OF sflight.

SELECT-OPTIONS: so_car FOR sflight-carrid,
                so_con FOR sflight-connid,
                so_fld FOR sflight-fldate.


START-OF-SELECTION.
  "заполняем внутреннюю таблицу
  SELECT
    *
  INTO TABLE lt_sflight
  FROM  sflight
         WHERE  carrid  IN so_car
         AND    connid  IN so_con
         AND    fldate  IN so_fld.

  DATA cls TYPE REF TO cl_salv_table.

*  TRY.
  cl_salv_table=>factory(
*    EXPORTING
*      list_display   = IF_SALV_C_BOOL_SAP=>FALSE
*      r_container    =
*      container_name =
  IMPORTING
    r_salv_table   = cls
  CHANGING
    t_table        = lt_sflight
    ).
*   CATCH cx_salv_msg .
*  ENDTRY.

  "настройка внешнего вида
  DATA cls_set TYPE REF TO cl_salv_display_settings.
  cls_set = cls->get_display_settings( ).
  "зебра
  cls_set->set_striped_pattern( 'X' ).
  "заголовок
  cls_set->set_list_header( 'Ну-у, пипец.' ).

  "узкие колонки
  DATA cols TYPE REF TO cl_salv_columns_table.
  cols = cls->get_columns( ).
  cols->set_optimize( 'X' ).

  "сортировка
  DATA lr_sorts TYPE REF TO cl_salv_sorts.
  lr_sorts = cls->get_sorts( ).
  lr_sorts->add_sort( EXPORTING columnname = 'CARRID'
                                       position   = '1'
                                       sequence   = '1' "направление сортировки 1(возраст) и 2(убыв)
                                       subtotal   = ' ' ).

  "агрегатные функции
  DATA aggrs TYPE REF TO cl_salv_aggregations.
  aggrs = cls->get_aggregations( ).
  aggrs->add_aggregation(
          EXPORTING
            columnname  = 'PRICE'
            aggregation = if_salv_c_aggregation=>total "выбираем сумму по колонке
         ).
  aggrs->add_aggregation(
          EXPORTING
            columnname  = 'PAYMENTSUM'
            aggregation = if_salv_c_aggregation=>average "выбираем среднее по колонке
         ).
  "если итоги надо сверху
  "aggrs->set_aggregation_before_items( ).

  "настраиваем обработчики событий класса
  DATA events TYPE REF TO cl_salv_events_table.
  events = cls->get_event( ).
  DATA even TYPE REF TO my_handle_events.
  CREATE OBJECT even.
  SET HANDLER even->on_double_click FOR events.

  "отображение данных таблицы
  cls->display( ).

*----------------------------------------------------------------------*
*       CLASS lcl_handle_events IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS my_handle_events IMPLEMENTATION.
  METHOD on_double_click.
    MESSAGE 'во блин хрень то' TYPE 'I'. " row column .
  ENDMETHOD.                    "on_double_click
ENDCLASS.                    "lcl_handle_events IMPLEMENTATION
...Показать Скрыть


11. Женька Ture (ture) 19.09.16 11:14
Работа с локальным текстовичком:
REPORT z_file_client_eturin.

PARAMETERS: p_file  TYPE text80  OBLIGATORY,  " filename-fileintern
            l_write AS CHECKBOX.


AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.

  DATA: filename TYPE string,
        path     TYPE string,
        fullpath TYPE string.
  IF l_write = abap_true.
    CALL METHOD cl_gui_frontend_services=>file_save_dialog
      EXPORTING
*       window_title      =
        default_extension = 'txt'
*       default_file_name =
*       with_encoding     =
*       file_filter       =
*       initial_directory =
*       prompt_on_overwrite       = 'X'
      CHANGING
        filename          = filename
        path              = path
        fullpath          = fullpath
*       user_action       =
*       file_encoding     =
*   EXCEPTIONS
*       cntl_error        = 1
*       error_no_gui      = 2
*       not_supported_by_gui      = 3
*       invalid_default_file_name = 4
*       others            = 5
      .
    IF sy-subrc <> 0.
*  Implement suitable error handling here
    ENDIF.
    p_file = fullpath.
  ELSE.
    DATA: file_table TYPE filetable,
          rc         TYPE i.

       CALL METHOD cl_gui_frontend_services=>file_open_dialog
         EXPORTING
           window_title            = 'Enter file'
*    default_extension       =
*    default_filename        =
*    file_filter             =
*    with_encoding           =
*    initial_directory       =
*    multiselection          =
         CHANGING
           file_table              = file_table
           rc                      = rc
*    user_action             =
*    file_encoding           =
*  EXCEPTIONS
*    file_open_dialog_failed = 1
*    cntl_error              = 2
*    error_no_gui            = 3
*    not_supported_by_gui    = 4
*    others                  = 5
          .
    IF sy-subrc <> 0.
* Implement suitable error handling here
    ENDIF.

    p_file = FILE_TABLE[ 1 ]-FILENAME.


  ENDIF.


START-OF-SELECTION.
  DATA: lt_data    TYPE TABLE OF text100,
        l_filename TYPE string.

  l_filename = p_file.
  IF l_write = abap_true.
    DO 3 TIMES.
      APPEND INITIAL LINE TO lt_data ASSIGNING FIELD-SYMBOL(<line>).
      <line> = |херня{ sy-index }. | && p_file.
    ENDDO.

    CALL METHOD cl_gui_frontend_services=>gui_download
      EXPORTING
*       bin_filesize              =
        filename = l_filename
*       filetype = 'ASC'
*       append   = SPACE
*       write_field_separator     = SPACE
*       header   = '00'
*       trunc_trailing_blanks     = SPACE
*       write_lf = 'X'
*       col_select                = SPACE
*       col_select_mask           = SPACE
*       dat_mode = SPACE
*       confirm_overwrite         = SPACE
*       no_auth_check             = SPACE
*       codepage = SPACE
*       ignore_cerr               = ABAP_TRUE
*       replacement               = '#'
*       write_bom                 = SPACE
*       trunc_trailing_blanks_eol = 'X'
*       wk1_n_format              = SPACE
*       wk1_n_size                = SPACE
*       wk1_t_format              = SPACE
*       wk1_t_size                = SPACE
*       show_transfer_status      = 'X'
*       fieldnames                =
*       write_lf_after_last_line  = 'X'
*       virus_scan_profile        = '/SCET/GUI_DOWNLOAD'
*  IMPORTING
*       filelength                =
      CHANGING
        data_tab = lt_data
*  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
*       not_supported_by_gui      = 22
*       error_no_gui              = 23
*       others   = 24
      .
    IF sy-subrc <> 0.
* Implement suitable error handling here
    ENDIF.

  ELSE.


    CALL METHOD cl_gui_frontend_services=>gui_upload
        EXPORTING
          filename                =  l_filename
*          filetype                = 'ASC'
*          has_field_separator     = SPACE
*          header_length           = 0
*          read_by_line            = 'X'
*          dat_mode                = SPACE
*          codepage                = SPACE
*          ignore_cerr             = ABAP_TRUE
*          replacement             = '#'
*          virus_scan_profile      =
*        IMPORTING
*          filelength              =
*          header                  =
      CHANGING
        data_tab = lt_data
*       isscanperformed         = SPACE
*        EXCEPTIONS
*       file_open_error         = 1
*       file_read_error         = 2
*       no_batch = 3
*       gui_refuse_filetransfer = 4
*       invalid_type            = 5
*       no_authority            = 6
*       unknown_error           = 7
*       bad_data_format         = 8
*       header_not_allowed      = 9
*       separator_not_allowed   = 10
*       header_too_long         = 11
*       unknown_dp_error        = 12
*       access_denied           = 13
*       dp_out_of_memory        = 14
*       disk_full               = 15
*       dp_timeout              = 16
*       not_supported_by_gui    = 17
*       error_no_gui            = 18
*       others   = 19
      .
    IF sy-subrc <> 0.
*       Implement suitable error handling here
    ENDIF.

  ENDIF.
...Показать Скрыть
12. Женька Ture (ture) 19.09.16 11:15
Чтение логических и физических файлов:
*&---------------------------------------------------------------------*
*& Report  Z_LOGIC_FILE_SERVER_ETURIN
*&
*&---------------------------------------------------------------------*
*&      
*&
*&---------------------------------------------------------------------*
REPORT z_logic_file_server_eturin.
 
PARAMETERS p_lfile TYPE fileintern OBLIGATORY.
PARAMETERS p_write AS CHECKBOX.
 
START-OF-SELECTION.
  DATA: l_file_name TYPE text100.
  CALL FUNCTION 'FILE_GET_NAME'
    EXPORTING
*     CLIENT           = SY-MANDT
      logical_filename = p_lfile
*     OPERATING_SYSTEM = SY-OPSYS
      parameter_1      = 'PARAM1'
      parameter_2      = 'PARAM2'
      parameter_3      = 'PARAM3'
*     USE_PRESENTATION_SERVER       = ' '
*     WITH_FILE_EXTENSION           = ' '
*     USE_BUFFER       = ' '
*     ELEMINATE_BLANKS = 'X'
*     INCLUDING_DIR    = ' '
    IMPORTING
*     EMERGENCY_FLAG   =
*     FILE_FORMAT      =
      file_name        = l_file_name
* EXCEPTIONS
*     FILE_NOT_FOUND   = 1
*     OTHERS           = 2
    .
  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.
 
  TRY.
      DATA: l_line    TYPE text100,
            l_endfile TYPE abap_bool.
      IF p_write = abap_on.
        OPEN DATASET l_file_name FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
 
        DO 3 TIMES.
          TRANSFER l_file_name TO l_file_name.
        ENDDO.
      ELSE.
        OPEN DATASET l_file_name FOR INPUT IN TEXT MODE ENCODING UTF-8.
        GET DATASET l_file_name ATTRIBUTES DATA(l_attr).
        WHILE l_endfile = abap_off.
          READ DATASET l_file_name INTO l_line.
          WRITE : / l_line.
          IF sy-subrc NE 0.
            l_endfile = abap_on.
 
          ENDIF.
        ENDWHILE.
      ENDIF.
 
      CLOSE DATASET l_file_name.
    CATCH cx_sy_file_access_error INTO DATA(lo_ex).
      WRITE: / lo_ex->get_text( ).
 
  ENDTRY.
...Показать Скрыть
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа