关于abap:ABAP-动态内表-read-table

这个程序展现了 如何动静内表的时候read 操作 loop 的时候 where条件的拼接 REPORT ztest_xy6.DATA: BEGIN OF lt_tmp OCCURS 10, hkont TYPE char10, sumty(2) TYPE c, END OF lt_tmp.DATA: ls_tmp LIKE lt_tmp, ls_tp2 LIKE lt_tmp.FIELD-SYMBOLS: <st_x> TYPE x.DEFINE m_tmp. clear lt_tmp. lt_tmp-hkont = &1. lt_tmp-sumty = &2. append lt_tmp.END-OF-DEFINITION.m_tmp '0090020020' '22'.m_tmp '0090020020' '21'.m_tmp '0090010010' 'C1'.m_tmp '0020110100' 'C1'.ASSIGN: ls_tmp TO <st_x> CASTING.ls_tmp-hkont = '0090020020'. ls_tmp-sumty = '22'.DATA gt_where TYPE TABLE OF string.gt_where = VALUE #(* ( |with key| ) ( | HKONT = '0090020020' AND| ) ( | SUMTY = '21'| ) ).DATA:gv_where TYPE string.gv_where = |Hello | & |world| .WRITE:/ gv_where.READ TABLE lt_tmp WITH KEY <st_x>.IF sy-subrc = 0. WRITE: / lt_tmp-hkont,lt_tmp-sumty.ENDIF.LOOP AT lt_tmp WHERE (gt_where). WRITE: / lt_tmp-hkont,lt_tmp-sumty.ENDLOOP.

April 1, 2021 · 1 min · jiezi

关于abap:一个问题CDS-view在HANA-studio里执行显示的耗时比在ABAP-open-SQL里少

Sent: Samstag, 8. Juli 2017 11:03Subject: RE: have a quick discussion about why the CDS view has a bad performance displayed in ST05 or SAT but the trace displayed in HANA studio shows a good performance Thanks a lot for your support. I have executed the report repeatedly for 5 times and the average time in ABAP is still 16 seconds. And when the SQLScript is executed in HANA studio, only 2.4 seconds is consumed.I plan to create an incident to HANA. ...

December 5, 2020 · 4 min · jiezi

关于abap:如何通过调试找到自己需要的ABAP增强

Jerry有一个SAP技术交换群,外面有很多参谋敌人们一起交换SAP开发技术。 有一个敌人提了这样一个对于加强点进口的问题。其实这类问题能够通过调试的方法本人找到答案。 场景一:查找SE18里的classic BAdI在CL_EXITHANDLER的GET_INSTANCE办法里设置断点,而后从新运行程序,如果断点触发,就把变量exit_name的值抄下来: SE18, 粘贴到BAdI Name字段里去, 就能看到这个加强定义下所有的实现了。 场景二 - 查找GET BADI关键字调用的旧式加强这种形式须要先以调试模式运行想要寻找加强的利用,在调试器的Break/Watchpoints里新建一个动静断点: 输出GET BADI, 回车: 动静断点创立胜利,此时F8继续执行: 如果断点停下来,双击GET BADI后的变量lr_badi, 把名称COM_MERGE_DATA_SET抄下来,这就是SE18里Enhancement Spot的BAdI定义名称。 把这个名称输出SE18的Enhancement Spot里,也能看到该Enhancement Spot下创立的所有加强实现。 更多Jerry的原创文章,尽在:"汪子熙":

December 5, 2020 · 1 min · jiezi

关于abap:不同类型的ABAP内表读写性能比较

I construct three internal tables with different table types: The complete test source code could be found in the end part of the blog. insert operation comparisonThe hashed table is least efficient since additional overhead is paid to maintain the internal administrative information for hash logic.The standard table is fastest due to the fact that there is no overhead. read operation comparisonThe standard table read is slowest due to o(n) complexity. ...

September 9, 2020 · 3 min · jiezi

关于abap:如何把一个ABAP视图添加到SAP-GUI的收藏夹里

The idea comes from Sougata Chatterjee’s anwser in this thread: Suppose I need to add the maintenance view COMV_PARTNER_FCT to my favorite list. I expect once the entry in the favorite list is double clicked, it will automatically navigate to the view detail like below ( the initial screen of SM30 is not expected ) Create a new transaction code and maintain SM30 as default value for transaction: ...

September 5, 2020 · 1 min · jiezi

关于abap:如何在SAP-CRM-WebClient-UI里创建web-service并使用ABAP消费

In this blog I will create a web service which is exposed via Genil model PROD in CRM web client UI and consume it via a simple ABAP program. Create web service in CRM Webclient UI(1) log on CRM Web UI with business role SERVICEPRO, work center Service Operation, Create a new Web service:Choose Material as Business Object, choose Product/Individual Product as Component, Product as Root object.Mark check box Read, Create and Change. ...

September 5, 2020 · 4 min · jiezi

关于abap:如何创建ABAP的text-table

(1) create a main table as usual: define the key field CHANNEL: (2) create another table which will be used as text table. Ensure a field with data element SPRAS is included as primary key. The primary key CHANNEL of main table must also be included in the text table. (3) mark field CLIENT and click button "Foreign Keys": Click Yes ...

September 5, 2020 · 1 min · jiezi

关于abap:SAP-CRM-Cross-Component级别的跳转如果出了问题该如何调试

Created by Jerry Wang on Feb 06, 2014(1) Click Hyperlink “Workflow document”: The following method is called to handle the navigation. Step into method SET_WORKAREA_CONTENT.(2) Inside method SET_WORKAREA_CONTENT, there is a method analyze_navigation: The information of navigation target is contained in the importing parameters. (3) Inside method SET_WORKAREA_CONTENT, there is a method analyze_navigation:The information of navigation target is contained in the importing parameters. ...

September 5, 2020 · 1 min · jiezi

关于abap:如何在SAP-ABAP系统里创建和消费Web-Service

This document could be used as guide for beginners to learn and use ABAP web service. How to create web service provider in ABAP systemThe following steps demonstrates how to expose a function module as a web service provider in SAP CRM system. (1) create a new function module to return product description by given input product ID.Signature and source code of function module: FUNCTION ZGET_PROD_DESCRIPTION.*"----------------------------------------------------------------------*"*"Local Interface:*" IMPORTING*" VALUE(IV_PROD_ID) TYPE COMM_PRODUCT-PRODUCT_ID*" EXPORTING*" VALUE(RV_TEXT) TYPE STRING*"----------------------------------------------------------------------SELECT SINGLE A~short_text INTO rv_text FROM COMM_PRSHTEXT AS A INNER JOIN comm_product AS B ON B~product_id = iv_prod_id AND B~product_guid = A~product_guid.ENDFUNCTION.Make sure the FM is marked as “Remote enabled”. ...

September 4, 2020 · 3 min · jiezi

关于abap:SAP-ABAP-Development-Tool的本地存储原理local-storage

Recently I have developed some CDS views in Eclipse and I would like to share the source codes in github. I am reluctant to manually copy the source code of each view one by one, as a result I am checking whether there are some folders in my local laptops where the source code are cached.I spent some time to research and here is the result.I have created three ABAP projects in Eclipse: ...

September 4, 2020 · 1 min · jiezi

关于abap:ABAP实现设计模式里的观察者发布者模式

This is an interview question from Wechat development team. The candidates are required to answer with JavaScript. Nevertheless I think it is also beneficial for an ABAPer if we master the design pattern contained in this question –Publish and Subscribe pattern. The requirement(1) The chain operations could be performed on instance of class ZCL_PERSON.For example, the red line 10 in ABAP code should generate the following output highlighted in red, and blue and green color accordingly.(2) The “sleep_first” operation has the highest priority, see ABAP line 14 and its output for reference. ...

August 31, 2020 · 3 min · jiezi

关于abap:使用ABAP实现Mock测试工具Mockito

What is Mockito? Mockito is a mocking framework, JAVA-based library that is used for effective unit testing of JAVA applications. In our unit test there are usually some dependency on other external service implementation for example network or database service. Usually in order to isolate our test code from these dependencies we have to create mock class against them. Mockito in Java can create transient mock class ( which is only available in current test session ) for us in a very easy way. See one example below: ...

August 31, 2020 · 5 min · jiezi

关于abap:干了SAP开发这么多年我都积累了哪些程序调试技巧

Tip1. Rubber Duck DebuggingTip1.1 blog your finding outTip1.2 Index your raw material into your knowledge repositoryTip2. ComparisonTip3. The Mini-System methodology for issue-isolationTip4. Google the error messageTip5. Try to be a master about the trouble shooting tool you useTip6. “I don’t know where to set breakpoint?”One of my new colleague is asking me whether I have some best practice which could be followed as a general way to analyze some issue more efficiently. ...

August 31, 2020 · 12 min · jiezi

关于abap:我ABAP开发生涯中搜集的一些有意思的数据库表

Magic tables CUS_IMGACH – IMG ActivitiesRFCATTRIB – Administration table for RFC destinationsSEOSUBCO – Class/interface subcomponentTVIMF – User routines called from view maintenanceMore to be added soonMagic reports RADPROTA – Display DDIC activation logRSTABLESIZE – Determining Table SizesRSSDOCTB – export transparent table definition locally4.A simple HTTP test tool RSICFCLTST01More to be added soon During my daily work I get to know the existence of some magic tables and reports which can enable me to achieve some work more efficiently and conveniently. Now I shared them with you. ...

August 31, 2020 · 4 min · jiezi

关于abap:用ABAP模拟JavaScript的柯里化语言特性Curry

As I mentioned in What should an ABAPer continue to learn as an application developer, function programming language is a mind -blower to ABAPers who have got used to ABAP as an imperative programming language. One of important concept in functional programming is Currying. Currying intensively manipulates functions. The name “Currying”, coined by Christopher Strachey in 1967, is a reference to logician Haskell Curry. Although the concept defined in wikipedia looks a little bit obscure, in fact every one should have already learned it during his / her high school in mathematics class. ...

August 31, 2020 · 5 min · jiezi

关于abap:使用ABAP-CLHTTPCLIENT类消费OData服务时如何避免CSRF令牌验证失败错误

Recently I meet with this cookie issue so I document it as a blog in case any other guys might meet with the same problem. I am trying to create some Opportunity transaction data by consuming OData service via CL_HTTP_CLIENT. Since this is a update operation which needs to be finished by HTTP POST, so a CSRF token is needed in this HTTP post. Let’s first have a look what is a typical scenario running in Chrome extension postman: ...

August 30, 2020 · 4 min · jiezi

关于abap:ABAP-Debugging-Script调试器脚本使用的一些实际例子

例子1:Use ABAP debugger script to view BOL entity content in an efficient wayIn CRM, if we could like to review a BOL entity content in debugger, for example consider the following sample code which fetches line item product of a given one order document: DATA: lo_collection TYPE REF TO if_bol_entity_col, lv_view_name TYPE crmt_view_name, lv_query_name TYPE crmt_ext_obj_name, ls_parameter TYPE genilt_query_parameters, lt_query_parameter TYPE genilt_selection_parameter_tab, ls_query_parameter LIKE LINE OF lt_query_parameter. ls_query_parameter-attr_name = 'OBJECT_ID'. ls_query_parameter-low = iv_oppt_id. ls_query_parameter-option = 'EQ'. ls_query_parameter-sign = 'I'. APPEND ls_query_parameter TO lt_query_parameter. ls_query_parameter-attr_name = 'PROCESS_TYPE'. ls_query_parameter-low = iv_process_type. ls_query_parameter-option = 'EQ'. ls_query_parameter-sign = 'I'. APPEND ls_query_parameter TO lt_query_parameter. so_core = cl_crm_bol_core=>get_instance( ). so_core->load_component_set( 'BT' ). lv_query_name = 'BTQ1Order'. DATA(lo_result) = so_core->dquery( iv_query_name = lv_query_name is_query_parameters = ls_parameter it_selection_parameters = lt_query_parameter iv_view_name = lv_view_name ). CHECK lo_result->size( ) = 1. DATA(lo_order_result) = lo_result->get_first( ). DATA(lo_bt_order) = lo_order_result->get_related_entity( 'BTADVS1Ord' ). CHECK lo_bt_order IS NOT INITIAL. DATA(lo_header) = lo_bt_order->get_related_entity( 'BTOrderHeader' ). CHECK lo_header IS NOT INITIAL. DATA(lo_items) = lo_header->get_related_entities( iv_relation_name = 'BTHeaderItemsExt' ). CHECK lo_items->size( ) = 1. DATA(lo_item) = lo_items->get_first( ). DATA(lo_admini) = lo_item->get_related_entity( 'BTItemsFirstLevel' ). CHECK lo_admini IS NOT INITIAL. DATA(lo_product) = lo_admini->get_related_entity( 'BTItemProductExt' ).If you would like to review the content of lo_product, you have to: ...

August 29, 2020 · 7 min · jiezi

关于abap:使用纯粹的ABAP位操作实现两个整数相加

Recently I came across this very funny picture and I would like to share with you. This picture shows totally five different approaches to implement “a + b”, and how your brain reacts when you read these code From this picture we know that for most guys, they will be crazy when they read the source code of the last solution as the code is really difficult to understand compared with all other four solutions. ...

August 28, 2020 · 3 min · jiezi

关于abap:如何找到ABAP里被动态调用的update-function-module

In this SCN discussion,Find a Function Module in Update Task dynamically called,a question is asked. For example, if the update function module CRM_PRODUCT_I_UPDATE_DU is called statically as:CALL FUNCTION ‘CRM_PRODUCT_I_UPDATE_DU’ … Then we can easily find all calling places where this function module is called.On the other hand, if the function module name is determined dynamicall in the runtime, for example: CALL FUNCTION lv_func_name, the where used list will not work.In this case, even though I have already set the breakpoint in update function module itself and the breakpoint is triggered in the runtime, I still could not figure out which programs calls this update function module. ...

August 27, 2020 · 1 min · jiezi

关于abap:ABAP数据库表的元数据

For project reason I need to fill some excel. The content of each column comes from content in SE11: In order to avoid such boring task, I write a small ABAP class to automate it. This class will first read corresponding database table name based on CRM settype id, then call function module DDIF_NAMETAB_GET to get all metadata of each table field, and then send the data to clipboard. ...

August 27, 2020 · 3 min · jiezi

关于abap:如何使用ABAP代码创建SAP-Product-Category

In ERP we can create new material type by copying from existing one using tcode OMS2: This new type could be downloaded into CRM system via customizing download. A product category with prefix MAT_ will be automatically created. And here below is source code to create new product category using MAT_ as parent category by ABAP code. METHOD replicate_category. CONSTANTS: BEGIN OF gc_application, sales TYPE comt_application VALUE '01', "r3-produkthier purchasing TYPE comt_application VALUE '02', "r3 mat class product TYPE comt_application VALUE '03', "r3 mat types config TYPE comt_application VALUE '04', internet TYPE comt_application VALUE '05', END OF gc_application. CONSTANTS: BEGIN OF gc_product_type, material TYPE comt_product_type VALUE '01', service TYPE comt_product_type VALUE '02', finance TYPE comt_product_type VALUE '03', ip_prod TYPE comt_product_type VALUE '04', warranty TYPE comt_product_type VALUE '05', tradeitem TYPE comt_product_type VALUE '06', fs_prod TYPE comt_product_type VALUE '07', END OF gc_product_type. rv_success = abap_false. DATA: lv_hierarchy_guid TYPE comt_hierarchy_guid, lv_parent_guid TYPE comt_category_guid, lt_categoryt TYPE comt_categoryt_tab.* Prerequisite: the corresponding hierarchy is already downloaded from ERP* Read the hierarchy which is assigned to application 03* (product type material) in transaction COMM_PRAPPLCAT CALL FUNCTION 'COM_HIERARCHY_READ_WITH_APPL' EXPORTING iv_application = gc_application-product iv_product_type = gc_product_type-material IMPORTING ev_hierarchy_guid = lv_hierarchy_guid EXCEPTIONS not_found = 1 OTHERS = 2. CHECK sy-subrc = 0. DATA(ls_cat_text) = VALUE comt_categoryt( langu = sy-langu category_text = iv_text text_upper_case = iv_text ). TRANSLATE ls_cat_text-text_upper_case TO UPPER CASE. APPEND ls_cat_text TO lt_categoryt. select single category_guid into lv_parent_guid FROM comm_category where category_id = 'MAT_'. CALL FUNCTION 'COM_PRODCAT_API_CREATE_CAT' EXPORTING iv_category_id = iv_cat_id iv_hierarchy_guid = lv_hierarchy_guid iv_parent_guid = lv_parent_guid iv_product_type = gc_product_type-material it_categoryt = lt_categoryt iv_logsys = iv_log_sys " 'QI3CLNT502' iv_non_assignable = abap_false EXCEPTIONS hierarchy_not_maintained = 1 wrong_call = 2 category_id_exists = 3 id_scheme_error = 4 error = 5 OTHERS = 6. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE 'X' NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. RETURN. ENDIF. CALL FUNCTION 'COM_PRODUCT_CATEGORY_SAVE_ALL' EXPORTING iv_update_task = ' ' iv_update_pme = ' ' iv_hierarchy_guid = lv_hierarchy_guid EXCEPTIONS internal_error = 1 OTHERS = 2. ASSERT sy-subrc = 0. COMMIT WORK AND WAIT. rv_success = abap_true. ENDMETHOD.Method signature: ...

August 27, 2020 · 2 min · jiezi

关于abap:Java和SAP-ABAP的异常处理

Recently I am prepare an internal training and have been racking my brains to find a real example for my attendees about writting a “correct” program which gets rejected by compiler. The tricky point here is as a programmer, we always treat compiler as our god: if compiler complains that our program has errors, then we are wrong. Programmers tend to believe in that compiler will NEVER make mistakes. ...

August 26, 2020 · 4 min · jiezi

关于abap:一些能提高ABAP开发人员日常工作效率的ABAP小工具

I write some small ABAP tools for my daily work. Some of them might not be so useful at first glance – I just write them for fun. Some of them could be used to improve work efficiency, to just reduce several mouse clicks – I am too lazy Tcode Usage Statistics ToolThis 56 lines of report can print the tcode usage for a given user per month. ...

August 26, 2020 · 14 min · jiezi

关于abap:ABAPJavaJavaScript里的字符串模板String-Template

As an ABAP you probably be very familiar with String Template. String Template in ABAPA string template creates a string from literal text, embedded expressions, and control characters in a string expression. The most powerful feature I like is we can insert ABAP variable inside the template by wrapper variable with “{ }”, see one example below: In the runtime, ABAP will replace the String Template content with actual value stored in that variable. This functionality is especially useful when you need to populate string dynamically based on some ABAP variable, for example you need to create some ABAP class or function module whose signature is only known in the runtime specified by consumer. ...

August 26, 2020 · 4 min · jiezi

关于abap:ABAP和JavaScript的懒加载单例和桥接模式的实现和比较

According to Wikipedia Lazy loading is a design pattern commonly used in computer programming to defer initialization of an object until the point at which it is needed. It can contribute to efficiency in the program’s operation if properly and appropriately used.In this blog, I will use an example of SCN log on to illustrate its usage in JavaScript and how to simulate the implementation in ABAP.When we click log on link in SCN: ...

August 25, 2020 · 6 min · jiezi

关于abap:ABAP数据库表的元数据

For project reason I need to fill some excel. The content of each column comes from content in SE11: In order to avoid such boring task, I write a small ABAP class to automate it. This class will first read corresponding database table name based on CRM settype id, then call function module DDIF_NAMETAB_GET to get all metadata of each table field, and then send the data to clipboard. ...

August 24, 2020 · 3 min · jiezi

关于abap:在SAP-ABAP里使用注解Inject模拟Java-Spring

Recently I will deliver a session regarding dependency inversion principle to my team. As Java Spring is already widely used in all other Java development teams in my site, some ABAPers are not well aware of its idea and implementation under the hood. In order for ABAPers to easily understand the mechanism of Java Spring dependency inversion, I wrote a prototype in ABAP after going through related Java source code of Spring. ...

August 24, 2020 · 5 min · jiezi

关于abap:如何使用ABAP代码创建SAP-Product-Category

