具有参数REF TO接口的动态CREATE OBJECT。

2020-08-26 07:39发布

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


我正在尝试动态调用类的构造函数,其中参数是引用接口的。 但是,我一直在获取转储DYN_CALL_METH_PARAM_TYPE,CX_SY_DYN_CALL_ILLEGAL_TYPE。

试图将当前参数传递给类"/img/UI2/CL_FLP_CONT_MGR"的方法" CONSTRUCTOR"的形式参数" IO_MESSAGING"。 这导致类型冲突。

我尝试使用RTTS,CREATE DATA dat TYPE REF TO(类名),但遇到相同的错误。 任何人都有如何使它工作的想法。 演示此问题的示例代码如下。 它在754,s4hana系统上运行。

数据lt_tile_tm_combination类型/ui2/if_flp_cont_mgr => tt_tile_tm_combination_sorted。
 数据lo_flp_cont_mgr TYPE REF TO对象。/ui2/if_flp_cont_mgr。
 DATA lo_catalog_api类型引用对象。/ui2/if_fdm_catalog_api。
 DATA lo_messaging TYPE REF TO对象。/ui2/if_fcm_messaging。
 数据lx_root类型参考cx_root。
 尝试。
     创建对象lo_catalog_api类型('/UI2/CL_FDM_CATALOG_API')
       出口
         iv_scope ='CUST'"或'CONF'
         iv_use_cache = abap_true。
   捕获cx_root INTO lx_root。
     消息lx_root TYPE'E'。
 ENDTRY。
 创建对象lo_messaging TYPE('/UI2/CL_FCM_MESSAGING')。
 创建对象lo_flp_cont_mgr TYPE('/UI2/CL_FLP_CONT_MGR')"/img/ui2/cl_flp_cont_mgr
   出口
     iv_scope ='CUST'
     io_catalog_api = lo_catalog_api"对/​​UI2/IF_FDM_CATALOG_API的类型引用
     io_messaging = lo_messaging。  " TYPE REF TO/UI2/IF_FCM_MESSAGING
 调用方法lo_flp_cont_mgr->('/UI2/IF_FLP_CONTR_MGR〜GET_ALL_TILES_TMS')
     接收rt_tile_tm_combination = lt_tile_tm_combination。
 

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


我正在尝试动态调用类的构造函数,其中参数是引用接口的。 但是,我一直在获取转储DYN_CALL_METH_PARAM_TYPE,CX_SY_DYN_CALL_ILLEGAL_TYPE。

试图将当前参数传递给类"/img/UI2/CL_FLP_CONT_MGR"的方法" CONSTRUCTOR"的形式参数" IO_MESSAGING"。 这导致类型冲突。

我尝试使用RTTS,CREATE DATA dat TYPE REF TO(类名),但遇到相同的错误。 任何人都有如何使它工作的想法。 演示此问题的示例代码如下。 它在754,s4hana系统上运行。

数据lt_tile_tm_combination类型/ui2/if_flp_cont_mgr => tt_tile_tm_combination_sorted。
 数据lo_flp_cont_mgr TYPE REF TO对象。/ui2/if_flp_cont_mgr。
 DATA lo_catalog_api类型引用对象。/ui2/if_fdm_catalog_api。
 DATA lo_messaging TYPE REF TO对象。/ui2/if_fcm_messaging。
 数据lx_root类型参考cx_root。
 尝试。
     创建对象lo_catalog_api类型('/UI2/CL_FDM_CATALOG_API')
       出口
         iv_scope ='CUST'"或'CONF'
         iv_use_cache = abap_true。
   捕获cx_root INTO lx_root。
     消息lx_root TYPE'E'。
 ENDTRY。
 创建对象lo_messaging TYPE('/UI2/CL_FCM_MESSAGING')。
 创建对象lo_flp_cont_mgr TYPE('/UI2/CL_FLP_CONT_MGR')"/img/ui2/cl_flp_cont_mgr
   出口
     iv_scope ='CUST'
     io_catalog_api = lo_catalog_api"对/​​UI2/IF_FDM_CATALOG_API的类型引用
     io_messaging = lo_messaging。  " TYPE REF TO/UI2/IF_FCM_MESSAGING
 调用方法lo_flp_cont_mgr->('/UI2/IF_FLP_CONTR_MGR〜GET_ALL_TILES_TMS')
     接收rt_tile_tm_combination = lt_tile_tm_combination。
 
