*&---------------------------------------------------------------------*
*& Report Z_VK11_BDC_CSV_UPLOAD
*&---------------------------------------------------------------------*
*& BDC Program for VK11 - Create Condition Records from CSV File
*&---------------------------------------------------------------------*
REPORT z_vk11_bdc_csv_upload NO STANDARD PAGE HEADING.
*----------------------------------------------------------------------*
* TYPE DECLARATIONS
*----------------------------------------------------------------------*
TYPES: BEGIN OF ty_vk11,
kschl TYPE konv-kschl, " Condition Type
vkorg TYPE vbak-vkorg, " Sales Organization
vtweg TYPE vbak-vtweg, " Distribution Channel
matnr TYPE vbap-matnr, " Material Number
kbetr TYPE konv-kbetr, " Condition Rate
konwa TYPE konp-konwa, " Condition Unit
datab TYPE rv13a-datab, " Valid From Date
datbi TYPE rv13a-datbi, " Valid To Date
END OF ty_vk11.
*----------------------------------------------------------------------*
* DATA DECLARATIONS
*----------------------------------------------------------------------*
DATA: it_vk11 TYPE TABLE OF ty_vk11,
wa_vk11 TYPE ty_vk11.
DATA: it_raw_data TYPE truxs_t_text_data,
wa_raw_data TYPE string.
DATA: it_bdcdata TYPE TABLE OF bdcdata,
wa_bdcdata TYPE bdcdata.
DATA: it_bdcmsgcoll TYPE TABLE OF bdcmsgcoll,
wa_bdcmsgcoll TYPE bdcmsgcoll.
DATA: it_error TYPE TABLE OF ty_vk11,
wa_error TYPE ty_vk11.
DATA: lv_filename TYPE rlgrap-filename,
lv_date TYPE char10,
lv_success TYPE i,
lv_error TYPE i.
*----------------------------------------------------------------------*
* SELECTION SCREEN
*----------------------------------------------------------------------*
SELECTION-SCREEN: BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
PARAMETERS: p_file TYPE rlgrap-filename OBLIGATORY.
SELECTION-SCREEN: END OF BLOCK b1.
SELECTION-SCREEN: BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-002.
PARAMETERS: p_sep TYPE c LENGTH 1 DEFAULT ',' OBLIGATORY.
SELECTION-SCREEN: END OF BLOCK b2.
SELECTION-SCREEN: BEGIN OF BLOCK b3 WITH FRAME TITLE TEXT-003.
PARAMETERS: p_sess RADIOBUTTON GROUP rad1 DEFAULT 'X',
p_call RADIOBUTTON GROUP rad1,
p_sname TYPE apqi-groupid DEFAULT 'VK11_CSV_UP'.
SELECTION-SCREEN: END OF BLOCK b3.
*----------------------------------------------------------------------*
* TEXT ELEMENTS
*----------------------------------------------------------------------*
* TEXT-001: File Upload Settings
* TEXT-002: CSV Format Settings
* TEXT-003: Processing Method
*----------------------------------------------------------------------*
* AT SELECTION-SCREEN EVENTS
*----------------------------------------------------------------------*
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
PERFORM f4_filename.
*----------------------------------------------------------------------*
* START-OF-SELECTION
*----------------------------------------------------------------------*
START-OF-SELECTION.
PERFORM upload_csv_file.
PERFORM convert_csv_data.
PERFORM validate_data.
PERFORM process_data.
PERFORM display_results.
*----------------------------------------------------------------------*
* SUBROUTINES
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form F4_FILENAME
*&---------------------------------------------------------------------*
FORM f4_filename.
DATA: lt_file_table TYPE filetable,
lv_rc TYPE i,
lv_action TYPE i.
CALL METHOD cl_gui_frontend_services=>file_open_dialog
EXPORTING
window_title = 'Select CSV File'
default_extension = 'csv'
file_filter = 'CSV Files (*.csv)|*.csv|Text Files (*.txt)|*.txt'
multiselection = ' '
CHANGING
file_table = lt_file_table
rc = lv_rc
user_action = lv_action.
IF lv_action = cl_gui_frontend_services=>action_ok AND lines( lt_file_table ) > 0.
READ TABLE lt_file_table INTO DATA(ls_file) INDEX 1.
p_file = ls_file-filename.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form UPLOAD_CSV_FILE
*&---------------------------------------------------------------------*
FORM upload_csv_file.
" Upload CSV file as raw text data
CALL FUNCTION 'GUI_UPLOAD'
EXPORTING
filename = p_file
filetype = 'ASC'
has_field_separator = ' '
TABLES
data_tab = it_raw_data
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
OTHERS = 15.
IF sy-subrc <> 0.
MESSAGE 'Error uploading CSV file' TYPE 'E'.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form CONVERT_CSV_DATA
*&---------------------------------------------------------------------*
FORM convert_csv_data.
" Convert raw CSV data to structured internal table
CALL FUNCTION 'TEXT_CONVERT_CSV_TO_SAP'
EXPORTING
i_field_seperator = p_sep
i_line_header = 'X'
i_tab_raw_data = it_raw_data
TABLES
i_tab_converted_data = it_vk11
EXCEPTIONS
conversion_failed = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE 'Error converting CSV data' TYPE 'E'.
ENDIF.
" Remove header line if present
IF lines( it_vk11 ) > 0.
READ TABLE it_vk11 INTO wa_vk11 INDEX 1.
IF wa_vk11-kschl = 'KSCHL' OR wa_vk11-kschl = 'Condition Type'.
DELETE it_vk11 INDEX 1.
ENDIF.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form VALIDATE_DATA
*&---------------------------------------------------------------------*
FORM validate_data.
DATA: lv_index TYPE i.
LOOP AT it_vk11 INTO wa_vk11.
lv_index = sy-tabix.
" Validate mandatory fields
IF wa_vk11-kschl IS INITIAL OR
wa_vk11-vkorg IS INITIAL OR
wa_vk11-vtweg IS INITIAL OR
wa_vk11-matnr IS INITIAL OR
wa_vk11-kbetr IS INITIAL.
WRITE: / 'Validation Error - Row', lv_index,
': Missing mandatory fields'.
wa_error = wa_vk11.
APPEND wa_error TO it_error.
DELETE it_vk11 INDEX lv_index.
CONTINUE.
ENDIF.
" Validate date format (YYYYMMDD)
IF strlen( wa_vk11-datab ) <> 8 OR NOT wa_vk11-datab CO '0123456789'.
WRITE: / 'Date Format Error - Row', lv_index,
': Invalid date format for DATAB:', wa_vk11-datab.
wa_error = wa_vk11.
APPEND wa_error TO it_error.
DELETE it_vk11 INDEX lv_index.
CONTINUE.
ENDIF.
IF strlen( wa_vk11-datbi ) <> 8 OR NOT wa_vk11-datbi CO '0123456789'.
WRITE: / 'Date Format Error - Row', lv_index,
': Invalid date format for DATBI:', wa_vk11-datbi.
wa_error = wa_vk11.
APPEND wa_error TO it_error.
DELETE it_vk11 INDEX lv_index.
CONTINUE.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form PROCESS_DATA
*&---------------------------------------------------------------------*
FORM process_data.
IF lines( it_vk11 ) = 0.
MESSAGE 'No valid records to process' TYPE 'I'.
RETURN.
ENDIF.
IF p_sess = 'X'.
PERFORM session_method.
ELSE.
PERFORM call_transaction_method.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form SESSION_METHOD
*&---------------------------------------------------------------------*
FORM session_method.
" Open BDC Session
CALL FUNCTION 'BDC_OPEN_GROUP'
EXPORTING
client = sy-mandt
group = p_sname
keep = 'X'
user = sy-uname
tcode = 'VK11'.
LOOP AT it_vk11 INTO wa_vk11.
REFRESH it_bdcdata.
PERFORM fill_bdc_data.
" Insert data into session
CALL FUNCTION 'BDC_INSERT'
EXPORTING
tcode = 'VK11'
TABLES
dynprotab = it_bdcdata.
ENDLOOP.
" Close BDC Session
CALL FUNCTION 'BDC_CLOSE_GROUP'.
WRITE: / 'BDC Session', p_sname, 'created successfully with',
lines( it_vk11 ), 'records'.
WRITE: / 'Execute session in SM35 transaction'.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form CALL_TRANSACTION_METHOD
*&---------------------------------------------------------------------*
FORM call_transaction_method.
LOOP AT it_vk11 INTO wa_vk11.
REFRESH: it_bdcdata, it_bdcmsgcoll.
PERFORM fill_bdc_data.
" Call transaction VK11
CALL TRANSACTION 'VK11' USING it_bdcdata
MODE 'N'
UPDATE 'S'
MESSAGES INTO it_bdcmsgcoll.
IF sy-subrc = 0.
lv_success = lv_success + 1.
WRITE: / 'Success - Material:', wa_vk11-matnr,
'Condition Type:', wa_vk11-kschl.
ELSE.
lv_error = lv_error + 1.
PERFORM handle_errors.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FILL_BDC_DATA
*&---------------------------------------------------------------------*
FORM fill_bdc_data.
" First Screen - Enter Condition Type
PERFORM bdc_dynpro USING 'SAPMV13A' '0100'.
PERFORM bdc_field USING 'BDC_CURSOR' 'RV13A-KSCHL'.
PERFORM bdc_field USING 'BDC_OKCODE' '/00'.
PERFORM bdc_field USING 'RV13A-KSCHL' wa_vk11-kschl.
" Second Screen - Condition Record Details
PERFORM bdc_dynpro USING 'SAPMV13A' '1004'.
PERFORM bdc_field USING 'BDC_CURSOR' 'RV13A-DATBI(01)'.
PERFORM bdc_field USING 'BDC_OKCODE' '/00'.
PERFORM bdc_field USING 'KOMG-VKORG' wa_vk11-vkorg.
PERFORM bdc_field USING 'KOMG-VTWEG' wa_vk11-vtweg.
PERFORM bdc_field USING 'KOMG-MATNR(01)' wa_vk11-matnr.
" Format dates from YYYYMMDD to DD.MM.YYYY
CONCATENATE wa_vk11-datab+6(2) wa_vk11-datab+4(2)
wa_vk11-datab+0(4) INTO lv_date SEPARATED BY '.'.
PERFORM bdc_field USING 'RV13A-DATAB(01)' lv_date.
CONCATENATE wa_vk11-datbi+6(2) wa_vk11-datbi+4(2)
wa_vk11-datbi+0(4) INTO lv_date SEPARATED BY '.'.
PERFORM bdc_field USING 'RV13A-DATBI(01)' lv_date.
" Third Screen - Enter amount and save
PERFORM bdc_dynpro USING 'SAPMV13A' '1004'.
PERFORM bdc_field USING 'BDC_CURSOR' 'KONP-KBETR(01)'.
PERFORM bdc_field USING 'KONP-KBETR(01)' wa_vk11-kbetr.
IF NOT wa_vk11-konwa IS INITIAL.
PERFORM bdc_field USING 'KONP-KONWA(01)' wa_vk11-konwa.
ENDIF.
PERFORM bdc_field USING 'BDC_OKCODE' '=SICH'.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form BDC_DYNPRO
*&---------------------------------------------------------------------*
FORM bdc_dynpro USING program screen.
wa_bdcdata-program = program.
wa_bdcdata-dynpro = screen.
wa_bdcdata-dynbegin = 'X'.
APPEND wa_bdcdata TO it_bdcdata.
CLEAR wa_bdcdata.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form BDC_FIELD
*&---------------------------------------------------------------------*
FORM bdc_field USING fname fval.
wa_bdcdata-fnam = fname.
wa_bdcdata-fval = fval.
APPEND wa_bdcdata TO it_bdcdata.
CLEAR wa_bdcdata.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form HANDLE_ERRORS
*&---------------------------------------------------------------------*
FORM handle_errors.
WRITE: / 'Error processing Material:', wa_vk11-matnr.
LOOP AT it_bdcmsgcoll INTO wa_bdcmsgcoll.
IF wa_bdcmsgcoll-msgtyp = 'E' OR wa_bdcmsgcoll-msgtyp = 'A'.
WRITE: / ' Message:', wa_bdcmsgcoll-msgv1, wa_bdcmsgcoll-msgv2,
wa_bdcmsgcoll-msgv3, wa_bdcmsgcoll-msgv4.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form DISPLAY_RESULTS
*&---------------------------------------------------------------------*
FORM display_results.
WRITE: / '==============================================='.
WRITE: / 'CSV File Upload Results for VK11'.
WRITE: / '==============================================='.
WRITE: / 'File Processed:', p_file.
WRITE: / 'Separator Used:', p_sep.
IF p_call = 'X'.
WRITE: / 'Total Records Processed:', lv_success + lv_error.
WRITE: / 'Successful Records:', lv_success.
WRITE: / 'Error Records:', lv_error.
ELSE.
WRITE: / 'BDC Session Method Used'.
WRITE: / 'Records in Session:', lines( it_vk11 ).
ENDIF.
IF lines( it_error ) > 0.
WRITE: / 'Validation Errors:', lines( it_error ).
ENDIF.
ENDFORM.
Create a CSV file with the following structure :
text
KSCHL,VKORG,VTWEG,MATNR,KBETR,KONWA,DATAB,DATBI
ZZ01,1000,10,100-100,500.00,INR,20240101,20241231
ZZ01,1000,10,100-200,600.00,INR,20240101,20241231
PR00,1000,20,200-100,750.00,USD,20240201,20241231