Thursday, September 16, 2010

User Exists

User Exit Code for Transactional Datasources to populate appended Custom fields

* Table Declaration

TABLES: bkpf, bseg, psguid, coep, cobk, payr.

* TYPES Declaration


TYPES:
  BEGIN OF t_seqnr,
    pernr TYPE pa0001-pernr,  "PERNR
    seqnr TYPE pc261-seqnr,   "PR sequence number
  END OF t_seqnr,

  t_it_seqnr TYPE STANDARD TABLE OF t_seqnr,

  BEGIN OF t_taxau,
    pernr TYPE pa0001-pernr,  "PERNR
    seqnr TYPE pc261-seqnr,   "PR sequence number
    cntr1 TYPE cntrn,         "Tax auth code
    taxau TYPE taxat,         "Tax auth text
  END OF t_taxau,

  t_it_taxau TYPE STANDARD TABLE OF t_taxau.

* Structures declaration corresponding to the Extract structures of respective datasources.



DATA:   l_s_fiap_4 LIKE dtfiap_3,
        l_s_fiar_4 LIKE dtfiar_3,
        l_s_figl_4 LIKE dtfigl_4,
        l_s_cats_1 LIKE cats_is_1,
        l_s_check_dt LIKE zoxde10195,
        l_s_co_om_nwa_2  LIKE icnwacsta1,
        l_s_co_om_wbs_6  LIKE icwbscsta1,
       
  l_tabix LIKE sy-tabix,

  l_s_dt TYPE TABLE OF zoxde10195,

        prev_pernr         TYPE pa0001-pernr,
        it_seqnr           TYPE t_it_seqnr,
        lwa_seqnr          TYPE t_seqnr,
        lwa_taxau          TYPE t_taxau,
        lref_pay_access    TYPE REF TO cl_hr_pay_access,
        lref_pay_result    TYPE REF TO cl_hr_pay_result,
        lref_pay_result_us TYPE REF TO cl_hr_pay_result_us,
        it_rgdir           TYPE hrpy_tt_rgdir,
        it_taxau           TYPE t_it_taxau.

FIELD-SYMBOLS:
  <lfs_lwa_rgdir>  TYPE pc261,
  <lfs_lwa_tax>    TYPE pc22t,
  <lfs_lwa_py_rec> TYPE hrms_biw_py_rec1,
  <lfs_lwa_seqnr>  TYPE t_seqnr,
  <lfs_lwa_taxau>  TYPE t_taxau.

* Custom Code for BW Extractors.

CASE i_datasource.

* Begin of Additional Accounts Payable Transaction data enhancement........

  WHEN '0FI_AP_4'.

* BKPF Field Structure declaration.
    TYPES: BEGIN OF s_bkpf,
          bukrs TYPE bkpf-bukrs,
          belnr TYPE bkpf-belnr,
          gjahr TYPE bkpf-gjahr,
          usnam TYPE bkpf-usnam,
          bvorg TYPE bkpf-bvorg,
          bktxt TYPE bkpf-bktxt,
          ppnam TYPE bkpf-ppnam,
          xref1_hd TYPE bkpf-xref1_hd,
          xref2_hd TYPE bkpf-xref2_hd,
          END OF s_bkpf.

* PRPS Field Structure declaration.

    TYPES: BEGIN OF s_prps,
          pspnr TYPE prps-pspnr,
          posid TYPE prps-posid,
          END OF s_prps.

*BSEG field structure declaration.

    TYPES: BEGIN OF s_bseg,
          bukrs TYPE bseg-bukrs,
          belnr TYPE bseg-belnr,
          gjahr TYPE bseg-gjahr,
          buzei TYPE bseg-buzei,
          koart TYPE bseg-koart,
          zuonr TYPE bseg-zuonr,
          sgtxt TYPE bseg-sgtxt,
          zkokrs TYPE bseg-kokrs,
          zkostl TYPE bseg-kostl,
          xref1 TYPE bseg-xref1,
          xref2 TYPE bseg-xref2,
          xref3 TYPE bseg-xref3,
          segment TYPE bseg-segment,
          END OF s_bseg.

** Internal Table declaration

    DATA: it_bkpf TYPE STANDARD TABLE OF s_bkpf,
          it_prps TYPE STANDARD TABLE OF s_prps,
          it_bseg TYPE STANDARD TABLE OF s_bseg.

    DATA: it_data TYPE STANDARD TABLE OF dtfiap_3.

