Enterprise Resource Planning Blogs by Members
Gain new perspectives and knowledge about enterprise resource planning in blog posts from community members. Share your own comments and ERP insights today!
cancel
Showing results for 
Search instead for 
Did you mean: 
ravi_kumar204
Active Participant

Hi Friends,


While doing the Variant configuration, we may came across scenarios where std. syntax of VC will not be sufficient. For this type of scenarios, we can use Variant functions to achieve the desired functionality.  Variant functions will use Function Modules, here we have to write the code using ABAP.

Overview

Variant functions allow us to integrate the function modules with all types of object dependencies. In the object dependencies we need to use the syntax for calling the function module as well as input and output parameters.

Variant conditions used where standard syntax is not sufficient to map desired functionality. This may be possible in following cases.

  • Complex processing of Char. values
  • Evaluation of database tables that cannot be addressed via reference characteristics.
  • Complex validity checks of allowed char. values.
  • Generation of custom information messages.

Example:

Using variant function to concatenate values of three characteristics into another characteristic.

Chars

Values

Processor

  • Core i7
  • Core i5
  • Core i3

Hard Disk

  • 500 GB
  • 750 GB
  • 1 TB

RAM

  • 2 GB
  • 4 GB
  • 6 GB

Label

Above 3 char selected values should be concatenated and displayed as label.

 

Creation of Variant Function:

T.Code: CU65

For creating variant function we have to provide required input and output parameters for the function module.

Give Function Name and Description   Click on Characteristics

Assign required input and output characteristics and save the variant function. In the above example PROCESSOR, HARD_DISK, RAM are input parameters.

Creating Function Module:

Note: For creating Function Modules requires developer access.

Open the variant function in change mode in CU66 T.code and click on Function Module button.

Function builder initial screen will appear system will propose the function module name click on Create button.

Enter the required details and press save button.

 

Interface of the Function Module

Import Parameters

Parameter Name

Typing

Reference Field

Content

GLOBALS

LIKE

CUOV_00

Global parameters for calling a function. However, the list of fields currently only contains the date.

Tables

Parameter Name

Typing

Reference Type

Content

QUERY

LIKE

CUOV_01

Table of input parameters and the expected output parameters

MATCH

LIKE

CUOV_01

Table of output parameters

All partial fields except ATCIO must be filled in a MATCH entry (especially format ATFOR)

Structure CUOV_01 comprises the following fields:

  • VARNAM (characteristic name)
  • ATFOR (format of the value)
  • ATWRT (alphanumeric characteristic value in internal format)
  • ATFLV (numeric characteristic value)
  • ATCIO (Indicator: input (I) or output (O) parameter)

  The fields ATFOR, ATWRT, and ATFLV only have values assigned for input parameters.

Exceptions:

FAIL

This exception shows that the condition represented by the function is not fulfilled.

INTERNAL_ERROR

This exception shows that a runtime error has occurred processing the function.


Source Code : Used for writing your own logic for the function module using ABAP.

The following help functions are supported for accessing import parameters:

  • CUOV_GET_FUNCTION_ARGUMENT: Read characteristics from the input parameters.
  • CUOV_GET_FUNCTION_ARGUMENT: Transfer value of characteristics to Variant configuration.

Write the ABAP code and Save and activate the function module.

Press back button, system will display the Change Function transaction.  Change the status to 1 – Released and Save Function.

Call Variant Function

Write the Procedure and assign it to configuration profile of the material. Below is the procedure for this example.

FUNCTION ZCOMP_LABEL

(PROCESSOR = $ROOT.PROCESSOR,

HARD_DISK = $ROOT.HARD_DISK,

RAM = $ROOT.RAM,

LABEL = $SELF.LABEL)

The characteristics on the left-hand side are characteristics of the function. The characteristics on the right-hand side are characteristics of the PC.

Characteristic LABEL must be referred to with the variable $SELF, because LABEL is a characteristic of the object currently being processed. Otherwise, values cannot be inferred. The default object $ROOT is assumed for the other characteristics.

Testing

As soon as all values assigned to the characteristics of variant function, function module will sets the value for LABEL.

Note:

When you call a user-defined function module, SAP Variant Configuration no longer has control of possible error situations: the person who writes the function module can use all ABAP language elements, but has sole responsibility for the code.

 

Example code for Function Module