付费偷看设置
发送
4条回答
蓋茨
1楼 · 2020-08-26 08:02.采纳回答

就像 Sandra Rossi 所说的那样-使用动态ABAP无法完成。 我采用的解决方案是在运行时一次生成该方法的代码。 我没有包括方法interface_exists 。 这可以使用RTTS轻松实现。

第一次运行类的构造函数时,方法get_all_tiles_tms的注释行将被删除,但前提是存在/UI2/IF_FLP_CONT_MGR接口。

 CLASS zcl_dynamic_method_change_demo定义
   上市
   最后
   创建公众。

   公共部分。
     类型:tt_tile_tm_combination_sorted TYPE字符串表。
     "我在这里使用string_Table。但是它可以在我们的754系统中使用
     "我们需要创建自己的实型Z版本
     "/img/ui2/if_flp_cont_mgr => tt_tile_tm_combination_sorted
     方法构造器。
     方法get_all_tiles_tms
       正在返回
         值(r_result)TYPE tt_tile_tm_combination_sorted。
   受保护的部分。
   专用部分。
     方法method_not_initialized
       正在返回
         值(r_result)TYPE abap_bool。
     方法initialise_method。
     方法strip_out_comments
       输入
         i_source_code TYPE siw_tab_code
       正在返回
         值(r_result)TYPE siw_tab_code。
 ENDCLASS。

 类别zcl_dynamic_method_change_demo IMPLEMENTATION。
   METHOD构造函数。
     IF interface_exists('/UI2/IF_FLP_CONT_MGR')EQ abap_false。
       消息"无法在此系统上运行",类型为" E"。
     万一。
     IF method_not_initialized()EQ abap_false。
       initialise_method()。
       讯息'请重新开始交易。 您不应再看到此消息"
          输入" E"。
     万一。
   终结法。

   方法get_all_tiles_tms。
 *数据lt_tile_tm_combination TYPE/ui2/if_flp_cont_mgr => tt_tile_tm_combination_sorted。
 *数据lo_flp_cont_mgr类型参考/ui2/if_flp_cont_mgr。
 *数据lo_catalog_api类型参考/ui2/if_fdm_catalog_api。
 *数据lo_messaging类型参考/ui2/if_fcm_messaging。
 *数据lx_root类型参考cx_root。
 *尝试。
 *创建对象lo_catalog_api类型/ui2/cl_fdm_catalog_api
 *出口
 * iv_scope ='CUST'"或'CONF'
 * iv_use_cache = abap_true。
 *捕捉cx_root INTO lx_root。
 *消息lx_root TYPE'E'。
 * ENDTRY。
 *创建对象lo_messaging类型/ui2/cl_fcm_messaging。
 *创建对象lo_flp_cont_mgr类型/ui2/cl_flp_cont_mgr
 *出口
 * iv_scope ='CUST'"或'CONF'
 * io_catalog_api = lo_catalog_api
 * io_messaging = lo_messaging。
 * r_result = lo_flp_cont_mgr-> get_all_tiles_tms()。
   终结法。

   方法initialise_method。
     数据写入器的类型参考if_siw_repository_writer。
     writer = cl_siw_resource_access => s_get_instance()。
     DATA source_code TYPE siw_tab_code。
     尝试。
         writer-> read_method_source(
                   出口
                     i_clsname ='ZCL_DYNAMIC_METHOD_CHANGE_DEMO'
                     i_methodname ='GET_ALL_TILES_TMS'
                     i_state ='I'
                    输入
                      e_tab_code = source_code)。
         source_code = strip_out_comments(source_code)。
         writer-> write_class_method(
             i_clsname ='ZCL_DYNAMIC_METHOD_CHANGE_DEMO'
             i_methodname ='GET_ALL_TILES_TMS'
             i_tab_code = source_code)。
         数据rf_error类型参考cx_siw_resource_failure ..
       捕获cx_siw_resource_failure。
         消息rf_error类型'E'。
     ENDTRY。
   终结法。

   方法method_not_initialized。
     数据写入器的类型参考if_siw_repository_writer。
     writer = cl_siw_resource_access => s_get_instance()。
     DATA source_code TYPE siw_tab_code。
     尝试。
         writer-> read_method_source(
                   出口
                     i_clsname ='ZCL_DYNAMIC_METHOD_CHANGE_DEMO'
                     i_methodname ='GET_ALL_TILES_TMS'
                     i_state ='I'
                    输入
                      e_tab_code = source_code)。
         数据rf_error类型参考cx_siw_resource_failure。
       捕获cx_siw_resource_failure INTO rf_error。
         消息rf_error类型'E'。
     ENDTRY。
     r_result = abap_false。
     FIELD-SYMBOLS <源代码行> TYPE siw_dte_code。
     循环AT source_code ASSIGNING 。
       检查sy-tabix NE 1和sy-tabix NE行(source_code)
                           AND(是INITIAL
                             或(1)NE'*')。
       r_result = abap_true。
       出口。
     结局。
   终结法。

   方法strip_out_comments。
     r_result = i_source_code。
     FIELD-SYMBOLS <源代码行> TYPE siw_dte_code。
     循环r_result ASSIGNING <源代码行>。
       检查sy-tabix NE 1和sy-tabix NE行(r_result)
                           AND 不是INITIAL
                           AND <源代码行>(1)EQ'*'。
       <源代码行> = <源代码行> +1。
     结局。
   终结法。
 ENDCLASS。
 