** Work Area declaration.

    DATA: wa_bkpf   TYPE s_bkpf,
          wa_prps   TYPE s_prps,
          wa_bseg   TYPE s_bseg.

** Variables.

    DATA: v_index TYPE sytabix.  "For looping

    REFRESH it_data.

** Move the data from c_t_data to internal table it_data.
   
it_data[] = c_t_data[].

** Sort the internal table it_data by BELNR.
    SORT it_data BY belnr.

** Refresh all internal tables.
    REFRESH: it_bkpf,
             it_prps,
             it_bseg.

    IF NOT it_data[] IS INITIAL.

** Select data from BKPF table for all entries in it_data.
      SELECT bukrs belnr gjahr usnam bvorg bktxt ppnam xref1_hd xref2_hd FROM bkpf
                INTO TABLE it_bkpf
                FOR ALL ENTRIES IN it_data
                WHERE bukrs = it_data-bukrs AND
                      belnr = it_data-belnr AND
                      gjahr = it_data-gjahr.

** Check sy-subrc and sort the internal table.
      IF sy-subrc = 0.
        SORT it_bkpf BY belnr bukrs gjahr.
        DELETE ADJACENT DUPLICATES FROM it_bkpf COMPARING ALL FIELDS.
      ENDIF.

** Select posid from prps table for all entries in it_data.
      SELECT pspnr posid
             FROM prps
             INTO TABLE it_prps
             FOR ALL ENTRIES IN it_data
             WHERE pspnr = it_data-projk.

** Check sy-subrc and sort the internal table.
      IF sy-subrc = 0.
        SORT it_prps BY pspnr.
        DELETE ADJACENT DUPLICATES FROM it_bkpf COMPARING ALL FIELDS.
      ENDIF.

**Select data from BSEG table for all entries in it_data table.
      SELECT bukrs belnr gjahr buzei koart zuonr sgtxt kokrs kostl xref1 xref2 xref3 segment
             FROM bseg
             INTO TABLE it_bseg
             FOR ALL ENTRIES IN it_data
             WHERE bukrs = it_data-bukrs AND
                   belnr = it_data-belnr AND
                   gjahr = it_data-gjahr.

** Check sy-subrc and sort the internal table.
      IF sy-subrc = 0.
        SORT it_bseg BY bukrs belnr gjahr buzei koart.

        DELETE ADJACENT DUPLICATES FROM it_bseg COMPARING ALL FIELDS.

      ENDIF.
    ENDIF.

    CLEAR v_index.

**Now loop at the c_t_data table and modify the table fields with the values from the
**above internal tables.

    LOOP AT c_t_data INTO l_s_fiap_4.

      v_index = sy-tabix.
      CLEAR wa_bkpf.
      READ TABLE it_bkpf INTO wa_bkpf WITH KEY bukrs = l_s_fiap_4-bukrs
                                               belnr = l_s_fiap_4-belnr
                                               gjahr = l_s_fiap_4-gjahr
                                               BINARY SEARCH.

      IF sy-subrc = 0.
        MOVE: wa_bkpf-xref2_hd   TO  l_s_fiap_4-zxref2_hd,
              wa_bkpf-xref1_hd   TO  l_s_fiap_4-zxref1_hd,
              wa_bkpf-usnam   TO  l_s_fiap_4-zusnam,
              wa_bkpf-bktxt   TO  l_s_fiap_4-zbktxt,
              wa_bkpf-ppnam TO  l_s_fiap_4-zppnam,
              wa_bkpf-bvorg TO  l_s_fiap_4-zbvorg.
      ENDIF.

      CLEAR wa_prps.
      READ TABLE it_prps INTO wa_prps WITH KEY pspnr = l_s_fiap_4-projk
             BINARY SEARCH.

      IF sy-subrc = 0.
        MOVE wa_prps-posid  TO  l_s_fiap_4-zposid.
      ENDIF.

      CLEAR wa_bseg.


      READ TABLE it_bseg INTO wa_bseg WITH KEY  bukrs = l_s_fiap_4-bukrs
                                                belnr = l_s_fiap_4-belnr
                                                gjahr = l_s_fiap_4-gjahr
                                                buzei = l_s_fiap_4-buzei
                                                BINARY SEARCH.

      IF sy-subrc = 0.
        MOVE: wa_bseg-xref2   TO  l_s_fiap_4-zzxref2_bseg,
              wa_bseg-xref1   TO  l_s_fiap_4-zzxref1_bseg,
              wa_bseg-xref3   TO  l_s_fiap_4-zzxref3_bseg,
              wa_bseg-segment TO  l_s_fiap_4-zzsegment_bseg,
              wa_bseg-zuonr   TO  l_s_fiap_4-zzzuonr_bseg,
              wa_bseg-zkostl  TO  l_s_fiap_4-zzkostl_bseg,
              wa_bseg-zkokrs  TO  l_s_fiap_4-zzkokrs_bseg.
      ENDIF.

      CLEAR wa_bseg.


      READ TABLE it_bseg INTO wa_bseg WITH KEY  bukrs = l_s_fiap_4-bukrs
                                                belnr = l_s_fiap_4-belnr
                                                gjahr = l_s_fiap_4-gjahr
                                                koart = 'S'
                                                BINARY SEARCH.

      IF sy-subrc = 0.
        MOVE:  wa_bseg-sgtxt   TO  l_s_fiap_4-zzsgtxt_bseg.

      ENDIF.

      MODIFY c_t_data FROM l_s_fiap_4 INDEX v_index.
      CLEAR l_s_fiap_4.

    ENDLOOP.

