Only first pass trough logic gates raising a flag, second deactivating it, others doing nothing - boolean-logic

I would like to model a bitarray of flags, where only the first pass through a logical expression sets a flag, but the second pass (computing with the previous state) deactivates the flag and all other passes do nothing to it.
I cannot think of a right combo of the previous state, the right logical expression and a second input (0/1).
bitarray[i] = operand(bitarray[i], value_making_a_change)
Desired value after the 1. pass: bitarray[i] = boolean_value.
Desired value after the second pass: bitarrayp[i] = neg(boolean_value).
Desired value after every consequential pass: bitarrayp[i] = neg(boolean_value).
I think I could just test the value, but my bitarray could get quite large, so I would not want to do that for every index. Is there a standard logic gate/expression I could use?
I tried just using XOR(old_value, 1), but that changes the value back and forth:
value = 0
value = XOR(value, 1) = XOR(0, 1) = 1
value = XOR(value, 1) = XOR(1, 1) = 0
value = XOR(value, 1) = XOR(0, 1) = 1
...

Related

SSRS multiple iif statements rounds instead of keeping 2 decimal calculation

I have the following statement in a calculated field that will only return whole numbers instead of a 2 decimal dollar amount. If I only use one of the 3 iif conditions it works fine but as soon as I add the second or all 3 it will not return a decimal value. Ive also tried all 3 iif conditions separaately and they all work. It appears to be just the OR's causing the issue???
=
(iif ((Fields!loc.Value = "C08") OR (Fields!loc.Value = "C09"), Fields!price1.Value, Fields!price1.Value - Fields!price2.Value) )
OR
(iif ((Fields!loc.Value = "C33") OR (Fields!loc.Value = "C32") OR (Fields!loc.Value = "C10") OR (Fields!loc.Value = "C30"), 0, Fields!price1.Value - Fields!price2.Value) )
OR
(iif (Fields!price1.Value = 0, 0, Fields!price1.Value - Fields!price2.Value))
You can't write and IIF like that, you would need to nest you IIFs which would get a bit messy.
You might find it easier to use a SWITCH statement which is a bit easier to read.
I might not have understood your logic properly but it should be close enough. Note that the first expression that returns true is what will get returned so in thsi case I have assume that if price1 is 0 then the returned value will always be zero, if this is incorrect, just re-order the expression pairs
=SWITCH(
Fields!price1.Value = 0, 0,
Fields!loc.Value = "C08" OR Fields!loc.Value = "C09", Fields!price1.Value,
Fields!loc.Value = "C33" OR Fields!loc.Value = "C32" OR Fields!loc.Value = "C10" OR Fields!loc.Value = "C30", 0,
True, Fields!price1.Value - Fields!price2.Value
)
This reads... "If price1 is zero then return 0" else "if loc is C08 or C09 return price1" else "if loc is C33, C32, C10 or C30 then return 0". Finally, if no previous test return true, then return price1-price2 .
The final True acts like and else
This could be simplified but I wanted to leave it as close to your original attempt as I could.

Update planned order - two committed modifications, only one saved

