Uploading files from PC(Presentation Server) |
|
There are also a number of other function modules which could be used for uploading/downloding files between SAP and the presentation server. |
|
*
Retrieve data file from presentation server(Upload from PC)
DATA: i_file like rlgrap-filename value '/usr/sap/tmp/file.txt'.
DATA: begin of it_datatab occurs 0,
row(500) type c,
end of it_datatab.
CALL FUNCTION 'GUI_UPLOAD'
EXPORTING
filename
= i_file
filetype
= 'ASC'
TABLES
data_tab
= it_datatab
"ITBL_IN_RECORD[]
EXCEPTIONS
file_open_error = 1
OTHERS
= 2.
|
Downloading files to PC(Presentation Server) |
|
There are also a number of other function modules which could be used for uploading/downloding files between SAP and the presentation server. |
|
*
Download internal table to presentation server file(PC)
DATA: ld_filename TYPE string,
* Pre version 4.7 declaration e_file like rlgrap-filename.
DATA: begin of it_datatab occurs 0,
row(500) type c,
end of it_datatab.
call function 'GUI_DOWNLOAD'
exporting
filename
= ld_filename
filetype
= 'ASC'
tables
data_tab
= it_datatab[]
exceptions
file_open_error
= 1
file_write_error = 2
others = 3. |
*
Download internal table to presentation server file(PC)
*
Separating fields/columns by a tab
DATA: ld_filename TYPE string,
* Pre version 4.7 declaration e_file like rlgrap-filename.
DATA: begin of it_datatab occurs 0,
col1(50) type c,
col2(50) type c,
col3(50) type c,
*
etc....
end of it_datatab.
CALL FUNCTION 'GUI_DOWNLOAD'
EXPORTING
filename
= ld_filename
filetype
= 'ASC'
*
APPEND
= 'X'
write_field_separator = 'X'
*
CONFIRM_OVERWRITE = 'X'
TABLES
data_tab
= it_datatab[]
EXCEPTIONS
file_open_error
= 1
file_write_error = 2
OTHERS = 3.
|
Uploading files from SAP(Application Server)) |
|
|
|
*
Retrieve Data file from Application server(Upload from Unix)
DATA: i_file like rlgrap-filename value '/usr/sap/tmp/file.txt'.
OPEN DATASET i_file FOR INPUT IN TEXT MODE.
IF sy-subrc NE 0.
MESSAGE e999(za) WITH 'Error opening file' i_file.
ENDIF.
DO.
*
Reads each line of file individually
READ DATASET i_file INTO wa_datatab.
*
Perform processing here
*
.....
ENDDO.
|
Downloading files to SAP(Application Server) |
|
|
|
*
Download internal table to Application server file(Unix)
DATA: e_file like rlgrap-filename value '/usr/sap/tmp/file.txt'.
open dataset e_file for output in text mode.
lOOP AT it_datatab......
transfer it_datatab to e_file.
ENDLOOP.
close dataset e_file.
|
Check if file exists before downloading |
|
ABAP code for downloading data to a file on the presentatuion server(PC). It also checks if file exists and allows user to replace existing file, change name or cancel during download process.
|
|
* This method of file download with check uses the latest techniques
* and achieves a very neat solution
DATA: ld_filename TYPE string,
ld_path TYPE string,
ld_fullpath TYPE string,
ld_result TYPE i.
* Display save dialog window
CALL METHOD cl_gui_frontend_services=>file_save_dialog
EXPORTING
*
window_title
= ' '
DEFAULT_EXTENSION = 'XLS'
default_file_name = 'accountsdata'
INITIAL_DIRECTORY = 'c:/temp/'
CHANGING
filename
= ld_filename
path
= ld_path
fullpath
= ld_fullpath
user_action
= ld_result.
* Check user did not cancel request
CHECK ld_result EQ '0'.
CALL FUNCTION 'GUI_DOWNLOAD'
EXPORTING
filename
= ld_fullpath
filetype
= 'ASC'
*
APPEND
= 'X'
write_field_separator = 'X'
*
CONFIRM_OVERWRITE = 'X'
TABLES
data_tab
= it_datatab[]
"need to declare and populate
EXCEPTIONS
file_open_error
= 1
file_write_error = 2
OTHERS = 3.
|
* File download, uses older techniques but achieves a perfectly
* acceptable solution which also allows the user to append data to
* an existing file.
PARAMETERS: p_file like rlgrap-filename.
* Internal table to store export data
DATA: begin of it_excelfile occurs 0,
row(500) type c,
end of it_excelfile.
DATA: rc TYPE sy-ucomm,
ld_answer TYPE c.
CALL FUNCTION 'WS_QUERY'
EXPORTING
query
= 'FE'
"File Exist?
filename = p_file
IMPORTING
return
= rc.
IF rc NE 0.
"If File alread exists
CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
*
TITLEBAR
= ' '
*
DIAGNOSE_OBJECT
= ' '
text_question
= 'File Already exists!!'
text_button_1
= 'Replace'
*
ICON_BUTTON_1
= ' '
text_button_2
= 'New name'
*
ICON_BUTTON_2
= ' '
*
DEFAULT_BUTTON
= '1'
*
DISPLAY_CANCEL_BUTTON = 'X'
*
USERDEFINED_F1_HELP
= ' '
*
START_COLUMN
= 25
*
START_ROW
= 6
*
POPUP_TYPE
=
IMPORTING
answer
= ld_answer
*
TABLES
*
PARAMETER
=
EXCEPTIONS
text_not_found
= 1
OTHERS
= 2.
* Option 1: Overwrite
*********************
IF ld_answer EQ '1'.
CALL FUNCTION 'GUI_DOWNLOAD'
EXPORTING
*
BIN_FILESIZE
=
filename
= p_file
"File Name
filetype
= 'ASC'
*
IMPORTING
*
FILELENGTH
=
TABLES
data_tab
= it_excelfile
"Data table
EXCEPTIONS
file_write_error
= 1
no_batch
= 2
gui_refuse_filetransfer = 3
invalid_type
= 4
OTHERS
= 5.
IF sy-subrc <> 0.
MESSAGE i003(zp) WITH
'There was an error during Excel file creation'(200).
exit. "Causes short dump if removed and excel document was open
ENDIF.
* Option 2: New name.
*********************
ELSEIF ld_answer EQ '2'.
CALL FUNCTION 'DOWNLOAD'
EXPORTING
filename
= p_file
"File name
filetype
= 'ASC'
"File type
*
col_select
= 'X'
"COL_SELECT
*
col_selectmask
= 'XXXXXXXXXXXXXXXXXXXXXXXXXX'
*
"COL_SELECTMASK
filetype_no_show
= 'X'
"Show file type selection?
*
IMPORTING
*
act_filename
= filename_dat
TABLES
data_tab
= it_excelfile
"Data table
*
fieldnames
=
EXCEPTIONS
file_open_error
= 01
file_write_error
= 02
invalid_filesize
= 03
invalid_table_width = 04
invalid_type
= 05
no_batch
= 06
unknown_error
= 07.
ENDIF.
ELSE.
"File does not alread exist.
CALL FUNCTION 'GUI_DOWNLOAD'
EXPORTING
*
BIN_FILESIZE
=
filename
= p_file
"File name
filetype
= 'ASC'
"File type
*
IMPORTING
*
FILELENGTH
=
TABLES
data_tab
= it_excelfile
"Data table
EXCEPTIONS
file_write_error
= 1
no_batch
= 2
gui_refuse_filetransfer = 3
invalid_type
= 4
OTHERS
= 5.
IF sy-subrc <> 0.
MESSAGE i003(zp) WITH
'There was an error during Excel file creation'(200).
exit. "Causes short dump if removed and excel document was open
ENDIF.
ENDIF.
|
Upload Excel document into internal table |
|
ABAP code for uploading an Excel document into an internal table. See code below for structures. The code is based on uploading a simple Excel spreadsheet or for an actual Excel file click here. There are also a couple of alternatives which use fucntion modules 'KCD_EXCEL_OLE_TO_INT_CONVERT' and 'ALSM_EXCEL_TO_INTERNAL_TABLE' but the method below is by far the simplest method to used. A big thanks to Jayanta for bringing this method to my attention. |
|
*..............................................................
*: Description
:
*: -----------
:
*: This is a simple example program to get data from an excel :
*: file and store it in an internal table.
:
*:
:
*: Author : www.sapdev.co.uk, based on code from Jayanta : *:
:
*: SAP Version : 4.7
:
*:............................................................:
REPORT
zupload_excel_to_itab.
TYPE-POOLS: truxs.
PARAMETERS: p_file TYPE
rlgrap-filename.
TYPES: BEGIN OF t_datatab,
col1(30)
TYPE c,
col2(30)
TYPE c,
col3(30)
TYPE c,
END OF t_datatab.
DATA: it_datatab type standard table of t_datatab,
wa_datatab type t_datatab.
DATA: it_raw TYPE truxs_t_text_data.
* At selection screen
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
CALL FUNCTION 'F4_FILENAME'
EXPORTING
field_name = 'P_FILE'
IMPORTING
file_name
= p_file.
***********************************************************************
*START-OF-SELECTION.
START-OF-SELECTION.
CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP'
EXPORTING
*
I_FIELD_SEPERATOR
=
i_line_header
=
'X'
i_tab_raw_data
=
it_raw
" WORK TABLE
i_filename
=
p_file
TABLES
i_tab_converted_data
= it_datatab[]
"ACTUAL DATA
EXCEPTIONS
conversion_failed
= 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.
***********************************************************************
* END-OF-SELECTION.
END-OF-SELECTION.
LOOP AT it_datatab INTO wa_datatab.
WRITE:/ wa_datatab-col1,
wa_datatab-col2,
wa_datatab-col3.
ENDLOOP.
|
Upload Tab delimited file from application server into internal table |
|
ABAP code for uploading a TAB delimited file into an internal table. See code below for structures. The code is base on uploading a simple txt file. |
|
*&---------------------------------------------------------------------*
*& Report
ZUPLOADTAB
*
*&
*
*&---------------------------------------------------------------------*
*& Example of Uploading tab delimited file
*
*&
*
*&---------------------------------------------------------------------*
REPORT
zuploadtab
.
PARAMETERS: p_infile
LIKE rlgrap-filename
OBLIGATORY DEFAULT
'/usr/sap/'..
DATA: ld_file LIKE rlgrap-filename.
*Internal tabe to store upload data
TYPES: BEGIN OF t_record,
name1 like pa0002-VORNA,
name2 like pa0002-name2,
age
type i,
END OF t_record.
DATA: it_record TYPE STANDARD TABLE OF t_record INITIAL SIZE 0,
wa_record TYPE t_record.
*Text version of data table
TYPES: begin of t_uploadtxt,
name1(10) type c,
name2(15) type c,
age(5)
type c,
end of t_uploadtxt.
DATA: wa_uploadtxt TYPE t_uploadtxt.
*String value to data in initially.
DATA: wa_string(255) type c.
constants: con_tab TYPE x VALUE '09'.
*If you have Unicode check active in program attributes then you will
*need to declare constants as follows:
*class cl_abap_char_utilities definition load.
*constants:
*
con_tab
type c value cl_abap_char_utilities=>HORIZONTAL_TAB.
************************************************************************
*START-OF-SELECTION
START-OF-SELECTION.
ld_file = p_infile.
OPEN DATASET ld_file FOR INPUT IN TEXT MODE ENCODING DEFAULT.
IF sy-subrc NE 0.
ELSE.
DO.
CLEAR: wa_string, wa_uploadtxt.
READ DATASET ld_file INTO wa_string.
IF sy-subrc NE 0.
EXIT.
ELSE.
SPLIT wa_string AT con_tab INTO wa_uploadtxt-name1
wa_uploadtxt-name2
wa_uploadtxt-age.
MOVE-CORRESPONDING wa_uploadtxt TO wa_upload.
APPEND wa_upload TO it_record.
ENDIF.
ENDDO.
CLOSE DATASET ld_file.
ENDIF.
************************************************************************
*END-OF-SELECTION
END-OF-SELECTION.
*!! Text data is now contained within the internal table IT_RECORD
* Display report data for illustration purposes
loop at it_record into wa_record.
write:/
sy-vline,
(10) wa_record-name1, sy-vline,
(10) wa_record-name2, sy-vline,
(10) wa_record-age, sy-vline.
endloop.
|
Upload Tab delimited file from PC into internal table |
|
ABAP code for uploading a TAB delimited file into an internal table. See code below for structures. The code is base on uploading a simple txt file. |
|
*&---------------------------------------------------------------------*
*& Report
ZUPLOADTAB
*
*&
*
*&---------------------------------------------------------------------*
*& Example of Uploading tab delimited file
*
*&
*
*&---------------------------------------------------------------------*
REPORT
zuploadtab
.
PARAMETERS: p_infile
LIKE rlgrap-filename
OBLIGATORY DEFAULT
'/usr/sap/'..
*DATA: ld_file LIKE rlgrap-filename.
DATA: gd_file type string.
*Internal tabe to store upload data
TYPES: BEGIN OF t_record,
name1 LIKE pa0002-vorna,
name2 LIKE pa0002-name2,
age
TYPE i,
END OF t_record.
DATA: it_record TYPE STANDARD TABLE OF t_record INITIAL SIZE 0,
wa_record TYPE t_record.
*Internal table to upload data into
DATA: BEGIN OF it_datatab OCCURS 0,
row(500) TYPE c,
END OF it_datatab.
*Text version of data table
TYPES: BEGIN OF t_uploadtxt,
name1(10) TYPE c,
name2(15) TYPE c,
age(5)
TYPE c,
END OF t_uploadtxt.
DATA: wa_uploadtxt TYPE t_uploadtxt.
*String value to data in initially.
DATA: wa_string(255) TYPE c.
CONSTANTS: con_tab TYPE x VALUE '09'.
*If you have Unicode check active in program attributes then you will
*need to declare constants as follows:
*class cl_abap_char_utilities definition load.
*constants:
*
con_tab
type c value cl_abap_char_utilities=>HORIZONTAL_TAB.
************************************************************************
*AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_INFILE.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_infile.
CALL FUNCTION 'WS_FILENAME_GET'
EXPORTING
def_filename
= p_infile
mask
= ',*.txt.'
mode
= 'O'
title
= 'Upload File'(078)
IMPORTING
filename
= p_infile
EXCEPTIONS
inv_winsys
= 1
no_batch
= 2
selection_cancel = 3
selection_error
= 4
OTHERS
= 5.
************************************************************************
*START-OF-SELECTION
START-OF-SELECTION.
gd_file = p_infile.
CALL FUNCTION 'GUI_UPLOAD'
EXPORTING
filename
= gd_file
has_field_separator
= 'X'
"file is TAB delimited
TABLES
data_tab
= it_record
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
OTHERS
= 17.
IF sy-subrc NE 0.
write: 'Error ', sy-subrc, 'returned from GUI_UPLOAD FM'.
skip.
endif.
* Alternative method, where by you split fields at each TAB after you
* have returned the data. No point unless you dont have access to
* GUI_UPLOAD but just included for information
*
*
CALL FUNCTION 'GUI_UPLOAD'
*
EXPORTING
*
filename
= gd_file
*
filetype
= 'ASC'
*
TABLES
*
data_tab
= it_datatab
"ITBL_IN_RECORD[]
*
EXCEPTIONS
*
file_open_error = 1
*
OTHERS
= 2.
*
IF sy-subrc NE 0.
*
ELSE.
*
LOOP AT it_datatab.
*
CLEAR: wa_string, wa_uploadtxt.
*
wa_string = it_datatab.
*
SPLIT wa_string AT con_tab INTO wa_uploadtxt-name1
*
wa_uploadtxt-name2
*
wa_uploadtxt-age.
*
MOVE-CORRESPONDING wa_uploadtxt TO wa_record.
*
APPEND wa_record TO it_record.
*
ENDLOOP.
*
ENDIF.
************************************************************************
*END-OF-SELECTION
END-OF-SELECTION.
*!! Text data is now contained within the internal table IT_RECORD
* Display report data for illustration purposes
LOOP AT it_record INTO wa_record.
WRITE:/
sy-vline,
(10) wa_record-name1, sy-vline,
(10) wa_record-name2, sy-vline,
(10) wa_record-age, sy-vline.
ENDLOOP.
|
Selecting a directory using object methods |
|
|
|
*Selecting a Directory
data: gd_path(500) type c.
parameters: p_path like rlgrap-filename.
at selection-screen on value-request for p_path.
CALL METHOD cl_gui_frontend_services=>directory_browse
EXPORTING window_title = 'File Directory'
initial_folder = 'C:'
CHANGING selected_folder = gd_path.
CALL METHOD cl_gui_cfw=>flush.
concatenate gd_path '' into p_path.
|
Selecting a File using object methods |
|
|
|
*Selecting a File, plus inserting default file extension
tables rlgrap.
data: it_tab type filetable,
gd_subrc type i.
selection-screen begin of block m with frame.
select-options so_fpath for rlgrap-filename.
selection-screen end of block m.
at selection-screen on value-request for so_fpath-low.
REFRESH: it_tab.
CALL METHOD CL_GUI_FRONTEND_SERVICES=>FILE_OPEN_DIALOG
EXPORTING
WINDOW_TITLE = 'Select File'
DEFAULT_FILENAME = '*.txt'
MULTISELECTION = 'X'
CHANGING
FILE_TABLE = it_tab
RC = gd_subrc.
loop at it_tab into so_fpath-low.
so_fpath-sign = 'I'.
so_fpath-option = 'EQ'.
append so_fpath. endloop.
|
Selecting a File using object methods |
|
|
|
*Selecting a file to save too, plus inserting default file extension .xls
tables rlgrap.
DATA: ld_filename TYPE string,
ld_path TYPE string,
ld_fullpath TYPE string,
ld_result TYPE i,
gd_file TYPE c.
selection-screen begin of block m with frame.
PARAMETERS: p_file TYPE
rlgrap-filename.
selection-screen end of block m.
* At selection screen
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
* Display save dialog window
CALL METHOD cl_gui_frontend_services=>file_save_dialog
EXPORTING
*
window_title
= ' '
default_extension = 'XLS'
default_file_name = 'accountsdata'
initial_directory = 'c:/temp/'
CHANGING
filename
= ld_filename
path
= ld_path
fullpath
= ld_fullpath
user_action
= ld_result.
p_file = ld_fullpath.
|
Browse files on Application Server(UNIX) |
|
When looking at/for files on the application server(UNIX) using AL11 you are restricted to only certian directories. The following ABAP program displays all files/directories on the application server(UNIX).
Simple copy and paste the following code into a new ABAP report program. Note will also need to created the following report which displays the actual file ZBROWSEFILE . |
|
*---------------------------------------------------------------------*
* Topic:
File Manager for UNIX environment
*
*
*
* Description:
With internal system command you can get access to *
*
the UNIX. The program list files in the Unix
*
*
environment and by using at line selecttion you are*
*
able to browse datasets.
*
*
*
* Authorization:
None, be careful you have unlimited access to Unix.*
*
Check that you are able to use the internal system *
*
command.
*
*
*
* Parameters:
Filename and path.
*
*
*
* Change of
Check that you are able to use the internal system *
* release
command.
*
*
*
* Release:
4.6b
*
*
*
***********************************************************************
REPORT ZUNIXFILES MESSAGE-ID Z1
NO STANDARD PAGE HEADING
LINE-COUNT 65
LINE-SIZE
132.
*---------------------------------------------------------------------*
* Global Variables.
*
*---------------------------------------------------------------------*
DATA: BEGIN OF TABL OCCURS 0,
LINE(2000),
END OF TABL.
DATA: PARCOM_LOC LIKE RS37A-LINE.
DATA: SIZE(10) TYPE C,
LINE
LIKE TABL-LINE,
SUM(16)
TYPE C.
DATA: FILE LIKE RS37A-LINE.
DATA: PATH(255) TYPE C.
*-------------------------------------------------------------------*
* Parameters.
*
*-------------------------------------------------------------------*
SELECTION-SCREEN SKIP 2.
PARAMETERS: PARCOM LIKE RS37A-LINE.
*********************************************************************
*AT SELECTION-SCREEN.
AT SELECTION-SCREEN.
CONDENSE: PARCOM NO-GAPS.
*********************************************************************
*TOP-OF-PAGE.
TOP-OF-PAGE.
PERFORM WRITE_PAGE_HEADING.
*********************************************************************
*INITIALIZATION.
INITIALIZATION.
PARCOM = '/usr/sap/*'.
"Only default value
*********************************************************************
*START-OF-SELECTION.
START-OF-SELECTION.
PERFORM MAKE_LOC.
PERFORM COLLECT_DATA.
PERFORM FILE_LIST.
*********************************************************************
*AT LINE-SELECTION.
AT LINE-SELECTION.
CLEAR FILE.
FILE = SY-LISEL+55.
REPLACE '|' WITH SPACE INTO FILE.
IF SY-LISEL+1(1) = 'd'.
PATH = FILE.
PATH+200 = '/*'.
CONDENSE PATH NO-GAPS.
SUBMIT ZUNIXFILES
WITH PARCOM = PATH
AND RETURN.
ENDIF.
SUBMIT ZBROWSEFILE "Call the browse program
WITH PARCOM = FILE
AND RETURN.
*---------------------------------------------------------------------*
* FORM MAKE_LOC.
*
*---------------------------------------------------------------------*
FORM MAKE_LOC.
CLEAR: PARCOM_LOC.
PARCOM_LOC(7)
= 'ls -ld '.
PARCOM_LOC+7(45) = PARCOM.
ENDFORM.
*---------------------------------------------------------------------*
* FORM COLLECT_DATA.
*
*---------------------------------------------------------------------*
FORM COLLECT_DATA.
REFRESH TABL.
CALL 'SYSTEM' ID 'COMMAND' FIELD PARCOM_LOC
ID 'TAB'
FIELD TABL-*SYS*.
ENDFORM.
*-------------------------------------------------------------------*
* FORM FILE_LIST.
*
*-------------------------------------------------------------------*
FORM FILE_LIST.
FORMAT RESET.
CLEAR SUM.
LOOP AT TABL.
CLEAR LINE.
LINE = TABL-LINE.
WRITE /2 LINE.
PERFORM VERTICAL_LINES.
SUM = SUM + SIZE.
ENDLOOP.
WRITE:/1(132) SY-ULINE.
ENDFORM.
*-------------------------------------------------------------------*
* FORM WRITE_PAGE_HEADING.
*
*-------------------------------------------------------------------*
FORM WRITE_PAGE_HEADING.
WRITE:/1(132) SY-ULINE.
PERFORM VERTICAL_LINES.
FORMAT INTENSIFIED.
WRITE: /2(131) SPACE COLOR 1.
WRITE:
2
SY-DATUM COLOR 1.
WRITE: 35 'File Manager' COLOR 1.
PERFORM VERTICAL_LINES.
WRITE:/1(132) SY-ULINE.
PERFORM VERTICAL_LINES.
FORMAT INTENSIFIED.
WRITE: /2(131) SPACE
COLOR 3.
PERFORM VERTICAL_LINES.
FORMAT RESET.
WRITE:/1(132) SY-ULINE.
ENDFORM.
*-------------------------------------------------------------------*
* FORM VERTICAL_LINES.
*
*-------------------------------------------------------------------*
FORM VERTICAL_LINES.
PERFORM WRITE_VLINE USING ' '
1.
PERFORM WRITE_VLINE USING ' '
132.
ENDFORM.
*-------------------------------------------------------------------*
* WRITE_VLINE.
*
*-------------------------------------------------------------------*
FORM WRITE_VLINE USING MODE POS.
IF MODE NE 'T'.
FORMAT INTENSIFIED.
ENDIF.
POSITION POS.
WRITE: SY-VLINE.
IF MODE NE 'T'.
FORMAT RESET.
ENDIF.
ENDFORM.
|