** End of Additional Accounts Payable Transaction data Enhancement....

** Begin of Additional Accounts Receivable Transaction data Enhancement....



  WHEN '0FI_AR_4'.

*Structure  declaration.

    DATA: BEGIN OF s_posid,
          posid TYPE prps-posid,
          END OF s_posid.

    CLEAR l_s_fiar_4.

**Now loop at the c_t_data table and modify the table fields with the values fetched from respective Tables.


    LOOP AT c_t_data INTO l_s_fiar_4.
      l_tabix = sy-tabix.

*SELECT statement for extracting field from PRPS table.
     
    CLEAR s_posid.

      SELECT SINGLE posid FROM prps INTO s_posid
      WHERE pspnr = l_s_fiar_4-projk.

      IF sy-subrc = 0.
        l_s_fiar_4-zposid = s_posid-posid.
        MODIFY c_t_data FROM l_s_fiar_4 INDEX l_tabix.
      ENDIF.

      CLEAR l_s_fiar_4.
    ENDLOOP.

** End of Additional Accounts Receivable Transaction data Enhancement....

** Begin of Additional CATTS Transaction data Enhancement....

  WHEN '0CA_TS_IS_1'.

*Structure  declaration.

    DATA: l_lgart LIKE catsdb-lgart.

    CLEAR l_s_cats_1.

**Now loop at the c_t_data table and modify the table fields with the values fetched from respective Tables.

    LOOP AT c_t_data INTO l_s_cats_1.

      l_tabix = sy-tabix.

      CLEAR l_lgart.

*SELECT statement for extracting LGART field from CATSDB table.

      SELECT SINGLE lgart FROM catsdb INTO l_lgart
                                         WHERE status = '30'  "l_s_cats_1-status
                                           AND pernr  = l_s_cats_1-pernr
                                           AND workdate = l_s_cats_1-workdate
                                           AND catshours = l_s_cats_1-catshours
                                           AND skostl = l_s_cats_1-skostl
                                           AND lstar  = l_s_cats_1-lstar
                                           AND lstnr = l_s_cats_1-lstnr
                                           AND rkostl = l_s_cats_1-rkostl
                                           AND raufnr = l_s_cats_1-raufnr
                                           AND rnplnr = l_s_cats_1-rnplnr
                                           AND rkdauf = l_s_cats_1-rkdauf
                                           AND rkdpos = l_s_cats_1-rkdpos
                                           AND rprznr = l_s_cats_1-rprznr
                                           AND reinr = l_s_cats_1-reinr
                                           AND waers = l_s_cats_1-waers
                                           AND kokrs = l_s_cats_1-kokrs
                                           AND meinh = l_s_cats_1-meinh
                                           AND tcurr = l_s_cats_1-tcurr
                                           AND price = l_s_cats_1-price
                                           AND werks = l_s_cats_1-werks
                                           AND autyp = l_s_cats_1-autyp
                                           AND apnam = l_s_cats_1-apnam
                                           AND ltxa1 = l_s_cats_1-ltxa1
                                           AND belnr = l_s_cats_1-belnr.

      IF sy-subrc = 0.
        l_s_cats_1-zzlgart = l_lgart.
        MODIFY c_t_data FROM l_s_cats_1 INDEX l_tabix.
      ENDIF.

      CLEAR l_s_cats_1.
    ENDLOOP.