I need to update two information on one object: the quantity (PLAF-gsmng) and refresh the planned order via the module function 'MD_SET_ACTION_PLAF'.
I successfully find a way to update each data separately. But when I execute the both solutions the second modification is not saved on the database.
Do you know how I can change the quantity & set the action on PLAF (Planned order) table ?
Do you know other module function to update only the quantity ?
Maybe a parameter missing ?
It's like if the second object is locked (sm12 empty, no sy-subrc = locked) ... and the modification is not committed.
I tried to:
change the order of the algorithm (refresh and after, change PLAF)
add, remove, move the COMMIT WORK & COMMIT WORK AND WAIT
add DEQUEUE_ALL or DEQUEUE_EMPLAFE
This is the current code:
1) Read the data
lv_plannedorder = '00000000001'
"Read PLAF data
SELECT SINGLE * FROM PLAF INTO ls_plaf WHERE plnum = lv_plannedorder.
2) Update Quantity data
" Standard configuration for FM MD_PLANNED_ORDER_CHANGE
CLEAR ls_610.
ls_610-nodia = 'X'. " No dialog display
ls_610-bapco = space. " BAPI type. Do not use mode 2 -> Action PLAF-MDACC will be autmatically set up to APCH by the FM
ls_610-bapix = 'X'. " Run BAPI
ls_610-unlox = 'X'. " Update PLAF
" Customize values
MOVE p_gsmng TO ls_plaf-gsmng. " Change quantity value
MOVE sy-datlo TO ls_plaf-mdacd. " Change by/datetime, because ls_610-bapco <> 2.
MOVE sy-uzeit TO ls_plaf-mdact.
CALL FUNCTION 'MD_PLANNED_ORDER_CHANGE'
EXPORTING
ecm61o = ls_610
eplaf = ls_plaf
EXCEPTIONS
locked = 1
locking_error = 2
OTHERS = 3.
" Already committed on the module function
" sy-subrc = 0
If I go on the PLAF table, I can see that the quantity is edited. It's working :)
3) Refresh BOM & change Action (MDACC) and others fields
CLEAR ls_imdcd.
ls_imdcd-pafxl = 'X'.
CALL FUNCTION 'MD_SET_ACTION_PLAF'
EXPORTING
iplnum = lv_plannedorder
iaccto = 'BOME'
iaenkz = 'X'
imdcd = ls_imdcd
EXCEPTIONS
illegal_interface = 1
system_failure = 2
error_message = 3
OTHERS = 4.
IF sy-subrc = 0.
COMMIT WORK.
ENDIF.
If I go on the table, no modification (only the modif. of the part 2. can be found on it).
Any idea ?
Maybe because the ls_610-bapco = space ?
It should be possible to update planned order quantity with MD_SET_ACTION_PLAF too, at least SAP Help tells us so. Why don't you use it like that?
Its call for changing the quantity should possibly look like this:
DATA: lt_acct LIKE TABLE OF MDACCTO,
ls_acct LIKE LINE OF lt_acct.
ls_acct-accto = 'BOME'.
APPEND lt_acct.
ls_acct-accto = 'CPOD'.
APPEND lt_acct.
is_mdcd-GSMNG = 'value' "updated quantity value
CALL FUNCTION 'MD_SET_ACTION_PLAF'
EXPORTING
iplnum = iv_plnum
iaenkz = 'X'
IVBKZ = 'X'
imdcd = is_mdcd "filled with your BOME-related data + new quantity
TABLES
TMDACCTO = lt_accto
EXCEPTIONS
illegal_interface = 1
system_failure = 2
error_message = 3.
So there is no more need for separate call of MD_PLANNED_ORDER_CHANGE anymore and no more problems with update.
I used word possibly because I didn't find any example of this FM call in the Web (and SAP docu is quite ambiguous), so I propose this solution just as is, without verification.
P.S. Possible actions are listed in T46AS table, and possible impact of imdcd fields on order can be checked in MDAC transaction. It is somewhat GUI equivalent of this FM for single order.

SAS - formula for creation of one column from another

My problem is following - I am creating a column (diskont_faktor) from another one (disc_pc_nonann) with the formula for creation differing based on the row number.
for row #1 the function is diskont_faktor = 1/disc_pc_nonann;
for row #2 to n the function is diskont_faktor = diskont_faktor(t-1)/disc_pc_nonann;
I tried following code:
data soubor2;
set srv.data;
disc_pc_nonann = (1+DISC_PC/100)**(1/12);
if _n_ = 1 then diskont_faktor = 1/disc_pc_nonann;
else diskont_faktor = lag1(diskont_faktor)/disc_pc_nonann;
run;
But SAS does not calculate values for rows > 1.
Is there some specific reason why function lag does not work in this setting of code ?
I tried even this version without success:
data soubor2;
set srv.data;
disc_pc_nonann = (1+DISC_PC/100)**(1/12);
if _n_ = 1 then diskont_faktor = 1/disc_pc_nonann;
else do; y=lag1(diskont_faktor);
diskont_faktor = y/disc_pc_nonann;
end;
run;
Thank you for any advice what I am doing wrong.
The LAG() function does not return the value from the previous observation. Instead it returns the previous value from the stack that it generates as it it is called. So by only executing the lag() for some of the observations you are not properly stacking the values.
One easy way to work around this is to place the value of the LAG() function call into a variable. That way it runs for every observation so it always returns the previous value. You can then conditionally reference the variable if you want without interrupting the stream of values for the LAG() function.
lag_diskont_faktor=lag(diskont_faktor);
if _n_ = 1 then diskont_faktor = 1/disc_pc_nonann;
else diskont_faktor = lag_diskont_faktor/disc_pc_nonann;
But for your problem it looks like you do not really need to use LAG(). You can just use RETAIN to prevent SAS from setting the new variable to missing when it starts the next iteration of the DATA step.
retain diskont_faktor;
if _n_ = 1 then diskont_faktor = 1/disc_pc_nonann;
else diskont_faktor = diskont_faktor/disc_pc_nonann;
You could even set the initial value for the variable in the RETAIN statement and simplify the code.
retain diskont_faktor 1;
diskont_faktor = diskont_faktor/disc_pc_nonann;
You need to initialize your variable diskont_faktor at the start of your program, so add an retain diskont_faktor; at the start.
The first call of lag1 returns you a . , because the queue is empty at that time, so for _n_ = 2 it would return nothing but store your value from _n_= 1 in the queue. _n_ = 3 should work but store your empty result from _n_=2 in the queue. Because for n=2 you had no result, _n_= 4 will return nothing again. This goes on and on, so that you have results for odd _n_ and no result for even _n_.
So i dont know how to solve this whith lag,
but I can provide you an alternative solution without lag:
data soubor2 (drop=diskont_faktor_old);
retain diskont_faktor_old;
set srv.data;
disc_pc_nonann = (1+DISC_PC/100)**(1/12);
if _n_ = 1 then diskont_faktor = 1/disc_pc_nonann;
else diskont_faktor = diskont_faktor_old/disc_pc_nonann;
diskont_faktor_old=diskont_faktor;
run;

