I have a sheet with a list of company names in column A - some of these company names are present within sheets of different users, who have a tickbox within a column beside these companies.
I want to have a column in my sheet which would tell me whether this company is ticked within one of the user's sheets and if so, put the user's name in the cell next to it. If not, it can remain blank. The likelihood at this time that the tickbox is TRUE for the same company in two different sheets is negligible.
In the sample sheet below, I've used the following formula in cell B2:
=ifs(vlookup(A2,Sheet2!$A$2:$B$11,2,false)=TRUE,"Sam",vlookup(A2,Sheet3!$A$2:$B$11,2,false)=TRUE,"Nick",vlookup(A2,Sheet4!$A$2:$B$11,2,false)=TRUE,"Mike")
It works for the first two conditions, but then it cannot seem to work with the third logical pair. Note that the sample sheet below uses the vlookup across tabs, the actual sheet will be using importrange, but I don't think it should make a difference.
What could be wrong?
Sample sheet here
A More General Problem
To make this more general so others find it useful (which is the whole point of StackOverflow), the general problem can be rephrased as
"How do I search for a value in lists in multiple sheets, and return a
result if there is at least one match?"
Generally, when using VLOOKUP(), QUERY(), or other matching functions, you have to account for any errors through non-matches. Those "move" outwards into the outer functions and can eventually be the reported result, unless explicitly handled. Sometimes, this is less obvious when you sometimes get answers but that's because the outer functions have ignored or not evaluated the matching function.
Therefore, always consider what happens if the matching function returns a N/A and explicitly handle it.
Your Example
In your case, IFS() is simply raising an error whenever VLOOKUP() does not match. However, since IFS() returns the first condition that matches, from left to right in the formula, it doesn't always get around to evaluating one of the non-matching VLOOKUP()s which is why you see it works sometimes.
So, you should explicitly handle the errors with e.g. IFERROR()
My approach was to avoid lookup functions, and just filter the list by those that had filled checkboxes, and then count the occurrence of interest ("Company 1", "Company 2", ...) using COUNTIF(). If the counted total is 1, we have a match, so grab that entry as an element in an array. Otherwise, leave an empty value.
At this point, you could drop the empty elements, and take the first non-empty element (or return a blank), but I opted to list out all of the names.
To get rid of the blanks, I use QUERY() and then JOIN() to make a list of each name. In the case, where nothing matched, and my array was empty, I simply wrap everything in one IFERROR().
=IFERROR(JOIN(", ",QUERY(TRANSPOSE({IF(COUNTIF(FILTER(Sam!A:A,Sam!B:B=TRUE),A2)=1,"Sam",""),IF(COUNTIF(FILTER(Nick!A:A,Nick!B:B=TRUE),A2)=1,"Nick",""),IF(COUNTIF(FILTER(Mike!A:A,Mike!B:B=TRUE),A2)=1,"Mike","")}),"SELECT Col1 WHERE Col1 IS NOT NULL",0)),"")
I found it convenient for your example to rename "Sheet2" as "Sam", "Sheet3" as "Nick", "Sheet4" as "Mike", which is what I think was your original meaning.
The formula can be easily modified to show just the first matching result.
use:
=ARRAYFORMULA(IFNA(VLOOKUP(A2:A, QUERY({
QUERY(Sheet2!A2:B, "select A,B,'Sam'");
QUERY(Sheet3!A2:B, "select A,B,'Nick'");
QUERY(Sheet4!A2:B, "select A,B,'Mike'")},
"where Col2=TRUE"), 3, )))
I am trying to display a button based on a yes/no value. I am using a value rule and have tried 0 and 1, true and false, and InvertResult of nothing.
Does anyone know what the correct value is for assessing a bool? The button should display when the value is true (or not false).
Here is the xml produced and screenshot.
<ValueRule Field="cc_cancloseaswon" Value="Yes" Default="false" InvertResult="false" />
EDIT
The use case is as follows. I have a bool column on the entity to indicate if the button should be visible.
When the correct stage of the BPF in entered, a workflow sets the value to true.
When other stages are entered in the BPF, a workflow sets the value to false:
I believe it would set the correct visibility when the value is true.
The command checker shows it evaluates as false on top of not being visible.
Level up shows the value is true:
I have refreshed to check it has evaluated when the value is definitely set.
When comparing a ValueRule use 0 or 1 as values. Example:
<DisplayRule Id="YourDisplayRuleId">
<ValueRule Field="cc_cancloseaswon" Value="1" />
</DisplayRule>
Also see this article.
Keep in mind in many cases you may need an enable rule instead of a "display rule". Since MS Dynamics 2013 both types of rules hide and show buttons. The main difference is that display rules are evaluated server-side, while enable rules are evaluated client-side. When you need to hide or show buttons as a result of the user's actions on the form, you need to use enable rules, e.g. a CustomRule calling a JavaScript function on the form returning a boolean value.
Be aware, after your ribbondiffxml has been imported and published your browser may keep the previous definition in its cache for some time, even after a page refresh.
The display rule only evaluates attributes available on the form. true is the correct value for a bool, I just needed to add the attribute to the form.
I assumed it would assess non-table data but the ribbon seems to use formContext.data.entity attributes. This only occurred to me when I started writing a custom rule and it was an easy idea to test. The attribute can of course be hidden on the form if it doesn't otherwise need to be there.
If the attribute is not present on the form, it will evaluate as an empty string ''.
I'm using XSLFast and was wondering if the following is possible:
I have a page with static content and one area containing a table that outputs XML-data. The table is set to a specific height so that the page breaks when the height is reached and continues outputting one the next page.
Now,
I want to add another area containing such a table with the exact feature. Is that possible on one side?
I have never used XSLFast, but...
XSL 1.1 allows an fo:simple-page-master to have multiple fo:region-body. (See https://www.w3.org/TR/xsl/#fo_simple-page-master.) I do not know if XSLFast supports it, but with a formatter that supports multiple fo:region-body, you could put the red table and the blue table in separate fo:flow and direct them to the two different fo:region-body. The formatter would then make another page whenever either fo:region-body overflowed.
I have a situation where I'm using the IEditorDataFilter interface within a custom UltraGrid editor control to automatically map values from a bound data source when they're displayed in the grid cells. In this case it's converting guid-based key values into user-friendly values, and it works well by displaying what I need in the cell, but retaining the GUID values as the 'value' behind the scenes.
My issue is what happens when I enable the built-in group by functionality and the user groups by a column using my editor. In that case the group by headers default to using the cell's value, which is the guid in my case, so I end up with headers like this:
Column A: 7F720CE8-123A-4A5D-95A7-6DC6EFFE5009 (10 items)
What I really want is the cell's display value to be used instead so it's something like this:
Column A: Item 1 (10 items)
What I've tried so far
Infragistics provides a couple mechanisms for modifying what's shown in group by rows:
GroupByRowDescriptionMask property of the grid (http://bit.ly/1g72t1b)
Manually set the row description via the InitializeGroupByRow event (http://bit.ly/1ix1CbK)
Option 1 doesn't appear to give me what I need because the cell's display value is not exposed in the set of tokens they provide. Option 2 looks promising but it's not clear to me how to get at the cell's display value. The event argument only appears to contain the cell's backing value, which in my case is the GUID.
Is there a proper approach for using the group by functionality when you're also using an IEditorDataFilter implementation to convert values?
This may be frowned upon, but I asked my question on the Infragistic forums as well, and a complete answer is available there (along with an example solution demonstrating the problem):
http://www.infragistics.com/community/forums/p/88541/439210.aspx
In short, I was applying my custom editors at the cell level, which made them unavailable when the rows were grouped together. A better approach would be to apply the editor at the column level, which would make the editor available at the time of grouping, and would provide the expected behavior.
I'm using an EMF model based on Modisco KDM metamodel. At some point of my Acceleo template I need to iterate over a collection, e.g.:
[for (e: AbstractCodeElement | action.codeElement) separator(', ')][e.generateCode() /]
The action.codeElement is a collection and modisco's kdm.ecore metamodel defines it as non-ordered.
Every time I run my generator, the output is generated on a different order. Cleary the serialized model xmi enforces a specific order, and every model editor (emf default editor, modisco editor) I open the model shows the same order always (matching the order the elements were serialized to the xmi file).
Since I cannot change the kdm.ecore metamodel to make the set ordered, would there be a workaround to get Acceleo to always iterate on the same order?
Thanks in advance
I'm afraid you can't.
Try and cast it to a sequence:
action.codeElement->asSequence()
but I don't think anything guarantees that the sequence you get will always be sorted in the same order.
If the metamodel is made that way, there should be a reason, so either you can contact the metamodel authors to check this reason, or you should sort the result of action.codeElement with some stable criterion:
action.codeElement->sortedBy( some OCL expression)
I don't know of a clean way. I solved the problem by altering the name attribute of a child element so that it was sortable alphabetically in the way I wanted.
I wanted Slots in the same order every time, so I changed the name of each of their "value" child.
The names looked like: "01_id", "02_username", "03_city", ... "10_instructions", "11_contact". I didn't have to change what the "value" elements held, just their name, which I wasn't using for anything anyways. Hope this helps.
[for (s : Slot | instanceSpecification.slot->select(definingFeature.name = 'column')->sortedBy(value->asSequence()->first().name)]
... do work here ...
[/for]