* End of Additional CATTS Transaction data Enhancement....

*Begin of Additional GeneralLedger Line Item Transaction data Enhancement as per Julish Requirement on 22/05...

 
WHEN '0FI_GL_4'.

*Structure  declaration.

    TYPES: BEGIN OF s_bseg2,
          bukrs TYPE bseg-bukrs,
          belnr TYPE bseg-belnr,
          gjahr TYPE bseg-gjahr,
          buzei TYPE bseg-buzei,
          nplnr TYPE bseg-nplnr,
          aufpl TYPE bseg-aufpl,
          aplzl TYPE bseg-aplzl,

          END OF s_bseg2.

    DATA: BEGIN OF s_afvc,
        vornr  TYPE afvc-vornr,
          END OF s_afvc.

** Internal Table declaration

    DATA:   it_bseg2 TYPE STANDARD TABLE OF s_bseg2.

    DATA: it_data2 TYPE STANDARD TABLE OF dtfigl_4.

**Work Area declaration.

    DATA: wa_bseg2   TYPE s_bseg2.

**Variables.
    DATA: v_index2               TYPE  sytabix.  "For looping

    REFRESH it_data2.

**Move the data from c_t_data to internal table it_data.
    it_data2[] = c_t_data[].

** Sort the internal table it_data by BELNR.
    SORT it_data2 BY belnr.

**  Refresh all internal tables.
    REFRESH: it_bseg2.

    IF NOT it_data2[] IS INITIAL.

**Select data from BSEG table for all entries in it_data table.
      SELECT bukrs belnr gjahr buzei nplnr aufpl aplzl
             FROM bseg
             INTO TABLE it_bseg2
             FOR ALL ENTRIES IN it_data2
             WHERE bukrs = it_data2-bukrs AND
                   belnr = it_data2-belnr AND
                   gjahr = it_data2-gjahr.

** Check sy-subrc and sort the internal table.
      IF sy-subrc = 0.
        SORT it_bseg2 BY bukrs belnr gjahr buzei.

        DELETE ADJACENT DUPLICATES FROM it_bseg2 COMPARING ALL FIELDS.

      ENDIF.
    ENDIF.

**Now loop at the c_t_data table and modify the table fields with the values from the
**above internal tables.
    CLEAR v_index2.

    LOOP AT c_t_data INTO l_s_figl_4.

      v_index2 = sy-tabix.

      CLEAR wa_bseg2.

      READ TABLE it_bseg2 INTO wa_bseg2 WITH KEY  bukrs = l_s_figl_4-bukrs
                                                belnr = l_s_figl_4-belnr
                                                gjahr = l_s_figl_4-gjahr
                                                buzei = l_s_figl_4-buzei
                                                BINARY SEARCH.

      IF sy-subrc = 0.

        MOVE: wa_bseg2-nplnr   TO  l_s_figl_4-znetwork.

        IF wa_bseg2-nplnr IS NOT INITIAL.

          CLEAR s_afvc.

          SELECT SINGLE vornr INTO s_afvc FROM afvc WHERE aufpl = wa_bseg2-aufpl AND aplzl = wa_bseg2-aplzl.

          IF sy-subrc = 0.

            l_s_figl_4-zactivity = s_afvc.

          ENDIF.

        ENDIF.

      ENDIF.


      MODIFY c_t_data FROM l_s_figl_4 INDEX v_index2.

      CLEAR l_s_figl_4.


    ENDLOOP.

*End of Additional GeneralLedger Transaction data Enhancement....

* Begin of Additional Cheque Details Transaction data enhancement of Accounts Payable Application........


  WHEN 'ZBW_BSAK_DT'.

*Structure  declaration.

    DATA: check TYPE payr-chect.

