2013 Nov 13 6:16 PM
Hello Experts,
I need to Build an internal table based on the Below two values.
a) lv_installements = 8.
b) License Fee = 1033.00 .
With the above two values, i need to build an internal table with 8 entries Equally Dividing the License fee.
1033/8 = 129.125 .
first 7 entries should have integer values 129 , the Decimal values should be adjusted in the last entry , I.E last entry should have 130.
WIth the above 2 values a) and b) , i want the internal table in the following way.
A B
1 129
2 129
3 129
4 129
5 129
6 129
7 129
8 130
Can any one suggest me how to do this efficiently. ?
Thanks and Regards,
Kaushik M
2013 Nov 13 6:59 PM
Hey,
Kaushik M wrote:
Hello Experts,
I need to Build an internal table based on the Below two values.
a) lv_installements = 8.
b) License Fee = 1033.00 .
With the above two values, i need to build an internal table with 8 entries Equally Dividing the License fee.
1033/8 = 129.125 .
first 7 entries should have integer values 129 , the Decimal values should be adjusted in the last entry , I.E last entry should have 130.
WIth the above 2 values a) and b) , i want the internal table in the following way.
A B
1 129
2 129
3 129
4 129
5 129
6 129
7 129
8 130
Can any one suggest me how to do this efficiently. ?
Thanks and Regards,
Kaushik M
its quite simple, just do the following:
Firstly,Once you create a internal table with the fields L_INSTALLMENT & LICENSE_FEE.
,then fill this table till no. of installments(Do this by simply).
Take Two dummy variables(mean while Var1 & Var2),
one for storing value without round-up (IE. VAR1)and second variable for storing rounded-up value IE.VAR 2(If in case needed like in your explained example is 130).
Now Simply use Var1 for first 7 entries and Var2 for reamaing.
now loop it on internal table so your internal table is ready to be used later.:-)
That's up to best of my knowledge the efficient and the simplest one as we want it could be efficiently done.
Thanks.
Regards : Pavan Golesar.
2013 Nov 13 7:39 PM
I guess I'd write something like:
Rate = fee / installments
m_rate = floor( rate )
e_rate = ceil( rate )
count = 1
do while count < installments
itab-count = count
itab-rate = m_rate
append itab
count = count + 1
enddo
itab-count = count
itab-rate = e_rate
append itab
Neal
2013 Nov 13 7:39 PM
2013 Nov 13 7:45 PM
Great job ..
AWESOME.. Thank You Neal.
Regards: Pavan Golesar
Message was edited by: Pavan Golesar
2013 Nov 14 3:30 AM
I checked the issue and started writing some code, later i saw my logic and logic given by you(pavan) and Neal, all are same. .. Good work Neal and Pavan.
2013 Nov 14 4:32 AM
Hi
Good Logic...but in this case your logic fails i think.... if i am wrong correct me...
TYPES : BEGIN OF ty_final,
lv_installements TYPE i,
license_fee TYPE i,
END OF ty_final.
DATA : it_final TYPE TABLE OF ty_final,
wa_final TYPE ty_final.
DATA : var TYPE p DECIMALS 2,
m_rate TYPE p DECIMALS 2,
e_rate TYPE p DECIMALS 2,
count TYPE i.
PARAMETER : p_inst TYPE i,
p_fee TYPE p DECIMALS 2.
var = p_fee / p_inst.
m_rate = FLOOR( var ).
e_rate = CEIL( var ).
Write : / m_rate,
/ e_rate.
last value should be 130.90 or 131 but result 130.00 is correct?
2013 Nov 14 4:08 AM
Hi Kaushik M
You can try like this
TYPES : BEGIN OF ty_final,
lv_installements TYPE i,
license_fee TYPE p DECIMALS 2,
END OF ty_final.
DATA : it_final TYPE TABLE OF ty_final,
wa_final TYPE ty_final.
DATA : var TYPE i,
cnt TYPE i,
tot TYPE i,
dif TYPE p DECIMALS 2.
PARAMETER : p_inst TYPE i,
p_fee TYPE P DECIMALS 2.
DO p_inst TIMES.
var = p_fee / p_inst.
cnt = cnt + 1.
tot = tot + var.
IF cnt < p_inst.
wa_final-lv_installements = cnt.
wa_final-license_fee = var.
APPEND wa_final TO it_final.
CLEAR wa_final.
ELSE.
dif = p_fee - tot.
wa_final-lv_installements = cnt.
wa_final-license_fee = ( var + dif ).
APPEND wa_final TO it_final.
CLEAR wa_final.
ENDIF.
enddo.
LOOP AT it_final INTO wa_final.
WRITE: / wa_final-lv_installements,
wa_final-license_fee.
ENDLOOP.
2013 Nov 14 5:50 AM
Hi Kaushik,
Try this here x_itab is a structure contain only two fields A and B and t_itab is the internal table.
DATA val TYPE i.
PARAMETERS :p_no TYPE i DEFAULT 1033,
p_div TYPE i DEFAULT 8.
val = floor( p_no / p_div ).
DO p_div TIMES.
IF p_div EQ sy-index.
val = val + p_no MOD p_div.
ENDIF.
x_itab-a = sy-index.
x_itab-b = val.
APPEND x_itab TO t_itab.
WRITE :/, AT 10 x_itab-a,
AT 20 x_itab-b.
ENDDO.
Regards,
Jeffin
2013 Nov 14 6:07 AM
2013 Nov 14 6:26 AM
Hello Ramesh T,
Thanks alot for your help. It works for all cases.
I will mark it as correct answer.
There is two more field also.
Start date and End date.
01.01.2013 | ||||||||
01.08.2013 | ||||||||
Licence Fee : 8000
Now the Duration is 8 months from 01.01.2013 to 01.08.2013 . now i need to divide 8 months into 8 installments.
Can you tel me how to convert these dates into days and then divide and finaly need to show the dates . I am trying to get the out put in the following way.
Once again thanks alot for your correct solution,
Date of instalment instalment no Licence fee
01.01.2013 1 1000
01.02.2013 2 1000
01.03.2013 3 1000
01.04.2013 4 1000
01.05.2013 5 1000
01.06.2013 6 1000
01.07.2013 7 1000
01.08.2013 8 1000
Thanks and Regards,
Kaushik M
2013 Nov 14 6:28 AM
Hi Ramesh,
Try this
Change the statment val = val + p_no MOD p_div to
val = val + floor( p_no MOD p_div ).
IF p_div EQ sy-index.
val = val + floor( p_no MOD p_div ).
ENDIF.
2013 Nov 14 8:19 AM
Hi Kaushik M
Try like this
TYPES : BEGIN OF ty_final,
date TYPE sy-datum,
lv_installements TYPE i,
license_fee TYPE p DECIMALS 2,
END OF ty_final.
DATA : it_final TYPE TABLE OF ty_final,
wa_final TYPE ty_final.
DATA : var TYPE i,
cnt TYPE i,
tot TYPE i,
dif TYPE p DECIMALS 2,
emonths TYPE vtbbewe-atage,
next TYPE sy-datum,
next_date TYPE sy-datum .
PARAMETER : s_date TYPE sy-datum,
e_date TYPE sy-datum,
p_inst TYPE i,
p_fee TYPE p DECIMALS 2.
CALL FUNCTION 'FIMA_DAYS_AND_MONTHS_AND_YEARS'
EXPORTING
i_date_from = s_date
i_date_to = e_date
i_flg_separate = ' '
IMPORTING
e_months = emonths.
DO p_inst TIMES.
var = p_fee / p_inst.
cnt = cnt + 1.
tot = tot + var.
IF cnt > 1.
IF next IS INITIAL.
next = s_date.
ELSE.
next = next_date.
ENDIF.
CALL FUNCTION 'RE_ADD_MONTH_TO_DATE'
EXPORTING
months = '1'
olddate = next
IMPORTING
newdate = next_date.
ENDIF.
IF cnt < p_inst.
IF cnt = 1.
wa_final-date = s_date.
ELSE.
wa_final-date = next_date.
ENDIF.
wa_final-lv_installements = cnt.
wa_final-license_fee = var.
APPEND wa_final TO it_final.
CLEAR wa_final.
ELSE.
dif = p_fee - tot.
wa_final-date = next_date.
wa_final-lv_installements = cnt.
wa_final-license_fee = ( var + dif ).
APPEND wa_final TO it_final.
CLEAR wa_final.
ENDIF.
ENDDO.
LOOP AT it_final INTO wa_final.
WRITE: / wa_final-date,
wa_final-lv_installements,
wa_final-license_fee.
ENDLOOP.
2013 Nov 14 9:05 AM
Hello Ramesh,
I am working on CRM system and this FM "RE_ADD_MONTH_TO_DATE" is not available on the system. Can you please tell me what is the alternative for this.
Thanks and Regards,
Kaushik M
2013 Nov 14 10:48 AM
Hi Kaushik M
Try with this function module
CALL FUNCTION 'SALP_CALC_DATE'
EXPORTING
in_rectype = 'M'
in_nbr_dwxmqy = '1'
in_date = next
IMPORTING
OUT_DATE = next_date
* EXCEPTIONS
* OTHER_ERROR = 1
* OTHERS = 2
.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
2013 Nov 14 6:29 AM
In case of
a) lv_installements = 8.
b) License Fee = 1038.00 .
Then the installment will be 129.75
Then the result should be
A B
1 129
2 129
3 129
4 129
5 129
6 129
7 129
8 130 0r 135.
Explain it so that In this u have to collect the remaining amt for last month as 129 + .75 * 8 = 135.
2013 Nov 14 6:50 AM
Hi,
Go through the following code :
TYPES : BEGIN OF TY_ITAB,
INST TYPE I,
AMOUNT TYPE I,
END OF TY_ITAB.
DATA : TEMP TYPE I,
LAST TYPE P LENGTH 15 DECIMALS 4,
TEMP2 TYPE P LENGTH 15 DECIMALS 4,
COUNT TYPE I,
ITAB TYPE TABLE OF TY_ITAB,
WA_ITAB TYPE TY_ITAB.
PARAMETERS : PA_INSTL TYPE I,
PA_AMT TYPE P LENGTH 15 DECIMALS 4.
TEMP2 = PA_AMT / PA_INSTL. "calculate installment amount with decimals
TEMP = TEMP2. "round off installment amount to remove decimals
LAST = ( TEMP2 - TEMP ) * ( PA_INSTL ). "calculate total of removed decimal values
DO PA_INSTL TIMES.
WA_ITAB-INST = SY-INDEX. "installment number to work area
WA_ITAB-AMOUNT = TEMP. "installment amount to work area
IF SY-INDEX = PA_INSTL. "if last installment then add total of truncated decimals
WA_ITAB-AMOUNT = WA_ITAB-AMOUNT + LAST.
ENDIF.
APPEND WA_ITAB TO ITAB. "insert row to internal table
CLEAR WA_ITAB.
ENDDO.
LOOP AT ITAB INTO WA_ITAB. "display internal table
WRITE : / WA_ITAB-INST,
WA_ITAB-AMOUNT.
ENDLOOP.
OUTPUT :
1 129
2 129
3 129
4 129
5 129
6 129
7 129
8 130
regards,
Ashish Rawat
2013 Nov 14 7:02 AM
Hello,
There are two more field also.
Start date and End date.
01.01.2013 | ||||||||
01.08.2013 | ||||||||
Licence Fee : 8000
Now the Duration is 8 months from 01.01.2013 to 01.08.2013 . now i need to divide 8 months into 8 installments.
Can you tel me how to convert these dates into days and then divide and finaly need to show the dates . I am trying to get the out put in the following way.
Once again thanks alot for your correct solution,
Date of instalment instalment no Licence fee
01.01.2013 1 1000
01.02.2013 2 1000
01.03.2013 3 1000
01.04.2013 4 1000
01.05.2013 5 1000
01.06.2013 6 1000
01.07.2013 7 1000
01.08.2013 8 1000
Thanks and Regards,
Kaushik M
2013 Nov 14 6:55 AM
Hi Kaushik M,
This might help you.
TYPES: BEGIN OF ty_s_itab,
a TYPE decfloat34,
b TYPE decfloat34,
END OF ty_s_itab.
DATA x_itab TYPE ty_s_itab.
DATA count TYPE i.
DATA t_itab TYPE STANDARD TABLE OF ty_s_itab.
DATA val TYPE decfloat34.
PARAMETERS :p_no TYPE decfloat34,
p_div TYPE decfloat34.
val = 0.
count = 1.
WHILE p_no GE count.
x_itab-a = count.
x_itab-b = floor( p_div / p_no ).
val = val + p_div / p_no - floor( p_div / p_no ).
IF count EQ p_no.
x_itab-b = x_itab-b + val.
ENDIF.
APPEND x_itab TO t_itab.
CLEAR x_itab.
count = count + 1 .
ENDWHILE.
LOOP AT t_itab INTO x_itab.
WRITE:/ x_itab-a,' ', x_itab-b.
ENDLOOP.
Thanks and regards,
Mujeeb
2013 Nov 14 7:02 AM
Hello,
There are two more field also.
Start date and End date.
01.01.2013 | ||||||||
01.08.2013 | ||||||||
Licence Fee : 8000
Now the Duration is 8 months from 01.01.2013 to 01.08.2013 . now i need to divide 8 months into 8 installments.
Can you tel me how to convert these dates into days and then divide and finaly need to show the dates . I am trying to get the out put in the following way.
Once again thanks alot for your correct solution,
Date of instalment instalment no Licence fee
01.01.2013 1 1000
01.02.2013 2 1000
01.03.2013 3 1000
01.04.2013 4 1000
01.05.2013 5 1000
01.06.2013 6 1000
01.07.2013 7 1000
01.08.2013 8 1000
Thanks and Regards,
Kaushik M
2013 Nov 14 7:39 AM
If the installments are going to be 1 per month then I don't think that end date is needed.
Refer to the following changed code :
TYPES : BEGIN OF TY_ITAB,
DATE TYPE SY-DATUM,
INST TYPE I,
AMOUNT TYPE I,
END OF TY_ITAB.
DATA : TEMP TYPE I,
LAST TYPE P LENGTH 15 DECIMALS 4,
TEMP2 TYPE P LENGTH 15 DECIMALS 4,
COUNT TYPE I,
ITAB TYPE TABLE OF TY_ITAB,
WA_ITAB TYPE TY_ITAB,
DAT TYPE sy-datum. "temporary variable for date
PARAMETERS : PA_INSTL TYPE I,
PA_AMT TYPE P LENGTH 15 DECIMALS 4,
PA_DATE TYPE SY-DATUM.
TEMP2 = PA_AMT / PA_INSTL. "calculate installment amount with decimals
TEMP = TEMP2. "round off installment amount to remove decimals
LAST = ( TEMP2 - TEMP ) * ( PA_INSTL ). "calculate total of removed decimal values
DAT = PA_DATE. "assign date to date variable
DO PA_INSTL TIMES.
WA_ITAB-DATE = DAT. "assign date
WA_ITAB-INST = SY-INDEX. "installment number to work area
WA_ITAB-AMOUNT = TEMP. "installment amount to work area
IF SY-INDEX = PA_INSTL. "if last installment then add total of truncated decimals
WA_ITAB-AMOUNT = WA_ITAB-AMOUNT + LAST.
ENDIF.
APPEND WA_ITAB TO ITAB. "insert row to internal table
CALL FUNCTION 'RP_CALC_DATE_IN_INTERVAL' "increase date by 1 month
EXPORTING
DATE = dat
DAYS = 0
MONTHS = 1
* SIGNUM = '+'
YEARS = 0
IMPORTING
CALC_DATE = dat
.
CLEAR WA_ITAB.
ENDDO.
LOOP AT ITAB INTO WA_ITAB. "display internal table
WRITE : / WA_ITAB-DATE,
WA_ITAB-INST,
WA_ITAB-AMOUNT.
ENDLOOP.
OUTPUT :
01.01.2013 1 1,000
01.02.2013 2 1,000
01.03.2013 3 1,000
01.04.2013 4 1,000
01.05.2013 5 1,000
01.06.2013 6 1,000
01.07.2013 7 1,000
01.08.2013 8 1,000
Regards,
Ashish Rawat
2013 Nov 14 7:46 AM
Hi Kaushik M,
Please see below code, dynamically we are calculating the number of days between two date and dividing it by the installment count. Hope this will help you.
TYPES: BEGIN OF ty_s_itab,
date TYPE sy-datum,
a TYPE decfloat34,
b TYPE decfloat34,
END OF ty_s_itab.
DATA x_itab TYPE ty_s_itab.
DATA count TYPE i.
DATA count1 TYPE i.
DATA:lv_diff TYPE i.
DATA:lv_diff1 TYPE i.
DATA lv_date TYPE eeind.
DATA t_itab TYPE STANDARD TABLE OF ty_s_itab.
DATA val TYPE decfloat34.
PARAMETERS :p_no TYPE decfloat34,
p_div TYPE decfloat34,
p_date1 TYPE dats OBLIGATORY,
p_date2 TYPE dats OBLIGATORY.
* Calculate days between two date
CALL FUNCTION 'DAYS_BETWEEN_TWO_DATES'
EXPORTING
i_datum_bis = p_date1
i_datum_von = p_date2
IMPORTING
e_tage = lv_diff
EXCEPTIONS
days_method_not_defined = 1
OTHERS = 2.
IF sy-subrc <> 0.
WRITE:/ 'Error'.
ENDIF.
val = 0.
count = 1.
count1 = 0.
WHILE p_no GE count.
lv_diff1 = abs( count1 * ( lv_diff / p_no ) ).
count1 = count1 + 1.
* Conver the date in out format
CALL FUNCTION 'CONVERSION_EXIT_PDATE_OUTPUT'
EXPORTING
input = p_date1
IMPORTING
output = lv_date.
* Calculate the date in future
CALL FUNCTION 'DATE_IN_FUTURE'
EXPORTING
anzahl_tage = lv_diff1
import_datum = lv_date
IMPORTING
export_datum_int_format = x_itab-date.
x_itab-a = count.
x_itab-b = floor( p_div / p_no ).
val = val + p_div / p_no - floor( p_div / p_no ).
IF count EQ p_no.
x_itab-b = x_itab-b + val.
ENDIF.
count = count + 1 .
APPEND x_itab TO t_itab.
CLEAR x_itab.
ENDWHILE.
LOOP AT t_itab INTO x_itab.
WRITE:/ x_itab-date, ' ',x_itab-a,' ', x_itab-b.
ENDLOOP.
Thanks and regards,
Mujeeb
2013 Nov 14 8:16 AM
CALL FUNCTION 'DATE_IN_FUTURE' is not Present in my system Mujeeb.
BR,
Kaushik M
2013 Nov 14 9:06 AM
Hi Kaushik M,
If that is the case in you need to do some calculation like
Use HR_E_NUM_OF_DAYS_OF_MONTH FM to get the number of days in given month after that you need to apply your own logic to calculate the future date.
Thanks and regards,
Mujeeeb
2013 Nov 14 10:46 AM
Hi Kaushik M,
otherwise you can directly add the number of days into date, Please have a look at below code.
TYPES: BEGIN OF ty_s_itab,
date TYPE sy-datum,
a TYPE decfloat34,
b TYPE decfloat34,
END OF ty_s_itab.
DATA x_itab TYPE ty_s_itab.
DATA count TYPE i.
DATA count1 TYPE i.
DATA:lv_diff TYPE i.
DATA:lv_diff1 TYPE i.
DATA lv_date TYPE eeind.
DATA t_itab TYPE STANDARD TABLE OF ty_s_itab.
DATA val TYPE decfloat34.
PARAMETERS :p_no TYPE decfloat34,
p_div TYPE decfloat34,
p_date1 TYPE dats OBLIGATORY,
p_date2 TYPE dats OBLIGATORY.
* Calculate days between two date
CALL FUNCTION 'DAYS_BETWEEN_TWO_DATES'
EXPORTING
i_datum_bis = p_date1
i_datum_von = p_date2
IMPORTING
e_tage = lv_diff
EXCEPTIONS
days_method_not_defined = 1
OTHERS = 2.
IF sy-subrc <> 0.
WRITE:/ 'Error'.
ENDIF.
val = 0.
count = 1.
count1 = 0.
WHILE p_no GE count.
lv_diff1 = abs( count1 * ( lv_diff / p_no ) ).
count1 = count1 + 1.
x_itab-date = p_date1 + lv_diff1.
x_itab-a = count.
x_itab-b = floor( p_div / p_no ).
val = val + p_div / p_no - floor( p_div / p_no ).
IF count EQ p_no.
x_itab-b = x_itab-b + val.
ENDIF.
count = count + 1 .
APPEND x_itab TO t_itab.
CLEAR x_itab.
ENDWHILE.
LOOP AT t_itab INTO x_itab.
WRITE:/ x_itab-date, ' ',x_itab-a,' ', x_itab-b.
ENDLOOP.
Thanks and regards,
Mujeeb
2013 Nov 14 6:58 AM
TYPES : BEGIN OF ty_s,
a TYPE p DECIMALS 2,
b TYPE p DECIMALS 2,
END OF ty_s.
DATA val TYPE p DECIMALS 2.
DATA : x_itab TYPE ty_s,
t_itab TYPE TABLE OF ty_s.
PARAMETERS :p_no TYPE i DEFAULT 1038,
p_div TYPE i DEFAULT 8.
val = p_no DIV p_div .
DO p_div TIMES.
IF p_div EQ sy-index.
val = val + p_no MOD p_div.
ENDIF.
x_itab-a = sy-index.
x_itab-b = val.
APPEND x_itab TO t_itab.
WRITE :/, AT 10 x_itab-a,
AT 20 x_itab-b.
ENDDO. check this..
2013 Nov 14 8:41 AM
data:
lv_amt type p decimals 2,
lv_part type i,
lv_count type i value 1.
lv_amt = '1033.00'.
lv_part = 8.
while lv_count LE lv_part.
lwa_tab-num = lv_count.
if lv_count LT lv_part.
lwa_tab-fee = lv_amt / lv_part.
CALL FUNCTION 'ROUND'
EXPORTING
input = lwa_tab-fee
IMPORTING
OUTPUT = lwa_tab-fee.
lv_sum = lwa_tab-fee.
else.
lwa_tab-fee = lv_amt - lv_sum.
endif.
append lwa_tab-fee to lt_tab-fee.
lv_count = lv_count + 1.
endwhile.
for the date part do the same logic... find difference in the dates using function modules... divide the dates by number of parts (8 here).. and then use function module to add dates.
for example if it is 57 days in between start and end days... find 57/8 = 7.125 (round to 7) so
day 2 = start day + 7
day 3 = start day + (7 x 2)
and... so on and finally
day 8 = end day - day 7.
there are various function modules for dates .. use any one you feel good.
hope this helps