Dear ODK community,
In ODK collect I need to take an answer and store it in two different
variables. The variables shall be calculated by spliting the answer at a
slash "/"
Hopefully someone can help me out !
Dear ODK community,
In ODK collect I need to take an answer and store it in two different
variables. The variables shall be calculated by spliting the answer at a
slash "/"
Hopefully someone can help me out !
substring-after
is likely what you need, but you won't be able to use
substring-after(${your-url-field} , '/')
as there are other /
in the string already (https://). Hopefully your URL has a known form, then you can make your target more specific, eg
substring-after(${your-url-field} , 'split-string-from-an-url/')
would return 54822
from this thread URL string.
Edited to fix string/target order
dear @ahblake ,
Thank you for your support
Please, let Me be more specific :
my url is : https://webapps01/Home/Mag/kilo22072021123937363
my wish is to extract kilo22072021123937363 and save It in other fild.
in attached, an overview of the form
Regards
Ok, if your URL in field ${id_barcode}
always begins with https://webapps01/Home/Mag/
and the part at the end that changes that you want is, for example kilo22072021123937363
, then you can get that either as a calculate
field, or with a calculate into a text
field with;
substring-after(${id_barcode} , 'https://webapps01/Home/Mag/')
or even
substring-after(${id_barcode} , 'Mag/')
Thank you very much
It is working perctly
For a more dynamic formula that takes the string after the last “/”. This solution is not pretty, but basically it counts how many “/” occur in the URL string and uses nested if statements to make a a specific calculation for each differing number of “/”. Not ideal for super large variations, but this should be plenty fine for most people who want to extract the end of the string after the nth occurrence of a certain character within reasonable quantities.
Column 1 | Column 2 | Column 3 | E | |
---|---|---|---|---|
type | name | label::English (en) | calculation | |
barcode | barcode1 | Scan Barcode 1.31 | ||
calculate | calc_b1_slash_count | string-length(${barcode1}) - string-length(translate(${barcode1}, '/', '')) | ||
calculate | calc_ID_from_URL | if(${calc_b1_slash_count} = 3, substring-after(substring-after(substring-after(${barcode1}, '/'), '/'), '/'), if(${calc_b1_slash_count} = 4, substring-after(substring-after(substring-after(substring-after(${barcode1}, '/'), '/'), '/'), '/'), if(${calc_b1_slash_count} = 5, substring-after(substring-after(substring-after(substring-after(substring-after(${barcode1}, '/'), '/'), '/'), '/'), '/'), if(${calc_b1_slash_count} = 6, substring-after(substring-after(substring-after(substring-after(substring-after(substring-after(${barcode1}, '/'), '/'), '/'), '/'), '/'), '/'), if(${calc_b1_slash_count} = 7, substring-after(substring-after(substring-after(substring-after(substring-after(substring-after(substring-after(${barcode1}, '/'), '/'), '/'), '/'), '/'), '/'), '/'), '' ) ) ) ) ) |
I like @ahblake’s solution since the format is known and consistent!
@Tyler_Depke is right that sometimes a more dynamic approach might be needed. One tip I think you’ll all like is that there’s a lot that can be done with space-separated lists because that’s the format of select multiple answers. I’ve seen @ahblake do some pretty creative things with that.
In this case, I think you can use the translate
function to replace “/”
with “ “
and store the result in a calculate
named something like url_parts
. Then you can selected-at
on url_parts
with an index of count-selected(url_parts) - 1
. That’s very similar to @Tyler_Depke’s approach but takes advantage of the fact that we can request an element at a specific position when we have a space-separated list.
I’ve filed an issue to mention space-separated lists more explicitly in docs https://github.com/getodk/docs/issues/1989
The exact formula as @LN describes works beautifully and here it is exactly:
selected-at(translate(${barcode1},"/"," "),count-selected(translate(${barcode1},"/"," "))-1)