Wie verhindere ich Endlosschleife bei abhängigen berechneten Feldern?
Corinna Hochheim
Ich habe zwei neue UDFs im Rechnungsformular angelegt: VK Brutto und Rabatt. Wenn der Benutzer einen Wert in eins der beiden Felder schreibt, soll auch das andere neu berechnet werden.Folgendes Beispiel:
VK Brutto hat den Wert 15,50
Rabatt hat den Wert 0,000
Wenn der Benutzer im Feld Rabatt 50,0000 einträgt, soll der VK Brutto auf 7,75 gesetzt werden.
Wenn der Benutzer im Feld VK Brutto 13,95 einträgt, soll der Rabatt auf 10,0000 gesetzt werden.
Beide Regeln funktionieren auch unabhängig voneinander, nur leider lösen in Kombination eine Endlosschleife aus!
Wie kann ich dies verhindern?????
Bastian Hofmeister
Hi Corinna,Kannst du mal deinen Code posten, damit wir sehen, wie du die Rule aufgebaut hast?
Corinna Hochheim
Hallo,bei Value Changed im Feld U_Rabatt wird folgender Code durchlaufen:
Dim current_row As Integer
Dim gross_price As String
Dim discount_price As Double
Dim discount As Double
current_row = pval.Row - 1
gross_price = Matrix.GetFromUID(pVal.Form, "38").GetDisplayValue("U_VK_Brutto", current_row)
discount_price = Matrix.GetFromUID(pVal.Form, "38").GetDisplayValue("U_VK_Brutto_Rabatt", current_row)
discount = discount_price * 100 / gross_price
Matrix.GetFromUID(pVal.Form, "38").SetDisplayValue("U_Rabatt", current_row, discount.ToString())
bei Value Changed im Feld U_VK_Brutto_Rabatt soll folgendes passieren:
Dim current_row As Integer
Dim gross_price As String
Dim discount As String
Dim discount_price As Double
current_row = pval.Row - 1
gross_price = Matrix.GetFromUID(pVal.Form, "38").GetDisplayValue("U_VK_Brutto", current_row)
discount = Matrix.GetFromUID(pVal.Form, "38").GetDisplayValue("U_Rabatt", current_row)
discount_price = gross_price * (100 - discount) / 100
Matrix.GetFromUID(pVal.Form, "38").SetDisplayValue("U_VK_Brutto_Rabatt", current_row, discount_price.ToString())
Also entweder wird Originalpreis x Rabatt = Rabattierter Preis oder Rabattier Preis / Originalpreis = Rabatt gerechnet.
Paolo Manfrin
Hi Corinna,you could use another UDF as "traffic light"
For example call it FirstWrite
in U_VK_Brutto_Rabatt you do something like
if (FirstWrite=="")
{
// FirstWrite="X"
// calculate and write U_Rabatt
}
and in U_Rabatt you do something like
if (FirstWrite=="")
{
// FirstWrite="X"
// calculate and write U_VK_Brutto_Rabatt
}
doing that you avoid the infinite loop.
Another option without the UDF would be to calculate U_Rabatt whenever you change U_VK_Brutto_Rabatt and write in Rabatt only if the current value in Rabatt is different from the calculated one.
You do the same once you write in U_VK_Brutto_Rabatt, before changing U_Rabatt you calculate U_Rabatt and you write the value only if the new value that you're gonna write is different from the one alredy written in U_Rabatt.
Pratically you check if the value has been already written before... avoiding the loop.
Corinna Hochheim
Hi Paolo,thanks a lot for your solution proposals. I meanwhile find out that one of my calculations was wrong and therefore triggered the infinite loop!
discount = discount_price * 100 / gross_price
has certainly to be replaced by
discount = 100 - ( discount_price * 100 / gross_price )
Then SAP automatically stops in the second loop, as the value is not changed any more.
However, because of rounding, there are rare scenarios when the double calculation does not lead to the same result, so that SAP runs a third loop and then adjusts the discount or the discount price to a value that was not entered by the user. For this reason I have implemented your solution proposal with the indicator flag. So I can avoid an automatic adjustment in case of rounding issues.
So this the coding that works perfect now:
In case of changing the U_VK_Brutto_Rabatt the following is done:
Dim current_row As Integer
Dim indicator As String
Dim discount_price As Double
Dim gross_price As Double
Dim discount As Double
current_row = pval.Row - 1
indicator = Matrix.GetFromUID(pVal.Form, "38").GetValue("U_Intern", current_row)
If indicator <> "" Then
Matrix.GetFromUID(pVal.Form, "38").SetValue("U_Intern", current_row, "")
Else
Matrix.GetFromUID(pVal.Form, "38").SetValue("U_Intern", current_row, "X")
discount_price = Matrix.GetFromUID(pVal.Form, "38").GetDisplayValue("U_VK_Brutto_Rabatt", current_row)
gross_price = Matrix.GetFromUID(pVal.Form, "38").GetDisplayValue("U_VK_Brutto", current_row)
discount = 100 - ( discount_price * 100 / gross_price )
Matrix.GetFromUID(pVal.Form, "38").SetDisplayValue("U_Rabatt", current_row, discount.ToString())
End If
In case of changing the U_Rabatt the following is done:
Dim current_row As Integer
Dim indicator As String
Dim gross_price As Double
Dim discount As Double
Dim discount_price As Double
current_row = pval.Row - 1
indicator = Matrix.GetFromUID(pVal.Form, "38").GetValue("U_Intern", current_row)
If indicator <> "" Then
Matrix.GetFromUID(pVal.Form, "38").SetValue("U_Intern", current_row, "")
Else
Matrix.GetFromUID(pVal.Form, "38").SetValue("U_Intern", current_row, "X")
gross_price = Matrix.GetFromUID(pVal.Form, "38").GetDisplayValue("U_VK_Brutto", current_row)
discount = Matrix.GetFromUID(pVal.Form, "38").GetDisplayValue("U_Rabatt", current_row)
discount_price = gross_price * (100 - discount) / 100
Matrix.GetFromUID(pVal.Form, "38").SetDisplayValue("U_VK_Brutto_Rabatt", current_row, discount_price.ToString())
End If
Paolo Manfrin
Very good Corinna!Thanks for sharing your solution.
Cheers,
paolo
0
Please sign in to leave a comment.
Comments
0 comments