web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

News and Announcements icon
Community site session details

Community site session details

Session Id :
Power Platform Community / Forums / Power Apps / Replacing a symbol in ...
Power Apps
Answered

Replacing a symbol in a string

(0) ShareShare
ReportReport
Posted on by 238

Hi,

I was wondering if it is possible to create a string which also replaces a symbol with alternating values?

 

At the moment I have: Concat(ListBox8.SelectedItems,Result & ". ")

 

I have a series of sentences being joined together and each one contains a ^

 

Sample:

 

^ has worked well and continues to improve. ^ has limited knowledge of quantum mechanics; however, does have a solid understanding of orbital theory. It is expected that with significant support ^ will develop the required skills.

 

The sentences are selected from a list box. One or more may be selected.

 

The persons name and pronoun are also available  - FirstN and PN

 

How can I get the string to form while also inserting the FirstN an PN in an alternating way....

 

Example:

 

Henry / He

 

Henry has worked well and continues to improve. He has limited knowledge of quantum mechanics; however, does have a solid understanding of orbital theory. It is expected that with significant support Henry will develop the required skills.

 

Any suggestions would be appreciated. 

 

Categories:
I have the same question (0)
  • BrianS Profile Picture
    2,407 Super User 2024 Season 1 on at

    You just need to create variables for the name and pronoun. Something like this:

    Set(varName,"Bob");Set(varPro,"He")

     

    Then you can create a collection for the sentences and use that to fill the list box:

    Collect(col_Sent,{Sent1:varName &" needs work. "},{ Sent1:varPro & " will be fine. "})

     

    Then your Concat will not need the &"."

  • RusselThomas Profile Picture
    4,014 on at

    Hi @Newbie2019 ,

     

    I hope I'm understanding this correctly, otherwise I'm solving a different problem 😊

     

    The idea would be to collect selected sentences that already have ^ placeholders in them into a paragraph, then replace the ^ iteratively with FirstN/PN in an alternating pattern throughout the paragraph - is that right?

     

    This may or may not be easy, depending on how strict your rules are around the construction of the sentences - more specifically the placing of FirstN, or PN.  What I mean is, ^ is a single character.  You can't just tell by looking at a sentence whether ^ should be FirstN or PN.

    If you have control over the sentences, you might want to consider making your life a little easier and using a ^ for FirstN and something like a # for PN - that way you can do a simple substitution, but if you don't have this control and you're stuck with ^ placeholders, then you need to rely on your rule.

    If your rule is that they will always alternate, (FirstN/PN/FirstN/PN) then it's doable with just a ^ placeholder.

     

    I took a stab at the code out of interest - if I missed the boat on your question maybe it will help someone else 😉

    Someone better than me can probably also tidy it up a bit or shorten it - eg: you can just use one collection for the paragraph, where I used first a variable and then a collection - but that was mainly to avoid First(collection).value statements messing up the code or just plain confusing me 😊

     

    To test, stick this code on a button OnSelect: property and put a label on the page, setting it's Text: property to outputSentence to see the result when you press the button;

    UpdateContext({varParagraph: "^ has worked well and continues to improve. ^ has limited knowledge of quantum mechanics; however, does have a solid understanding of orbital theory. It is expected that with significant support ^ will develop the required skills.", FirstN: "Bob", PN: "He"}); //sets up the sentence and FirstN/PN vars
    
    ClearCollect(CollectPlaceholders, 
     AddColumns(Split(varParagraph, "^"), 
     "Index", 0,
     "Alt", "placeholder"
     )
     ); //sets up a collection that splits out the paragraph wherever ^ appears
    
    UpdateIf(CollectPlaceholders, Index=0, {
     Index: Last(SortByColumns(CollectPlaceholders, "Index", Ascending)).Index + 1
     }); //sets up an index for each instance of the ^ - now we know how many there are
    
    UpdateIf(CollectPlaceholders, Alt="placeholder", {
     Alt: If(Mod(Index, 2)=1, FirstN, PN)
    }); //alternately sets each instance of ^ to FirstN if the index is odd, or PN if its even
    
    ClearCollect(collectParser, {outcome: varParagraph}); //puts our sentence into a new collection, just to keep it clean for now - can consolidate later if needed
    
    ForAll(CollectPlaceholders As currentRecords,
     Collect(collectParser, {outcome: 
     Substitute(
     Last(collectParser).outcome, "^", currentRecords.Alt, 1
     )
     })
    ); //for each split instance of ^, substitute only the first ^ in the original sentence with the instance alt. (once it's substituted and runs to the next "instance of ^" it will substitute the next "first" one - thereby working through the sentence until all ^'s are replaced
    
    Set(outputSentence, Last(collectParser).outcome) //updates our output var so we can see the result

    Should be enough there for you to pull apart and repackage how you need it - assuming again I understood your question correctly 😁

    If your rule isn't "alternating" then perhaps some clarification?

     

    Otherwise I hope this helps,

     

    RT

  • Newbie2019 Profile Picture
    238 on at

    Hi @RusselThomas 

    Thank you so much for your reply.😁

     

    Yes, "The idea would be to collect selected sentences that already have ^ placeholders in them into a paragraph, then replace the ^ iteratively with FirstN/PN in an alternating pattern throughout the paragraph - is that right?" is correct.

     

    With regards to the symbol, Yes, my organisation has a rule that they always must alternate.  This is annoying, but a requirement.

     

    I tested the code, placing it into a button and it worked. 😀

     

    I would appreciate some direction as to how to adapt it to my context. At the moment I have created a collection called ColN.

     

    Within this collection I have the following:

    CustIDDateCommentFirstNPN
    s15489451/07/2021^ has worked well and continues to improve. ^ has limited knowledge of quantum mechanics; however, does have a solid understanding of orbital theory. It is expected that with significant support ^ will develop the required skillsHenryHe

     

    With the code that you provided, I can see the following in collections:

    Newbie2019_0-1625085546225.png

     

     

    Newbie2019_1-1625085591243.png

     

    I am hoping to take the comment in the ColN collection and replace it with the formatted version with FirstN / PN (collectParser - row 5).

     

    Any further advice would be appreciated.

     

    Thanks for your time.

     

  • RusselThomas Profile Picture
    4,014 on at

    Hi @Newbie2019 ,

     

    Will there only ever be a single row in CoIN, or are you wanting to do it for multiple rows?

    The reason I ask is that if it's multiple, you'll want to use a ForAll, and in that case you'd have to stage a collection with the updated comments within the ForAll, then update the original collection outside of it.

    If not, it's likely to be a little simpler.

     

    Kind regards,

     

    RT

     

    Kind regards,

    RT

  • Newbie2019 Profile Picture
    238 on at

    Hi @RusselThomas ,

    Thank you for getting back to me. Yeah, there will only be one row at a time. The application is for teachers to make comments each lesson and then save them to a global SharePoint list. Once the collection is populated, it will then be displayed for the teacher to check before being submitted to the list. On hitting submit, the ColN collection will be reset / cleared for the next entry. 

     

    Thank you so much for helping.

  • RusselThomas Profile Picture
    4,014 on at

    Hi @Newbie2019 ,

     

    Try this on a button OnSelect: property - It's a lot, but I've also included a bunch of commentary to try and explain each step.  If it works you can put it on any behaviour property so it happens more seamlessy with the user experience (instead of having to push a button 😁);

     

     

    //This first bit is just my preference, if you like you can just work with the collection, but if it's only ever going to have one record, then I prefer to create a variable of type record to work with, then update the collection when I'm done.
    //This just simplifies complex code for me and avoids using First() lookup functions every time I want to get a reference.
    
    UpdateContext({recWorkingRecord: First(CoIN)});
     
    //*******************************placeholder Collection prep************************** 
     //split the Comment paragraph into a collection of rows and make space for an Index and the alternating FirstN / PN placeholders - 1 row for each instance of ^
     ClearCollect(CollectPlaceholders, 
     AddColumns(
     Split(recWorkingRecord.Comment, "^"), 
     "Index", 0,
     "Alt", "placeholder"
     )
     );
     
     //set up the index for each instance of the ^ so we can index them and calculate odd/even for alternating
     UpdateIf(CollectPlaceholders, Index=0, {
     Index: Last(SortByColumns(CollectPlaceholders, "Index", Ascending)).Index + 1
     }); 
    
     //use Mod() to determine if an index number is odd or even, and set "Alt" value to FirstN if it's odd or PN if it's even
     UpdateIf(CollectPlaceholders, Alt="placeholder", {
     Alt: If(Mod(Index, 2)=1, recWorkingRecord.FirstN, recWorkingRecord.PN)
     }); 
    //*******************************end placeholder Collection prep**************************
    
     //put the original paragraph into a new collection to work on, just to keep CoIN clean and save us some tidying up afterwards
     ClearCollect(collectParser, {outcome: recWorkingRecord.Comment}); 
     
     //Iterate through our list of alternates, and for each substitute only the first ^ in the original paragraph with the current alt. As each "First ^" is replaced, the next iteration will automatically replace the next "First ^" - and so we work through the paragraph in accordance with our ^ Splits
     ForAll(CollectPlaceholders As currentRecords,
     Collect(collectParser, {outcome: 
     Substitute(
     Last(collectParser).outcome, "^", currentRecords.Alt, 1
     )
     })
     ); 
    
    //Lastly, update the original CoIN collection with the updated paragraph (the last iteration of the previous step)
    Patch(CoIN, First(CoIN), {Comment: Last(collectParser).outcome})

     

     Hope this helps,

    RT

  • Newbie2019 Profile Picture
    238 on at

    Hi @RusselThomas 

    Thank you for the speedy reply. I am a little confused to be honest and think that I have over complicated things. I have limited experience with Power Apps.😫

    When selecting the comments to add to the paragraph, I had been concatenating them before saving the to the collection. I did this as I kept getting the table in the collection with everything separate when I did it directly.

    I have just completed a test to show you:

     

    Newbie2019_0-1625132070963.png

     

    I then get this in the ColN collection:

     

    Newbie2019_1-1625132134032.png

     

    When I click on the table I get:

     

    Newbie2019_2-1625132175732.png

    To get around this, I have been adding in a step to make it a paragraph. I inserted a label and then used then collected that:

     

    Newbie2019_3-1625132529936.png

     

    I then added this to the collection:

     

    Newbie2019_4-1625132750279.png

     

     

    I'm sorry for the confusion.

     

    From what I can tell, I'm turning it into a paragraph when it needs to be kept in separate numbered rows to then have the FirstN & PN added.

     

    I would appreciate any further advice.

     

    Kind regards,

     

     

     

     

     

  • RusselThomas Profile Picture
    4,014 on at

    Hi @Newbie2019 ,

     

    You probably don't need to add a period to the Concat() as your sentences already end in periods - there are traditionally two spaces between one sentence and the next, but most style guides just recommend one, so I'd replace the period with a space instead and see how it looks.

    You can drop the label step just by Concatenating the listbox selections directly in though and dumping the conversion code straight after it.  

     

    Try this on the OnChange: event property of your listbox;

    ClearCollect (CoIN, { 
     Date: DatePicker1.SelectedDate, 
     FirstN: Dropdown7_1.SelectedText.Value, 
     PN: Dropdown9_1.SelectedText.Value, 
     CustID: Dropdown10_1.SelectedText.Value, 
     Comment: Concat(ListBox5.SelectedItems, Comment, " ")
    }
    );
    
    //Create variable of type record to simplify code and avoid using First() lookup functions every time I want to get a reference
    UpdateContext({recWorkingRecord: First(CoIN)});
     
    //*******************************placeholder Collection prep************************** 
     //split the Comment paragraph into a collection of rows - 1 for each instance of ^
     ClearCollect(CollectPlaceholders, 
     AddColumns(
     Split(recWorkingRecord.Comment, "^"), 
     "Index", 0,
     "Alt", "placeholder"
     )
     );
     
     //set up an index for each instance of the ^ so we can index them and calculate odd/even for alternating
     UpdateIf(CollectPlaceholders, Index=0, {
     Index: Last(SortByColumns(CollectPlaceholders, "Index", Ascending)).Index + 1
     }); 
    
     //use Mod() to determine if an index number is odd or even, and set "Alt" value to FirstN if it's odd or PN if it's even
     UpdateIf(CollectPlaceholders, Alt="placeholder", {
     Alt: If(Mod(Index, 2)=1, recWorkingRecord.FirstN, recWorkingRecord.PN)
     }); 
    //*******************************end placeholder Collection prep**************************
    
     //put the paragraph into a new collection, just to keep it clean for now - can consolidate later if needed
     ClearCollect(collectParser, {outcome: recWorkingRecord.Comment}); 
     
     //Iterate through our list of alternates, and for each substitute only the first ^ in the originaly paragraph with the current alt.
     //this will work through each ^ and alternate it as it goes, until all are done
     ForAll(CollectPlaceholders As currentRecords,
     Collect(collectParser, {outcome: 
     Substitute(
     Last(collectParser).outcome, "^", currentRecords.Alt, 1
     )
     })
     ); 
    
    //Lastly, update the original CoIN collection with the updated paragraph (the last iteration of the previous step)
    Patch(CoIN, First(CoIN), {Comment: Last(collectParser).outcome})
    

     See if that helps?

     

    Kind regards,

    RT

  • Newbie2019 Profile Picture
    238 on at

    Hi @RusselThomas 

    OMG, it worked. I have been trying to find out how to do this for months. Thank you so much. This will save an enormous amount of time at my school.😁🍾🍻

     

    I was wondering if the following is possible:

    1) automatically make the start of a sentence a capital

    2) add in another symbol that does not alternate.

     

    I am thinking of having a possessive adjective.

     

    So there would be the FirstN & PN for the ^  and PA to replace any ~

     

    The FirstN, PN & PA would all be lowercase in the reference table.

     

    For example:

     

    ^ had difficulty solving simultaneous equations under exam conditions. While ^ tried ~ best, further practice is required.

     

    This would then become:

     

    henry, he & his

     

    Henry had difficulty solving simultaneous equations under exam conditions. While he tried his best, further practice is required.

     

    I understand that I am pushing the favour.

     

    Thanks again.

     

    Kind regards,

     

     

  • Verified answer
    RusselThomas Profile Picture
    4,014 on at

    Hi @Newbie2019 ,

    Glad to hear it 🙂

     

    You can use Proper() to capitalise the first letter of a word.  Figuring out if it's also the first word in a sentence is likely to involve something like StartsWith() or getting the index of the first space in the sentence and working from that.  It depends a lot on what you're trying to do, and what you're trying to do it with.  It does become more difficult if you're trying to figure this out mid-paragraph though, so it's best to do it sentence by sentence first.

    In your case, you'd need to fall back on collecting the sentences before concatenating them, and applying the substitution to each sentence, ensuring that if the placeholder starts the sentence, it has a capital letter.

    Beware though, this can become a slippery slope and you could end up building a real spaghetti farm of code just to deal with this.

     

    Things would be much simpler (code-wise anyway) if you allocated each type of placeholder it's own special character - including capitalised or lowercase variants. 

    If you're going to start adding additional placeholders you may also want to get rid of the ambiguity between FirstN and PN as a starting point and give PN it's own character as well.  Then add placeholders for properPN, PA and properPA to hold casing variants.

     

    This shifts the responsibility onto the sentence creator to put the right characters in their place, instead of relying on complex code to alternate or figure it out.  That way, reams of code can become a few simple lines.  

    For example, if;

    FirstN = ^ 

    PN = # 

    properPN = ##

    PA = % 

    properPA = %% 

    Then your sentence would look like this;

    ^ had difficulty solving simultaneous equations under exam conditions. While # tried % best, further practice is required.  %% lecturer is awesome though.  

    Then you just have to substitute, without mucking around with alternating indexes and trying to figure out if a placeholder is starting a sentence or not. So;

    Substitute(
     Substitute(
     Substitute(
     Substitute(
     Substitute(
     varParagraph, 
     "^", FirstN), 
     "#", PN), 
     "##", properPN), 
     "%", PA), 
     "%%", properPA)
    

    would do pretty much everything all the previous code I've shared with you does, (and actually more, if you consider the inclusion of the additional placeholders) - and it does it more efficiently.

     

    I'd always suggest starting a new thread with a new question if your original questions is answered though - it helps other people find answers easier.  Most of the responders on this forum may also not bother reading something that has already been responded to - so you'll be stuck with one point of view.  By posting a new question as a new thread you might find someone can offer an even better overall solution. 

     

    Kind regards,

    RT

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Season of Sharing Community Challenge Winners!

Congratulations to our community stars!

Kudos to our 2025 Community Spotlight Honorees

Expanding mentorship, skilling, and AI innovation

Congratulations to the July Top 10 Community Leaders!

These are the community rock stars!

Leaderboard > Power Apps

#1
WarrenBelz Profile Picture

WarrenBelz 358 Most Valuable Professional

#2
11manish Profile Picture

11manish 214 Super User 2026 Season 2

#3
Mohsin Ali Profile Picture

Mohsin Ali 185

Last 30 days Overall leaderboard