In ERP we can create new material type by copying from existing one using tcode OMS2: This new type could be downloaded into CRM system via customizing download. A product category with prefix MAT_ will be automatically created. And here below is source code to create new product category using MAT_ as parent category by ABAP code. METHOD replicate_category. CONSTANTS: BEGIN OF gc_application, sales TYPE comt_application VALUE '01', "r3-produkthier purchasing TYPE comt_application VALUE '02', "r3 mat class product TYPE comt_application VALUE '03', "r3 mat types config TYPE comt_application VALUE '04', internet TYPE comt_application VALUE '05', END OF gc_application. CONSTANTS: BEGIN OF gc_product_type, material TYPE comt_product_type VALUE '01', service TYPE comt_product_type VALUE '02', finance TYPE comt_product_type VALUE '03', ip_prod TYPE comt_product_type VALUE '04', warranty TYPE comt_product_type VALUE '05', tradeitem TYPE comt_product_type VALUE '06', fs_prod TYPE comt_product_type VALUE '07', END OF gc_product_type. rv_success = abap_false. DATA: lv_hierarchy_guid TYPE comt_hierarchy_guid, lv_parent_guid TYPE comt_category_guid, lt_categoryt TYPE comt_categoryt_tab.* Prerequisite: the corresponding hierarchy is already downloaded from ERP* Read the hierarchy which is assigned to application 03* (product type material) in transaction COMM_PRAPPLCAT CALL FUNCTION 'COM_HIERARCHY_READ_WITH_APPL' EXPORTING iv_application = gc_application-product iv_product_type = gc_product_type-material IMPORTING ev_hierarchy_guid = lv_hierarchy_guid EXCEPTIONS not_found = 1 OTHERS = 2. CHECK sy-subrc = 0. DATA(ls_cat_text) = VALUE comt_categoryt( langu = sy-langu category_text = iv_text text_upper_case = iv_text ). TRANSLATE ls_cat_text-text_upper_case TO UPPER CASE. APPEND ls_cat_text TO lt_categoryt. select single category_guid into lv_parent_guid FROM comm_category where category_id = 'MAT_'. CALL FUNCTION 'COM_PRODCAT_API_CREATE_CAT' EXPORTING iv_category_id = iv_cat_id iv_hierarchy_guid = lv_hierarchy_guid iv_parent_guid = lv_parent_guid iv_product_type = gc_product_type-material it_categoryt = lt_categoryt iv_logsys = iv_log_sys " 'QI3CLNT502' iv_non_assignable = abap_false EXCEPTIONS hierarchy_not_maintained = 1 wrong_call = 2 category_id_exists = 3 id_scheme_error = 4 error = 5 OTHERS = 6. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE 'X' NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. RETURN. ENDIF. CALL FUNCTION 'COM_PRODUCT_CATEGORY_SAVE_ALL' EXPORTING iv_update_task = ' ' iv_update_pme = ' ' iv_hierarchy_guid = lv_hierarchy_guid EXCEPTIONS internal_error = 1 OTHERS = 2. ASSERT sy-subrc = 0. COMMIT WORK AND WAIT. rv_success = abap_true. ENDMETHOD.Method signature: ...

August 24, 2020 · 2 min · jiezi

关于abap:ABAP面试问题-不使用加减乘除等操作比较两个整数大小

Our team architect has asked us this question which is said to be an interview question from Microsoft long time ago:Please implement one function which accepts two integers as input and generate the following result accordingly: If a > b, return 1,if a = b, return 0,if a < b, return -1For simplification reason here we can just consider unsigned int ( that is, all importing parameter of integers are greater than or equal to 0 ). ...

August 23, 2020 · 4 min · jiezi

关于abap:使用ABAP的RTTI和Java反射机制访问static-private属性

In ABAP we can define a static attribute for a class via keyword CLASS-DATA, whose validity is not associated with instances of a class but with the class itself. In order to prove this fact I use the following simple Pointer class for demonstration: class ZCL_POINT definition public final create public .public section. data X type I . methods CONSTRUCTOR importing !IV_X type I !IV_Y type I .private section. data Y type I . class-data COUNT type I .ENDCLASS.CLASS ZCL_POINT IMPLEMENTATION. method CONSTRUCTOR. me->x = iv_x. me->y = iv_y. count = count + 1. endmethod.ENDCLASS.In this class, static attribute count is responsible to maintain the number of created Point instances.Then create four point instances: ...

August 23, 2020 · 3 min · jiezi

关于abap:ABAPJava和JavaScript的local-class

Local class in ABAPSuppose I have a global class with a public method ADD with following signature. I would like to implement with a local class inside this global class. The local class could be created by clicking button “Local Definitions/Implementions”: Now in my global class I can just delegate the ADD implementation to the local class. Notice that even ADD method is marked as public, it is still displayed as a red light in class builder, which makes sense since this ADD method in local class is not visible to outside consumers. ...

August 23, 2020 · 4 min · jiezi

关于abap:ABAPJava和JavaScript的整型数据类型比较

When I first begin to program with ABAP I get confused with different kinds of integer type available for ABAP developers: i, int1, int2, int4, and int8. According to ABAP help, predefined data types consists of two types: (1) predefined ABAP types: b, c, d, decfloat16, decfloat34, f, i, int8, n, p, s, string, t, x, and xstring.(2) predefined dictionary types: INT1, INT2, INT4, INT8,DEC,DF16_DEC,DF16_RAW,DF34_DEC,DF34_RAW and FLTP. ...

August 23, 2020 · 7 min · jiezi

关于abap:ABAP和Java的tagmarker-interface

In my previous blog How many fat interfaces are there in SAP system I introduce the concept of “fat interface”. In this blog let’s explore the concept of tag interface.There is definition for tag interface in ABAP help: “Specific predefined global interface. By integrating the tag interface, classes or other interfaces stand out against the ABAP runtime environment. A tag interface generally does not contain its own interface components, but instead assigns a particular task to the integrating classes or interfaces and changes the way they are handled by the ABAP Compiler.“And in fact this is not a specific concept of ABAP, but exists in many other language as well. ...

August 23, 2020 · 3 min · jiezi

关于abap:ABAP整型类型的几种位操作-OR-AND-XOR

For training purpose I need to explain to my ABAP team colleagues about how bitwise operation on Integer in Java like below is done. And since the bitwise operation in ABAP can only support data type X and XSTRING, so now I create a prototype which can support bitwise operation OR, AND, XOR on int4 in ABAP for teaching purpose. Still remember the wrapper class Integer in Java which is explained in my blog Integer in ABAP, Java and JavaScript? ...

August 23, 2020 · 3 min · jiezi

关于abap:使用ABAP-Channel实现一个订单跟踪工具提高日常工作效率

There are already many nice blogs introducing nice features provided by ABAP channels in community, for example ABAP Channels Examples. In that blog some demo examples are explained. After going through those impressive tutorials and demos, have you ever thought about building some useful stuff for your daily work by leverage this powerful feature in ABAP? As ABAPers we use various trace / monitor tools in our daily work, such as SAT and ST05. And in CRM, all business transactions are managed by so called One Order framework. This framework uses function module CRM_ORDER_MAINTAIN to create, update and delete the document. ...

August 22, 2020 · 4 min · jiezi

关于abap:SAP-ABAP和Java跨域请求问题的解决方案

There is an excellent blog Cross-domain communications with ABAP and JSONP written by Alessandro Spadoni.And in this blog, I just record down my own study experience about how to achieve cross domain request in ABAP and Java. Cross Domain Request in ABAPCreate a new ICF node in tcode SICF, implement the following source code in its handler class.4 METHOD if_http_extension~handle_request. DATA: lv_text TYPE string value 'hello world'. server->response->append_cdata( data = lv_text length = strlen( lv_text ) ). ENDMETHOD.Access the url in browser, and it works as expected. ...

August 22, 2020 · 3 min · jiezi

关于abap:SAP数据库表DDLOG的设计原理

Today when I am reading this SAP help, I find out this sentence: Then I have opened the definition of table DDLOG in the system and found I cannot directly view the content of field NOTEBOOK due to its data type LRAW. So I have chosen one table with buffer activated, and made some changes on it. Since I can only query this table via timestamp, I cannot figure out which entry is for my change on CRMC_PROC_TYPE. ...

August 21, 2020 · 1 min · jiezi

关于abap:SAP-ABAP数据库表字段checktable的实现原理

For project reasons I need to find all tables whose fields have used a given table say COMM_PRODUCT as check table. The only information I know is that such kind of table metadata is stored in table with name prefix DD*. Unfortunately there are huge number of table starting with DD: How to efficiently find the exact one by yourself? (1) Make the check table field selected, and press F1: ...

August 20, 2020 · 1 min · jiezi

关于abap:SAP-ABAP报表依赖设计原理详解

In SAP note 1230076 “Generation of ABAP loads: Tips for the analysis”, a tool report RSDEPEND is introduced. It is explained in the note “An ABAP program generally depends on many other repository objects. If an object like this changes (for example, an include or a DDIC type), the load of all dependent programs must be invalidated. The load of these programs is then regenerated with the next use, and valid loads are generated again.” ...

August 20, 2020 · 3 min · jiezi

关于abap:ABAP-740里的新语法-LET表达式

A LET expression defines variables var1, var2, … or field symbols <fs1>, <fs2>, … as local auxiliary fields in an expression and assigned values to them. When declared, the auxiliary fields can be used in the operand positions of the expression. There is no way of accessing an auxiliary field statically outside its expression. See example below: in line 25 and line 26 we define two auxiliary fields date and sep with keyword LET, which are used in LET expressions in line 27.in line 27 we define a LET expression by keyword INfinally the value of LET expression will be calculated and filled to inline variable isodate defined in line 24. We use CONV string to explicitly specify that inline defined variable isodate has type STRING. ...

August 6, 2020 · 1 min · jiezi

关于abap:ABAP-740的新语法-使用BO-association的方式进行内表连接操作

ABAP Mesh is also a new feature in 740. Let’s use an example to demonstrate how it works:I have defined two types for developers and managers. developer type has a field manager which points to his manager, while manager type does not have any reference to his managing employee. types: begin of t_manager, name type char10, salary type int4, end of t_manager, tt_manager type sorted table of t_manager with unique key name.types: begin of t_developer, name type char10, salary type int4, manager TYPE char10, end of t_developer, tt_developer type sorted table of t_developer with unique key name.I also use the new grammar – inline data declaration to fill developer and manager table. So far nothing special. ...

August 6, 2020 · 2 min · jiezi

关于abap:ABAP-740新的OPEN-SQL增强特性

The following open SQL statement looks a little weird, however it could really works in 740. (1) The field name of my structure ty_my_sflight is different from field defined in sflight, so in SQL statement I use the format <field in DB table> AS <field in my own structure> to move the content from DB to the corresponding fields of my internal table. (2) I want to calculate the percent about how many seat are occupied and put the result into my field my_seatrate. Now I could push the calculation to DB layer instead of calculating it in ABAP side. ...

August 6, 2020 · 2 min · jiezi

关于abap:ABAP-Webdynpro-如何使用用户自定义的value-help

For input attribute totally five input help mode could be selected. In most of time we would always like to leverage the existing dictionary search help defined in DDIC. However if existing one could not fulfill our requirement, we have to develop our own value help by ourselves. I have used a simple example to demonstrate how to use “Freely Programmed” input help mode. I have one consumer component ZCONSUMER, and one component ZUSER_HELP.ZCONSUMER just have one input field for post ID and post description. When click value help of Post ID, the view of ZUSER_HELP will be opened and there is a SQL select to fetch the description according to post ID from database table. ...

August 6, 2020 · 2 min · jiezi

关于abap:ABAP-Webdynpro里Component-Usage的用法

In NET311 the topic component usage clone is discussed there. One example is also given there:The user of a Web Dynpro application can mark multiple lines of a table to display details for each selected data set. The details of one data set is displayed by one usage of a certain component. Thus, the number of component usages equals the number of marked lines, which is not known at design time. ...

August 6, 2020 · 3 min · jiezi

关于abap:ABAP-Webdynpro-Interface-View的用法

If the component usage is not defined at design time, it is not possible to embed an interface view of this component usage into a ViewUIElementContainer of another view. It is also not possible to define a navigation link connecting any outbound plug of an existing view to an inbound plug of this interface view at design time. In this case methods of the Web Dynpro API have to be applied. ...

August 6, 2020 · 3 min · jiezi

关于abap:ABAP-Webdynpro的跟踪工具WDTRACETOOL

You can use tcode WD_TRACE_TOOL to switch on trace. After that when you launch your webdynpro application, you can observe there is a Webdynpro trace window embedded in the bottom of the application. You can either deactivate the trace in old Dynpro tool or in that embedded window. After you click Store trace as Zip File & Finish trace,you can save the trace file as zip locally. ...

August 6, 2020 · 1 min · jiezi

关于abap:判断ABAP代码是否处于update模式下运行的工具类

The class cl_system_transaction_state contains several useful utility methods: get_in_update_task: return the flag whether current code is running with normal work process or in update work processget_on_commit: return flag whether current code is called because of a previous registration via PERFORM ON COMMIT and triggered by COMMIT WORKget_sap_luw_key: return current LUW IDI just use a very simple report to test them. First I call the FM ZSQF in a normal way, then call it via update task, then register it with PERFORM ON COMMIT and trigger it via COMMIT WORK. ...

August 6, 2020 · 2 min · jiezi

关于abap:四种ABAP单元测试隔离test-isolation技术

Hi friends,As far as I know test isolation is widely used in SAP internal to build unit test code, at least in my team. Test isolation in unit test means that in your production code you make use of some API(class method/Function module) which are developed by other team, and you would not like to really consume them during your unit test, since you would not accept that most red lights in your unit test report are caused by the bugs in those external API,right? Instead, you expect that the call of those external API during your unit test execution will be replaced by some dummy code written by yourself.I will show you four different ways to achieve that.The example comes from one productive class in my project. For simplicity reasons I don’t list unrelevant code here. The class is ZCL_DESTRUCTION_IMG_TOOL_S1. ...

August 2, 2020 · 5 min · jiezi

关于abap:四种ABAP单元测试隔离test-isolation技术

Hi friends,As far as I know test isolation is widely used in SAP internal to build unit test code, at least in my team. Test isolation in unit test means that in your production code you make use of some API(class method/Function module) which are developed by other team, and you would not like to really consume them during your unit test, since you would not accept that most red lights in your unit test report are caused by the bugs in those external API,right? Instead, you expect that the call of those external API during your unit test execution will be replaced by some dummy code written by yourself.I will show you four different ways to achieve that.The example comes from one productive class in my project. For simplicity reasons I don’t list unrelevant code here. The class is ZCL_DESTRUCTION_IMG_TOOL_S1. ...

August 2, 2020 · 5 min · jiezi

关于abap:ABAP工作流workflow的调试方式

There are several posts in SCN talking about workflow debugging. Most of them are manually generating an endless loop and then can launch debugger in SM50. However, if you try to debug standard workflow, you are not allowed to manual inject any endless loop in standard code. If the original developer is not so kind to leave any switchable endless loop in standard code, you have to go another way. ...

August 2, 2020 · 2 min · jiezi

关于abap:ABAP工作流workflow的调试方式

There are several posts in SCN talking about workflow debugging. Most of them are manually generating an endless loop and then can launch debugger in SM50. However, if you try to debug standard workflow, you are not allowed to manual inject any endless loop in standard code. If the original developer is not so kind to leave any switchable endless loop in standard code, you have to go another way. ...

August 2, 2020 · 2 min · jiezi

关于abap:ABAP-Development-Tool前后台交互的原理

在S/4HANA零碎里,SE16,查看表PRGN_CORR2的内容: REL_NAME(release name)指定成751: S_TCODE是ECC里的事务码,而T_TCODE是对应的S/4HANA的新事务码。 Have you even thought about why you could operate on ABAP backend system using ADT? This document just gives a brief introduction about how does the ADT backend infrastructure respond your operation done in Eclipse. It contains a hands-on exercise which you could finish in your own ABAP system. Explore ADT by switching on ABAPcommunication logIn order to explore what has happened when we do operations in Eclipse, we need to switch on ABAP communication log.Click Windows->show view. Make view “ABAP Communication Log” is displayed. ...

August 2, 2020 · 5 min · jiezi

关于abap:给你的ABAP对象打上标签Tag

标签(Tag)简直是信息管理软件的一个必备性能,目标是帮忙用户更迅速地检索出本人须要的数据,以及对海量数据进行更无效的治理。 现在在ABAP Development Tool里也反对标签性能了,能够像应用各种云笔记一样,给罕用类型的ABAP对象增加自定义的标签。这个标签调配的性能并未给ABAP对象削减任何新的性能,而是帮忙使用者可能依照本人的理论需要,迅速将须要的ABAP资源检索进去。 本文先展现给ABAP对象加标签的操作形式,再介绍如何给ABAP Development Tool增加标签性能。 在ABAP Development Tool里增加标签的形式十分间接,右键菜单里抉择Assign Tags即可。但凡应用过云笔记里标签增加和治理性能的敌人们,对此应该十分相熟。 通过Add Tag和Add User Tag按钮治理标签构造,每个ABAP零碎都有一个全局的标签零碎(Global Tag), 这些标签在同一ABAP零碎里所有登录用户均可见。也能够创立只有本人可见的User Tag: 和云笔记的标签零碎一样,ABAP Development Tool里的标签治理也反对树状的层级构造。 在快捷键为Ctrl+H的全局搜寻页面里,削减了一项依据标签搜寻ABAP对象的选项: ABAP Development Tool的标签治理性能来自开源社区的奉献,因而须要使用者自行装置。 Jerry之前的一篇博客介绍了用户在ABAP Development Tool里操作时前后台交互的原理: An example to help you understand how does ADT workhttps://blogs.sap.com/2014/08... 因而这个标签治理性能咱们须要别离装置ABAP Development Tool前后台对应的加强。 首先是前台加强,即ABAP Development Tool里的标签增加,标签树形构造治理和依据标签进行全局搜寻的UI实现。 前台加强间接通过Eclipse的Help菜单里的Install New Software选项在线装置即可,装置网址为:https://stockbal.github.io/ec... 后盾加强的ABAP实现源代码,位于Github上:https://github.com/stockbal/a... 该仓库的源代码须要应用abapGit装置到ABAP后盾零碎上。 如果你的ABAP零碎没有abapGit这个客户端,须要先进行装置,其实就是新建一个报表,再将上面这个Github仓库里的abapGit源代码拷贝到报表里,激活即可。 https://github.com/larshp/aba... 将下图高亮的zabapgit.abap蕴含的源代码下载到本地,用任意一个文本编辑器关上,Ctrl C再Ctrl V到ABAP零碎的报表里,激活: 激活之后运行报表,看到的首页如下。点击右上角的New Online: 将ADT标签治理的后盾实现应用abapGit pull到以后的ABAP零碎,点击Clone online repo: ...

August 2, 2020 · 1 min · jiezi

关于abap:给你的ABAP对象打上标签Tag

标签(Tag)简直是信息管理软件的一个必备性能,目标是帮忙用户更迅速地检索出本人须要的数据,以及对海量数据进行更无效的治理。 现在在ABAP Development Tool里也反对标签性能了,能够像应用各种云笔记一样,给罕用类型的ABAP对象增加自定义的标签。这个标签调配的性能并未给ABAP对象削减任何新的性能,而是帮忙使用者可能依照本人的理论需要,迅速将须要的ABAP资源检索进去。 本文先展现给ABAP对象加标签的操作形式,再介绍如何给ABAP Development Tool增加标签性能。 在ABAP Development Tool里增加标签的形式十分间接,右键菜单里抉择Assign Tags即可。但凡应用过云笔记里标签增加和治理性能的敌人们,对此应该十分相熟。 通过Add Tag和Add User Tag按钮治理标签构造,每个ABAP零碎都有一个全局的标签零碎(Global Tag), 这些标签在同一ABAP零碎里所有登录用户均可见。也能够创立只有本人可见的User Tag: 和云笔记的标签零碎一样,ABAP Development Tool里的标签治理也反对树状的层级构造。 在快捷键为Ctrl+H的全局搜寻页面里,削减了一项依据标签搜寻ABAP对象的选项: ABAP Development Tool的标签治理性能来自开源社区的奉献,因而须要使用者自行装置。 Jerry之前的一篇博客介绍了用户在ABAP Development Tool里操作时前后台交互的原理: An example to help you understand how does ADT workhttps://blogs.sap.com/2014/08... 因而这个标签治理性能咱们须要别离装置ABAP Development Tool前后台对应的加强。 首先是前台加强,即ABAP Development Tool里的标签增加,标签树形构造治理和依据标签进行全局搜寻的UI实现。 前台加强间接通过Eclipse的Help菜单里的Install New Software选项在线装置即可,装置网址为:https://stockbal.github.io/ec... 后盾加强的ABAP实现源代码,位于Github上:https://github.com/stockbal/a... 该仓库的源代码须要应用abapGit装置到ABAP后盾零碎上。 如果你的ABAP零碎没有abapGit这个客户端,须要先进行装置,其实就是新建一个报表,再将上面这个Github仓库里的abapGit源代码拷贝到报表里,激活即可。 https://github.com/larshp/aba... 将下图高亮的zabapgit.abap蕴含的源代码下载到本地,用任意一个文本编辑器关上,Ctrl C再Ctrl V到ABAP零碎的报表里,激活: 激活之后运行报表,看到的首页如下。点击右上角的New Online: 将ADT标签治理的后盾实现应用abapGit pull到以后的ABAP零碎,点击Clone online repo: ...

