logo

Coding Shortcut: Using LotusScript Replace() Without Having To Define Arrays

Imagine you have a field called "Quantity" on a document that stores how many of something you bought. You want to tell the user how many they chose but in a "wordy" way. If they chose 1, 2 or 3 then you want to display the words one, two or three respectively. Any other choice and you just show the number they chose.

In @Formula this is easy:

"You chose to buy " + @Replace(@Text(Quantity); "1":"2":"3"; "one":"two":"three") + " items."

What about in LotusScript though? There's an equivalent method called Replace() but it requires Arrays and, if you're to follow the help file examples, requires mucky coding like this:

Dim FromArray(2) As string
Dim ToArray(2) As string

FromArray(0) = "1"
FromArray(1) = "2"
FromArray(2) = "3"

ToArray(0) = "one"
ToArray(1) = "two"
ToArray(2) = "three"

Print "You chose to buy " + 
Replace(
 Cstr(document.Quantity(0)),
 FromArray,
 ToArray
)
+ " items."

All very well. It works. It's just so verbose. All that dimming and defining of arrays just to do a basic text replacement. I've never liked defining arrays just for this and I sometimes find myself coding things like instead:

Print "You chose to buy "

If document.Quantity(0)=1 Then
        Print "one"
Elseif document.Quantity(0)=2 Then
        Print "two"
Elseif document.Quantity(0)=3 Then
        Print "three"
Else
        Print Cstr(document.Quantity(0))
End If

Print " items."

On occasion I've even resorted to tricks like this:

Print "You chose to buy " + Implode(Evaluate(|@Replace(@Text(Quantity); "1":"2":"3"; "one":"two":"three")|, document)) + " items."

All that just to avoid messing about with arrays. The Implode() trick used on the Evaluate in the line above is also there to avoid having to dim Variants all over the shop.

Well today, in a moment of (increasingly-rare) inspiration I came up with the following shorthand approach to replacing text in LotusScript:

Print "You chose to buy " + Replace(
 Cstr(document.Quantity(0)),
 Split("1, 2, 3", ", "),
 Split("one, two, three", ", ")
) + " items."

This will now become one of those oh-so-simple tricks that I find myself using all the time. Much like the Implode(Evaluate()) trick that Tommy Valand first highlighted and which I've used continuously ever since.

I know some developers prefer to have more lines of code if it makes it more "readable". Personally I think less is more and try to produce the least amount of code as possible. I don't have time to be defining arrays and whatnot when I've got so much else to do.

Will I be able to support it in the future though? Will another developer be able to make sense of it? In this case, yes, on both counts.