FUNCTION ZCOMP_LABEL.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(GLOBALS) LIKE  CUOV_00 STRUCTURE  CUOV_00
*"  TABLES
*"      QUERY STRUCTURE  CUOV_01
*"      MATCH STRUCTURE  CUOV_01
*"  EXCEPTIONS
*"      FAIL
*"      INTERNAL_ERROR
*"----------------------------------------------------------------------


DATA : LV_PROCESSOR TYPE CUOV_01-ATWRT,
LV_HARDDISK
TYPE CUOV_01-ATWRT,
LV_RAM
TYPE CUOV_01-ATWRT,
LV_LABEL
TYPE CUOV_01-ATWRT.

REFRESH MATCH.

CALL FUNCTION 'CUOV_GET_FUNCTION_ARGUMENT'
EXPORTING
ARGUMENT           
= 'PROCESSOR'
IMPORTING
*   VTYPE               =
SYM_VAL            
= LV_PROCESSOR
*    NUM_VAL             =
*   IO_FLAG             =
TABLES
QUERY              
= QUERY
EXCEPTIONS
ARG_NOT_FOUND      
= 1
OTHERS              = 2
.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.


CALL FUNCTION 'CUOV_GET_FUNCTION_ARGUMENT'
EXPORTING
ARGUMENT           
= 'HARD_DISK'
IMPORTING
*   VTYPE               =
SYM_VAL            
= LV_HARDDISK
*    NUM_VAL             =
*   IO_FLAG             =
TABLES
QUERY              
= QUERY
EXCEPTIONS
ARG_NOT_FOUND      
= 1
OTHERS              = 2
.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.

CALL FUNCTION 'CUOV_GET_FUNCTION_ARGUMENT'
EXPORTING
ARGUMENT           
= 'RAM'
IMPORTING
*   VTYPE               =
SYM_VAL            
= LV_RAM
*    NUM_VAL             =
*   IO_FLAG             =
TABLES
QUERY              
= QUERY
EXCEPTIONS
ARG_NOT_FOUND      
= 1
OTHERS              = 2
.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.

CONCATENATE LV_PROCESSOR LV_HARDDISK LV_RAM INTO LV_LABEL SEPARATED BY '|'.

CALL FUNCTION 'CUOV_SET_FUNCTION_ARGUMENT'
EXPORTING
ARGUMENT                     
= 'LABEL'
VTYPE                        
= 'CHAR'
SYM_VAL                      
LV_LABEL
*   NUM_VAL                       =
TABLES
MATCH                        
= MATCH
EXCEPTIONS
EXISTING_VALUE_REPLACED      
= 1
OTHERS                        = 2
.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
ENDFUNCTION.

12 Comments
Former Member
0 Kudos

ravi.kumar204 ,

I just did a quick read and find it very useful, can you tell me even if i have very little knowledge knowledge on ABAP can i build it in sand box? or do you want me to suggest to read few document on ABAP which will help me using this document effectively.

My request is if you can add some more information on basic ABAP understanding one should develop while building this example will made this document awesome.

Hope you will agree on it. :smile:

Thanks

Pal

kyusufzai
Participant
0 Kudos

This is very helpful. I was looking something like this for  few days.

Thanks for sharing

0 Kudos

Thanks , very helpful. Can we call BRF+ function at dependency instead of Function module?

former_member228481
Contributor
0 Kudos

Hi Ravi,

Thanks for your effort on document its great..!

I have a query, how to address this when we have series of trasports flowing from DEV - Q - P?

Chars. are master data, can be present in all three servers, but the if function module we need to create through CU66, then i am confused if its client to cleint creation or to move FM from DEV to Q to P?

How to address this situation?

Thanks..!

Flavio
Active Contributor
0 Kudos

Hi Raghu,

Indeed, we have two objects when dealing with variant functions:

  • the variant function itself (CU66)
  • the ABAP function (SE37)

So, the first is usually tranported by ALE, transaction CUFD - 'Distribute Variant Functions', that will generate a 'VFNMAS' ALE message. It can then be imported in the other systems in the flow (Q & P) via BD87 (IDocs).

The second is an ABAP object, usually transferred to the other system with Transport Orders.

Hope this is helping in some way.

Thanks and best regards,

Flavio

former_member183045
Contributor
0 Kudos

I linked your document as a good example in my blog post, I hope thats OK for you:

