I need help with an Excel formula to extract a value from a string, based on delimiters.
This is the string I would like to extract the first 10 fields from: ES_ABC_FACEBOOK_SocialImage_FACEBOOK_Reach(CPM)_DEM_18-45_Apr19_abc_def_ghi
In other words, I would need to get ES_ABC_FACEBOOK_SocialImage_FACEBOOK_Reach(CPM)_DEM_18-45_Apr19_abc
Bearing in mind that the number of fields (separated by delimiters) may vary in the dataset but that I need to consistently only pick up the first 10 fields and drop however many fields are succeeding the 10th field.
Thanks in advance!
Robin
You could try this:
=LEFT(<your cell>,FIND("||",SUBSTITUTE(<your cell>,"_","||",10))-1)
e.g. =LEFT(A1,FIND("||",SUBSTITUTE(A1,"_","||",10))-1)
The formula finds the 10th underscore, and the gives you all the characters up to it (minus the underscore).
If you need to change how many fields it gives you back, change the 10. The -1 at the end just removes the final underscore. Of note, the || is just a simple set of characters I can't imagine will ever appear in your strings. If it does, something else will need to be selected.
Lastly, if some of your strings will have less than 10 fields, try:
=IF(ISERROR(FIND("||",SUBSTITUTE(<your cell>,"_","||",10))-1),<your cell>,LEFT(<your cell>,FIND("||",SUBSTITUTE(<your cell>,"_","||",10))-1))
This gives you the whole string in the event that there are less than 10 fields.
Hope that helps.
Trying to write a custom data validation formula that would only allow values in the following format: 2-digit year (this can be just 2 numbers), dash ("-"), then a 1 or 2 letter character(s) (would prefer upper case, but would settle for lower case), another dash ("-"), and then a 5-digit number. So the final value looks like: 17-FL-12345 ...or 16-G-00008...
I actually have a but more, but if I could get the above working, that would be terrific. I don't know if there's a way, but it would be great if additionally I could use custom formatting to get the dashes to appear when they are not entered, i.e., user enters "17FL12345" and it gets automatically formatted to "17-FL-12345". Finally, again, this isn't a deal breaker either, but it would also be great if the last 5 digits would add any leading zero's, i.e., the user enters 17-G-8 (or just 17G8) and it gets formatted to 17-G-00008.
Can't use VBA unfortunately. Some potential solutions to similar questions I've viewed include:
https://www.mrexcel.com/forum/excel-questions/615799-data-validation-mixed-numeric-text-formula-only.html
Data VAlidation - Text Length & Character Type
Excel : Data Validation, how to force the user to enter a string that is 2 char long?
Try this:
=AND(ISNUMBER(VALUE(LEFT(A1,2))),MID(A1,3,1)="-",OR(ISNUMBER(FIND(MID(A1,4,1),$C$1)),AND(ISNUMBER(FIND(MID(A1,4,1),$C$1)),ISNUMBER(FIND(MID(A1,5,1),$C$1)))),MID(A1,LEN(A1)-5,1)="-",ISNUMBER(VALUE(RIGHT(A1,5))),OR(LEN(A1)=11,LEN(A1)=10),LEN(A1)-LEN(SUBSTITUTE(A1,"-",""))=2,LEN(A1)-LEN(SUBSTITUTE(A1,"+",""))=0,LEN(A1)-LEN(SUBSTITUTE(A1," ",""))=0)
Assuming, you want to validate A1. I inserted the letters in C1.
Edit:
I edited the original function, to be more secure and left out the Isnumber part and rather went digit by digit.
If you want exceed the 255 limit, you have to slice the function up.
I created 5 functions.
=AND(ISNUMBER(FIND(LEFT(A1),$C$2)),ISNUMBER(FIND(MID(A1,2,1),$C$2)))
=MID(A1,3,1)="-"
=IF(LEN(A1)=10,AND(ISNUMBER(FIND(MID(A1,4,1),$C$1)),MID(A1,5,1)="-"),IF(LEN(A1)=11,AND(ISNUMBER(FIND(MID(A1,4,1),$C$1)),ISNUMBER(FIND(MID(A1,5,1),$C$1)))))
=IF(LEN(A1)=10,MID(A1,5,1)="-",IF(LEN(A1)=11,MID(A1,6,1)="-"))
=IF(LEN(A1)=10,AND(ISNUMBER(FIND(MID(A1,6,1),$C$2)),ISNUMBER(FIND(MID(A1,7,1),$C$2)),ISNUMBER(FIND(MID(A1,8,1),$C$2)),ISNUMBER(FIND(MID(A1,9,1),$C$2)),ISNUMBER(FIND(MID(A1,10,1),$C$2))),IF(LEN(A1)=11,AND(ISNUMBER(FIND(MID(A1,7,1),$C$2)),ISNUMBER(FIND(MID(A1,8,1),$C$2)),ISNUMBER(FIND(MID(A1,9,1),$C$2)),ISNUMBER(FIND(MID(A1,10,1),$C$2)),ISNUMBER(FIND(MID(A1,11,1),$C$2)))))
Set up data validation as on the picture:
I have two string fields of unspecified length, lets call them One and Two. Now I would like to concat them, so that if One = "aaa" and Two = "bbb" the result becomes "aaabbb". Using the Concat fields step seems like a reasonable first guess for how to do this.
However, if I leave the "Length of target field" setting with the standard value of 0 I get no output. If I set it to something large, like 100, I always get extra spaces at the end. I want the resulting field to be as long as necessary to contain One + Two, not longer and not shorter. Is there anyway to do this using this step or some other one?
I have tried using the trim setting, but it trims the input and not the output. Clicking the "Minimal width" button does absolutely nothing.
This seems like it should be a pretty simple standard task. Am I missing something here?
EDIT: My input here is just a few rows from a Data grid step, without anything between the grid and the concat. I tried replacing the grid with a Generate rows step, but I get the same result (both when using fixed length for the generated fields, and when leaving the length fields blank).
My version of Kettle is 5.4.0.1-130. I am running it on a Windows 7 x64 platform.
Do the configuration as shown in the figure. It correctly gives the result as the second figure.
Result:
Used Data Grid step to get data.
The configuration suggested by Marlon Abeykoon works. It also works with type "String" instead of "None".
My problem was not in the Concat fields step, but the Text file output step I used to write the result to a file. It takes its metadata about the fields from the Concat fields step, and inherits the zero length for the field therefore printing zero characters to the text file.
The solution is to go to the "Fields" tab of the output step, and there press "Get fields". That explicitly adds all the fields and their metadata to the list, so you can change the lenght field of the output field from the concat step to be empty instead of 0.
I have : <xp:repeat id="repeatColor" value="#{productcolors}"
var="rowData" indexVar="rownum" >
PROBLEM : rownum goes from 0 to the last correct value, but rowData is always the same
This repeat control is bound to a view "productcolors" , a view with a key on product code.
This view has a first column with the product code , ascending (for the key).
It also has a second and a third column with ascending multiple value fields.(second is framecolor, third is upholstery color)
The idea is that the repeat control goes through the different colors for the selected product, but it only shows the first one and does that the number of times (rownum increases correctly)that there are colors for the selected product.
EDIT :
So I have for example a product called "A" available in framecolors "1" "2" and "3"
When I am using the repeat control rownum changes from 0 to 2 but rowData is always the reference of framecolor "1". I don't know why rowData isn't changing.
When I use rowData.getUniversalID() I am getting 3 times the ID of the document containing the multiple value field with the 1 , 2 and 3 in it, which is I guess normal ? But how can I get a handle to those different values inside it ?
SECOND EDIT
I tried :
var testje:string = rowData.getUniversalID();
var db:NotesDatabase = session.getDatabase(database.getServer(),"product/colors.nsf");
var doc:NotesDocument = db.getDocumentByUNID(testje);
test = doc.getItemValueString("colorUpholstery");
The result is that "test" only holds the first item of the multiple value field "colorUpholstery" .
How is that possible ? I thought I would get the complete value of the "colorUpholstery" field ?
Maybe because I only have reader access(Publicaccess) to the colors.nsf database ?
It would be nice to see a little more code... like what's inside the repeat.. just to get a better feel for it to go along with your description of the Notes View.
rowData should be an XSPViewEntry... basically a NotesViewEntry... I suggest you first do something like rowData.getDocument().getUniversalId() to make sure it is iterating the documents correctly. I'm sure it is.
It sounds like you're trying to do something with a multi-value field.. are you also setting the view to use display multiple values as row entries? or whatever that setting is? That might get dicey if that's turned on. Not sure.
Again I'm not totally following what what the goal is but I would first test to make sure it is actually repeating the expected documents. then it's all about fine tuning.
EDIT: Ok... some thoughts based on your additional info:
I suspect that your problem is the use of the view setting "show multiple values as separate entries". Each is the same document really. So that's likely not helping you here. I'm still a little fuzzy on exactly what you want for the output. Is this from a "view page" of maybe products? a "form page" of a single product?
I ASSUME you want all the colors for a single product? And this is a lookup view right? so you're on your product "document" and now you want to list all the colors?
Assuming so...
Use SSJS and the object model. Do a lookup to find the SINGLE document that has the multi-value color field for your current product. then return to a repeat control something like:
lookupDoc.getItemValue("colorField")
I'm not 100% sure that's the correct syntax. The point is you can send a multi-value field to a repeat control and it will repeat it. Much easier then trying to use view tricks.
If your goal is to have a Repeat of multiple products.. and in side each "row" to show all the available colors then you're looking to have a nested repeat really... The outer repeat (outerData) to iterate over all the main products and inside that another repeat (innerData) for the colors. Inside that repeat code you use the "outerData" to get the multi-value field. Something like:
outerData.getDocument().getItemValue("colorField")
Assuming I'm understanding you correctly these are my suggestions.
I did do an example of nested repeats like this on an early NotesIn9. I believe it was this one: http://notesin9.com/index.php/2010/03/30/notes-in-9-show-14-repeats-repeated/
Maybe that will help.
Second Edit Response:
Based on the code you added you're using "doc.getItemValueString()" By design that will only get you the first value of a multi-value field. This is the same as saying in LotusScript:
doc.colorUpholstery(0)
or the less commonly used
doc.getItemValue("colorUpholstery")(0) ' I might have that wrong. I never really used it
Again if you want to make a list of all the colors I'd use a repeatControl and pass in:
doc.getItemValue("colorUpholstery") then your "rowData" for that repeat will be each value. I've seen others avoid the repeat and doing some javascript explode or implode type thing I believe. using "\N" or something as a separator for a new line. I just use a repeat. Easer for me to understand.
Again I THINK everything you need really is in NotesIn9 episode 14.
I have a ListBox where I need to restrict the number of options selected to two. I'm using 8.5.2 so cannot use the SSJS custom validator, but I can use a Java validator. The Java validator received the submittedValue as a comma-separated String.
The problem occurs if a value contains a comma. In that case, if I split the submittedValue String on commas, my code will think more options have been selected than actually have been.
When the value is written back into the underlying Notes Document, the conversion to getValue() has correctly mapped values. So if getSubmittedValue() was a single option from the ListBox that contained a comma, getValue() gives me a single element rather than two elements.
My query is how to reproduce the getSubmittedValue() to getValue() conversion, to correctly work out how many options have been selected.
Paul, you actually can control the commas. The option has a display string and a value. You could substitute the comma for e.g. # and later before saving it back check if you have a # at the same position the display values have a , and save it then.
It's a lot more work - so not smart.
The other option: take the possible values out one by one:
sort them by size, longest first (this way you avoid having a value that is contained in another value to screw up (e.g. "Red boat" vs "boat"
take them out of the return string (if removal worked, then you have one, stop when you hit the 3rd)
.... but probably the easiest on is to do that in a little client side JavaScript counting the checked=checked values