August 2, 2020 · 1 min · jiezi

一段让人瑟瑟发抖的ABAP代码

昨天11月1日是万圣节,Jerry在继续忙着调研SAP Commerce Cloud里的产品主数据管理。晚上回家到SAP国外的社交媒体上一看,好热闹啊。国外的SAP从业者们纷纷以各种各样的方式庆祝万圣节。 西方的万圣节也是一个历史悠久的节日了:早在两千多年前,欧洲基督教会就把每年的11月1日定为“天下圣徒之日”(All Hallows' Day)。这一天被看作是夏天正式结束之日,也就是新年伊始,严酷的冬天开始的第一天。当时的人们相信,故人的亡灵会在这一天回到故居地,在活人身上找寻生灵,借此再生。而活人则惧怕死人的魂灵来夺生,于是人们在这一天熄掉炉火和烛光,让死人的魂灵无法找到活人,同时又把自己打扮成妖魔鬼怪把死人的魂灵吓走。 所以,国外的ABAP开发者们在这天也不甘寂寞,一位老哥提出了用“Scare with ABAP”的主题来搞事情,为万圣节增添一些节日气氛。 这一提议得到了大家的纷纷响应。 对于这种ABAP字符串模板和字符串内嵌函数的使用,肯定不能够让ABAP老司机们瑟瑟发抖。 这种程度的ABAP代码显然也不足以让ABAP老司机们受到惊吓: 那么看看Jerry这段ABAP代码?没有任何语法错误,能够成功激活,成功执行。 源代码如下: REPORT 汪子熙的Report,吓死人了!!!!!. INCLUDE NOT. IF NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT NOTNOT NOT NOT NOT NOT NOT NOT NOT NOT NOT !NOT OR NOTNOT NOT !NOT OR NOT NOT NOT NOT NOT=>NOT( NOT ) ANDNOT NOT NOT !NOT OR NOT NOT !NOT AND NOT !NOT ... NOT. ...

November 5, 2019 · 1 min · jiezi

利用ABAP-740的新关键字REDUCE完成一个实际工作任务

ABAP 740从2013年发布至今已经过去很长的时间了,下面这张图来自SAP社区博客: ABAP News for Release 7.40 – What is ABAP 7.40? 图中的ABAP 8.0, 即现在的SAP Cloud for Customer和Business By Design后台使用的ABAP版本NGAP - Next Generation ABAP Platform,里面存在不少只在8.0版本可用的关键字和语言特性。 因为C4C和BYD的ABAP后台,客户和partners们是无法访问的,所以咱们回到ABAP 740这个版本。从该版本开始,ABAP支持了很多新的关键字和语法特性,“看起来有点不像传统的ABAP编程语言了”。 本文咱们就来看一个具体的例子:ABAP 740里的一个新关键字REDUCE. 这个关键字的作用和在大规模数据集并行计算领域里广泛使用的"Map-Reduce"编程模型中的Reduce操作类似,可以按照字面意思理解为“归约”。 下图是Map Reduce框架的工作步骤,统计一个海量输入数据集(比如大于1TB)中的单词出现次数。作为ABAP开发人员,我们没必要了解Map Reduce框架的每个执行步骤,只需紧盯框架的输入,以及执行结果就行了。 回到Jerry接受的实际工作任务。德国同事让Jerry在某个CRM测试系统上做个统计,列出在数据库表CRM_JSTO里,OBTYP(Object Type)和STSMA(Status Schema)这两列拥有相同值的内表行的个数。大家可以把"OBTYP和STSMA两列具有相同值的内表行"类比成上图中重复出现的单词。 下图是CRM_JSTO的部分行: 下图是Jerry完成的任务: 测试系统上内表一共有55多万行,其中有90279行,只维护了OBTYP为TGP,而没有维护STSMA. 排名第二的是COH和CRMLEAD的组合,出现了78722次。 稍稍做过一些ABAP开发的朋友们,一定会立即写出下面的代码: 利用SELECT COUNT直接在数据库层完成统计工作。这也是SAP推荐的做法,所谓Code pusudown准则,即能放到HANA数据库层面进行的操作,就尽量放进去,以充分利用HANA强大的计算能力。在数据库能够完成计算逻辑的前提下,尽量避免把计算逻辑放到Netweaver ABAP应用层去做。 不过,我们也需要注意到这种方式的局限性。Jerry之前曾经引用过SAP CTO的名言: There is no future with ABAP aloneThere is no future in SAP without ABAP ...

November 4, 2019 · 1 min · jiezi

使用代码列出金庸小说中使用过的所有成语

去年的今天,金庸与世长辞,当时Jerry在成都地铁一号线下班的路上得知了这个消息,回到家立即写了一篇文章来悼念:金庸的武侠世界和SAP的江湖。 一年的时间转瞬即逝,大家都忙碌于各自的生活,很多人对金老的离世已经淡忘了,不过Jerry这种金庸的死忠粉,对于这个一周年忌日还是记得很清楚的。 因为Jerry手上事情很多,没时间在这个特殊的日子写文章纪念了,就发一小段代码吧。 需求:列出金庸任意一本小说里出现的所有成语。 实现:Jerry部署在Github上的一个web应用,链接如下: http://jerrywang-sap.cn/Fiori... 首先点击超链接“成语全集”: 点击之后,存储于该web应用本地存储的一个文本文件里的全部19830个成语,以树的形式加载到内存中,并显示在网页上: 然后复制一本金庸小说的内容,粘贴到网页的“内容”区域,点击按钮“测试”: 可以看到仅仅用了246毫秒,就将这部一百多万字的《倚天屠龙记》里出现的所有成语,以红色高亮的方式高亮出来。 这个功能咋实现的?Chrome打开Jerry的网页,F12开启开发者工具,就能看到JavaScript源代码,当然也可以从我的Github上获得. Jerry简单讲下实现原理。Web应用里有一个文本文件,里面维护了汉语里全部的成语,通过分号分隔。 运行时,这些内容会被加载到内存中,构建成一棵树,如下图所示: 其中叶节点以属性end为true区分。 成语检索的核心逻辑位于search函数里,让我们用《笑傲江湖》里一句响亮的口号“日月神教千秋万载,一统江湖”来单步调试,了解其实现逻辑。 进入165行的外层while循环,再进入173行的内层for循环,检测是否有测试字符串第一个字符“日”开头的成语。因为成语是由4个字符组成,所以需要用内层for循环逐一试探,如果遇到tblCur.end为true的元素,说明在测试字符串中发现了一个成语。 下图是内层for循环第一次执行后的tblCur内容: 内层循环执行第二次,此时tblCur指向一棵由所有“日月”开头的成语组成的树: 执行内层循环的第三次迭代,因为在树“日-月”这个分支下面没有“神”这个节点,所以结束当前的内层循环,通过break返回到外层的while循环,进行输入字符串第二个字符“月”的新一轮试探,以此类推。 最后从“千”这个字符出发,沿着内存中的树经过路径"秋-万",最后来到end属性为true的叶节点“载”,记下“千”在输入字符串中的偏移量,存到一个数组arrMatch中去。 待输入字符串全部试探完毕后,根据arrMatch中存放的偏移量,高亮显示对应的字符串,完成检索。 树这个数据结构在这个需求的实现里有着完美的表现。 金庸虽然离开了我们,但他笔下那些人物和发生的故事,将永远流传于这个世上。 更多阅读金庸的武侠世界和SAP的江湖金庸和古龙,Netweaver和微服务,以及SAP Hybris Revenue Cloud作为一名SAP从业人员,需要专门学习数学么要获取更多Jerry的原创文章,请关注公众号"汪子熙":

November 4, 2019 · 1 min · jiezi

我是怎么和SAP结缘的-Jerry的SAP校园招聘之路

2006年9月,结束了一年的北京中科院实习后,我回到了电子科技大学,此时已经是研三上学期了。有着“金九银十”之称的秋季校园招聘正式开始了。 准备好了简历后,Jerry也加入了浩浩荡荡的求职大军。十年前的计算机专业求职市场和今天有很大不同——我们的首选是微软,谷歌,思科,IBM等外企,包括在成都本地设有研发中心的诺基亚,摩托罗拉,阿尔卡特等通讯企业。而现在求职市场上炙手可热的BAT,十年前在我们学生心中的影响力还远远不是现在可以比的。 当时Jerry所在的电子科技大学计算机8020教研室也有很多师兄师姐在成都这些本土通信企业工作,Jerry平时听他们介绍里面的工作环境非常好,工资待遇在成都也非常有竞争力,在加上当时外企在学生心中普遍都具有光环,所以找工作时将这些通信企业作为首选。 不巧的是2006年秋季,这些通讯企业在成都本地几乎没有校园招聘,Jerry也曾打电话询问在里面工作的几位师兄师姐,得到的答复是只有社招,因此首选去通讯企业的计划没法实现了。 电子科技大学在当年和现在一样,是向华为和中兴这两家公司输送毕业生的大户。华为和中兴的笔试我至今记得很清楚,是在清水河校区的第二教学楼进行的,因为参加笔试的同学太多了,那规模好比某一学科的期末考试。笔试题过了这么多年已经印象很模糊了,并不是编程基础的技术题目,而是以逻辑思维题为主,有点像考公务员题目。这两家公司的笔试环节Jerry都顺利通过了,华为的面试第一轮是小组面试,考官出一道题目,同学们组成一个小组讨论,然后由一位同学汇报,完毕后考官发问,所有组员回答。据说华为的考官们喜欢通过这种方式考察应聘者能否承受压力。后来面试结束后,等了一段时间,接到了华为HR的电话,询问我是否接受因为工作原因而分配到不同的城市去工作,就是所谓的是否“接受调配”,我对这个是有些抗拒的,所以回答了否,也就没有下文了。 当时我们有一个不成文的传统,把华为和中兴的offer拿在手上保底,然后再寻找更好的。于是Jerry顺利的拿到了中兴的offer,然后继续参加仍在进行的各大公司秋季校园招聘。 让Jerry印象深刻的是,2006年的时候,深圳迅雷也曾经到电子科大来招聘过,当时的迅雷,应该只是一个一百多人的小公司,尽管当时几乎我们每一位同学的电脑里都装了这款下载软件。迅雷的技术人员对我们教研室同学的项目背景很感兴趣,因为我们在北京实习,做的就是一个P2SP的内容分发项目(顺便说一句,两千年初那段时间,BT和电驴这种P2P内容分发软件在国内真的很火啊)。当时Jerry通过了迅雷的比试和面试,然后在电子科大宾馆里参加了HR面试,HR是一位小伙子,当时他谈了很多对迅雷美好前景的憧憬。 Jerry满以为能拿到迅雷的offer了,没过多久,我的邮箱里收到了一封迅雷要求加试的笔试题目,要求完成后把源代码发到邮箱里。因为我当时还在准备其他公司的笔试,所以就没有理会。 后来2014年的时候,看到迅雷成功上市的消息,因为当时在SAP已经工作7年了,对这消息也没有任何感觉。 因为是大四上学期了,专业课和外出实习都已结束,除了找工作之外我们没有其他事情可以做,因为工作没落实,也没心思写论文,所以大家即使手上已经有了offer,也仍然继续参加其他公司的面试笔试。后来我又陆续拿了一些中小公司的offer,不过和现在的同学们动则互联网大厂可观的package相比不值一提,这里就略过了。 稍稍值得一提的就是深圳腾讯的offer,岗位和Jerry研究生所学非常对口:Linux后台开发工程师,进去之后应该是从事后台服务器端开发。Jerry所在的8020教研室从开创的祖师卢教授到众多在电子科大留校任教的师兄们一直都在和Unix系统打交道,所以我们教研室每位成员的Linux编程功底都非常扎实。 Jerry当初为什么要选择成都SAP而不是深圳腾讯?可能Oliver之前的演讲打动了我,也可能是因为2006年的腾讯,在学生中的影响力还远远不能和十三年后的今天相比。 2006年10月份下旬的时候,SAP来电子科技大学开宣讲会了,在科大的厦新厅开的。当时Jerry对SAP一无所知,不过我所在的教研室有两位很优秀的同学已经在里面实习一段时间了。他们告诉我,这家德国企业是世界上非常顶尖的企业管理软件公司,在成都软件园刚刚创建研发中心,现在招聘的正式员工都是在该行业摸爬滚打的精英。即使是实习生进去,如果表现优秀,也有可能被送往德国总部去培训。 有了这两位同教研室的同学提供的信息,我按时参加了SAP的招聘会。会上主讲的是Wang Oliver,也就是后来我老板的老板。Oliver拿起讲台前的一瓶矿泉水,告诉我们,这瓶水从采集到生产,再到最后出现在超市货架里,几乎每个步骤背后都离不开SAP软件的管理,这让我们觉得这家公司的软件如此神奇和伟大。 当时因为宣传的原因,SAP还不像今天这样,被广大学生所熟知。虽然Oliver的演讲里那句“The Best Run Businesses Run SAP”给我们学生留下了深刻的印象,但是和演讲的幻灯片里那些高大上的描述相比,我们还是不太清楚假设进入SAP后,我们具体的工作内容是什么。宣讲会结束,到了投递简历的时候,我在我简历上写下的应聘职位是“Associate Application Consultant”. 这是我在英文课本以外的地方第一次使用Consultant这个词。 等到11月份,Jerry在电子科大的物理电子学院的教学楼里参加了SAP成都的笔试。题目是纯英文的阅读理解和推理题。笔试通过后,Jerry在参加一家公司面试等待的间隙,接到了SAP HR的电话面试,时间不长,主要是HR用英文提问,我用英文作答。 接下来的第一轮现场面试,是到位于成都天府软件园B区6栋3楼的SAP成都研发服务中心参加小组群面。群面的形式和之前提到的华为群面类似,同学们分成人数相同的几个组,同时根据考官出的题目开始小组讨论,考官们在旁观察,等规定的时间结束之后,每个小组的每位组员需要用英语来汇报题目要求回答的各个维度的问题。 和Jerry当时一起参加小组面试的几位同学,她们流利的口语和超出一般学生的那份成熟,给当时的我留下了深刻的印象。有缘的是,这几位同学现在也都还留在成都SAP,而且早已成为各自团队的核心成员。时间过得真快,12年转瞬即逝。 小组面试结束后,是两轮的一对一面试,很有意思的是,这两轮的面试官都是Jerry后来的同事 :) 这一系列的面试结束后,等了两周,我终于收到了SAP成都的实习offer,此时已经是2006年12月底了。拿着SAP的offer,我度过了一个愉快的元旦。2007年1月,我以实习生的身份加入了SAP成都,领到了属于自己的第一台ThinkPad电脑,型号为经典的T60. 接下来就是大家熟悉的故事,我顺利通过了考核,结束了一年的实习生涯,在2007年底转正,成为一位SAP成都的正式员工。 这就是Jerry和SAP结缘的始末。各位SAP从业者,你们是怎样进入SAP这个行业的呢?欢迎留言,说出你的故事。感谢阅读。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

October 14, 2019 · 1 min · jiezi

如何在SAP云平台ABAP编程环境里创建自己的Z表

选中ABAP包,右键创建一个新的Database Table: 维护表名为ZBOOKING: 表实现的源代码: @EndUserText.label : 'Jerry''s booking'@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE@AbapCatalog.tableCategory : #TRANSPARENT@AbapCatalog.deliveryClass : #A@AbapCatalog.dataMaintenance : #LIMITEDdefine table zbooking { key client : abap.clnt not null; key booking : abap.int4 not null; customername : abap.char(50); numberofpassengers : abap.int2; emailaddress : abap.char(50); country : abap.char(50); dateofbooking : timestampl; dateoftravel : timestampl; @Semantics.amount.currencyCode : 'zbooking.currencycode' cost : abap.curr(15,2); currencycode : abap.cuky; lastchangedat : timestampl;}激活: 下一步,创建一个ABAP类,以代码的方式往Z表里插入数据。 这个ABAP类要实现if_oo_adt_classrun接口,类似Java里的console应用: ...

October 14, 2019 · 1 min · jiezi

如何在SAP云平台ABAP编程环境里把CDS-view暴露成OData服务

Jerry 2016年在学习SAP CDS view时,曾经写过一个CDS view的自学系列,其中有一篇提到了一个很方便的注解: @OData.publish: true 加上这个注解的CDS view,一旦激活后就会在ABAP Netweaver自动生成一个OData服务,在事务码/IWFND/MAINT_SERVICE里将其搜索出来并添加,就能够以OData服务的方式,消费这个view暴露出来的数据了。 当然@OData.publish这个注解为什么有这种神奇的魔力,在Jerry之前的博客里有详细介绍。 那么到了SAP云平台ABAP环境上,因为我们无法访问SAP GUI,所以要实现同样的效果,无法直接照搬上述步骤。幸运的是,在云上进行CDS view暴露的步骤依然简洁,整个过程5分钟就能搞定。 用ABAP Development Tools像登录On-Premises ABAP系统那样登录ABAP云环境,新建一个Service definition: 在Service的实现体里,使用关键字expose将ABAP环境里的标准view,I_Currency以Service的方式暴露出来。 这个Service需要以Service Binding的方式暴露成OData服务: 把第一步创建的Service分配给这个Service Binding: 注意下图右边的Service Details标签页里,此时是空的。点击Publish按钮: 发布成功后,我们看到了之前在Service实现里把I_Currency暴露成的名为Currency的实体: 对这个Currency Entity点右键,选择Open Fiori Elements App Preview,就能在预览模式下通过一个标准通用的Fiori Elements应用把当前系统上I_Currency里的数据显示出来: 点击这个Service URL超链接,也能直接打开对应OData服务的元数据(metadata)链接: 至此我们就可以用各种消费端来使用这个通过I_Currency暴露成的OData服务了,当然也可以开发一个SAP Fiori来消费,Jerry后续会介绍。 感谢阅读。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

October 14, 2019 · 1 min · jiezi

云端的ABAP-Restful服务开发

愉快的暑假结束了,今天是小朋友新学期开学后的第一个周日,不知道各位家长是否和小朋友们一起,已经适应了新学期的生活了么?Jerry从少的可怜的属于自己的周末时光挤了一小部分时间出来,写了这篇文章。 Jerry之前的一篇文章 从ABAP Netweaver的SICF到SAP Kyma的Lambda Function,我曾经提到过,如果想将ABAP Netweaver里的资源以Restful API的方式暴露出来,SICF这个事务码绝对是一大利器。 我们只需要在SICF里合适的路径下创建节点,为该节点创建一个ABAP类,就可以专注于实现接口定义的方法IF_HTTP_EXTENSION~HANDLE_REQUEST, 在里面编写应用逻辑了。应用开发人员无需关注和操心这些ABAP类什么时候被实例化和调用,可以把这个HANDLE_REQUEST方法看作是一个回调函数,当请求到来时,由Netweaver的ICF框架(Internet Communication Framework)负责把请求路由到对应的ICF节点并创建ABAP类,调用HANDLE_REQUEST方法。每个SICF节点会根据其路径被分配一个url, 如果是Corporate网络里,用浏览器或者编程语言直接访问该url,就能消费SICF暴露的资源了。如果想让这个位于Corporate网络内的url被Internet网络访问,就得借助SAP Cloud Connector: 具体步骤在我之前的文章使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数 里介绍过。 对于ABAP开发人员来说,一个好消息是,SAP Cloud Platform如今也支持ABAP运行环境了。现在我们通过在SAP云平台 ABAP运行环境里完成类似之前在On-Premises ABAP系统的SICF事务码里的开发任务,来感受ABAP到了云端之后,给ABAP开发者带来的巨大便利。 按照Jerry之前的文章在SAP云平台ABAP编程环境上编写第一段ABAP程序 里介绍的步骤,通过ABAP Development Tools连接SAP云平台 ABAP运行环境的一个实例,完成登录后,后续的操作步骤,同使用ABAP Development Tools连接一个On-Premises ABAP系统,几乎没有差别。 下图是在云上的ABAP环境里,允许我们创建的ABAP对象列表,既有ABAP开发人员感到亲切的ABAP字段对象,ABAP开发包,ABAP消息类等等,也有上了云端之后的新面孔,比如Cloud Communication Management和Cloud IAM等。为了完成在On-Premises的SICF事务码里的开发工作,现在我们要在云上的ABAP环境里创建一个新的HTTP Service: 新建一个名为ZHELLOWORLD的service,创建完毕之后界面如下: ABAP老司机们看到这界面,立即知道下一步怎么做了吧。点击Handler class,就可以进入ABAP类的编辑界面,实现这个HTTP服务的业务逻辑。而通过url字段里维护的值,我们可以在PC或移动设备里,浏览器或代码里访问这个服务。该服务实现类和On-Premises的区别,不过是接口名称从IF_HTTP_EXTENSION换成了IF_HTTP_SERVICE_EXTENSION. 当然,前者因为是直接在云端编写的ABAP代码,所以还要遵循Jerry之前的文章 在SAP云平台ABAP编程环境上编写第一段ABAP程序 里提到的那些限制。 上述的ABAP代码只是简单地返回给消费者一个Hello World的文本信息,保存激活之后,把url贴到浏览器里,就能看到期望的Hello World: 我们从url里,容易得出这样的结论,SAP Cloud Platform ABAP运行环境里支持创建的HTTP服务,其实现原理,其实就是在Netweaver服务器的SICF路径/sap/bc/http/sap/下面增加一个新的节点罢了,只是这个操作,在云端不再需要由ABAP开发人员手动完成,云端的ABAP环境,会自动创建这一底层设施。希望传统ABAP开发人员,能从这个最简单的Hello World级别的例子,体会到云端ABAP开发的便利之处。感谢阅读。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