Comments

    • avatar
    • Dan King
    • Thu 13 Mar 2008 06:20 AM

    This can work in certain situations, but try replacing the number 11 with this code and see what happens (you get oneone).

    The same would apply to multiple variances of the same phrase in an array.

    Dan

  1. I agree with you, that's very readable -and- maintainable.

    Since there is no Array literal in LS, like there is in Java/etc, Split( [string] ) is the fastest way to get a String-array in LS.

    Java:

    String[] oneTwoThree = { "1", "2", "3" };

    • avatar
    • Jake Howlett
    • Thu 13 Mar 2008 06:48 AM

    Probably a bad example thinking about it Dan.

    Leaves me wondering why lotuscript replace doesn't behave exactly like its formula counterpart!?

    @Replace("11"; "1":"2"; "one":"two") WILL return 11 whereas Replace("11", Split("1 2"), Split("one two")) will return "oneone" as you stated.

    Is there now direct equivalent of @replace in LS?

    Anyhow -- not a good example for me to use numbers but still the method is useful nonetheless if you know you don't risk running in to these "oddities".

    Jake

  2. What about using lists..?

    Since a list is an array could you not do something like

    Dim myWords List As String

    Dim myNumber As Integer

    myNumber = 2

    myWords("1") = "one"

    myWords("2") = "two"

    myWords("3") = "three"

    Messagebox( "you chose "+myWords(Format(xxx,"###0")))

    Where you use the ordinal value in the array as the List Key. You still have to declare your list somewhere but you don't have to get all jiggy with Redims and variants

    Steve

    • avatar
    • veer
    • Thu 13 Mar 2008 07:59 AM

    This is weird.

    The following works:

    Print Cstr(Replace( "1", Split("1, 2, 3", ", ") ,Split("one, two, three", ", ")))

    This comes up with a Type Mismatch:

    Dim src, dest

    frmS = Split("1, 2, 3", ", ")

    toS = Split("one, two, three", ", ")

    Print Cstr(Replace( "1", frmS ,toS))

    • avatar
    • veer
    • Thu 13 Mar 2008 08:05 AM

    Never mind, I should have read the help which says:

    If sourceArray, replaceArray, or replacementArray is not either a String, or an Array of type String, then a run-time type mismatch error is thrown.

    Also, explains on how it works, which we are seeing in oneone for 11.

  3. For the really complex calculations, I've used a temporary document, referenced a Form name, and then ComputeWithForm to compute various fields on the document.

    Dim pref as NotesDocument

    Set pref = New NotesDocument( db )

    Call pref.ReplaceItemValue( "Form", "$PrefCalculations" )

    {add stuff to this temporary document}

    Call pref.ComputeWithForm( false, false )

    {read stuff from the temporary document}

    {don't save the pref doc}

    That form contains Computed Fields and @Formula.

  4. Your statement "Replace() but it requires Arrays" is not entirely correct. Had a similar approach in my sntt entry: {Link}, where Julian Robichaux pointed out that sourceArray, findArray, replacementArray may all be strings. In almost the last line in the design help your given the hint that strings actually works qoute: "If sourceArray, replaceArray, or replacementArray is not either a String, or an Array of type String, then a run-time type mismatch error is thrown."!

    • avatar
    • Jan Van Puyvelde
    • Thu 13 Mar 2008 11:21 AM

    >> Is there no direct equivalent of @replace in LS?

    ArrayReplace ?

    • avatar
    • Jake Howlett
    • Thu 13 Mar 2008 11:31 AM

    Didn't think of that Jan.

    So, to get round the anomaly of 11 becoming oneone in my - albeit poor - example you can use:

    Implode(Arrayreplace( Split(document.Quantity(0)), Split("1, 2, 3", ", "), Split("one, two, three", ", ")))

    What a mouthful...

  5. You don't need Split and (0) on document.Quantity, in your latest example, as more or less all field values are arrays.

    Implode(Arrayreplace( document.Quantity, Split("1, 2, 3", ", "), Split("one, two, three", ", ")))

    This would -probably- also work:

    Arrayreplace( document.Quantity, Split("1, 2, 3", ", "), Split("one, two, three", ", ") )(0)

    But still ugly.. :)

    • avatar
    • Andy
    • Mon 17 Mar 2008 05:37 AM

    Isn't this a good opportunity to use Select, Case statement, a little more verbose perhaps, but equally as good as the compound Else If statements...

    Select Case document.Quantity(0)

    Case 1 : Print "One"

    Case 2 : Print "Two"

    Case 3 : Print "Three"

    Case Else : Print "Not Recognised"

    End Select

    andy

    • avatar
    • Lee
    • Mon 17 Mar 2008 08:20 AM

    Hi Jake,

    I know you are asking about Lotusscript but -out of interest -why wouldn't you use this in formula..

    "You chose to buy " + @Select(Quantity;"One";"Two";"Three";"Four") + " items."

    It saves having to convert quantity and only requires a single list to be updated.

    • avatar
    • Rod Stauffer
    • Mon 17 Mar 2008 03:24 PM

    I'm with Steve. Lists provide a nice combination of readability and brevity. And they're fast too (course that doesn't matter as much for something small like this).

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:


About This Page

Written by Jake Howlett on Thu 13 Mar 2008

Share This Page

# ( ) '

Comments

The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

More Content