**Now loop at the c_t_data table and modify the table fields with the values derived from Select Statements.

    CLEAR l_s_check_dt.
    LOOP AT c_t_data INTO l_s_check_dt.

      IF l_s_check_dt-augbl <> l_s_check_dt-belnr.
        APPEND l_s_check_dt TO l_s_dt.
      ENDIF.

      CLEAR l_s_check_dt.
    ENDLOOP.

    REFRESH c_t_data.

    CLEAR l_s_check_dt.
    LOOP AT l_s_dt INTO l_s_check_dt.
      CLEAR check.

*SELECT statement for extracting CHECT field from PAYR table.

      SELECT SINGLE chect FROM payr INTO check
      WHERE zbukr = l_s_check_dt-bukrs AND
            vblnr = l_s_check_dt-augbl.

*      IF sy-subrc = 0.

      l_s_check_dt-zzchect = check.

      MODIFY l_s_dt FROM l_s_check_dt TRANSPORTING zzchect.
      APPEND l_s_check_dt TO c_t_data.

*      ENDIF.

      CLEAR l_s_check_dt.
    ENDLOOP.

*End of Additional Cheque Details Transaction data enhancement…….

*Begin of Additional Netw. Activity Actual Costs Transaction data enhancement…

  WHEN '0CO_OM_NWA_2'.

*Structure  declaration.

    DATA: BEGIN OF s_bkpf_2,
            blart TYPE bkpf-blart,
          END OF s_bkpf_2,

          BEGIN OF s_bseg_2,
            umsks TYPE bseg-umsks,
          END OF s_bseg_2,


          BEGIN OF s_coep_2,
            vrgng TYPE coep-vrgng,
          END OF s_coep_2.

**Now loop at the c_t_data table and modify the table fields with the values derived from Select Statements.

    CLEAR l_s_co_om_nwa_2.
    LOOP AT c_t_data INTO l_s_co_om_nwa_2.

      l_tabix = sy-tabix.

      CLEAR s_bkpf_2.

*SELECT statement for extracting BLART field from BKPF table.

      SELECT SINGLE blart FROM bkpf INTO s_bkpf_2
      WHERE bukrs = l_s_co_om_nwa_2-bukrs AND
            belnr = l_s_co_om_nwa_2-belnr.

      IF sy-subrc = 0.
        l_s_co_om_nwa_2-zblart = s_bkpf_2-blart.
      ENDIF.

      CLEAR s_bseg_2.

*SELECT statement for extracting UMSKS field from BSEG table.

      SELECT SINGLE umsks FROM bseg INTO s_bseg_2
      WHERE bukrs = l_s_co_om_nwa_2-bukrs AND
            belnr = l_s_co_om_nwa_2-belnr AND
            buzei = l_s_co_om_nwa_2-buzei.

      IF sy-subrc = 0.
        l_s_co_om_nwa_2-zumsks = s_bseg_2-umsks.
      ENDIF.

      CLEAR s_coep_2.

*SELECT statement for extracting VRGNG field from COEP table.

      SELECT SINGLE vrgng FROM coep INTO s_coep_2
      WHERE kokrs = l_s_co_om_nwa_2-kokrs AND
            belnr = l_s_co_om_nwa_2-belnr AND
            buzei = l_s_co_om_nwa_2-buzei.

      IF sy-subrc = 0.
        l_s_co_om_nwa_2-zzvrgng = s_coep_2-vrgng.
      ENDIF.

      MODIFY c_t_data FROM l_s_co_om_nwa_2 INDEX l_tabix.

      CLEAR l_s_co_om_nwa_2.
    ENDLOOP.

*End of Additional Netw. Activity Actual Costs Transaction data enhancement…

*Begin of Additional Payroll Results Transaction data enhancement…


 WHEN '0HR_PY_REC_51'.

**Now loop at the c_t_data table and modify the table fields with the values derived from respective Tables.

    LOOP AT c_t_data ASSIGNING <lfs_lwa_py_rec>.
      CHECK <lfs_lwa_py_rec>-cntr1 <> '00'.
      lwa_seqnr-pernr = <lfs_lwa_py_rec>-pernr.
      lwa_seqnr-seqnr = <lfs_lwa_py_rec>-seqnr.
      COLLECT lwa_seqnr INTO it_seqnr.
    ENDLOOP.  "at c_t_data
    SORT it_seqnr BY pernr seqnr.
    CREATE OBJECT lref_pay_access.
    LOOP AT it_seqnr ASSIGNING <lfs_lwa_seqnr>.
      IF prev_pernr <> <lfs_lwa_seqnr>-pernr.
        CLEAR it_rgdir.