October 14, 2019 · 1 min · jiezi

如何在Web应用里消费SAP-Leonardo的机器学习API

去年5月的时候,Jerry曾经写了一篇文章:使用Java程序消费SAP Leonardo的机器学习API,而最近另外做的一个项目,需要在Web应用里做同样的事情。 因为有了前一篇文章的铺垫,避免了很多重复的工作量。本文还是选择使用SAP Leonardo里的一个Product Image Classification API,即给定一张产品的图片,该API能识别出此产品的类别。 再回顾下这个API的功能:该API的模型是由SAP基于大约5万张Icecat图片训练而成,能区分29种不同的类别,这些类别具体罗列于官方文档上,比如电脑显示器,数码相机,外部存储设备,键盘,液晶电视,手机充电器,笔记本和其他外设等等。如果我们消费这个API时指定的图片代表的产品不属于这29种类别之一,API的表现如何?先卖个关子,文末解答。 关于如何在api.sap.com里找到这个API并且在API console里测试,请参考Jerry之前的文章:使用Java程序消费SAP Leonardo的机器学习API。 这里假定我们已经找到了该API,点击进入明细页面,将API Key复制下来,后续的UI5应用需要使用到。 然后进入SAP云平台的Neo环境。Jerry这个练习,使用免费的SAP Cloud Platform Neo测试环境即可。 在Service列表里找到WebIDE——我们将使用WebIDE进行UI5应用的开发。 Jerry已经开发好了一个UI5应用上传到我的Github上了:https://github.com/i042416/Ma... 大家可以直接在WebIDE里clone这个仓库,或者把仓库的内容以zip包的形式下载到本地,再使用WebIDE的本地Import功能导入。 我们要告诉UI5应用这个API的url,因此在Neo环境里创建一个Destination(作用和ABAP Netweaver事务码SM59里创建的Destination相同): 属性如上图所示,因为是Neo测试环境,所以url为对应的sandbox环境:https://sandbox.api.sap.com/ml 记下这个Destination名称sapui5ml-api, 因为稍后的UI5代码里需要使用。 记得维护额外的属性WebIDEnabled为true,这样该Destination才能在UI5应用里被使用。点击Check Connection确保看到绿灯。 打开WebIDE里UI5工程里的settings.json文件,将您之前从API console里拷贝的API Key粘贴到此处: 在项目根目录下的neo-app.json文件里,把类型为destination的target对象的名称维护成之前在SAP Cloud Platform Cockpit里创建的destination相同的名称。 运行这个UI5应用,能看到如下界面: 做一些简单的测试: SAP Leonardo的机器学习API,识别出这张图片有74.7%的可能性是一台笔记本电脑,13.8%的可能性是键盘,11.3%的可能性是Tablets。 点击按钮View JSON,能看到调用SAP Leonardo API返回的技术明细。 鼠标的图片也成功识别出来了: 本文开始曾经提到这个API能识别出29种不同的产品类别,现在换一种产品,如下图: 这是Jerry小时候就很痴迷的《终结者》系列的T800,我在2017年回复SAP社区上一篇博客时也引用到了这款经典的模型,和阿诺德 - 施瓦辛格那句激励无数中老年程序员的著名台词:I am old but I am NOT OBSOLETE ...

July 14, 2019 · 1 min · jiezi

如何把SAP-WebIDE里的Web项目同Github仓库连接起来

我们在SAP WebIDE里进行UI5应用开发时,当然也希望能将开发的代码纳入到github版本管理中去。 步骤其实非常简单。 右键点击WebIDE里UI5应用,git->Initialize Local Repository: 输入github上的用户名和密码,稍后WebIDE会用这个credential与Github建立连接。 在Github上新建一个空的代码仓库: 把生成的url复制下来,粘贴到SAP WebIDE的git repository配置对话框中: 然后再使用右键菜单创建一个远端branch,取名Master: 之后,利用右侧的git面板提供的各种命令,即可进行常规的commit,pull,push等操作。 在WebIDE里触发的Github操作成功施加到了Github的仓库里 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

July 14, 2019 · 1 min · jiezi

当SAP云平台account的service-Marke-place里找不到Machine-Learning服务该怎么办

问题症状:我在CloudFoundry环境的Service Market place里根本找不到Leonardo ML foundation这组服务。 解决方案: 进入global Account->Entitlements->Subaccount Assignments, 点击Configure Entitlements: 再点击Add Service Plans按钮: 从Service Catalog的All Categories列表里,选中SAP Leonardo Machine Learning foundation: 之后这个Service就出现在Service Assignments里了: 现在,该account的Service Marketplace里终于能看见SAP Leonardo Machine Learning服务了。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

July 14, 2019 · 1 min · jiezi

使用CDS-view开发SAP-Marketing-contact的facet追溯工具

这篇SAP社区博客里,我的一位同事介绍了SAP Marketing里contact facet数据模型的存储表:https://blogs.sap.com/2016/07... 主要是这两张表: CUAND_CE_IC_ROOT CUAND_CE_IC_FCET 现在我的需求是:对系统里Contact的Origin Data数据来源渠道个数从高到低的顺序进行排序: 解决方案:开发两个CDS view zcontact_origin@AbapCatalog.sqlViewName: 'SQL_VIEW_NAME'@AbapCatalog.compiler.compareFilter: true@AbapCatalog.preserveKey: true@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Contact Origin tool'define view zcontact_origin as select from cuand_ce_ic_root as a inner join cuand_ce_ic_fcet as b on a.db_key = b.parent_key { key a.db_key, a.name_text, a.smtp_addr, b.db_key as children_key, b.id_origin} zcontact_count@AbapCatalog.sqlViewName: 'ZCONCOUNT'@AbapCatalog.compiler.compareFilter: true@AbapCatalog.preserveKey: true@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'count aggregation'define view ZCONTACT_COUNT as select from zcontact_origin { key zcontact_origin.db_key, zcontact_origin.smtp_addr, count(*) as facet_count} group by db_key, smtp_addr最后的效果: ...

July 14, 2019 · 1 min · jiezi

如何在阿里云上运行SAP-UI5应用

本来Jerry觉得这个知识点太简单了完全不值得写成微信公众号文章,但转念一想,可能网络上有一些刚刚初学UI5的朋友们可能会问到,所以还是写了。 今天一个成都同事问我这个问题,因为SAP WebIDE可以非常方便地将开发好的UI5应用一键部属到SAP的其他系统,比如On-Premises环境的SAP gateway系统;但对于SAP Cloud Platform之外的其他云平台,比如AWS或者阿里云,SAP官方文档讲得不多。 其实如果已经在WebIDE里完成了UI5应用的开发,要让它运行在其他IaaS云平台上比如AWS或者阿里云上,步骤也是比较简单的。 Jerry已经做好了一个简单的SAP UI5 Hello World应用,上传到了我的github上: https://github.com/i042416/we... 这个UI5应用的源代码,在该Github仓库的webapp文件夹下面: 这里面全是标准的UI5应用开发资源。 在这个项目的根目录即webapp文件夹的外层,多了两个文件:server.js和package.json, 分别是nodejs应用的入口文件和项目描述文件。 server.js的实现很简单,用nodejs的express module起一个server,把来自url "/ui5"的请求路由到文件夹webapp里,最后监听在环境变量PORT指定的端口号或者3000这个端口上。 最后登录阿里云,git clone把这个仓库克隆到阿里云上,npm install安装package.json文件里描述的依赖: 然后使用命令行node server.js启动服务器, 就可以通过<阿里云服务器的IP地址>:3000这个url访问这个UI5应用了。 如果想以守护进程的方式启动server, 也可以用pm2, 一个开源的nodejs进程管理工具。 用命令pm2 start server.js启动服务器即可, 这样即使阿里云服务器的SSH终端关闭,该UI5应用依然可以通过url <阿里云服务器的IP地址>:3000访问。 其实啰嗦了这么多,用一句话概括就是,在IaaS级别的云平台上启动Web服务器(nodejs express, Tomcat, Nginx等都行),运行在上面的UI5应用就能通过云平台被各种终端访问到了。 感谢阅读。 Jerry原创的关于SAP Fiori和UI5的更多文章 SAP Fiori应用的三种部署方式Jerry的Fiori原创文章合集SAP Fiori + Vue = ?Jerry的UI5框架代码自学教程Jerry的碎碎念:SAPUI5, Angular, React和Vue在Kubernetes上运行SAP UI5应用(上)在Kubernetes上运行SAP UI5应用(下)要获取更多Jerry的原创文章,请关注公众号"汪子熙":

July 14, 2019 · 1 min · jiezi

在SAP云平台ABAP编程环境上编写第一段ABAP程序

距2017年秋季的SAP TechEd大会上一位大佬Björn Goerke,SAP’s Chief Technology Officer宣布了SAP Cloud Platform即将支持ABAP至今,已经过去了两年的时间。 目前国内的技术媒体平台上,已经有了部分概要性介绍SAP Cloud Platform ABAP编程环境的中文文章,但涉及到具体操作细节的文章比较少。 Jerry最近会做一系列关于如何在SAP Cloud Platform上的ABAP编程环境上做开发的分享。 其实对于一个已经能够熟练使用ABAP Development Tools连接On-Premises ABAP Netweaver服务器做开发的传统开发人员而言,迁移到从On-Premises迁移到SAP云平台上的难度不大,只是需要注意一些开发理念上的转变,这个转变我们在后续具体做开发时会提到。 这种相对平缓的迁移和学习曲线,对于SAP全球庞大生态圈的企业和开发人员来说,无疑是一个好消息——这意味着SAP正在进行中的向云端数字化转型的旅程里,这些企业和个人也能够加入其中,并且他们以前在On-Premises时代积累的宝贵的技术和业务领域知识,能够继续在云时代发光发热。 我曾经在网络上了解到,很多自学SAP ABAP的朋友们,面临的第一道关卡就是在自己本地搭一台Netweaver服务器出来。作为一个写了12年代码的老开发人员,Jerry也搭过各种本地开发环境,深知这里面的水有多深。我以前的老板,也给我们分享过他当年来SAP成都研究院面试的时候,自己本地也搭过Netweaver,并且短短几天啃完几百页的Netweaver英文文档的经历。 相信每一位在本地搭建Netweaver的ABAP学习者,当成功看到Hello World输出的那一刻,成就感一定爆棚。 然而,当Jerry第一次在SAP Cloud Platform的ABAP编程环境上看到Hello World时,却没有多少成就感,因为直接按照ABAP Development Tool里的项目创建向导一步步操作就可以了,过程比较简单易懂——这也体现了云时代到来后,对传统应用开发人员工作方式的影响:无需费神去关心底层硬件或者操作系统等资源,可以把精力集中于应用程序逻辑的编写上。换言之,SAP负责管理和维护底层HANA数据库和中层的ABAP runtime,用户只需管理顶层的ABAP应用代码。 使用ABAP Development Tools的项目创建向导:New->ABAP Cloud Project: Service Instance Connection,选择SAP Cloud Platform CloudFoundry environment: 选择Region,输入用户名密码,前提是你得在这个region下有一个global Account。 下图是我在SAP Cloud Platform的CloudFoundry环境里的Global Account: 这个Global Account所属的space下面我创建了一个ABAP系统实例,ID为ME1: 这个ABAP运行实例具有16GB运行内存,64GB的HANA内存。 再回到ABAP Development Tools, 在项目创建向导里使用Cockpit里维护的上述属性: 点Next,在ABAP Development Tools里会看到一个嵌入的登录窗口。因为Jerry使用的是SAP社区Mentor的账号,所以登录窗口显示的标题是:Welcome to Mentors! ...

July 4, 2019 · 1 min · jiezi

一个SAP开发人员的养蚕流水帐

Jerry打算以此文来给汪子熙全家进行了一个多月的养蚕经历画上一个圆满的句号。 南方长大的80后,对蚕应该不会太陌生。大家还记得你们小时候学过的课文《蚕姑娘》么?课文开头是这样的: 春天天气暖洋洋,蚕卵里钻出蚕姑娘。 又黑又小的蚕姑娘,吃了几天桑叶,就睡在蚕床上,不吃也不动,脱下黑衣裳。醒了,醒了,变成黄姑娘。 又黄又瘦的蚕姑娘,吃了几天桑叶,又睡在蚕床上,不吃也不动,脱下黄衣裳。醒了,醒了变成白姑娘。 又白又嫩的蚕姑娘,吃了几天桑叶,又睡在蚕床上,脱下旧衣裳,换上新衣裳。醒了,醒了,从此一天一天发胖。。。 Jerry小时候当然也学过这篇课文,也按照语文老师的吩咐,在家里养了十几只桑蚕,并且观察它们每天的生长情况。准确的说,我小时只负责观察,一切其他的后勤工作都由我父母完成。由于年龄太小,当时所有的细节我都淡忘了,只依稀记得每只蚕最后都在纸盒里结出了洁白的茧。 时光荏苒,现在Jerry成为了父亲,开始协助汪子熙完成他的语文老师布置的养蚕观察作业。 感谢现在科技水平的飞速发展,我手上30倍的放大镜和三星手机1600万像素的摄像头,让我能够比小时候更清晰地观察蚕们的一举一动。 知乎上有一些很有意思的问题,概括起来大致为:为什么很多人喜欢蚕,但是讨厌,甚至害怕毛毛虫? 我养了一个多月的蚕,我想对于这个问题我有一定的发言权。以下是Jerry对这个问题的看法。下文所说的蚕,如无特殊说明,都指大家为了完成学校作业所养的桑蚕里的大白蚕。 1. 作为一个长期以农业占主导地位的国家,蚕因为能出产具有极高经济价值的蚕丝,从而在我国悠久的农业历史中始终享有很高的地位。早在商周时期,古人们就已经开始在室内养蚕,这个传统延续了几千年一直到现在。 秦汉以后,咱们的养蚕技术通过举世闻名的丝绸之路传入到中亚、南亚及西亚地区,进而传播到欧洲。简单的说,因为蚕对人类有用,所以人类喜爱它们。再加上文人墨客从人类的视角出发,在观察了蚕吃桑叶吐丝的行为之后,发出了"春蚕到死丝方尽,留赠他人御风寒"这种极富褒义色彩的感叹,这使得蚕又经常和另一个具有崇高意义的名词——教师关联起来。在我们从小就接受这些对于蚕正面评价的教育下,我们很难对蚕讨厌得起来。 2. 从外观上看,虽然都是软体动物,蚕和毛毛虫的颜值可谓一个在天上,一个在地上。蚕的全身洁白,白色在我国一直是纯洁的象征,而毛毛虫的颜色往往都很非主流;蚕的全身很光滑,不像毛毛虫那样浑身长满了让人害怕的绒毛。 蚕的性情非常温顺,不会对人造成任何伤害,所以Jerry经常把它们放在自己手上让它们爬来爬去,近距离观察。有的毛毛虫,身上的绒毛蜇到人的皮肤后,会让人很不适,因此大家都不喜欢。 3. 养蚕的环境散发出来的气味很香,至少Jerry闻到的味道是如此。那些动辄饲养上万只蚕的场所发出的气味不在本文讨论之内。蚕吃的桑叶本身带着植物特有的芳香,Jerry也曾经把鼻子凑在自己手上爬来爬去的蚕附近使劲闻,也没有闻到任何味道。而一般的毛毛虫,看着就够恶心了,我实在没有勇气去闻闻它们是什么味道。 4. 蚕很萌。蚕吃得白白胖胖圆圆滚滚在桑叶上蠕动着身子一节节地爬来爬去的样子很萌。如果养了一大群蚕,那么你一定能观察到这种情况:有时在忙忙碌碌啃桑叶的蚕们中间,间杂着几只高昂着头“思考蚕生”的另类: 比如下图正中这只。 关于蚕为什么会昂着头一动不动,网上公认的说法是它们这是在休息,在睡觉。每当这时,我都会忍不住,用手指头轻轻去摸摸它们。有的时候它们被我揩油之后,没有任何反应;有的时候像是受惊了一样,昂起的上半身猛地一缩,很好笑。 5. 蚕的一身都是宝。除了蚕丝能用来做丝绸,蚕丝被,蚕沙(蚕的粪便)能入药,做枕头,蚕蛹能食用之外,很多心灵手巧的小朋友们还用蚕茧做成了各种各样的小工艺品: 透过这些纯天然纯绿色的小手工,我们能看到孩子们如水晶般纯洁的心灵。 前面说到我那30倍放大镜和1600万摄像头的三星手机(这配置在2019年来看应该很渣吧), 是时候让它们出来发挥作用了。 下面是一张蚕宝宝的靓照,最左边棕色的椭圆形部分就是蚕的头部,剩下的都是它的躯干,在靠近头部的胸部部分有三对足,其后每一节身躯的底部都有一对足,总共7对14只足;大家如果仔细看这张照片,会发现蚕的足上其实长了绒毛,而且足的底部还有洗盘,能使自己牢牢吸附在桑叶上,这样能保证蚕即使在桑叶背面爬动时,也不会因为重力原因落到地上。 在躯干的最末一节还有一根小小的向上凸起的尖刺,这是蚕的尾角,我们可以用来辨别蚕的雌雄:雌蚕尾角往前翘且有黑点;雄蚕尾角往上翘而无黑点。这根看似不起眼的尾角对蚕来说是非常重要的器官:其生理作用主要是平衡蚕体内的水压,使蚕前后水压保持相同。蚕的体壁内,肠部,气管和神经等组织都浸泡在血液之中,从蚕的照片我们一眼就能看出蚕的体型是前部稍大尾部稍小,因此需要借助尾角,确保蚕尾部承受液体的压力和胸部的一致。  蚕躯干的每一节都还有一个非常醒目的黑点,这是所有昆虫都具有的呼吸器官——气门,只是蚕的比较明显容易被观察罢了。当蚕周围的气温发生变化时,蚕会借助开关气门的方法来调节体温,让身体的体温适应周围的温度。 那么蚕的眼睛和嘴呢? 先来张头部的正面特写。这小脑袋是不是很萌? 我们很容易根据人类的五官,去揣度蚕的眼睛所在的部位,即头部正中那两个小黑点,事实并不是这样。下面这张图才是蚕的眼在头部的正确部位。是的,我们说眼而不是眼睛,因为蚕作为昆虫,眼部构造和人的眼睛相差太多太多。蚕不像苍蝇,蜻蜓那些昆虫一样具有复眼,蚕的眼是单眼,包含一些感光细胞,能够感觉到光线的强弱,但并没有视觉作用。实际上蚕是靠嗅觉和触觉来判断前方的物体和前进方向,而非视觉。 蚕的嘴也非常有意思。 准确地讲,蚕是用“咀嚼式口器”来进食桑叶的。咀嚼式口器是昆虫具备的另一个非常典型的器官,用来取食固体食物,和人的嘴巴一样有上唇、下唇、上颚(牙齿)和舌,但同时它还有下唇须、下颚和下颚须。蚕的口器上颚前端有锋利的齿,叫做切区,用来切断桑叶纤维。当然,这个锋利是从蚕的角度出发针对桑叶而言的,对人的手指皮肤没有一丁点的破坏力。蚕进食桑叶时,口器会上下蠕动,在桑叶上留下一道道半圆形的缺口。 大家请看下面这段Jerry拍摄的蚕们狼吞虎咽进食桑叶的视频,注意观察文中提到的半圆形缺口: https://v.qq.com/x/page/n08915ahnh1.html 蚕的一生会经历下图四个阶段,在我们小学语文课文《蚕姑娘》里已经阐述清楚了。 蚕蛾产下的卵: 这些卵逐渐变成褐色后,就意味着新的蚕即将来到这个世上了。刚刚破卵而出的蚕个头非常小,遍体黑色,因为很像小蚂蚁,我们称之为“蚁蚕”。 蚁蚕不停得啃桑叶,逐渐长成了大家印象中的蚕的白白胖胖的样子。 蚕一生中总共会蜕4次皮,和其他很多昆虫一样,蚕在生长发育过程中其表皮不能随着身体长大而长大,因此当蚕的身体长大受到限制时,蚕就要蜕皮。Jerry也不知道导演雷德利·斯科特(Ridley Scott)的《异形》系列里的异形蜕皮生长的设定,是否受到了蚕蜕皮的启发。 看一段Jerry拍摄的蚕蜕皮的视频(这种视频很不容易拍到): https://v.qq.com/x/page/t0891... 这是Jerry收集的蚕蜕下的皮,也是一种中药。 ...