Enhanced variant configuration tool                

ravi_kumar204
Active Participant
0 Kudos

Thanks & OK. :smile:

Former Member
0 Kudos

Very useful document with a simple example, easy to understand for beginners in Variant Functions.

Just one clarification needed; if I have a scenario, where I need to set two characteristics for output, can this also be done?

Please let me know.

Thanks

Adithya

Former Member
0 Kudos
Hi Ravi,

This is very help full,

Thanks for sharing the information.

 

Regards,

Taraka
0 Kudos
Hi Ravi,

Thanks for sharing.

i have one alternate solution, instead of using variant function we can achieve by using Object

dependency (Procedure) and some reference characteristics(without SAP table). Characteristics

values will get concatenated dynamically as per input given to the Characteristics.

Note: You can concatenate multiple Characteristics for an output.

Regards,

Meraj Ansari
Sergiu
Contributor
0 Kudos

When an input characteristic is not specified than the function is not executed. To solve this you can create a characteristic as a intermediate variable. Let's assume that for RAM.

* Define in transaction CT04 characteristic RAM_VAR.
* Characteristic RAM_VAR works without assignment to a class

$SELF.RAM_VAR = 'NULL' IF NOT SPECIFIED RAM,
$SELF.RAM_VAR = RAM IF SPECIFIED RAM,

FUNCTION ZCOMP_LABEL
(PROCESSOR = $ROOT.PROCESSOR,
HARD_DISK = $ROOT.HARD_DISK,
RAM = $ROOT.RAM_VAR,
LABEL = $SELF.LABEL).

You can use also include in the function the code to transfer values for further processing.

CONSTANTS: c_mem_id  type c LENGTH 10  VALUE 'ZCOMP_LABEL'.
CONSTANTS: c_mem_var type c LENGTH 10 VALUE 'ZCOMP_LABEL_CHAR'.
DATA: BEGIN OF ZCOMP_LABEL_CHAR,
ZRAM LIKE CUOV_01-atwrt,
END OF ZCOMP_LABEL_CHAR.

FREE MEMORY ID c_mem_id.
ZCOMP_LABEL_CHAR-ZRAM = LV_RAM.
EXPORT c_mem_var FROM ZCOMP_LABEL_CHAR TO MEMORY ID c_mem_id.

You can validate data after exiting configuration screen with an enhancement.

* Transaction CMOD - CCUX0000, SE37: EXIT_SAPLCUKO_001, SE38: ZXCUCU02.

CONSTANTS: c_mem_id type c LENGTH 10 VALUE 'ZCOMP_LABEL'.
CONSTANTS: c_mem_var type c LENGTH 10 VALUE 'ZCOMP_LABEL_CHAR'.
DATA: BEGIN OF ZCOMP_LABEL_CHAR,
ZRAM LIKE CUOV_01-atwrt,
END OF ZCOMP_LABEL_CHAR

data: lv_answer(1) TYPE C,
data: lv_question(400) TYPE C.

IMPORT c_mem_var TO ZCOMP_LABEL_CHAR FROM MEMORY ID c_mem_id.
concatenate 'Is value' ZCOMP_LABEL_CHAR-ZRAM 'correct?' into lv_question separated by space.

CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
titlebar = 'Check characteristics RAM'
text_question = lv_question
text_button_1 = 'Yes'
icon_button_1 = 'ICON_OKAY'
text_button_2 = 'No'
icon_button_2 = 'ICON_CANCEL'
default_button = '2'
display_cancel_button = ''
IMPORTING
answer = lv_answer.

IF lv_answer eq '2'.
RAISE CONFIGURATION_INCORRECT.
ENDIF.

 

 

0 Kudos
Hello Ravi, Sergiu,

Nice blog and even better comments!

I've used the check IS SPECIFIED and a tmp var to overcome the issue that indeed a FM was never executed when the characteristic was still initial.

Now we see that because the characteristic was set by the dependency, SAP is clearing its value before calling the dependencies. (Verified by setting the trace). Like this, the FM is always called, even if the char was already populated by the FM in a previous run. However, we only want to run it once. As soon as the right value was returned, it shouldn't be executed again.

Is there a way to "protect" a char to be cleared like this by SAP?

If not, is there a way to pass the material number to the FM in de dependency? (so we can check in there if the FM was already called for our material)

Thanks in advance,

Erik
Labels in this area