* Read list of payroll results for this pernr

        CALL METHOD lref_pay_access->read_cluster_dir
          EXPORTING
            pernr       = <lfs_lwa_seqnr>-pernr
          IMPORTING
            cluster_dir = it_rgdir
          EXCEPTIONS
            OTHERS      = 0.
        prev_pernr  = <lfs_lwa_seqnr>-pernr.
      ENDIF.
      READ TABLE it_rgdir ASSIGNING <lfs_lwa_rgdir>
        WITH KEY seqnr = <lfs_lwa_seqnr>-seqnr.
      CHECK sy-subrc = 0.

* Read single payroll result entry for this pernr

      CALL METHOD lref_pay_access->read_pa_result
        EXPORTING
          pernr                         = <lfs_lwa_seqnr>-pernr
          period                        = <lfs_lwa_rgdir>
          molga                         = '10'
        IMPORTING
          payroll_result                = lref_pay_result
        EXCEPTIONS
          no_authorization              = 1
          read_error                    = 2
          country_version_not_available = 3
          OTHERS                        = 4.
      CHECK sy-subrc = 0.
      lref_pay_result_us ?= lref_pay_result.
      CHECK sy-subrc = 0.

* Read tax authority description from tax table

      LOOP AT lref_pay_result_us->natio-tax ASSIGNING <lfs_lwa_tax>.
        lwa_taxau-pernr = <lfs_lwa_seqnr>-pernr.
        lwa_taxau-seqnr = <lfs_lwa_seqnr>-seqnr.
        lwa_taxau-cntr1 = <lfs_lwa_tax>-cntr1.
        lwa_taxau-taxau = <lfs_lwa_tax>-taxau.
        COLLECT lwa_taxau INTO it_taxau.
      ENDLOOP.  "at lref_pay_result_us
    ENDLOOP.   "at it_seqnr
    LOOP AT c_t_data ASSIGNING <lfs_lwa_py_rec>.
      CHECK <lfs_lwa_py_rec>-cntr1 <> '00'.
      READ TABLE it_taxau
        WITH KEY pernr = <lfs_lwa_py_rec>-pernr
                 seqnr = <lfs_lwa_py_rec>-seqnr
                 cntr1 = <lfs_lwa_py_rec>-cntr1
        ASSIGNING <lfs_lwa_taxau>.
      CHECK sy-subrc = 0.
      <lfs_lwa_py_rec>-zztaxau = <lfs_lwa_taxau>-taxau.
    ENDLOOP.   "at c_t_data

*End of Additional Payroll Results Transaction data enhancement…

*Begin of Additional WBS Elements: Actual Costs Transaction data enhancement…

 WHEN '0CO_OM_WBS_6'.

*Structure  declaration.

    DATA: v_vrgng LIKE coep-vrgng.

**Now loop at the c_t_data table and modify the table fields with the values derived from Select Statements

    CLEAR l_s_co_om_wbs_6.
    LOOP AT c_t_data INTO l_s_co_om_wbs_6.

      l_tabix = sy-tabix.

      CLEAR v_vrgng.

*SELECT statement for extracting VRGNG field from COEP table.

      SELECT SINGLE vrgng FROM coep INTO v_vrgng
      WHERE kokrs = l_s_co_om_wbs_6-kokrs AND
            belnr = l_s_co_om_wbs_6-belnr AND
            buzei = l_s_co_om_wbs_6-buzei.

      IF sy-subrc = 0.
        l_s_co_om_wbs_6-zzvrgng = v_vrgng.
      ENDIF.

      MODIFY c_t_data FROM l_s_co_om_wbs_6 INDEX l_tabix.

      CLEAR l_s_co_om_wbs_6.

    ENDLOOP.

*End of Additional WBS Elements: Actual Costs Transaction data enhancement…

  WHEN OTHERS.
    EXIT.

ENDCASE.



1 comment:

  1. Hello all,

    The main intention of using user exits is when we want to do the computation or calculations or perform some functions apart from oracle say suppose we have a DLL coded in VB or VC then we need to use the user exits. Thanks a lot!

    Extract Data From Web

    ReplyDelete