July 4, 2019 · 1 min · jiezi

SAP-Marketing-Cloud的Contact导入配置和数据合并原理

SAP很多系统的主数据都支持从外部系统导入,SAP Marketing Cloud也是如此,contact主数据可以来自Hybris Commerce,CRM,ERP或者Twitter,Facebook等社交媒体。来自不同渠道的contact可能对应的是真实世界里同一个人,那么就存在一个过程,该过程的逻辑是将不同渠道的contact数据进行整合,拼凑出一个包含完整信息的contact主数据存储到Marketing Cloud系统里,这个拼凑的过程称之为合并(merge),拼凑后形成的完整Contact结构称为Golden record。 下面这张示意图里的蓝色圆环称为Main facet,代表每个contact数据在某个源系统上的ID,比如在ERP系统上的ID为123,在Twitter上的ID为456等等。而黄色圆环是contact在各自源系统里的属性,比如在Twitter网站上ID为456的一个contact,其name属性为jerrywang@sap。黄色圆环称之为additional facet. 通过在SAP Marketing Cloud里进行一系列配置,告诉系统,当检测到来自不同数据源的contact数据,存在至少一个相同属性的情况下,应该执行何种contact操作,也就是合并或者新建。 比如下图在ERP,Facebook和Web Shop上有三条contact数据,其Email地址的值都相同,那么进行数据导入时,基于预定义好的配置,Marketing Cloud认为这三条数据指向的是同一个人,所以最后merge出来生成唯一一条contact记录。 Marketing Cloud具体merge的过程,就是根据SAP Marketing Cloud系统里的customizing配置,将三条Email地址都相同的记录作为当前merge的输入,然后逐一将本记录内的属性“投影”到最终的Golden Record里。如果把Golden Record想象成最终完整的拼图,那么这个merge过程就有些类似于拼图操作——将散布在各个数据源中的零散信息合并成一个整体,存储在Marketing Cloud系统内以便进行后续处理。 Marketing Cloud里针对contact导入系统时的merge操作的相关customizing设置,在整个contact导入过程中起着至关重要的作用。 和SAP Cloud for Customer等很多云产品一样,SAP Marketing Cloud的customizing也是在浏览器里完成。 点击Fiori Launchpad里的Manage Your Solution这个tile, 进入Configure Your Solution,  根据关键字contact进行搜索,在搜索结果列表里找到Contacts and Profiles相关的配置: 其中第六步, OriginContactID-Configure这一步,就是合并时针对来自不同平台的contact数据,执行合并或新建操作的配置。 点击之后,能看到一个contact属性列表,从这些属性列表不难推断出SAP Marketing Cloud支持导入contact的数据源有S/4HANA,ERP,CRM,Hybris Commerce,SAP Cloud for Customer,Gigya,Qualtrics和社交媒体如Twitter,Facebook等等。 上图有两列,分别对应为每个属性指定One Per Contact和Shareable为true还是false的界面。前者顾名思义,如果设置为true,意味着一个contact在同一个数据源系统里只能拥有一个唯一值,比如一个人的护照号码,或者SAP系统里的Customer ID;反之像Email,座机号,传真号这种属性,一个contact在同一个数据源系统里如果允许存在多个值,则One Per Contact设置为false。而Shareable属性置为true,适合那些在同一个数据源系统里允许多个不同contact具有相同值的属性,比如一家人的contacts的座机号允许相同。 对每一个Contact属性,One Per Contact和Shareable的true/false状态排列组合共有四种,其中One Per Contact为true的两种情况,即使系统在检测到匹配的属性情况下,也可能会导致contact数据的创建,而不是merge,也就是下图中第二行和第四行标注了感叹号的情况。 ...

July 3, 2019 · 1 min · jiezi

一步步用ABAP-Development-Tools连接SAP云平台上的ABAP编程环境

使用ABAP Development Tools的项目创建向导: New->ABAP Cloud Project: Service Instance Connection,选择SAP Cloud Platform CloudFoundry environment: 选择Region,输入用户名密码,前提是你得在这个region下有一个global Account。 下图是我在欧洲法兰克福(Frankfurt)这个Region的Global Account: 这个Global Account所属的space下面我创建了一个ABAP系统实例,ID为ME1: 这个ABAP运行实例具有16GB运行内存,64GB的HANA内存。 再回到ABAP Development Tools, 在项目创建向导里使用Cockpit里维护的上述属性: 点Next,在ABAP Development Tools里会看到一个嵌入的登录窗口: 点Finish: Finish点了之后,在ABAP Development Tools左侧的项目列表里就能看见创建好的ABAP Cloud项目了,接下来在这个项目里编写ABAP代码进行开发的方式,和我们用ADT连接On-Premises系统基本一致。大家可以看到下图创建好的高亮的ABAP Cloud项目(系统ID为ME1), 和其他On-Premises上的ABAP项目外观上没有区别。 这两种ABAP项目的差异在于,ABAP Cloud项目里能够使用的ABAP语言特性,只是传统ABAP语言的一个子集,比如传统ABAP语言里和Dynpro相关的关键字,即只能工作在SAPGUI中的那些关键字,因为在Cloud环境下不再适用了,所以在ABAP Development Tools的ABAP Cloud项目里禁止使用。 至于上图ABAP Cloud项目里的Released Objects如何使用,等Jerry有时间再继续写。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

July 3, 2019 · 1 min · jiezi

2019年6月SAP发布的未来ABAP平台的发展方向

未来ABAP平台将始终是这些产品的技术平台: S/4HANA On-Premises和Cloud将基于一个统一的ABAP codeline: SAP云平台上的ABAP编程环境: 什么是SAP Cloud Platform上的ABAP编程环境?该编程环境使用基于云优化之后的ABAP编程语言,是传统ABAP编程语言的一个子集,有部分关键字和ABAP语言特性因为不适合云的使用场合,故在SAP Cloud Platform的ABAP环境上无法使用。 在SAP Cloud Platform的ABAP编程环境里推荐使用ABAP Restful编程模型,能方便地扩展云和On-Premises系统上的SAP解决方案。 使用基于Eclipse的ABAP Development Tool这个开发IDE,同时能充分利用SAP云平台上提供的各种服务。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

July 3, 2019 · 1 min · jiezi

CRM和C4C里的组织架构-Organizational-Structure

CRM(WebClient UI) CRM(SAP GUI,事务码PPOMA_CRM) C4C以列表方式显示: 以图形方式显示: UI模型:/SAP_BYD_APPLICATION_UI/mom/org/COD_OrgUnit_OWL.OWL.uicomponent 明细页面:/SAP_BYD_APPLICATION_UI/mom/org/COD_OrgUnit_TI BO name: OrganisationalUnit通过递归执行association ChildOrganisationalUnit就可以得到unit hierarchy: 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

July 2, 2019 · 1 min · jiezi

SAP-Marketing-Cloud里的contact-main-facet是什么意思

界面如下: Basically, contact data for SAP Hybris Marketing can be loaded from various sources, such as an ERP system, a web shop, social media and many more.Contact数据源可以来自各个渠道,例如ERP系统,电商,社交媒体账号等等。每个渠道都可以成为Marketing Cloud系统里最终完整contact实例的一块拼图,这个完整的contact实例也称为Golden record。Each source may contribute to the building of the Golden Record, which represents the most valuable contact master data stored in one single record per contact.而数据源渠道自身也被称为Main facets,用于提供常规意义上的contact信息,以及额外信息,例如地址信息,电子邮箱地址,信用卡号,手机号等等。这些额外信息也称为additional facet。Therefore, the sources themselves are considered as Main Facets, which might provide general contact data, such as address data or data for customer-specific fields. A Main Facet might also have data, for example, a loyalty card number, an email address, a phone, a mobile or a fax number. Because of their identifyingnature, we consider these attributes as Additional Facets. ...

July 2, 2019 · 1 min · jiezi

一步步用ABAP-Development-Tools连接SAP云平台上的ABAP编程环境

使用ABAP Development Tools的项目创建向导: New->ABAP Cloud Project: Service Instance Connection,选择SAP Cloud Platform CloudFoundry environment: 选择Region,输入用户名密码,前提是你得在这个region下有一个global Account。 下图是我在欧洲法兰克福(Frankfurt)这个Region的Global Account: 这个Global Account所属的space下面我创建了一个ABAP系统实例,ID为ME1: 这个ABAP运行实例具有16GB运行内存,64GB的HANA内存。 再回到ABAP Development Tools, 在项目创建向导里使用Cockpit里维护的上述属性: 点Next,在ABAP Development Tools里会看到一个嵌入的登录窗口: 点Finish: Finish点了之后,在ABAP Development Tools左侧的项目列表里就能看见创建好的ABAP Cloud项目了,接下来在这个项目里编写ABAP代码进行开发的方式,和我们用ADT连接On-Premises系统基本一致。大家可以看到下图创建好的高亮的ABAP Cloud项目(系统ID为ME1), 和其他On-Premises上的ABAP项目外观上没有区别。 这两种ABAP项目的差异在于,ABAP Cloud项目里能够使用的ABAP语言特性,只是传统ABAP语言的一个子集,比如传统ABAP语言里和Dynpro相关的关键字,即只能工作在SAPGUI中的那些关键字,因为在Cloud环境下不再适用了,所以在ABAP Development Tools的ABAP Cloud项目里禁止使用。 至于上图ABAP Cloud项目里的Released Objects如何使用,等Jerry有时间再继续写。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 28, 2019 · 1 min · jiezi

有选择性的启用SAP-UI5调试版本的源代码

在低版本的SAP UI5应用中,我们一旦切换成调试模式,那么应用程序源代码和UI5框架程序的源代码的调试版本都会重新加载,耗时很长。 我最近发现UI5新版本1.66.1提供了选择性加载调试版本的源代码的选项,即下图中的Select Specific modules: 如果确认问题出在我们应用程序,只想调试自己编写的应用代码,那么我们可以只切换应用程序成为调试版本,这样速度大大提高。 此时浏览器地址栏里看到的参数为sap-ui-debug=dis/#, 意思是仅仅disnamespace下的所有资源加载成调试版本: 调试速度大大提高: 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 28, 2019 · 1 min · jiezi

SAP-WebIDE里UI5应用的隐藏文件projectjson

在SAP WebIDE UI5应用编辑器里的菜单View->Show Hidden files点击后,即可发现项目文件夹下有一个隐藏文件project.json: 内容如下: 这也解释了为什么build之后,UI5应用文件夹下会多出一个dist的文件夹,内容和webapp里的代码几乎一致: databinding节点下罗列出了每个视图绑定的OData数据集的节点名称,非常实用: generation节点记录了应用创建的时间戳和基于的Fiori模板ID和版本号,translation包含了和翻译相关的资源名称。 basevalidator维护了SAP WebIDE提供的校验实现,当前有fioriXmlAnalysis和fioriJsValidator。 codeCheckingTriggers定义了校验出的错误是否会阻止UI5实际部署到SAP云平台上。hcpdeploy包含了和UI5应用部署相关的信息,比如SAP Cloud Platform的用户id,和部署到云平台之后的应用名称。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 27, 2019 · 1 min · jiezi

SAP-UI5的support-Assistant

SAP UI5的support Assistant给UI5刚入门的开发人员提供了一种极便利的快速熟悉UI5代码的途径。 召唤方式: ctrl+shift+alt+p四个键同时按,在弹出的对话框里点击按钮“activate Support Assistant即可。 之后屏幕下方会出现一个视图,视图左边包含了SAP预定义的检查条目,以及您当前的UI5应用基于这些检查条目校验出的结果。右边则是检查条目检查的具体内容,针对检查出来的问题给出的解决方案,以及具体的检查代码等等。 我觉得对我自己帮助最大的就是Code标签里每个检查条目的具体实现,能让我学习到很多SAP UI5的编程细节。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 27, 2019 · 1 min · jiezi

Marketing-Cloud-contact主数据的csv导入

使用这个mock数据生成器网站https://www.mockaroo.com/b679...,创建一个基于Marketing Cloud contact schema的csv文件。 如果偷懒的话,每个contact字段的值都可以选择随机生成。点Download Data下载到本地。 打开csv文件之后,还可以用文本编辑器对值进行微调。 进入Marketing Cloud,点Import进行导入: 在business administration这个catalog里的import monitor对导入过程进行监控: 导入成功: 导入的数据可以在Marketing Cloud里使用了: 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 23, 2019 · 1 min · jiezi

SAP-Cloud-Platform上Destination属性为odatagen的具体用途

今天工作发现,SAP Cloud Platform上创建Destination维护的WebIDEUsage属性很有讲究: 帮助文档:https://help.sap.com/viewer/8... 这个属性的枚举值: 看个例子。我维护的是odata_gen: 根据标准文档描述,拥有odata_abap属性的Destination指向的是一个gateway系统,将在SAP webIDE创建UI5应用的向导中的service catalog界面出现,如下图所示: 意思是终端用户可以通过Service Catalog界面,任意选择该Destination指向的gateway系统上激活的service。 odata_abap: 目标是个SAP gateway系统 而另一方面,如果把Destination的属性改成odata_gen: 此时该Destination不会出现在Service Catalog的下拉菜单里: 取而代之的是它会出现在service url里: 而我们必须手动维护某一个具体OData服务的地址:/sap/opu/odata/sap/CRM_OPPORTUNITY 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 23, 2019 · 1 min · jiezi

如何用SAP-WebIDE的Fiori创建向导基于ABAP-OData-service快速创建UI5应用

如果我们手上已经有可以正常工作的OData服务,无论位于ABAP on-premise系统还是public上的internet OData service,都可以用SAP WebIDE里的Fiori创建向导,几分钟之内轻松创建出可以持续开发的UI5应用。 打开SAP云平台上的WebIDE,New->Project from Template: 选择Master Detail风格的Fiori应用: 这里就要指定这个UI5应用消费的OData服务url了。下拉菜单里看到的是一个我在SAP云平台创建的Destination,指向on premise系统: url路径选择/sap/opu/odata/sap/CRM_OPPORTUNITY,做过CRM的朋友们会知道这个路径指向的是CRM ABAP里的OData服务CRM_OPPORTUNITY: 点击Test,会解析出OData服务的metadata,然后可以点Next按钮: 点了Next之后,需要指定Master list和detail视图里重要字段的绑定路径。这些字段的说明在上图右边的缩略图里有展示。 点finish后,应用成功创建。执行应用: 最后渲染的应用如下: 至此我们没有编写一行代码,就得到了一个可以工作的master-detail风格的Fiori应用。 压缩过后webIDE自动生成的JavaScript总共代码也不过500多行: 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 23, 2019 · 1 min · jiezi

Marketing-Cloud里取得系统contact数目的API

Marketing Cloud里的Contact标准tile(下图红色tile)上是没有当前系统contact数字显示的,请对比profile tile(下图黑色tile)。 客户有需求希望在Launchpad Contact tile上也显示这个数字,因此我新建了一个tile。 需要给这个tile配置一个OData API url: /sap/opu/odata/sap/CUAN_CONTACT_SRV/InteractionContacts/$count?$filter=YY1_FACEID_MPS%20ne%20%27%27postman里测试确保工作: 最终效果: 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 1, 2019 · 1 min · jiezi

SAP分析云及协同计划

大家好, 我是SAP成都研究院S/4HANA Sales 团队的软件工程师Derek。四年前我从SAP Consulting团队转到SAP Labs从事Sales Analytics相关应用的开发,在加入S/4HANA Sales 团队之前是BI咨询顾问,主要工作经历集中在BI(BW&BO), EIM, BPC, ECC, S/4 HAHA相关产品。 之前我所在团队同事Zhang Sean已经在他的文章 S/4HANA中的销售计划管理 里给大家分享过了S/4HANA的销售计划管理,今天我给大家带来的是S/4HANA分析云的协同计划。 前言 当今是数字经济的时代,数字经济就是决策经济。企业做出的决策越明智、越及时,企业的业务增长能力就越强。拖延是破坏者和被破坏者之间的区别,公司要么适应这个规则要么等待灭亡。 如果说数据是数字经济世界的燃料,那么分析就是引擎。研究表明,要使数据驱动的决策处于数字引领者的前沿,采用数据驱动思维的分析能力至关重要。 目前市场上的大多分析解决方案只能提供下图中的一部分功能。 商务智能(Business Intelligence)技术通常依赖于历史数据或已发生的事情,但与未来的计划和结果无关。这些分散的缺乏整合的方案很难帮助企业快速准确地做出决定并采取行动。而SAP分析云(SAP Analytics Cloud,以下简称SAC)能很好地解决这些问题。 作为基于SAP云平台构建的新一代SaaS,SAC可以在一个解决方案中为所有用户提供企业商务智能,预测,协同计划等功能。 什么是SAP分析云 SAC是商务智能和协同计划相结合的解决方案,通过预测分析和机器学习技术的强大功能为企业决策提供实时支持。无论是在客户前线还是在董事会,都能让企业实体洞察到新的见解并采取行动。SAC通过在一个产品中为用户提供所有分析功能来重新定义云分析(Cloud Analytics)。作为一个部署在SAP Cloud Platform上的SaaS解决方案,SAP负责完成硬件和软件的管理,以便客户可以专注于分析其业务。 SAP分析云主要功能 SAC让员工能够自由分析企业的业务,模拟并预测接下来会发生什么,设计协同计划并采取行动,实施决策以获得即时价值。业务成功需要完整的分析功能,如商务智能,计划和预测等来支持战略、运营和战术决策,而SAC则能够授权用户在需要实时分析业务的场景下进行情景洞察,以帮助其做出决策。 SAC解决方案为每个负责制定智能决策以提高其成果的用户提供分析。 什么是SAP分析云协同计划(SAC Planning) SAC的核心优势在于其计划功能,除了计划功能之外,SAC还包括大量分析和报告功能,以及易于专业人员和其他计划人员使用的集成预测功能。例如,用户可以在输入数据或更改值后自动预测。商业智能,协同计划,以及基于机器学习的预测分析是SAC的三大核心功能。很多朋友认为SAC只是SAP Business Objects Business Intelligence的云版本而已,其实不然——SAC除了商业智能外, 协同计划和预测分析才是其核心部分。本文将重点介绍SAC的财务计划和分析功能。在探讨SAC Planning前我们需要理解计划,预算,预测等术语: 计划:提供公司启动方向和财务目标的整体流程(如战略计划,长期计划,年度计划等)预算:提供计划的执行路径。计划提供了什么是可能,预算提供了基于被批准计划的预期(如销售/毛利预算,资本支出预算,人数预算,运营开支预算等)预测:使用实际业绩数据来预测业绩的剩余未知部分(如滚动预测)SAC Planning提供了如下主要功能:条件模拟,数据输入,复杂分配,分解及数据转播,协同计划及评论,基于驱动程序的计划,工作流,替代层次结构的支持,版本管理(乐观版本、悲观版本、私有版本),内置财务功能等。 1. SAC为计划人员提供了强大的功能 为了支持计划用户,SAC表中使用的表组件提供了数据的交互式可视化功能。在网格中,存在许多可用的Microsoft Excel快捷方式,凭借新的自定义行和列功能,计划人员可以使用常见的Microsoft Excel类公式轻松地将其他信息添加到网格中。自定义单元格还支持单元格图表,计划用户可以很快地创建出符合IBCS(International Bussiness Communication Standard, 国际商业标准图表)的差异报告。 2. 与SAP Analysis for Microsoft Office无缝集成 新版本的SAP Analysis for Microsoft Office可以直接消费SAC Planning模型, 计划用户可以通过其熟悉的Microsoft Excel环境连接到SAC进行工作。简化的Excel样式允许用户通过强大的排序/过滤功能轻松访问各种维度。图形化的拖拽结构管理,创建报表公式以聚合值或在摘要表中执行简单分析,报表公式可用于汇总来自多个来源的信息。 ...