Tong__Ming
2楼-- · 2020-08-26 08:14

对不起,我错过了至关重要的信息。 在不包含这些类和接口且实际上在7.54系统上运行的7.31系统中,该语法在语法上必须正确。 数据定义中使用的类型在7.31中不存在,但很容易复制。 在7.31中不存在,但是它们很容易复制。

clever101
3楼-- · 2020-08-26 08:03

问题是您正在使用类型为 object 的通用引用变量来访问您的实例 创建并将它们传递给构造函数会导致类型冲突,因为在运行时会检查变量的静态类型。 为什么要避免使用接口类型,是否有特定原因? 这样应该可以正常工作:

 DATA lt_tile_tm_combination TYPE/ui2/if_flp_cont_mgr => tt_tile_tm_combination_sorted。
 数据lo_flp_cont_mgr类型参考/ui2/if_flp_cont_mgr。
 数据lo_catalog_api类型参考/ui2/if_fdm_catalog_api。
 数据lo_messaging类型参考/ui2/if_fcm_messaging。
 数据lx_root类型参考cx_root。

 尝试。
     创建对象lo_catalog_api类型('/UI2/CL_FDM_CATALOG_API')
       出口
         iv_scope ='CUST'"或'CONF'
         iv_use_cache = abap_true。
   捕获cx_root INTO lx_root。
     消息lx_root TYPE'E'。
 ENDTRY。
 创建对象lo_messaging TYPE('/UI2/CL_FCM_MESSAGING')。
 创建对象lo_flp_cont_mgr类型('/UI2/CL_FLP_CONT_MGR')
   出口
     iv_scope ='CUST'
     io_catalog_api = lo_catalog_api
     io_messaging = lo_messaging。

 lt_tile_tm_combination = lo_flp_cont_mgr-> get_all_tiles_tms()。
 

如果出于某种原因不能更改变量类型,则其他选项是应用CAST运算符:

创建对象lo_flp_cont_mgr TYPE('/UI2/CL_FLP_CONT_MGR')
   出口
     iv_scope ='CUST'
     io_catalog_api = CAST/ui2/if_fdm_catalog_api(lo_catalog_api)
     io_messaging = CAST/ui2/if_fcm_messaging(lo_messaging)。

 lt_tile_tm_combination = CAST/ui2/if_flp_cont_mgr(lo_flp_cont_mgr)-> get_all_tiles_tms()。
 
哎,真难
4楼-- · 2020-08-26 08:13

谢谢,GáborMárián马修·比林汉姆,我现在明白了。 我看不到ABAP解决方案,因为它是ABAP的局限性:如果您使用方法的静态调用,则在运行时获得的简短转储等同于语法错误:

 DATA lo_flp_cont_mgr类型REF TO/ui2/cl_flp_cont_mgr。
 DATA lo_catalog_api类型引用对象。
 DATA lo_messaging TYPE REF TO对象。
 创建对象lo_flp_cont_mgr
 出口
 iv_scope ='CUST'
 io_catalog_api = lo_catalog_api"语法错误" LO_CATALOG_API"与形式参数" IO ..."不兼容。
 io_messaging = lo_messaging。  "语法错误" LO_MESSAGING"与形式参数" IO ..."类型不兼容

要么不将代码复制到7.31系统(几个源系统),要么生成源代码 在运行时(GENERATE SUBROUTINE POOL)。

一周热门 更多>