SSRS Row Visibility

I am using the Switch function in Reporting Services to determine the visibility of a row. It happens that I am using more that one column or field to test my expression like so:
=Switch(Parameters!View.Value = "Green" AND Fields!Tax.Value = "N",TRUE,Parameters!View.Value = "Current" AND Fields!PastVal.Value = 0 AND Fields!DatePay.Value = 0 AND Fields!Comment.Value = 0,True)
With the expression above, I want that if the first part is true, the row should be hidden likewise for the second part of the expression, I want to hid a row when all the conditions are met. But this not yielding the desired result.
I equally tried with another expression like so:
=IIF(Parameters!View.Value = "Green" AND Fields!Tax.Value = N",False, IIF(Parameters!View.Value = "Current" AND Fields!PastVal.Value = 0 AND Fields!DatePay.Value = 0 AND Fields!Comment.Value = 0,True,False))
That still did not work.
I anticipate your help. Thank you
If I follow you correctly, I think putting both conditions in an IIF and separating them with an "OR" will work:
=IIF( (Parameters!View.Value = "Green" AND Fields!Tax.Value = "N") OR (Parameters!View.Value = "Current" AND Fields!PastVal.Value = 0 AND Fields!DatePay.Value = 0 AND Fields!Comment.Value = 0) ),True,False)

Correlate 2 columns in SQL

SELECT ica.CORP_ID, ica.CORP_IDB, ica.ITEM_ID, ica.ITEM_IDB,
ica.EXP_ACCT_NO, ica.SUB_ACCT_NO, ica.PAT_CHRG_NO, ica.PAT_CHRG_PRICE,
ica.TAX_JUR_ID, ica.TAX_JUR_IDB, ITEM_PROFILE.COMDTY_NAME
FROM ITEM_CORP_ACCT ica
,ITEM_PROFILE
WHERE (ica.CORP_ID = 1000)
AND (ica.CORP_IDB = 4051)
AND (ica.ITEM_ID = 1000)
AND (ica.ITEM_IDB = 4051)
AND ica.EXP_ACCT_NO = ITEM_PROFILE.EXP_ACCT_NO
I'm trying basically say since the exp account code is '801500' then the Name should return "Miscellaneous Medic...".
It seems as if what you are showing is not possible. Have you edited the data in the editor??? You are joining using ica.EXP_ACCT_NO = ITEM_PROFILE.EXP_ACCT_NO . Therefore, every entry with EXP_ACCT_NO = 801500, should also have the same COMDTY_NAME.
However, it could be the case that your IDs are not actually numbers and that they are strings with whitespace (801500__ vs 801500 ). But since you are not performing a left-outer join, it would also mean you have an entry in ITEM_PROFILE with the same whitespace.
You also need to properly normalize your table data (unless this is a view) but it still means you have erroneous data.
Try to perform the same query, but using the TRIM function to remove whitespace: https://stackoverflow.com/a/6858168/1688441 .
Example:
SELECT ica.CORP_ID, ica.CORP_IDB, ica.ITEM_ID, ica.ITEM_IDB,
ica.EXP_ACCT_NO, ica.SUB_ACCT_NO, ica.PAT_CHRG_NO, ica.PAT_CHRG_PRICE,
ica.TAX_JUR_ID, ica.TAX_JUR_IDB, ITEM_PROFILE.COMDTY_NAME
FROM ITEM_CORP_ACCT ica
,ITEM_PROFILE
WHERE (ica.CORP_ID = 1000)
AND (ica.CORP_IDB = 4051)
AND (ica.ITEM_ID = 1000)
AND (ica.ITEM_IDB = 4051)
AND trim(ica.EXP_ACCT_NO) = trim(ITEM_PROFILE.EXP_ACCT_NO);