June 1, 2019 · 1 min · jiezi

nodejs-request-module里的json参数的一个坑

今天工作的时候遇到一个坑,在客户端用nodejs给服务器发送HTTP请求,服务器老是报错:In the context of Data Services an unknown internal server error occurred 经过服务器端调试发现,服务器根本就没有正确解析出这个请求的content-type。在postman里能工作的场景下,正确解析出的content-type是multipart/mixed: 而我的nodejs代码里明明指定了这个content-type的啊? 经过一行行代码分析,最后发现问题出在第63行的json字段的值。我错误的赋成了true。 这个参数起什么作用?调试一下就知道了。如果为true,进入第403行。 如果请求内部有entity的content-type不是application/x-www-form-urlencoded, 则进入第1293行。 safeStringify的实现逻辑就是浏览器原生的JSON.stringify, 把应用程序传入的json对象序列化成字符串。但是我的代码里,传入request module的请求体是一个字符串,而json参数设的又是true,所以逻辑上就不对了。把这个json参数的值改为false后,一切正常。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

May 25, 2019 · 1 min · jiezi

使用nodejs实现OData的batch操作在Marketing-Cloud里读取contact信息

我们先来看看Marketing Cloud系统里的contact信息:一共1218374条数据。 我们用如下的nodejs代码通过OData来获取这些数据: var request = require('request');var config = require("./mcConfig");var url = config.getContactBatchURL;var sBody = "--batch_c914-a60c-1877" + "\n" + "Content-Type: application/http" + "\n" + "Content-Transfer-Encoding: binary" + "\n" + "\n" + "GET InteractionContacts?sap-client=100&$skip=0&$top=2&$select=ImageURL%2cName%2cContactLevelName%2cCountryName%2cCity%2cEMailAddress%2cPhoneNumber%2cMobilePhoneNumber%2cCorporateAccountName%2cInteractionContactUUID%2cRelationship%2cType&$inlinecount=allpages HTTP/1.1" + "sap-cancel-on-close: true" + "\n" + "Cache-Control: max-age=360" + "\n" + "sap-contextid-accept: header" + "\n" + "Accept: application/json" + "\n" + "Accept-Language: en" + "\n" + "DataServiceVersion: 2.0" + "\n" + "MaxDataServiceVersion: 2.0" + "\n" + "\n" + "\n" + "--batch_c914-a60c-1877--";var getContactOptions = { url: url, method: "POST", json:false, headers: { "content-type": "multipart/mixed;boundary=batch_c914-a60c-1877", 'Authorization': 'Basic ' + new Buffer(config.user + ":" + config.password).toString('base64') }, body: sBody};function getContact() { return new Promise(function(resolve,reject){ var requestC = request.defaults({jar: true}); console.log("Step1: get contact via url: " + url ); requestC(getContactOptions,function(error,response,body){ if( error){ console.log("error occurred: " + error); reject(error); } console.log("response:" + body); var nStartIndex = body.indexOf("{"); var nLastIndex = body.lastIndexOf("}"); if( nStartIndex < 0 || nLastIndex < 0) return; var sPayload = body.substring(nStartIndex, ++nLastIndex); resolve(JSON.parse(sPayload)); }); });}function displayResult(oResult){ console.log(oResult);}getContact().then(displayResult);使用node命令直接执行这个.js文件: ...

May 25, 2019 · 1 min · jiezi

如何在Marketing-Cloud里创建extension-field扩展字段

首先在Marketing Cloud里找到创建扩展字段的tile入口,搜索关键字extension: 这会进入Fiori应用“Custom fields”,能看到系统里所有创建好的extension field。点击+加号按钮新建一个: 维护这个扩展字段的技术信息,比如标签,类型,长度等等。 创建好之后点击按钮Publish,确保字段处于publish状态。 接下来需要为特定的UI enable这个字段的显示。在标签页UIs and Reports里,在对应的UI记录后点击按钮"Enable Usage": 最后一步,在UI上这个扩展字段放出来。点击Adapt UI: 进入Contact UI,点击加号按钮: 选择刚才创建好的扩展字段: 保存并publish发布change,至此这个扩展字段创建成功。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

May 25, 2019 · 1 min · jiezi

使用nodejs创建Marketing-Cloud的contact数据

源代码如下: var config = require("./mcConfig");var request = require('request');var url = config.tokenURL;console.log("user: " + config.user + " password: " + config.password); var getTokenOptions = { url: url, method: "GET", json:true, headers: { 'Authorization': 'Basic ' + new Buffer(config.user + ":" + config.password).toString('base64'), "content-type": "application/json", "x-csrf-token" :"fetch" }};function getToken() { return new Promise(function(resolve,reject){ var requestC = request.defaults({jar: true}); console.log("Step1: get csrf token via url: " + url ); requestC(getTokenOptions,function(error,response,body){ var csrfToken = response.headers['x-csrf-token']; if(!csrfToken){ reject({message:"token fetch error: " + error}); return; } console.log("Step1: csrf token got: " + csrfToken); resolve(csrfToken); }); });}function createContact(token){ return new Promise(function(resolve, reject){ var oPostData = {"CountryCode":"CN", "City":"Chengdu", "FirstName":"Jerry4", "LastName":"Wang2", "PostalCode":"610093", "RegionCode":"", "Street":"天府软件园", "HouseNumber":"天府软件园", "DateofBirth":null, "ContactPersonFacets":[ {"Id":"jerry1@sap.com", "IdOrigin":"EMAIL", "Obsolete":false, "Invalid":false}, {"Id":"", "IdOrigin":"PHONE", "Obsolete":false, "Invalid":false}, {"Id":"", "IdOrigin":"MOBILE", "Obsolete":false, "Invalid":false}, {"Id":"", "IdOrigin":"FAX", "Obsolete":false, "Invalid":false} ], "IsConsumer":true, "Filter":{ "MarketingAreaId":"CXXGLOBAL" } }; var requestC = request.defaults({jar: true}); var createOptions = { url: config.createContactURL, method: "POST", json:true, headers: { "content-type": "application/json", 'x-csrf-token': token }, body:oPostData }; requestC(createOptions,function(error,response,data){ if(error){ reject(error.message); }else { var oCreatedContact = data; console.log("created contact ID: " + oCreatedContact.d.ContactPersonId); resolve(data); } }); });}getToken().then(createContact).catch((error) =>{ console.log("error: " + error.message);});这里我把创建的contact的名称字段硬编码成Jerry4: ...

May 25, 2019 · 1 min · jiezi

使用postman创建Marketing-Cloud的Contact

首先在Marketing Cloud的UI上创建一个contact: 观察Chrome开发者工具network标签页里的HTTP请求: https://jerry.gcdemo.hybris.c... 这个请求用于读取CSRF token: 点击保存,会发送一个新的HTTP post请求: 请求url:https://jerry.hybris.com/sap/...再看下重要的请求头部字段: 把第一步获得的CSRF token填到Postman里的header字段里,如图: body: {"CountryCode":"CN","City":"Chengdu","FirstName":"Jerry1","LastName":"Wang1","PostalCode":"610093","RegionCode":"","Street":"天府软件园","HouseNumber":"天府软件园","DateofBirth":null,"ContactPersonFacets":[{"Id":"jerry1@sap.com","IdOrigin":"EMAIL","Obsolete":false,"Invalid":false},{"Id":"","IdOrigin":"PHONE","Obsolete":false,"Invalid":false},{"Id":"","IdOrigin":"MOBILE","Obsolete":false,"Invalid":false},{"Id":"","IdOrigin":"FAX","Obsolete":false,"Invalid":false}],"IsConsumer":true,"Filter":{"MarketingAreaId":"CXXGLOBAL"}} 状态码201,证明创建成功了: 可以在前端看到创建成功的contact: 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

May 25, 2019 · 1 min · jiezi

使用nodejs对Marketing-Cloud的contact主数据进行修改操作

