Hi,
I have a table with three NoYes fields.
for each record, only one of those fields can be yes.
Where is the best place to put this validation... Do i need to put this condition on both Insert and update of this table? or validate write.. what is the best way?
if(this.Field1 == NoYes::Yes && (this.Field2 == NoYes::Yes || this.Field3 == NoYes::Yes) || this.Field2 == NoYes::Yes && (this.Field1 == NoYes::Yes || this.Filed3 == NoYes::Yes) || this.Field3 == NoYes::Yes && (this.Field1 == NoYes::Yes || this.Field2 == NoYes::Yes) ) { throw error ("only one field can be true"); }
Thanks for confirming it, Martin.
Mohit Rampal Yes, the statement 'If input bits are the same, then the output will be false(0)' is true for XOR operator. This is what makes it XOR, rather than the normal OR.
But... there is a indeed an error in my code. You're right that the first expression returns 0, therefore the second one will return 1 (because 0 or 1 is 1).
Hi Martin, Thank you for clarifying and agree with your below statement
'It'll be interpreted as (x ^ y) ^ z, i.e. the binary operator is applied to two values, and then the same operator is applied to the result and the remaining operand.'
Just one query, Can you please verify this statement 'If input bits are the same, then the output will be false(0) else true(1).' is true to XOR binary operator
If both statements are true then if input in x, y and z is 1 then output will be 1
(x ^ y) ^ z
(1^1) ^ 1
(0) ^ 1
1
I have tested with creating new table, 3 checkbox and a runnable class and input all checkbox 1 (True) and got output 1 (True).
I have not used this operator before so I'll explore more on this.
As earlier suggested put this code in validate write() of table assuming that this method should call for all the forms/entities where this table is referenced.
Also in another approach, you can create a list with these 3 fields. So once list is created you will loop through it and if it finds more than 1 yes then throw error. Check which is faster.
XOR is binary operator, therefore there is nothing like the "3-input Ex-OR Gate" that the table is for.
x ^ y ^ z is an expression with two binary operators, not an example of an operator taking three values at once. It'll be interpreted as (x ^ y) ^ z, i.e. the binary operator is applied to two values, and then the same operator is applied to the result and the remaining operand.
Hi, I think that's expected behavior of XOR with 3 inputs. If all 3 values are yes then output will be yes.
In this diagram, 0 is False (No) and 1 is True (Yes).
check this out if interested
https://www.electronics-tutorials.ws/logic/logic_7.html
Anyways, agree with Martin to do your code as you want. If you still want to try XOR, you can refactor your code with above details and share how you have done it.
HI Martin,
there is nothing extra in the code, it allows the three fields to be true (it 2 are true, then it doesn't allow me as expected but if three are ticked it allows me)
public boolean validateWrite() { boolean ret; ret = next validateWrite(); if(ret) { NoYesId exactlyOneChecked = this.Field1 ^ this.Field2 ^ this.Field3; if(!exactlyOneChecked) { ret = checkFailed("only one can be ticked"); } } return ret; }
XOR is exclusive OR. It returns 0 if both operands are 1. It's unlikely that you've found a bug in a basic X++ operator, therefore the problem must be in something else than that "XOR Is not working". But OK, let's not waste time with it; do it as you like. Otherwise the solution would be debugging code, instead of just saying that it doesn't work.
Hi Martin,
XOR Is not working because currently it allows the three fields to be set as true.
Only one field can be true from the three fields.
Okay, let me put in a simpler way: Use validateWrite().
validateWrite() is called automatically by forms and data entities, but it needs to be called explicitly (and its return value taken into account) when data is manipulated by code.
André Arnaud de Cal...
291,965
Super User 2025 Season 1
Martin Dráb
230,836
Most Valuable Professional
nmaenpaa
101,156