Hello all,
I am struggling to find a valid_if expression, which to push the user to fill a form field with "Pascal Case" method only:
Example: Correct should be - "Samuel Smith Smith". The wrong must be: "Samuel smith Smith".
Every new word (it will be used for the customer name field) must start with the capital letter.
I found a way to push the users to use only Upper case, but with this one I stucked.
Thanks in advance.
Solved! Go to Solution.
With two words I have used this method with the Valid_IF which checks the first upper letter and small letters after that.
AND(
FIND(
UPPER(LEFT(INDEX(SPLIT([_THIS]," "),1),1))&LOWER(MID(INDEX(SPLIT([_THIS]," "),1),2,10)),
INDEX(SPLIT([_THIS]," "),1)
)
>0,
FIND(
UPPER(LEFT(INDEX(SPLIT([_THIS]," "),2),1))&LOWER(MID(INDEX(SPLIT([_THIS]," "),2),2,10)),
INDEX(SPLIT([_THIS]," "),2)
)
>0
)
@MultiTech This came from AleksiAI 😉
Thanks,
This is what I was able to do with your help. It it almost as a PROPER function and works for 1 word OR 2 words OR 3 words:
OR(AND(
FIND(
UPPER(LEFT(INDEX(SPLIT([_THIS]," "),1),1))&LOWER(MID(INDEX(SPLIT([_THIS]," "),1),2,15)),
INDEX(SPLIT([_THIS]," "),1)
)
>0,COUNT(SPLIT([_THIS]," "))=1),
AND(
FIND(
UPPER(LEFT(INDEX(SPLIT([_THIS]," "),2),1))&LOWER(MID(INDEX(SPLIT([_THIS]," "),2),2,15)),
INDEX(SPLIT([_THIS]," "),2)
)
>0,COUNT(SPLIT([_THIS]," "))=2),
AND(
FIND(
UPPER(LEFT(INDEX(SPLIT([_THIS]," "),3),1))&LOWER(MID(INDEX(SPLIT([_THIS]," "),3),2,15)),
INDEX(SPLIT([_THIS]," "),3)
)
>0,COUNT(SPLIT([_THIS]," "))=3)
)
Thanks again,
BR
Hi @e4omir
What about:
SWITCH(COUNT(SPLIT([_THIS], " ")),
1,
FIND( LEFT([_THIS],1) , UPPER( LEFT([_THIS],1) ) ) = 1,
2,
AND(
FIND( LEFT(INDEX(SPLIT([_THIS]," "),1),1) , UPPER( LEFT(INDEX(SPLIT([_THIS]," "),1),1) ) ) = 1,
FIND( LEFT(INDEX(SPLIT([_THIS]," "),2),1) , UPPER( LEFT(INDEX(SPLIT([_THIS]," "),2),1) ) ) = 1
),
3,
AND(
FIND( LEFT(INDEX(SPLIT([_THIS]," "),1),1) , UPPER( LEFT(INDEX(SPLIT([_THIS]," "),1),1) ) ) = 1,
FIND( LEFT(INDEX(SPLIT([_THIS]," "),2),1) , UPPER( LEFT(INDEX(SPLIT([_THIS]," "),2),1) ) ) = 1,
FIND( LEFT(INDEX(SPLIT([_THIS]," "),3),1) , UPPER( LEFT(INDEX(SPLIT([_THIS]," "),3),1) ) ) = 1
),
[and so on],
FALSE (this is the default result)
)
For reference:
Inspired by this:
EDIT:
minor correction for adding the default result to the SWITCH() expression.
Hi Aurelien,
It works for checking the First letter of each new word, however it is possible to be filled:
example - "SaMuel SmiTH SMITH".
The Pascal case basically is capital letter only for the first letter of the word, the rest letters should be in lower case. The excel function for this is PROPER, but the appsheet does not have it.
Thank you very much for your help.
BR
Complicated, as you've no doubt found so far.
----------------------------------------------------------------------------------------------------------------------
[Appster]
In AppSheet, there is no built-in function for the PROPER or Pascal case format. But, you can use a combination of other functions to achieve your goal.
You can first split the text at the spaces, then capitalize each separate word, and finally combine the words back together. Here's a general formula you can use as a starting point:
TEXT(
CONCATENATE(
UPPER(LEFT([Your_Column], 1)),
LOWER(MID([Your_Column], 2, LEN([Your_Column]) - 1))
)
)
This formula first separates the first letter of the input and turns it to uppercase, then extracts the rest of the string, turns it to lowercase, and finally combines them back together.
Here is where it gets more complicated: if you have more than one word (with spaces involved), then the formula would have to be enhanced significantly.
Unfortunately manipulating text in AppSheet to the degree needed for this functionality would be difficult, as you need to cycle through each word in your string and apply the formula to each.
In many cases, it might be more efficient to handle this kind of transformation in the data source (like Google Sheets or Excel) before fetching the data into AppSheet.
For specifically enforcing the Pascal case, you might want to create an assessment logic that checks if the first character in the string is not equal to its capital counterpart then shows an error message to the user. Keep in mind that AppSheet does not have the capability to transform a text string into Pascal case automatically.
[ME]
What if I wanted to check the first 4 words? Is there a way to accomplish this?
Yes, it is definitely possible to check the first four words within AppSheet. Here is how you can do it using a rather slightly more complex formula:
TEXT(
CONCATENATE(
UPPER(LEFT(INDEX(SPLIT([Your_Column], " "), 1), 1)),
LOWER(MID(INDEX(SPLIT([Your_Column], " "), 1), 2))
)
) & " " &
TEXT(
CONCATENATE(
UPPER(LEFT(INDEX(SPLIT([Your_Column], " "), 2), 1)),
LOWER(MID(INDEX(SPLIT([Your_Column], " "), 2), 2))
)
) & " " &
TEXT(
CONCATENATE(
UPPER(LEFT(INDEX(SPLIT([Your_Column], " "), 3), 1)),
LOWER(MID(INDEX(SPLIT([Your_Column], " "), 3), 2))
)
) & " " &
TEXT(
CONCATENATE(
UPPER(LEFT(INDEX(SPLIT([Your_Column], " "), 4), 1)),
LOWER(MID(INDEX(SPLIT([Your_Column], " "), 4), 2))
)
) & " " &
IF(COUNT(SPLIT([Your_Column], " ")) >= 5, MID([Your_Column], FIND(INDEX(SPLIT([Your_Column], " "), 5), [Your_Column]), LEN([Your_Column])), "")
Please replace `[Your_Column]` with the name of the actual column containing your data.
This formula splits up the first four words in your column ([Your_Column]), and then for each word, it changes the first character to uppercase and the rest of the word to lowercase.
Notice the "IF" at the end, which checks if there are more than 4 words. If there are 5 or more words in the text string, this piece will return everything starting with the 5th word (in the original case).
This solution is still a bit complicated and might be resource intensive if used on large texts, thus you should consider the balance between usability and formula complexity.
Also this does not force the Pascal case, but it would check if the first characters of initial four words are uppercase and rest lowercase. You might want to contact Matt at MultiTech Visions for additional support in optimizing your formula based on your specific requirements.
--------------------------------------------------------------------------------------------------------------------------
Thanks for the shout out my little Ai friend! (^_^) 🤖🧠💪
Taking a critical look at that last formula... I'm not sure if the MID() would work.
--------------------------------------------------------------------------------------------------------------------------
[ME]
MID() requires that you specify the 3rd parameter; the length of text to select. Here's the documentation:
Syntax
MID(text, begin-at, length)
text - Any textual type.
begin-at - Number that specifies the position, equal to or greater than 1, of the first character in text to return. A non-Number value may be accepted but may produce unexpected results.
length -Non-negative number of characters from text to return. A non-Number value may be accepted but may produce unexpected results.
[Appster]
You're right, I apologize for the oversight. For the MID() function, the third argument, which signifies the length of the substring, must be specified.
Here is the revised formula for the first 4 words ensuring the third parameter of MID() function, the length, is properly defined:
TEXT(
CONCATENATE(
UPPER(LEFT(INDEX(SPLIT([Your_Column], " "), 1), 1)),
LOWER(MID(INDEX(SPLIT([Your_Column], " "), 1, MID(LEN(INDEX(SPLIT([Your_Column], " "), 1))-1)))
)
) & " " &
TEXT(
CONCATENATE(
UPPER(LEFT(INDEX(SPLIT([Your_Column], " "), 2), 1)),
LOWER(MID(INDEX(SPLIT([Your_Column], " "), 2, MID(LEN(INDEX(SPLIT([Your_Column], " "), 2))-1)))
)
) & " " &
TEXT(
CONCATENATE(
UPPER(LEFT(INDEX(SPLIT([Your_Column], " "), 3), 1)),
LOWER(MID(INDEX(SPLIT([Your_Column], " "), 3, MID(LEN(INDEX(SPLIT([Your_Column], " "), 3))-1)))
)
) & " " &
TEXT(
CONCATENATE(
UPPER(LEFT(INDEX(SPLIT([Your_Column], " "), 4), 1)),
LOWER(MID(INDEX(SPLIT([Your_Column], " "), 4, MID(LEN(INDEX(SPLIT([Your_Column], " "), 4))-1)))
)
) & " " &
IF(COUNT(SPLIT([Your_Column], " ")) >= 5, SUBSTR([Your_Column], LEN(LEFT([Your_Column], FIND(INDEX(SPLIT([Your_Column], " "), 5), [Your_Column]))+1), "")
This formula splits up the first four words in your string, then for each word, it changes the first character to uppercase and the rest of the character in that word to lowercase.
If there are 5 or more words in the text string, this piece of the formula will return everything starting with the 5th word onward, in the original case using the SUBSTR() function.
Remember, there is complexity and significant computational overhead associated with this formula. If you're dealing with a large volume of data, you may want to consider optimizing this process, possibly on the spreadsheet side.
However, this is already quite complex. Providing a perfect custom formula will depend on your exact requirements, you might want to discuss this problem with Matt at MultiTech Visions or someone who can guide you through building a more optimized AppSheet formula based on your exact needs.
I think it's really getting lost here... 🤣🤣🤣
Well... that's why it's still a prototype. haha
-------------------------------------------------------------------------------------------------------------------
[ME]
If you take a critical look at the formula you provided, there are some very basic syntax errors; such as the closing parenthesis for the 2nd index() formula:
CONCATENATE(
UPPER(LEFT(INDEX(SPLIT([Your_Column], " "), 1), 1)),
LOWER(MID(INDEX(SPLIT([Your_Column], " "), 1, MID(LEN(INDEX(SPLIT([Your_Column], " "), 1))-1)))
)
)
You also did not indicate a number for the length property for the MID() function; you started another mid(), but the syntax for this is incorrect as well.
Let's take things slower; please give me a formula that would work for 2 words, from there we can expand and work further.
[Appster]
I apologize for the confusion earlier, you're correct in noticing the error. Here is how you can break down the formula to process the first two words:
CONCATENATE(
UPPER(LEFT(INDEX(SPLIT([Your_Column], " "), 1), 1)),
LOWER(MID(INDEX(SPLIT([Your_Column], " "), 1), 2, LEN(INDEX(SPLIT([Your_Column], " "), 1)) - 1))
) & " " &
CONCATENATE(
UPPER(LEFT(INDEX(SPLIT([Your_Column], " "), 2), 1)),
LOWER(MID(INDEX(SPLIT([Your_Column], " "), 2), 2, LEN(INDEX(SPLIT([Your_Column], " "), 2)) - 1))
)
Replace `[Your_Column]` with the name of the actual column containing your string. This formula splits the string into words, then for each of the first two words, it changes the first character to uppercase and the rest of the word to lowercase.
Still, understand that this function doesn't validate whether a string is in Pascal Case or not; it simply attempts to convert the first two words into Pascal Case. This function does not solve multi-word strings that have hyphen separated words or other non-space delimiters.
-------------------------------------------------------------------------------------------------------------------------
Well at least you can continue to work with it, pointing out specifics like that, and it will eventually figure it out. There might have been a way to word this at the beginning that might have accomplished the output we were hoping for (that being some monster formula that would work like 99% of the time).
With two words I have used this method with the Valid_IF which checks the first upper letter and small letters after that.
AND(
FIND(
UPPER(LEFT(INDEX(SPLIT([_THIS]," "),1),1))&LOWER(MID(INDEX(SPLIT([_THIS]," "),1),2,10)),
INDEX(SPLIT([_THIS]," "),1)
)
>0,
FIND(
UPPER(LEFT(INDEX(SPLIT([_THIS]," "),2),1))&LOWER(MID(INDEX(SPLIT([_THIS]," "),2),2,10)),
INDEX(SPLIT([_THIS]," "),2)
)
>0
)
@MultiTech This came from AleksiAI 😉
Thanks AleksiAlkio,
Your expression is working fine, but it should contain exact 2 names "Smith Smith", however you can fill "Smith Smith smiTH" with no problems. I changed it and added 3th name into the expression, but still the problem will be if someone fill 4 words into that field.
If someone from google is looking in this, please add the PROPER function to the appsheet.
BR
You can add another validation like COUNT(SPLIT([_THIS]," "))<4 and then the user is not able to add more than 3 words.
Thanks,
This is what I was able to do with your help. It it almost as a PROPER function and works for 1 word OR 2 words OR 3 words:
OR(AND(
FIND(
UPPER(LEFT(INDEX(SPLIT([_THIS]," "),1),1))&LOWER(MID(INDEX(SPLIT([_THIS]," "),1),2,15)),
INDEX(SPLIT([_THIS]," "),1)
)
>0,COUNT(SPLIT([_THIS]," "))=1),
AND(
FIND(
UPPER(LEFT(INDEX(SPLIT([_THIS]," "),2),1))&LOWER(MID(INDEX(SPLIT([_THIS]," "),2),2,15)),
INDEX(SPLIT([_THIS]," "),2)
)
>0,COUNT(SPLIT([_THIS]," "))=2),
AND(
FIND(
UPPER(LEFT(INDEX(SPLIT([_THIS]," "),3),1))&LOWER(MID(INDEX(SPLIT([_THIS]," "),3),2,15)),
INDEX(SPLIT([_THIS]," "),3)
)
>0,COUNT(SPLIT([_THIS]," "))=3)
)
Thanks again,
BR
You need to wrap the COUNT() inside of the AND(), Now the validation will accept what ever word if there are 3 of them because of the OR().
This is exactly what I want, since the user could fill the name with only First Name OR with First and Last OR First, Second and Last Name. That's why I used OR at the beginning.
BR
Okay 🙂
User | Count |
---|---|
18 | |
14 | |
11 | |
7 | |
4 |