假设在Marketing Cloud有这样一个contact主数据: 现在需求是使用编程语言比如nodejs修改这个contact实例的高亮属性。 代码如下: var config = require("./mcConfig");var request = require('request');var url = config.tokenURL;console.log("user: " + config.user + " password: " + config.password); var getTokenOptions = { url: url, method: "GET", json:true, headers: { 'Authorization': 'Basic ' + new Buffer(config.user + ":" + config.password).toString('base64'), "content-type": "application/json", "x-csrf-token" :"fetch" }};function getToken() { return new Promise(function(resolve,reject){ var requestC = request.defaults({jar: true}); console.log("Step1: get csrf token via url: " + url ); requestC(getTokenOptions,function(error,response,body){ var csrfToken = response.headers['x-csrf-token']; if(!csrfToken){ reject({message:"token fetch error: " + error}); return; } console.log("Step1: csrf token got: " + csrfToken); resolve(csrfToken); }); });}function updateContact(token){ return new Promise(function(resolve, reject){ var sPostData = "--batch_1f7d-bd35-caed" + "\n" + "Content-Type: multipart/mixed; boundary=changeset_8f9e-9a44-9f9e" + "\n" + "\n" + "--changeset_8f9e-9a44-9f9e" + "\n" + "Content-Type: application/http" + "\n" + "Content-Transfer-Encoding: binary" + "\n" + "\n" + "MERGE Consumers('02000A21209F1EE99CDF1A1FC9AA8065')?sap-client=100 HTTP/1.1" + "\n" + "Cache-Control: max-age=360" + "\n" + "sap-contextid-accept: header" + "\n" + "Accept: application/json" + "\n" + "Accept-Language: en" + "\n" + "DataServiceVersion: 2.0" + "\n" + "MaxDataServiceVersion: 2.0" + "\n" + "x-csrf-token: fQ2Pwfmf0K_LVYoKV9QYUw==" + "\n" + "Content-Type: application/json" + "\n" + //"Content-Length: 215" + "\n" + "\n" + "{\"YY1_CustomerType_ENH\":\"Jerry测试1\"}" + "\n" + "--changeset_8f9e-9a44-9f9e--" + "\n" + "\n" + "--batch_1f7d-bd35-caed--"; var requestC = request.defaults({jar: true}); var createOptions = { url: config.updateContactURL, method: "POST", json:false, headers: { "content-type": "multipart/mixed;boundary=batch_1f7d-bd35-caed", 'x-csrf-token': token }, body:sPostData }; requestC(createOptions,function(error,response,data){ if(error){ reject(error.message); }else { debugger; console.log("Contact updated successfully"); resolve(data); } }); });}getToken().then(updateContact).catch((error) =>{ console.log("error: " + error.message);});我在nodejs代码里把需要更改的字段值赋为"Jerry测试1”: ...

May 25, 2019 · 2 min · jiezi

Marketing-Cloud-demo环境和API使用方法说明

version 1.0作者:Wang Jerry更多问题请联系我 demo 系统url:https:/jerry.hybris.com/sap/b... 用户名/密码:Jerry1/Diablo1登录成功之后,可以在菜单"快速启动"->"Manage Contacts"里找到Marketing Cloud contact管理应用。单击: 这里就能看到该系统里所有的contact列表了。左边的1218377是系统contact总个数,正下方Create就是新建按钮,可以通过这个按钮打开contact创建页面。右边的search bar就是一个Google风格的模糊搜索入口。 这个界面第一次使用的话需要注意一些小技巧。 上图高亮的四个控件实际上是四个过滤器,例如当前系统里并不存在状态为For Review的contact,数字为0,因此单击这个过滤器后: 表格会显示0条数据。这是用户期望的行为,因此大家如果看到表格是空的,不要觉得奇怪。 当单击某条contact数据的超链接后, 会跳转到contact明细页面. 下图url里高亮的guid就是这条contact在SAP数据库里的主键值。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

May 25, 2019 · 1 min · jiezi

最不合格的SAP应聘者-从大学生到SAP成都研究院开发工程师

让我们把时光之轮倒拨回2006年,SAP成都研究院刚刚成立的时候,有一位年轻的电子科技大学研究生,网名雷米兰(这名字一看就是AC米兰铁杆粉丝),加入了SAP成都研究院并被派遣到SAP德国总部进行实习。雷米兰将自己的实习和成长经历写成了一个系列的博客,这个系列的名称就叫做《一个SAP全球研发服务中心(成都)新进工程师日记》,在当时全国各大本科生和研究生求职网站和论坛上引起了强烈的反响, 也给当时刚刚成立不久的SAP成都研究院在网络上吸引了很多人气。 Jerry当时也拜读了米兰君的每一篇文章,确实对当时同为实习生的我有着非常大的启发作用。 感兴趣的朋友们,可以点击下面的链接,读一读来自这几篇来自13年前,这位优秀的SAP成都研究院实习生雷米兰的文章: 一个SAP全球研发服务中心(成都)新进工程师日记 http://blog.sina.com.cn/s/blo... 历史总是惊人的相似,SAP成都研究院成立13年之后,又有一位年轻的小伙子,和他的前辈雷米兰当前一样,以"最不合格“的应聘者身份成功加入SAP成都研究院,并沿着前辈当年相同的足迹一路前行。 这位小伙子就是Jerry同组的同事,SAP成都研究院数字创新空间的Xu Haytham,在办公室里就坐我对面。这是他的工位: 关于Haytham生活中的兴趣爱好,已经在Jerry之前公众号的这两篇文章提到了,这里不再赘述。 SAP成都研究院数字创新空间沟通S/4HANA和C/4HANA的智能服务演示视频和Coresystems分享预告SAP成都研究院许聚龙:Hello, Coresystems!虽然Haytham今年7月份大学毕业后才会结束实习期,以正式员工的身份加入SAP成都研究院,但在Jerry心中,早已把他当作团队的正式成员了:Haytham在Jerry目前参与的开发项目中,早已成为一位合格的前端开发人员。他用Vue开发的前端界面,会和Jerry用nodejs开发的微服务进行对接。 值得一提的是,Haytham在进入这个项目之前,没有接触过Vue,进入项目后,也没有其他同事和他共同用Vue开发,所有前端Vue开发的技术问题都由他自己想办法解决。这种如此年轻就能独立工作的能力,远远超过当时的Jerry——我2007年加入SAP成都研究院开始实习后,很长一段时间都无法独立工作,遇到解决不了的难题都只好求助身边的资深同事。 下面是Haytham的正文。 *从2018年6月正式加入SAP成都研究院开始实习至今,已经过去了10个月有余,这10个月对我来说是异常独特且难忘的。从一开始的“最不合格”的应聘者,到后来的最早拿到offer,再到现在的SAP德国总部实习,以及中间各种独特小插曲,共同构成了这让我难忘的10个月,也因此让我十分想将这一切付诸文字,记录和分享我参与的VT项目(Vocational Training)、我所在的团队、以及我眼中的SAP。 截至动笔前已在德国生活了近2个月,所见所闻甚多,如果时间允许的话,我想把这些经历都陆续分享给大家。在正式开始前,我想说明一点:SAP是一家伟大的公司,我仅仅只是管中窥豹;如同电影《两杆大烟枪》中的角色一样,我只能做到个体视角下的复述。 在很久以前的时候,我听说过一个“传说”,当时正在读高中,记不清缘由的在和朋友开始吹牛聊国外的IT公司,我们列举了微软、IBM、因特尔等等,进行了一番“高谈阔论”,然后突然有人提到一家叫“思爱普”的奇特公司,据说这家公司非常精通企业管理和运行,每次帮一家公司开发一套系统,都会派人过去帮助他们梳理和规范流程,而且每套系统价格都比较昂贵。当时聊天的其他细节都已经记不清楚了,但是这个“传说”却深深的印在了我的脑子里。 再一次听到SAP是2017年的7月份,当时正在IBM实习,于北京驻场开发,项目的产品经理正是一个和SAP有很深交集的人,期间他偶尔会向我讲起他在SAP的经历。4个月后实习结束,我也返校继续学业,并且次年春季开始投递简历,确定最后的入职公司。在这期间,之前这位产品经理把SAP实习生招聘的信息发给了我,我和SAP的交集,也从此开始。 文章标题我用“最不合格”一词来形容我自己,主要因为当时的我是非常不符合SAP的招聘标准的,因为招聘主要面向研究生,岗位是软件工程师。首先我是一个本科生,其次虽然我的专业是计算机,但是在校期间除了课程内的编码作业外,几乎没有任何其他的代码经验。虽然在上学期间加入了以web技术为主的技术工作室,但做过的事情基本和技术不相关,主要集中在沟通协调、绘制原型、测试等方面,因此除了大量的和技术相关的名词,我的脑子里并没有留下其他和技术相关的东西,也因此常常的被其他成员“鄙视”,给我留下了深深的“阴影”,以至于到了现在我会很谨慎的用“程序员”称呼自己。总结一下就是,我有很大的信心应聘项目助理,但是SAP的软件工程师,我觉得自己是不合格的。 我很清楚自己是喜欢技术的,很想将技术岗作为自己将来的职业发展方向,但是当时的自己确实技术水平是“不合格”的,所以即便没有抱太大的希望,但还是投递了简历,而且出乎意料的,简历通过了初筛,我收到了面试邀请。这是一场我至今难忘的面试经历。实习生面试共分为两轮,第一轮群面、第二轮小组面。群面是常规的无领导讨论,小组面考察的方面比较广,包括计算机的基础知识:数据库、数据结构、算法、操作系统、软件工程等;除此之外还有智力题和个人履历询问等。 第一轮的小组面是让我比较惊讶的。对于参与过项目助理面试的我当然是不陌生的,但是大部分互联网公司对技术岗是不设群面环节的,因为这不是程序员的长项。正如此,群面是我认为自己表现的最好的环节。第二轮的小组面3人一组,有书写作答也有抢答,和我同组的是两个具有开发经验的研究生,这轮面试是非常有戏剧性的,至今回忆起来我都觉得非常有趣,面试过程呈现了严重的两级分化情况,凡是涉及计算机技术相关的题目,我回答的都很糟糕,甚至交过一次白卷,而两位同组的研究生却基本都能答上;但提问到软件工程和智力题时,情况完全翻转了,我能够非常快速的给出答案,但是两位同伴却出现了卡壳的情况。就这样几轮问答之后,面试官根据面试过程得到的信息,分别再询问了我们的个人履历后,面试结束了。 离开时我的心态是非常放松的,因为我认为自己交了一份本末倒置的答卷,唯一能和其他面试者横向对比的只有难以定性的“潜力”,我觉得自己获得实习offer的机会微乎其微。但是通过这次面试,SAP VT项目却给我留下了深刻的印象。因为在当时互联网公司的招聘氛围下,”面试造火箭,实习拧螺丝“是普遍现象,没有刷过面经和题库的面试者都很难在笔试环节存活下来。而在这种氛围下,SAP VT的面试内容却聚焦在学科基础知识,而且着重考察面试者的综合素质,是完全出乎我这个大学生的意料的。正因如此,当我再通过第三轮电话面试,接到实习offer时,内心的激动是真的难以言表。 就这样,我这个“最不合格”的应聘者神奇的拿到了SAP成都研究院的实习offer,时至今日我都没有特别明白当初面试官是认可了我哪一点,以至于给我发了offer,又或者我只是运气好,在那个入围名单的最后一位。就像开头说的,我就像《两杆大烟枪》中的戏中一角,没有全知的上帝视角,具体原因我也无从而知。但是很高兴自己获得这个在实习中证明自己对得起这个实习offer的机会。在后来多次和工作室的学弟们提到SAP,讲到VT项目时,我都会提到我的面试经过,让他们知道在当下的应届生招聘环境下,还是有像SAP这样的公司会注重一个人的“潜力”,并愿意投入资源助其成长的。 希望我这段SAP成都研究院的求职经历能对广大应届毕业生们有些启发。如果您对SAP成都研究院优秀的职场人士们的工作生活感兴趣,欢迎阅读下面这些文章: SAP成都研究院35岁以上的开发人员都去哪儿了?从程序猿到SAP产品经理,我是如何转型的?SAP成都研究院马洪波:提升学习力,增强竞争力,收获一生乐趣汶川大地震中的SAP成都研究院SAP成都研究院的体育故事一个SAP顾问在美国的这些年SAP成都研究院飞机哥:程序猿和飞机的不解之缘ABAP vs Java, 蛙泳 vs 自由泳一个SAP开发人员的双截棍之路SAP成都研究院Sunshine: 我的C4C实习感受和保研之路金庸的武侠世界和SAP的江湖SAP成都研究院2018年总共87篇技术文章合集Jerry的2017, 编程与游泳一个SAP开发人员的2018年终总结要获取更多Jerry的原创文章,请关注公众号"汪子熙":

May 11, 2019 · 1 min · jiezi

S4HANA中的销售计划管理

大家好,我所在的S/4HANA Sales(SD)成都研发团队,主要负责S/4HANA里销售模块相关的标准产品研发。 作为产品研发团队,我们遵循SCRUM迭代式增量软件开发过程,以两个星期为一个迭代,并且以一个季度一次发布新版本。通常在新版本的开发之初,研发团队会有计划和统筹,而在开发后期会有一个完整的回顾。团队回顾的目的,主要是总结和对未来进行准备和展望,回顾的形式有时比较正式,有时会多样一些。 上一次我们团队的回顾总结发生在黑龙湖湖畔: 有没有感受到大家的无限爆发力????? S/4HANA Sales(SD) 成都招新啦! 借Jerry的地盘打一广告:我所在的S/4HANA SD成都研发团队最近再次迎来增长的机会,我们将组建两个全新的SCRUM开发团队,渴求多元化角色:研发经理,产品经理,架构师,质量管理,各级别开发人员,用户体验设计师,文档人员等等。 欢迎有兴趣的朋友自荐或推荐。SAP内部的同事可以直接在招聘网站搜“SAP S/4HANA Sales (SD)”申请。如果有任何问题,请联系Zhang Sean(成都)。外部的朋友请直接在链接中申请,请关注 S/4HANA Sales(SD)开头的,另外部分职位目前外部不能直接申请,如果有兴趣请联系认识的朋友转递: https://jobs.sap.com/search/?... 前言 回到本文话题,就像我们的产品在每个新版本和每个迭代前都会有计划一样,每个企业的销售团队也需要有计划。所以今天跟大家一起探讨S/4HANA里的销售计划应用如何帮助企业实现销售计划的灵活管理。 在SAP的产品中,针对不同的业务有不同的计划或规划的解决方案,比如供应链管理领域的集成业务计划, Integrated Business Planning(IBP),其提供了端到端的供应链计划业务流程,支持对数据实时分析以及与合作伙伴的快速协同;财务相关领域的全面预算及合并Business Planning and Consolidation(BPC);以及SAP分析云Analytics Cloud(SAC)上也能实现通用的规划,后续我的同事会单独就后者进行分享。 当然也有今天这篇文章的主角,S/4HANA 销售领域的销售计划管理应用,其主要是帮助销售相关人员对销售团队的计划和绩效进行管理。 销售经理业务角色 上一篇 S/4HANA业务角色概览之订单到收款篇 中,我们介绍了销售经理的主要职责: 负责监控和优化销售流程和销售计划,并分析销售特定的关键性能指标 (KPI),例如销售量和利润率。对于每个企业的销售,没有销售计划就谈不上科学的销售管理,而销售经理的管理过程就是销售计划的制订、实施、监控和评价的过程。因此,销售经理的活动会从订单到付款的整个过程贯穿始终,而监控和优化销售流程和销售计划作为销售管理的首要任务。 在S/4HANA里销售经理模板是SAP_BR_SALES_MANAGER,包括了多个业务目录,这些业务目录跟最佳实践范围项目(Scope Item)关联,每个企业可以根据自己的实际业务选择激活对应的范围项目,从而可以使用对应业务目录里的应用。如需了解每个范围项目的详情,可以访问其对应的最佳实践网站链接。 这里列举销售经理的三个典型业务目录: ·       SAP_SD_BC_SALES_ANALYTICS 分析目录:利用此业务目录,您可以通过查看各种维度的分析报表了解实时的销售绩效和 KPI。 https://rapid.sap.com/bp/scop... ·       SAP_SD_BC_SP_PROC_PC 销售计划目录:利用此业务目录,您可以创建、更改、审批和显示销售计划。此外,可实时将计划数据与实际数据进行比较。 https://rapid.sap.com/bp/scop... ·       SAP_SD_BC_SALES_PREDICTION_PC 销售预测目录:利用此业务目录,您可以按不同维度查看实际和预测值,对销售绩效进行监控。您还可以选择现有销售计划,以便对实际值、预测值和计划值进行比较。 https://rapid.sap.com/bp/scop... 销售分析的相关应用主要来自于SAP_SD_BC_SALES_ANALYTICS,如下图中的应用。 销售计划的相关应用主要是在业务目录SAP_SD_BC_SP_PROC_PC中。图中的两个应用都是在S/4HANA里的Fiori应用。 管理销售计划 作为销售经理,您可以通过此应用创建、更改、审批和显示销售计划。此外,为了与团队的其他用户共享销售计划,您可以将销售计划分配至团队。通过该操作,团队中的每个成员都可以访问您的销售计划,并使用您的计划数据进行分析。如果未将您的销售计划分配到任何团队,则销售计划仅对您可见。 在销售计划中,针对计划期间的不同维度设置销售目标。根据您为销售计划定义的属性,系统会自动为您生成计划布局。将此计划布局下载至本地另存成Microsoft Excel的XLSX格式文件,此后可以在本地输入计划数据,并重新上传导入至S/4HANA销售计划应用中。 应用使用了ABAP DRAFT 框架(能支持数据更改的自动草稿存储,类似于Excel或Word的自动保存,但是这里实现的是草稿保存, 即随时可以取消,并且在用户显式点击保存后,会转移到永久存储区域),同时,该应用使用事务操作的CDS(Core Data Service)建模继而通过BOPF框架实现业务对象管理,并通过OData将后台数据服务发布,最终通过前端的Fiori应用进行呈现。 下图是该应用的概略架构图。 Fiori应用的技术实现,可分为基于模板(Smart Element)和自由式(Freestyle)实现两类。 ...

May 11, 2019 · 1 min · jiezi

Jerry-Wang在SAP社区上获得的徽章

要获取更多Jerry的原创文章,请关注公众号"汪子熙":

May 11, 2019 · 1 min · jiezi

ABAP很厉害是怎么一种体验?

知乎上偶然看到这个问题,觉得很有意思,我也来回答一发。我本科和研究生学的是计算机专业,做项目用C/C++,研究生三年项目的代码量大概在三到四万行左右。2007年大学毕业加入SAP成都研究院一直工作到现在,工作中用的最熟练的编程语言是ABAP,Java和JavaScript。当然做SAP Cloud application Studio这个工具开发时,也用过一段时间的C#。做一个SAP内部的大数据项目也用过一阵子Scala,Python和Go语言在做Hyperledge Fabric on SAP Cloud Platform时也学了一些皮毛。我没有把自己定位成“ABAP开发人员”或是“Java开发人员”,而是“SAP应用开发人员”。也就是说组织给我分配一个开发任务,我自己就得去琢磨,选择合适的编程语言来完成。ABAP,Java和JavaScript这三门我工作中用的最多的编程语言,在我眼中没有优劣之分,就是不同的编程工具,有各自的适用场合,如此而已。我曾经写过一篇文章:Jerry的ABAP, Java和JavaScript乱炖百度即可找到,里面包含了我对这三门语言一些特性的横向比较。文章链接:https://www.cnblogs.com/sap-j…回到ABAP语言本身,我认识SAP总部Walldorf很多资深的ABAP应用开发人员,当然也包括ABAP编程语言本身的开发人员,即用C语言开发ABAP虚拟机和运行时的那些同事,称呼他们为计算机科学家更合适。我想任何资深的ABAP应用开发人员,在他们面前也没有资格说自己“ABAP如何如何厉害”,因为这些计算机科学家们才是ABAP世界的创世主和维护者。C和ABAP的关系,可以参考我这篇文章:聊聊C语言和ABAP文章链接:https://www.jianshu.com/p/a99…至于一些网络上老生常谈的问题,诸如:做ABAP开发有前/钱途吗?为什么ABAP开发的收入比Java开发高/低?我已经在一些文章里表明了我的个人意见:上图文章的链接:https://blogs.sap.com/2017/01…中文版:ABAP开发人员未来应该学些什么文章链接:https://www.jianshu.com/p/b74…我写过的其他一些关于ABAP的文章:Jerry 2017年的五一小长假:8种经典排序算法的ABAP实现:https://www.jianshu.com/p/ceb…Jerry的ABAP原创技术文章合集:https://www.jianshu.com/p/020…300行ABAP代码实现一个最简单的区块链原型:https://www.jianshu.com/p/844…ABAP vs Java, 蛙泳 vs 自由泳:https://www.jianshu.com/p/4a0…动手使用ABAP Channel开发一些小工具,提升日常工作效率:https://www.jianshu.com/p/1cb…我用ABAP做过的那些无聊的事情:https://www.jianshu.com/p/688…使用Visual Studio Code编写和激活ABAP代码 (上):https://www.jianshu.com/p/0db…你的ABAP程序给佛祖开过光么?来试试Jerry这个小技巧:https://www.jianshu.com/p/97c…关注Jerry的公众号“汪子熙”,轻松获得所有SAP文章:要获取更多Jerry的原创文章,请关注公众号"汪子熙":

April 13, 2019 · 1 min · jiezi

我做SAP CRM One Order redesign的一些心得体会

框架开发和应用程序的开发完全不一样。举个具体的最近折腾我的例子: 创建新的service order,维护header的shipping data,此时order和shipping data的mode 都是creation,然后创建line item,添加product,header的shipping data带到line item,然后在line shipping data做修改,item的mode变成了change,此时不存盘,直接删除该item,然后马上另外创建一个item,继续编辑,此时第二个item的mode是creation,前一个item的change mode变为deletion,然后再删除第二次加的line item,不存盘,再创建第三个project,维护一些数据,存盘。此时我代码里的buffer处理会出问题,存到DB确实有一条item数据,但是已经corrupt掉了。 由于我buffer 处理logic有bug, 我花了很大功夫最后发现是第二次被删除的那条数据的内容被错误存到了DB里: 我甚至花了大量的时间来找重现这个错误的办法,因为最初我是偶然的机会发现这个错误,但是没留意我的操作,最后才找到能稳定复现问题的步骤,赶紧记录下来: 这个buffer处理的bug直接导致了今天三个新bug: 这就是框架开发的难度。如果是做应用,可以和PO商量,哪个客户吃饱了做这种操作?不支持。但是这些操作从Oneorder框架的角度来看,无非就是create, update和delete三个local buffer的处理罢了,没有任何理由不支持这种sequence的操作。反过来说,当developer经过一段时间努力之后能够自如地应对这些挑战,从这些bug中抽丝剥茧定位问题,给出correction,他的开发能力一定能得到很大提升。Developer对于自己编程能力的提升是没有止境的,我来之前本早已对自己的编程能力非常自信,但是经过这21天的开发,我还是造了一共40个bug出来。但我最终都fix了他们,每解决一个bug就像以前Wuji老师用游戏打比方一样,获得一定经验值。bug越难经验值越高。我做这个POC确实是全神贯注拿出全部精力去做,就这样都还生产了这么多bug,确实很烧脑。我每踩一个坑,都会用Jerry : timestamp这种格式写下注释. 如果用Jerry做关键字搜索,能发现34处坑:每一处坑趟过之后都增加了我对one order的理解,我把这些bug当作我的一笔财富。比如看这个"this code is ugly"的注释,点进去看: 确实很ugly,这恰恰就是fix注1里提到那个buffer更新bug的correction的一部分,加了注释估计没接触过one order的人也看不懂。我们拿成都现在已经完成一部分的product harmonization为例来看:7531行代码。而这个POC,做到今天是第21天,代码量已经超过product harmonization一半了。请看其中我highlight的这个class,是我的搭档IMS写的,他从2010年开始做One order。这个class 到现在写了921行,就为了实现一个功能:把partner的数据从新表里读出来,放到对应的buffer里去。为什么有921行?因为buffer的插入很有讲究。我每天吃饭,骑车的时候都在想这些buffer的东西。这个redesign的关键用三个词来概括的话,就是buffer, buffer, buffer.2017-05-15 9:45PMModel redesign targetOne order model redesign主要发生在下图我画的黑色方框内的模块, 下列是需要完全重新开发, 而非harmonization的内容新的数据库表。每个object type一张表,比如BUS2000116是Service process,有且仅有一张header 表,BUS2000131是sales item,有且仅有一张item表围绕这些数据库表的CRUD API.简单的说,就是这两件事。当然和One order 框架的复杂程度相关。Scope其中有9个component是硬骨头,当前POC已经done了两个,我用黄色标记。现有的POC,整体框架已经搭起来了,one order在新的model下已能正常工作,productive实现除了上述提到的7个硬骨头之外,不存在做不出来的东西和Feature. 当然,根据大家这么多年的开发经验,POC不可能100%暴露productive开发的所有问题。概括起来说,就是我们不需要从头空想一套东西来实现,一切以现有的POC为基础,这也是Carsten现在对这个POC非常重视的原因,每个方法,每行代码,在他力所能及可以抽出时间review的时候,他都不放过。开发这个事情并不是说工作认真负责就能deliver高质量的代码。打个不恰当的例子,我和Oliver工作都很认真,但我们还是生产了38个bug.和Carsten一起工作一个月,我对他工作风格的体会:一方面,他review你东西的时候非常仔细,非常注重细节,包括我之前举的例子,比如某方法是在LOOP里call还是外面call好,method的参数设置等等。另一方面,对于什么才是正确的design,他往往只给出大方向,overall的思路,但不会具体到可以直接拿来实现那么细的粒度,比如他不会告诉你为了实现他的思路,需要几个class,每个class几个方法,每个方法参数如何定义。他这种工作方式make sense,因为Chief Architect不需要把事情拆分这么细。这样就造成我最近按照我自己的理解去实现他那些思路,所以经常返工,refact. 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

March 10, 2019 · 1 min · jiezi

你的ABAP程序给佛祖开过光么?来试试Jerry这个小技巧

最近Jerry在忙一个项目,技术栈换成了nodejs平台,语言换成了JavaScript,因为赶项目进度,一直没时间更新公众号。感谢大家的支持,关注人数还是慢慢地增长到了3000。今天我们来聊聊一个比较轻松的话题。当今这个数字化时代,大家的生活都离不开互联网。互联网公司为了确保服务器不会因为软硬件问题宕机而影响自己的业务,纷纷使出浑身解数,包括设计更健壮的架构,实现高质量的代码,提供硬件条件更好的机房等。当然也有一些脑洞大开的公司,另辟蹊径,采取让佛祖对服务器进行开光的方式,来实现"服务器永不宕机"的美好愿望。下面是Jerry从一则搜狐新闻上看到的一些有趣的图片,转贴于此,新闻原文网址:http://www.sohu.com/a/1166219…有请高僧给服务器贴上灵符:看着这个符咒,Jerry想起了自己曾经通关过无数遍的仙剑奇侠传98柔情版里各种各样的灵符。高僧正在认真地进行开光仪式:这些难道是IT管理员,或者SAP称呼的Basis们,虔诚地跪在服务器前向佛祖祈祷“永不宕机”吗?除了“永不宕机”外,“永无bug”也是程序员们另一个美好的愿望。于是乎,有些程序员希望通过在代码头部加上这种注释,来获得一些心理上的慰藉。而对于SAP ABAP程序员,一看到bug这个词,最容易联想到什么?不知道大家心中的答案是什么,Jerry的答案是:ST22。ABAP程序在执行时,如果遇到了没有捕捉的异常,程序会终止,同时ABAP运行时会产生一个类似Windows系统蓝屏的core dump:这种dump可以在事务码ST22里查看。一般来说,一个有经验的ABAP程序员,通过分析ST22里提供的程序崩溃时的上下文信息,系统变量的内容,调用栈等等,不难修复这种bug。下图是ST22里dump的一个例子,值得一提的是大家可能会忽略的BASIS Developer View, 里面包含了引起运行时错误的ABAP语句对应的C语言实现的具体文件位置,比如下图的//bas/753_STACK/src/krn/abap/runt/abassert.c。大家还记得我写过的聊聊C语言和ABAP 这篇文章么?这里我偷个懒,把那篇文章里介绍C语言和ABAP语言关系的文字引用过来:为什么这篇文章要把C语言和ABAP放在一起讲,而不是别的语言比如Java和ABAP呢?因为ABAP语言底层是基于C/C++实现的,包括其关键字(比如最简单的关键字WRITE的C++实现有2千多行)和虚拟机(ABAP Runtime)。SAP内部的一群计算机科学家们发明了ABAP这门伟大的语言,由它实现的各种SAP应用帮助了全球超过180个国家和地区的客户们更好地运行其业务。通过Google我们能搜索到一些关于这些SAP计算机科学家们的介绍,比如这个链接:http://sapexperts.wispubs.com…SAP内部的Netweaver开发服务器上是能够浏览这些C语言代码的。Jerry 2017年在德国工作时,业余时间比较多,相关的C代码也阅读了不少,比如ABAP里最简单的WRITE关键字,其C语言实现有2000多行。可惜因为这些C语言实现对客户和partner不可见,因此无法在这里给大家分享它们的逻辑。再回到ST22。相信每一位ABAP程序员运行代码看到ST22的dump后,心里都会很沮丧。这个时候,如果有佛祖能够给引起bug的代码开开光,那将是一件很鼓舞人心的事情。相信无论使用何种编程语言的程序员,看到下图红色高亮的这两行字,都会精神为之一振:佛祖保佑,永无bug这段代码佛祖已经做过开光处理,绝无可能再产生bug如何实现ST22里这个显示效果?其实ST22和Windows系统蓝屏显示逻辑一样,都是一段静态模板文本加上运行时异常的实际动态内容合并而成。模板文字存储在ABAP Netweaver服务器的数据库表里。我们只需要在ST22的框架代码把模板文本从数据库表读出之后,将佛祖开光的文本动态添加到模板文本的头部,就大功告成了。实现步骤非常简单,在ST22标准程序SAPMS380的subroutine read_snapt内创建一个隐式增强。从read_snapt的代码能看出ST22的模板文本是存储在数据库表SNAPT里的。把佛祖开光的文本注入到read_snapt输出的头部:这段隐式增强的代码我放在了我的Github上:https://github.com/i042416/Kn…最终效果就是每次出现了运行时程序执行错误后,程序员到ST22里查看dump时,总能看到“佛祖保佑,永无BUG”几个字。这个例子其实也再次体现了Jerry之前提到的,作为ABAP开发环境和运行环境和二而一的Netweaver,给开发者提供了强大的可扩展性。最后也是最重要的1. 本文提供的步骤涉及到了对ABAP框架代码的隐式增强,请谨慎使用。禁止在测试服务器和生产服务器使用! 否则由此造成的一切负面后果,Jerry本人及SAP概不负责。2. 如果真的想确保自己交付的代码“永无BUG”,程序员还是得老老实实练好自己的内功,而不要把自己的命运交给佛祖。毕竟国内这么多程序员,这么多行代码,要是每一位程序员每一行代码都要由佛祖开光,佛祖得多累鸭,佛祖忙不过来鸭!更多阅读动手使用ABAP Channel开发一些小工具,提升日常工作效率聊聊C语言和ABAPABAP vs Java, 蛙泳 vs 自由泳300行ABAP代码实现一个最简单的区块链原型Jerry的ABAP原创技术文章合集ABAP开发人员未来应该学些什么Jerry的ABAP, Java和JavaScript乱炖我用ABAP做过的那些无聊的事情不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧那些年我用过的SAP IDE使用Visual Studio Code编写和激活ABAP代码

March 10, 2019 · 1 min · jiezi

SAP CX Upscale Commerce : SAP全新推出的电商云平台

大家好,我是Andy Chen,是SAP成都研究院年轻的SAP CX Upscale Commerce (后面将会以Upscale简称)开发团队的一名产品经理。CX的全称是Customer Experience。今天很高兴能够从一个产品经理的视角,给大家初步介绍一下这个SAP全新推出的面向中端市场的电商云平台。SAP CX Upscale Commerce是SAP专为零售商,B2C品牌商,CPG(快速消费品)和Direct-to-Consumer(直接面向消费者)行业而设计的下一代中端市场电商SaaS云平台。当前目标市场是美国(未来会逐步推向全球其他区域),目标客户主要包含以下特征:目标公司的软件采购和实施预算低于25万美元总收入(total revenues)低于10亿美元的General Business公司大型公司(包括SAP Enterprise Commerce Platform和SAP Commerce Cloud客户)寻求快速部署上线某些子品牌的快闪店(popo-upstore),小型的online或者in-store应用商店。在选择Upscale方案之前,这些公司通常会选择部署在其他电商平台上,比如Shopify Plus或Magento2018年10月,SAP的两位大佬, CX总裁Alex Atzberge以及SAP Upscale Commerce的高级副总裁Charles Nicholls,在巴塞罗那CX Live会议上宣布 SAP CX Upscale Commerce上线。2019年1月,SAP Upscale Commerce被评选为SAP Labs China 2018最佳产品之一,本人也很荣幸代表成都Upscale团队上台领取该奖项。Upscale研发部门分布在全球多个城市,波士顿主要负责前端应用研发,成都、蒙特利尔、慕尼黑和伦敦主要负责后端微服务交付。接下来开始我们分三个大的章节进行的产品介绍,首先介绍目前美国零售行业数字化转型的挑战,接下来是Upscale产品概念与部分特征,最后介绍如何通过Upscale在30分钟内快速部署一个iOS移动原生电商应用。如果大家有任何关于Upscale产品以及技术架构的问题,可以留言讨论。零售行业数字化转型面临的挑战(以美国为例)1. 电商移动用户体验的提升势在必行根据comScore关于移动端的统计报告,尽管占据了全网约70%的流量,但是只有20%的交易发生在移动端。这份报告的详细地址:https://www.comscore.com/Insi…市场主流的在线商店应用都是为PC桌面为出发点设计的,而移动设备应用只是PC端购物体验的延伸和扩展,用户体验没有针对移动应用进行深度定制,体验较差。2. 品牌就是体验用户体验越来越成为用户是否下单的关键要素,个性化服务体验是其中非常关键的因素之一。大规模的个性化功能实现是非常挑战和困难的:今天大多数终端个性化呈现都是商家手动配置的。弊端非常明显 – 人工工作量大、效果差、伪个性化、无法及时响应用户需求。3. Channel-less vs Cross Channel消费者希望在线上、线下渠道都可以购买该品牌的同一个商品,并且能够享受高度一致的用户体验和服务。为了给消费者提供一致性的良好体验,构建强大的分布式订单管理系统是许多品牌的首要任务。4. 敏捷性品牌商和零售商需要能够快速投放商品进入市场试错。新产品如何才能快速同步线上线下推向市场,并且响应市场需求变化?传统电商方案的平台搭建是一项艰巨的任务,需要大量的自定义代码,花费数月时间(甚至更长)和巨大的财务支出来实施。即便如此,有时也很难满足业务快速部署和调整的需求。面对以上挑战,我们需要一个全新的零售策略和支持这个策略的电商云解决方案 - SAP Upscale!SAP Upscale和传统本地部署的电商解决方案相比,有哪些优势?1. Upscale极大地简化了传统电商的数字化转型之路,开启了基于速度和敏捷的新时代。从商家tenant的创建到上线,只需要几天到几周的配置时间。2. Upscale专为移动消费者量身定做,包含移动端原生iOS、Android应用和PWA应用(Progressive Web App, 渐进性网页应用, 一种新的网页开发技术)。Upscale模糊了渠道之间的界限,使线上或者门店购物变得轻松有趣。3. Upscale内嵌的AI功能可以自动帮助商家为每个用户提供个性化服务,真正做到“千人千面”。4. 通过提供优秀的用户体验和个性化、线上线下一致性服务,商家将会从中得到最大化的收入和利润。快速部署 & 灵活响应市场动态Upscale深深刻着零售DNA的烙印,团队主要成员拥有数十年的零售行业领域知识的深厚沉淀。通过将传统的零售产品(Product)、品类(Category)管理经验和深度学习、人工智能的高效结合,Upscale模糊了传统意义上的三个独立学科:商品推销(Merchandising),个性化(Personalization)和分布式订单管理(Distributed Order Management)之间的界限。通过实时记录和分析用户在App上的每次点击、浏览、收藏等事件,结合历史销售订单、商品数据为每个客户提供最佳购物体验,同时为每个商家自动优化销售利润和收入。另外与大多数传统商务平台不同,Upscale使用最先进的微服务构建,一切都是API优先。商家可以根据自己业务和数字化转型的需求,灵活订阅和部署需要的前端应用和后端服务。在获得灵活快速的市场响应能力的同时,TCO(总体拥有成本)将会明显下降。The MobigramMobigrams是基于AI的1对1个性化商店应用。我们的目标是:1. 为每一个终端用户提供自动化的个性化服务,真正做到“千人千面”;2. 为每一个零售商或者品牌商自动化地优化收入和利润。每个消费者打开App都有自己独特的Mobigram,在消费者整个浏览商品和下单购物的过程中,App会通过后端AI实时计算的结果,为每个用户动态组装个性化的产品集合、品类、内容等模块。AI实时计算考虑的变量包括但不限于零售商想要销售的产品,产品库存位置,库存可用性等。使用AI和深度学习技术来平衡零售商的需求(出售库存,利润率,产品周转速度和曝光度)与客户的体验(访问速度,便利性,产品相关性,购物愿望),从而推动能为零售商或品牌商带来最大利润的客户体验。目前Upscale在3个领域已经上线的AI功能:Continuity CommerceSAP Upscale Commerce具有内置的AI预测订单连续性引擎,可自动甄别潜在可能从单次商品购买转换为连续性订单的客户。比如,用户以相对固定的周期购买某一品牌洗发露,那么系统可以识别此类购物行为。Upscale会向此类客户自动发送邀请,用户只需要在邀请里面点击一下购买,那么就可以立刻加入Continuity Program。商家将会在未来按照用户喜好的周期,定期的自动递送该商品给客户)。 对于客户而言,这意味着他/她们“永远不会买不到”喜欢的产品,也不会因为疏忽而遗忘购买某些商品。在这个过程中,用户自然也成为了该品牌最忠实的会员。对于商家而言,科学和准确的预测潜在购买需求有了有效的输入, 从而可以进一步研究和实现库存自动管理优化。延伸阅读:Getting Started with Continuity Ecommerce, Part 1: Approaches, Expectationshttps://www.practicalecommerc…30分钟快速搭建一个SAP Upscale移动原生iOS应用本章节将会为大家简单介绍如何在30分钟快速搭建一个移动原生iOS应用。1. Upscale tenant订阅SAP Upscale为商家提供一键on-boarding tenant的工具,只需要提供tenant的名称、subDomain信息以及需要创建tenant的系统环境,后台就会为用户订阅专属的tenant。2. 移动零售应用配置完成了tenant的订阅,商家即可配置自己的电商移动原生应用。SAP Upscale Commerce为商家提供了工作台作为配置的界面,几乎所有跟搭建一个电商网店的相关工作都可以在这个界面完成,其中:Configuration该部分包括一个电商应用所需的最基本配置,比如库存(仓库或者门店)、收款、税务、发货、用户账号管理、客户服务、订单管理(取消、退货)等。产品、产品与品类的关联关系,库存初始化信息等相关工作我们都是通过后台作业来执行。商家准备好产品CSV文件,可以配置周期性或者一次性作业来导入主数据。Upscale提供非常灵活的字段匹配、自定义属性的功能来帮助客户完成主数据集成。另外一个基本配置是App,商家可以在这里配置原生App(iOS,Android)以及PWA等应用,并且可以按照商家的策略,关联同样或者不一样的用户体验配置。Inventory作为Channel-less的电商解决方案,线上线下库存透明化是基础。在该配置目录下,商家可以看到全局库存、单品库存以及库存调拨等功能。EditionEdition是一组对象组合,包括产品品类(Category)、单品(product)以及AI自动推荐的Trend category。这些对象在一段时间内可用并在特定渠道上供消费者购买,例如2017年秋季Edition。商家可以灵活的配置多个Editions,并按照自身策略激活发布其中一个,关联到一个渠道然后开放给消费者。Experience用于定义一个App的布局、模块和模板。Upscale提供基于模板的一键生成功能,商家只需要按照自己业务需求一键生成默认的experience,所见即所得。然后根据自己品牌的风格,变更配色、logo等主题,即可关联edition来搭建原生应用。3. 全渠道用户体验完成以上配置后,商家即可部署App到应用商店供用户或者门店使用。全渠道的用户体验让客户能够在任何地方购物,并且真正得到全渠道个性化体验。下图是通过Xcode 模拟iPhone应用的一个截图:我们可以看到,每个客户拥有自己量身定制的个性化界面,系统会动态清除客户不喜欢的内容和产品,改变商品推销的内容和方式,引导客户进入跟自身最贴切并且最容易下单购买的类别。用户得到最佳体验的同时,Upscale也能最大限度地提高零售商的收入和利润。Upscale支持的应用平台有:Mobile App – iOS & AndroidMobile Web (PWA)Tablet (PWA)Desktop (PWA)Kiosk & In Store通过本文对SAP Upscale Commerce的基本介绍,相信大家应该对于这款SAP全新的SaaS电商云解决方案有了初步的了解。限于篇幅,如果有任何问题和更多的兴趣,欢迎讨论,感谢阅读。要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 24, 2019 · 1 min · jiezi

SAP 前端技术的演化史简介

Jerry之前曾经写过一篇微信公众号文章,题目叫<<SAP UI和Salesforce UI开发漫谈>>关注我的公号“汪子熙”后,在历史菜单“前端开发相关”里即可找到这篇文章:该文章简单回顾了SAP UI技术的发展历史,然后提了下Salesforce的Apex和Lighting Component等技术和框架。目录SAP UISAP GUI + DynproWeb DynproBSP/CRM WebClient UISAP UI5/FioriUI5 in SAP Cloud for CustomerHybris Enterprise Commerce PlatformSalesforce UIApexLightning ExperienceAura FrameworkLightning Component FrameworkVisualforce我也画了张简单的图:R1和针对于大型机的R2对我们来说实在太古老了,对我们来说,只能通过SAPGUI里的复古主题,即Classical Theme来体验一下这些老古董的外观风采。到了1992年出现了类似JSP技术的BSP(business server page),能够借助在服务器端执行的ABAP语言实现动态网页效果。在运行时,每个BSP页面会自动生成一个临时的ABAP类,执行这些BSP页面上嵌入的ABAP代码,执行的结果再渲染成原生的HTML代码。值得一提的是,BSP技术兼容普通的HTML/JavaScript应用,换句话说,几乎所有能运行在除Netweaver以为的web服务器上的基于HTML/JavaScript的web应用,也能以BSP为载体,运行在Netweaver上。因此,即使是如今SAP的旗舰级产品S/4HANA里的很多Fiori UI应用,也是以BSP应用为载体存储在Netweaver上的。比如S/4HANA物料主数据管理的Fiori应用,其名称在Chrome开发者工具里能看到:这个BSP应用在Netweaver上能找到:诞生于1992年的BSP技术到了今天还在服役,这本身就是一个奇迹了。当然它本身由于历史原因也有一些局限:开发效率不够高,没有类似后来UI5里控件库的概念,导致开发人员需要重复造很多轮子。SAP后来自己也发布了一些BSP Extension,类似JSP里的tag,以此来弥补开发效率的缺陷。另外BSP的开发工具在SAPGUI里只有事务码SE80,这个工具在做HTML和JavaScript开发时显得不够友好。因此后期SAP Fiori开发也采取了在本地现代IDE比如Eclipse里做开发,完毕后再上传到Netweaver自动生成BSP的方式。没有MVC的概念,在大型企业级应用开发中显得力不从心。正是由于暴露了这两个缺陷,促成了WebUI和Webdynpro的问世。对这两种前端技术的详细介绍,请参考Jerry之前提到的微信文章:SAP UI和Salesforce UI开发漫谈,这里不再重复,只是聊聊一些该文章中没有提过的内容。ABAP Webdynpro的亮点就是能够以所见即所得的方式进行UI界面开发,缺点是不再支持类似BSP那样兼容传统的HTML/JavaScript,因此无法实现某些对界面复杂度和交互性要求较高的需求。而WebUI在继承了BSP所有优点的同时,在BSP基础上提供了对MVC的封装,使得开发效率大大提高,同时开发出来的Web应用结构清晰,不再会出现一个视图页面几千行代码的情况。下图是一个典型的WebUI模型,MVC三层在workbench里有清晰的界定。WebUI和ABAP Webdynpro至今仍广泛应用于SAP产品中。在S/4HANA的CRM模块里,WebUI继续扮演着非常重要的角色,详情请阅读我下面这篇文章:Hello World, S/4HANA for Customer Management 1.0而Webdynpro,是SAP SRM UI开发的主流技术。搜索公网上所有使用了SAP BSP技术的网站:https://www.google.com/search…:/sap/bc/bsp/&gws_rd=ssl使用了Webdynpro的:随着时间的推移,用户对移动设备上访问网页的体验要求越来越高,因此有了SAP从业者现在很熟悉的前端技术:SAP UI5。关于UI5最新的技术发展方向,请关注我的公众号“汪子熙”,阅读我写的这篇文章:Fiori Fundamentals和SAP UI5 Web Components要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 24, 2019 · 1 min · jiezi

用ABAP代码读取S/4HANA生产订单工序明细

在S/4HANA事务码CO03显示的Production Order里,我希望用ABAP代码显示出该订单的operation(工序)ID,描述和状态Status,如下图所示:很简单的几行ABAP代码:DATA: lt_operation TYPE TABLE OF afvgd.CALL FUNCTION ‘PM_ORDER_DATA_READ’ EXPORTING order_number = ‘000001000381’ TABLES iafvgd = lt_operation EXCEPTIONS order_not_found = 1.IF sy-subrc <> 0. WRITE:/ ’not exist’. RETURN.ENDIF.需要读取的数据都在这里:要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 24, 2019 · 1 min · jiezi

使用Visual Studio Code编写和激活ABAP代码 (上)

猪年春节后的第一篇,Jerry祝各位猪年大吉!2019年的六分之一马上就快过完了,不知道大家在新的一年是否给自己定了新的小目标呢?这里Jerry先预祝大家到2019年年底的时候,在年初制定的小目标都能实现。2018年4月之前,Jerry一半时间为SAP S4CRM团队工作,剩下的一半时间为SAP C4C团队工作,所以那段时间大家能发现,Jerry公众号的文章主要是围绕着这两个SAP产品来写的。4月之后,Jerry换组,到了新的部门,工作内容也发生了变化,不再专注于某个特定的SAP产品,而是项目需要我熟悉什么产品,我就得熟悉什么产品,所以之后我的公众号文章,主题也逐渐多种多样起来。言归正传,Jerry之前的文章 那些年我用过的SAP IDE 曾经介绍过除了SAPGUI之外的其他ABAP开发工具和ABAP代码浏览工具。得益于Netweaver职责清晰的三层架构,提供了ABAP开发环境和运行环境的应用服务器层(下图中间的Application server layer)作为ABAP应用的核心, 其上可以灵活适配不同的展现层(Presentation layer), 比如WebIDE, Eclipse,和今天要介绍的Visual Studio Code。上图中应用服务器层的底层是数据库服务器层,Netweaver也支持多种主流数据库提供商的服务。例如下图是Jerry使用的一个Netweaver系统,支持包括SAP HANA在内的十种数据库管理系统(DBMS)。我们简单回顾下之前Jerry介绍过的不同的ABAP开发工具。首先是ABAP Development Tool(简称ADT), 对ABAP程序提供增删查改和激活操作的函数,通过位于路径sap/bc/下面的SICF服务节点adt暴露给外部消费者。ABAP Development Tool的Java端实现就是Eclipse的一个扩展,使用JCO(Java Connector)连接ABAP后台的adt服务,实现对ABAP程序的操作。关于ABAP Development Tool的细节,Jerry以前已经做过详细介绍,这里不再赘述,可以参考我这些文章:不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧Jerry在SAP Community上写给老外看的文章:https://blogs.sap.com/2014/08…而在浏览器里编写ABAP,即通常意义上的ABAP WebIDE,实现方式有两种。一种是通过传统的ITS(Internet Trasaction Server),通过这种方式在浏览器里显示的ABAP代码缺乏语法高亮:Jerry写过的相关博客:Open your SAP GUI transaction in Fiori launchpadhttps://blogs.sap.com/2016/12…How is old SAP GUI transaction embedded into Fiori launchpadhttps://blogs.sap.com/2016/12…另一种技术就是S/4HANA某些应用,比如Custom Logic采用的,支持语法高亮。当然这个语法高亮的支持不是天上掉下来的,详细实现参考我的博客:How ABAP syntax highlight is implemented in WebIDE launched via browserhttps://blogs.sap.com/2018/03…再回到今天聊的Visual Studio Code。SAP成都研究院很多前端开发的同事都向我推荐过这个IDE。Jerry试用过之后,印象最深的就是它那超快的启动速度,一流的扩展性和繁荣的生态圈。其扩展应用的丰富程度不亚于Sublime Text和Eclipse这些老牌开发工具。和SAP自研的ABAP Development Tool思路一样,本文介绍的Visual Studio Code扩展应用,ABAP Remote File System,也是通过另一种编程语言TypeScript去远程消费ABAP后台程序的增删查改服务。该扩展应用的作者叫Marcello,一位居住在伦敦的程序猿(Jerry想起了西甲皇家马德里足球队昔日的队宠)。这个Visual Studio Code的扩展是开源的,github仓库地址:https://github.com/marcellour…安装和配置的步骤在仓库的readme里有详细说明,最简单的方式就是在Visual Studio Code里直接用abap作为关键字搜索Market place,然后点Install安装。这个扩展的配置文件settings.json的内容可以参考下图:配置完成后,在Visual Studio Code的命令栏里能看到连接ABAP系统的指令和settings.json里配置的两条记录,任选一个后登入系统,显示该系统下的ABAP程序资源。操作它们的方式和基于Eclipse的ABAP Development Tool大同小异。当然也有一些Visual Studio Code提供的特色功能,比如下图这种类Google的即时搜索。这个扩展本身是不提供ABAP代码语法高亮的,需要安装另一个来自Lars Hvam贡献的语法高亮扩展。安装完毕后,ABAP的语法高亮也能顺利在Visual Studio Code里工作了。下面这张动图来自Marcello,演示了通过Visual Studio Code的这个扩展实现ABAP代码的基本编辑。作者在他的readme也明确注明,这个扩展还处于Beta测试阶段,使用者需自己承担风险。在Jerry看来,Visual Studio Code的这个扩展,如果用来做ABAP开发的话,功能还相对局限,但是如果对SAPGUI或者ABAP Development Tool产生了审美疲劳,想换一种工具来阅读ABAP源代码,那么它和下图的Sublime Text一样,都是不错的选择。将来如果Jerry有空,会在这篇文章的下半部分简单介绍下这个扩展的TypeScript实现细节。另外,今年Jerry也会争取能分享一些SAP云平台上ABAP编程环境的相关内容,敬请期待。感谢阅读。更多阅读动手使用ABAP Channel开发一些小工具,提升日常工作效率聊聊C语言和ABAPABAP vs Java, 蛙泳 vs 自由泳300行ABAP代码实现一个最简单的区块链原型Jerry的ABAP原创技术文章合集ABAP开发人员未来应该学些什么Jerry的ABAP, Java和JavaScript乱炖我用ABAP做过的那些无聊的事情不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧那些年我用过的SAP IDE要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 24, 2019 · 1 min · jiezi

Salesforce的多态存储和SAP C4C的元数据存储仓库

SalesforceForce.com integrates and optimizes several different data persistence technologies to deliver transparent polyglot persistence for all your applications and devices. With Force.com, you don’t have to deal with the complexity of trying to integrate, manage, test, and support several systems, and you only have to code to a single API, no matter which type of persistence is optimal for a given situation. The following figure is an overview of a sampling of Force.com’s persistence technology.Salesforce存在一个Polyglot Persistence多态存储的概念。应用程序可以通过Polyglot persistence暴露出的统一接口去访问平台上的数据,而无需关心这些数据背后具体的存储技术到底是Transaction Engine, 还是由常驻内存提供,亦或是由支持全文本查找的搜索引擎提供。SAP C4C(Cloud for Customer)作为SAP提供的一款SaaS CRM解决方案,C4C也存在类似Salesforce Polyglot Persistence的设计,我们称之为元数据仓库存储。我们在cloud application studio的package下面能看到许许多多的开发对象:可以想象,这二三十种开发对象后台的存储逻辑和技术都各不相同。每次用户登录Cloud application studio,打开自己工作的package后,都会从后台将自己创建的类型各异的开发对象取出然后显示在studio里。为了给Cloud application studio工具端和其他消费者(比如C4C前端UI)提供一个统一高效的API去C4C后台读取这些模型的数据,C4C设计了一个元数据存储仓库,该仓库提供了一个优化过后的API,相当于设计模式里的Facade(外观模式/门面模式)。该API会根据具体被访问的对象,将请求转发到该对象对应的存储服务提供者(Access service provider)上去。对于API的消费者来说,这些对象具体的存储技术是完全透明的,不需要知道。要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 15, 2019 · 1 min · jiezi