Home All Groups Group Topic Archive Search About

Replace one occurence of string within string at certain position

Author
26 Mar 2009 9:17 PM
RB Smissaert
Looking for a fast way to replace at a given position a string within
another string
and it looks the only way is with CopyMemory:

Private Declare Sub CopyMemory _
                     Lib "kernel32" _
                         Alias "RtlMoveMemory" _
                         (pDst As Any, _
                          pSrc As Any, _
                          ByVal ByteLen As Long)

Sub ReplaceAt(lStringPtr As Long, _
               lReplacePtr As Long, _
               lReplacePos As Long, _
               lReplaceLenB As Long)

  'lStringPtr will the StrPtr of the string to do the replace in
  'lReplacePtr will the StrPtr of the string to do the replace with
  'lReplacePos will be the string position (as in Mid$ etc.) to do the
replace
  'lReplaceLenB will be LenB of strReplace
  '----------------------------------------------------------------------------
  Dim lMemPos As Long

  lMemPos = (lStringPtr + lReplacePos * 2) - 2

  CopyMemory ByVal lMemPos, _
             ByVal lReplacePtr, _
             lReplaceLenB

End Sub

The only other way I can see is with concatenation, so do Left$( etc. &
strReplace & Right$  etc.,
but that will be slow. The method with CopyMemory seems to work fine, but
ideally I would like
to avoid it as the error handling will be more tricky.
Is there a way to do this fast without CopyMemory?


RBS

Author
26 Mar 2009 9:36 PM
Michael Williams
"RB Smissaert" <bartsmissa***@blueyonder.co.uk> wrote in message
news:OH6t2flrJHA.3864@TK2MSFTNGP02.phx.gbl...

> Looking for a fast way to replace at a given position a
> string within another string and it looks the only way is
> with CopyMemory:

Unless I've misread your question then you should be able to do what you
want using the native VB Mid statement, as in the following example:

Dim s1 As String, s2 As String
s1 = "1234567890123456789012345678901234567890"
s2 = "ABCDE"
Print s1
Mid$(s1, 20) = s2
Print s1

There is a third optional parameter, which I have not used above, enabling
you to specify how many characters to replace, otherwise the whole of s2
will be used. Post again if you meant something different.

Mike
Are all your drivers up to date? click for free checkup

Author
26 Mar 2009 9:57 PM
RB Smissaert
Yes, thanks, you are absolutely right.
I thought I had a look at that a while ago and decided it
couldn't work, but it clearly does.
Even better, the simple Mid$ is in fact faster by a factor 4 in my test.

RBS


Show quoteHide quote
"Michael Williams" <M***@WhiskeyAndCoke.com> wrote in message
news:uFyDEslrJHA.3848@TK2MSFTNGP02.phx.gbl...
> "RB Smissaert" <bartsmissa***@blueyonder.co.uk> wrote in message
> news:OH6t2flrJHA.3864@TK2MSFTNGP02.phx.gbl...
>
>> Looking for a fast way to replace at a given position a
>> string within another string and it looks the only way is
>> with CopyMemory:
>
> Unless I've misread your question then you should be able to do what you
> want using the native VB Mid statement, as in the following example:
>
> Dim s1 As String, s2 As String
> s1 = "1234567890123456789012345678901234567890"
> s2 = "ABCDE"
> Print s1
> Mid$(s1, 20) = s2
> Print s1
>
> There is a third optional parameter, which I have not used above, enabling
> you to specify how many characters to replace, otherwise the whole of s2
> will be used. Post again if you meant something different.
>
> Mike
>
>
Author
26 Mar 2009 10:05 PM
RB Smissaert
I know now why I thought this couldn't work.
Previously I was interested in inserting a string into another string, so
not replacing existing text.
In that case the Mid$ function can't work and I think you will need to
concatenate.

RBS


Show quoteHide quote
"Michael Williams" <M***@WhiskeyAndCoke.com> wrote in message
news:uFyDEslrJHA.3848@TK2MSFTNGP02.phx.gbl...
> "RB Smissaert" <bartsmissa***@blueyonder.co.uk> wrote in message
> news:OH6t2flrJHA.3864@TK2MSFTNGP02.phx.gbl...
>
>> Looking for a fast way to replace at a given position a
>> string within another string and it looks the only way is
>> with CopyMemory:
>
> Unless I've misread your question then you should be able to do what you
> want using the native VB Mid statement, as in the following example:
>
> Dim s1 As String, s2 As String
> s1 = "1234567890123456789012345678901234567890"
> s2 = "ABCDE"
> Print s1
> Mid$(s1, 20) = s2
> Print s1
>
> There is a third optional parameter, which I have not used above, enabling
> you to specify how many characters to replace, otherwise the whole of s2
> will be used. Post again if you meant something different.
>
> Mike
>
>
Author
26 Mar 2009 10:34 PM
RB Smissaert
I explained that wrongly, I meant I was thinking at a situation where the
replacing string is longer than the string to be replaced.
In that case I think you will need something like this, which is slow due to
the string concatenations:

Private Function ReplaceAt(strToSearch, strToFind, strReplace, lPos) As
String

  'will replace strToFind in strToSearch with strReplace,
  'but only if strToFind appears at position lPos
  '------------------------------------------------------
  Dim strTest As String

  strTest = Mid$(strToSearch, lPos, Len(strToFind))

  If strTest = strToFind Then
    ReplaceAt = Left$(strToSearch, lPos - 1) & _
                strReplace & _
                Right$(strToSearch, Len(strToSearch) - (lPos +
(Len(strToFind) - 1)))
  Else
    ReplaceAt = strToSearch
  End If

End Function


RBS


Show quoteHide quote
"RB Smissaert" <bartsmissa***@blueyonder.co.uk> wrote in message
news:O72am6lrJHA.1300@TK2MSFTNGP05.phx.gbl...
>I know now why I thought this couldn't work.
> Previously I was interested in inserting a string into another string, so
> not replacing existing text.
> In that case the Mid$ function can't work and I think you will need to
> concatenate.
>
> RBS
>
>
> "Michael Williams" <M***@WhiskeyAndCoke.com> wrote in message
> news:uFyDEslrJHA.3848@TK2MSFTNGP02.phx.gbl...
>> "RB Smissaert" <bartsmissa***@blueyonder.co.uk> wrote in message
>> news:OH6t2flrJHA.3864@TK2MSFTNGP02.phx.gbl...
>>
>>> Looking for a fast way to replace at a given position a
>>> string within another string and it looks the only way is
>>> with CopyMemory:
>>
>> Unless I've misread your question then you should be able to do what you
>> want using the native VB Mid statement, as in the following example:
>>
>> Dim s1 As String, s2 As String
>> s1 = "1234567890123456789012345678901234567890"
>> s2 = "ABCDE"
>> Print s1
>> Mid$(s1, 20) = s2
>> Print s1
>>
>> There is a third optional parameter, which I have not used above,
>> enabling you to specify how many characters to replace, otherwise the
>> whole of s2 will be used. Post again if you meant something different.
>>
>> Mike
>>
>>
>
Author
26 Mar 2009 11:00 PM
Karl E. Peterson
RB Smissaert wrote:
> I explained that wrongly, I meant I was thinking at a situation where the
> replacing string is longer than the string to be replaced.

In that case, you can use the Replace function. <g>

   ?replace("1234567", "4", "abc")
   123abc567

If you need a VB5 implementation, here's one I stole from somewhere:

   Public Function Replace(ByVal Expression As String, ByVal Find As String, ByVal
Replase As String, Optional Start As Long = 1, Optional Count As Long = -1, Optional
Compare As VbCompareMethod = vbBinaryCompare) As String
      Dim nC As Long, nPos As Long
      Dim nFindLen As Long, nReplaceLen As Long

      nFindLen = Len(Find)
      nReplaceLen = Len(Replase)

      If (Find <> "") And (Find <> Replase) Then
         nPos = InStr(Start, Expression, Find, Compare)
         Do While nPos
            nC = nC + 1
            Expression = Left(Expression, nPos - 1) & Replase & Mid(Expression, nPos
+ nFindLen)
            If Count <> -1 And nC >= Count Then Exit Do
            nPos = InStr(nPos + nReplaceLen, Expression, Find, Compare)
         Loop
      End If

      Replace = Expression
   End Function

--
..NET: It's About Trust!
http://vfred.mvps.org
Author
26 Mar 2009 11:24 PM
RB Smissaert
Unless I am overlooking something simple again, I don't think that will
work.
The thing is I need to replace at a specified position:

Sub test()

  Dim str1 As String
  Dim str2 As String

  str1 = "123456789"

  str2 = "XX"

  str1 = Replace(str1, "4", str2, 4, 1)

  'I need result to be "123XX56789"
  'but will get "XX56789
  MsgBox str1

End Sub


RBS


Show quoteHide quote
"Karl E. Peterson" <k***@mvps.org> wrote in message
news:eFSc1amrJHA.1212@TK2MSFTNGP04.phx.gbl...
> RB Smissaert wrote:
>> I explained that wrongly, I meant I was thinking at a situation where the
>> replacing string is longer than the string to be replaced.
>
> In that case, you can use the Replace function. <g>
>
>   ?replace("1234567", "4", "abc")
>   123abc567
>
> If you need a VB5 implementation, here's one I stole from somewhere:
>
>   Public Function Replace(ByVal Expression As String, ByVal Find As
> String, ByVal Replase As String, Optional Start As Long = 1, Optional
> Count As Long = -1, Optional Compare As VbCompareMethod = vbBinaryCompare)
> As String
>      Dim nC As Long, nPos As Long
>      Dim nFindLen As Long, nReplaceLen As Long
>
>      nFindLen = Len(Find)
>      nReplaceLen = Len(Replase)
>
>      If (Find <> "") And (Find <> Replase) Then
>         nPos = InStr(Start, Expression, Find, Compare)
>         Do While nPos
>            nC = nC + 1
>            Expression = Left(Expression, nPos - 1) & Replase &
> Mid(Expression, nPos + nFindLen)
>            If Count <> -1 And nC >= Count Then Exit Do
>            nPos = InStr(nPos + nReplaceLen, Expression, Find, Compare)
>         Loop
>      End If
>
>      Replace = Expression
>   End Function
>
> --
> .NET: It's About Trust!
> http://vfred.mvps.org
>
Author
27 Mar 2009 12:11 AM
Karl E. Peterson
RB Smissaert wrote:
Show quoteHide quote
> Unless I am overlooking something simple again, I don't think that will
> work.  The thing is I need to replace at a specified position:
>
> Sub test()
>  Dim str1 As String
>  Dim str2 As String
>
>  str1 = "123456789"
>
>  str2 = "XX"
>
>  str1 = Replace(str1, "4", str2, 4, 1)
>
>  'I need result to be "123XX56789"
>  'but will get "XX56789
>  MsgBox str1
> End Sub

Well, I'm not sure what exactly you're overlooking, but when I do this in the
Immediate Window:

   ?Replace("123456789", "4", "XX",  4, 1)
   123XX56789

It seems to do what you say you want it to?  Maybe it's that I'm taking what you say
you need too literally, and what you really need is what you allude you need? <g>
IOW, you don't care what's at position four, and it may be entirely non-unique, but
you need to replace it?  Yeah, in that case, it's a mess.  You can split and
concatenate.  Or you can slide stuff around with CopyMemory.  Is this something you
need to do repeatedly?
--
..NET: It's About Trust!
http://vfred.mvps.org
Author
27 Mar 2009 12:27 AM
RB Smissaert
Did you run the exact code as posted?
Yes, in this case I needed to replace at the exact position
and the string to replace could be anywhere else.
As you say it looks in that case you need to concatenate.

RBS


Show quoteHide quote
"Karl E. Peterson" <k***@exmvps.org> wrote in message
news:%23Xc9MCnrJHA.1504@TK2MSFTNGP03.phx.gbl...
> RB Smissaert wrote:
>> Unless I am overlooking something simple again, I don't think that will
>> work.  The thing is I need to replace at a specified position:
>>
>> Sub test()
>>  Dim str1 As String
>>  Dim str2 As String
>>
>>  str1 = "123456789"
>>
>>  str2 = "XX"
>>
>>  str1 = Replace(str1, "4", str2, 4, 1)
>>
>>  'I need result to be "123XX56789"
>>  'but will get "XX56789
>>  MsgBox str1
>> End Sub
>
> Well, I'm not sure what exactly you're overlooking, but when I do this in
> the Immediate Window:
>
>   ?Replace("123456789", "4", "XX",  4, 1)
>   123XX56789
>
> It seems to do what you say you want it to?  Maybe it's that I'm taking
> what you say you need too literally, and what you really need is what you
> allude you need? <g> IOW, you don't care what's at position four, and it
> may be entirely non-unique, but you need to replace it?  Yeah, in that
> case, it's a mess.  You can split and concatenate.  Or you can slide stuff
> around with CopyMemory.  Is this something you need to do repeatedly?
> --
> .NET: It's About Trust!
> http://vfred.mvps.org
>
Author
27 Mar 2009 3:12 AM
Rick Rothstein
Let's combine some of the techniques (VB6 version)...

Function Substitute(FullText As String, Position As Long, _
                    Length As Long, NewText As String) As String
  Substitute = FullText
  Mid(Substitute, Position) = String(Length, Chr$(1))
  Substitute = Replace(Substitute, String(Length, Chr$(1)), NewText)
End Function

Of course, a final version should probably have some kind of error testing I
suppose.

--
Rick (MVP - Excel)


Show quoteHide quote
"Karl E. Peterson" <k***@exmvps.org> wrote in message
news:%23Xc9MCnrJHA.1504@TK2MSFTNGP03.phx.gbl...
> RB Smissaert wrote:
>> Unless I am overlooking something simple again, I don't think that will
>> work.  The thing is I need to replace at a specified position:
>>
>> Sub test()
>>  Dim str1 As String
>>  Dim str2 As String
>>
>>  str1 = "123456789"
>>
>>  str2 = "XX"
>>
>>  str1 = Replace(str1, "4", str2, 4, 1)
>>
>>  'I need result to be "123XX56789"
>>  'but will get "XX56789
>>  MsgBox str1
>> End Sub
>
> Well, I'm not sure what exactly you're overlooking, but when I do this in
> the Immediate Window:
>
>   ?Replace("123456789", "4", "XX",  4, 1)
>   123XX56789
>
> It seems to do what you say you want it to?  Maybe it's that I'm taking
> what you say you need too literally, and what you really need is what you
> allude you need? <g> IOW, you don't care what's at position four, and it
> may be entirely non-unique, but you need to replace it?  Yeah, in that
> case, it's a mess.  You can split and concatenate.  Or you can slide stuff
> around with CopyMemory.  Is this something you need to do repeatedly?
> --
> .NET: It's About Trust!
> http://vfred.mvps.org
>
Author
27 Mar 2009 3:20 AM
Rick Rothstein
Oh, I meant to add "... without using concatenation" to the opening
sentence.

--
Rick (MVP - Excel)


Show quoteHide quote
"Rick Rothstein" <rick.newsNO.SPAM@NO.SPAMverizon.net> wrote in message
news:O9l2hnorJHA.6040@TK2MSFTNGP02.phx.gbl...
> Let's combine some of the techniques (VB6 version)...
>
> Function Substitute(FullText As String, Position As Long, _
>                    Length As Long, NewText As String) As String
>  Substitute = FullText
>  Mid(Substitute, Position) = String(Length, Chr$(1))
>  Substitute = Replace(Substitute, String(Length, Chr$(1)), NewText)
> End Function
>
> Of course, a final version should probably have some kind of error testing
> I suppose.
>
> --
> Rick (MVP - Excel)
>
>
> "Karl E. Peterson" <k***@exmvps.org> wrote in message
> news:%23Xc9MCnrJHA.1504@TK2MSFTNGP03.phx.gbl...
>> RB Smissaert wrote:
>>> Unless I am overlooking something simple again, I don't think that will
>>> work.  The thing is I need to replace at a specified position:
>>>
>>> Sub test()
>>>  Dim str1 As String
>>>  Dim str2 As String
>>>
>>>  str1 = "123456789"
>>>
>>>  str2 = "XX"
>>>
>>>  str1 = Replace(str1, "4", str2, 4, 1)
>>>
>>>  'I need result to be "123XX56789"
>>>  'but will get "XX56789
>>>  MsgBox str1
>>> End Sub
>>
>> Well, I'm not sure what exactly you're overlooking, but when I do this in
>> the Immediate Window:
>>
>>   ?Replace("123456789", "4", "XX",  4, 1)
>>   123XX56789
>>
>> It seems to do what you say you want it to?  Maybe it's that I'm taking
>> what you say you need too literally, and what you really need is what you
>> allude you need? <g> IOW, you don't care what's at position four, and it
>> may be entirely non-unique, but you need to replace it?  Yeah, in that
>> case, it's a mess.  You can split and concatenate.  Or you can slide
>> stuff around with CopyMemory.  Is this something you need to do
>> repeatedly?
>> --
>> .NET: It's About Trust!
>> http://vfred.mvps.org
>>
>
Author
27 Mar 2009 3:28 AM
Rick Rothstein
Of course, with concatenation, it is just a one-liner<g>....

Function Substitute(FullText As String, Position As Long, _
                    Length As Long, NewText As String) As String
  Substitute = Left(FullText, Position - 1) & NewText & _
                     Mid(FullText, Position + Length)
End Function

--
Rick (MVP - Excel)


Show quoteHide quote
"Rick Rothstein" <rick.newsNO.SPAM@NO.SPAMverizon.net> wrote in message
news:uuTHCsorJHA.3648@TK2MSFTNGP05.phx.gbl...
> Oh, I meant to add "... without using concatenation" to the opening
> sentence.
>
> --
> Rick (MVP - Excel)
>
>
> "Rick Rothstein" <rick.newsNO.SPAM@NO.SPAMverizon.net> wrote in message
> news:O9l2hnorJHA.6040@TK2MSFTNGP02.phx.gbl...
>> Let's combine some of the techniques (VB6 version)...
>>
>> Function Substitute(FullText As String, Position As Long, _
>>                    Length As Long, NewText As String) As String
>>  Substitute = FullText
>>  Mid(Substitute, Position) = String(Length, Chr$(1))
>>  Substitute = Replace(Substitute, String(Length, Chr$(1)), NewText)
>> End Function
>>
>> Of course, a final version should probably have some kind of error
>> testing I suppose.
>>
>> --
>> Rick (MVP - Excel)
>>
>>
>> "Karl E. Peterson" <k***@exmvps.org> wrote in message
>> news:%23Xc9MCnrJHA.1504@TK2MSFTNGP03.phx.gbl...
>>> RB Smissaert wrote:
>>>> Unless I am overlooking something simple again, I don't think that will
>>>> work.  The thing is I need to replace at a specified position:
>>>>
>>>> Sub test()
>>>>  Dim str1 As String
>>>>  Dim str2 As String
>>>>
>>>>  str1 = "123456789"
>>>>
>>>>  str2 = "XX"
>>>>
>>>>  str1 = Replace(str1, "4", str2, 4, 1)
>>>>
>>>>  'I need result to be "123XX56789"
>>>>  'but will get "XX56789
>>>>  MsgBox str1
>>>> End Sub
>>>
>>> Well, I'm not sure what exactly you're overlooking, but when I do this
>>> in the Immediate Window:
>>>
>>>   ?Replace("123456789", "4", "XX",  4, 1)
>>>   123XX56789
>>>
>>> It seems to do what you say you want it to?  Maybe it's that I'm taking
>>> what you say you need too literally, and what you really need is what
>>> you allude you need? <g> IOW, you don't care what's at position four,
>>> and it may be entirely non-unique, but you need to replace it?  Yeah, in
>>> that case, it's a mess.  You can split and concatenate.  Or you can
>>> slide stuff around with CopyMemory.  Is this something you need to do
>>> repeatedly?
>>> --
>>> .NET: It's About Trust!
>>> http://vfred.mvps.org
>>>
>>
>
Author
27 Mar 2009 12:34 AM
Larry Serflaten
"RB Smissaert" <bartsmissa***@blueyonder.co.uk> wrote
> Unless I am overlooking something simple again, I don't think that will
> work.
> The thing is I need to replace at a specified position:

Here is one that will get the job done.  You'd have to run timed tests to
see if its faster than concatenation....  (it should be...)

LFS

Private Sub Form_Load()
Debug.Print Replace("1234567", "4", "ABC")
Debug.Print Replace("1234321", "2", "ABC", 2)
Debug.Print Replace("1234321", "3", "XYZ", -1)
Debug.Print Replace("1234567", "345", "X")
Debug.Print Replace("1234321", "3", "XYZ", 1, 5)
End Sub


Function Replace(ByVal Source$, _
                 ByRef Find$, _
                 ByRef Insert$, _
                 Optional Repeat As Long = 1, _
                 Optional Position As Long = 0) As String
Dim tmp As String
Dim diff As Long
Dim begin As Long
Dim pos As Long
Dim all As Boolean

   begin = 1
   diff = Len(Insert) - Len(Find)

   If Repeat < 0 Then
     all = True
     Repeat = 2
   End If

   If Position > 0 Then
     pos = InStr(Position, Source, Find)
     If pos = Position Then
       Repeat = 1
       begin = pos
     Else
       Repeat = 0
     End If
   End If

   Do While Repeat > 0

      pos = InStr(begin, Source, Find)

     If pos > 0 Then
       tmp = Space$(Len(Source) + diff)
       Mid(tmp, 1) = Mid$(Source, 1, pos - 1)
       Mid(tmp, pos + Len(Insert)) = Mid$(Source, pos + Len(Find))
       Mid(tmp, pos) = Insert
       begin = pos + Len(Insert)
       Repeat = Repeat - 1
       If all Then Repeat = 2
       Source = tmp
     Else
       Repeat = 0
     End If
   Loop
   Replace = Source

End Function
Author
27 Mar 2009 12:41 AM
RB Smissaert
Thanks, will have a look at that.
Will it work if the replacing string is longer than the string to be
replaced?

RBS


Show quoteHide quote
"Larry Serflaten" <serfla***@usinternet.com> wrote in message
news:%23MNOaOnrJHA.2368@TK2MSFTNGP06.phx.gbl...
>
> "RB Smissaert" <bartsmissa***@blueyonder.co.uk> wrote
>> Unless I am overlooking something simple again, I don't think that will
>> work.
>> The thing is I need to replace at a specified position:
>
> Here is one that will get the job done.  You'd have to run timed tests to
> see if its faster than concatenation....  (it should be...)
>
> LFS
>
> Private Sub Form_Load()
> Debug.Print Replace("1234567", "4", "ABC")
> Debug.Print Replace("1234321", "2", "ABC", 2)
> Debug.Print Replace("1234321", "3", "XYZ", -1)
> Debug.Print Replace("1234567", "345", "X")
> Debug.Print Replace("1234321", "3", "XYZ", 1, 5)
> End Sub
>
>
> Function Replace(ByVal Source$, _
>                 ByRef Find$, _
>                 ByRef Insert$, _
>                 Optional Repeat As Long = 1, _
>                 Optional Position As Long = 0) As String
> Dim tmp As String
> Dim diff As Long
> Dim begin As Long
> Dim pos As Long
> Dim all As Boolean
>
>   begin = 1
>   diff = Len(Insert) - Len(Find)
>
>   If Repeat < 0 Then
>     all = True
>     Repeat = 2
>   End If
>
>   If Position > 0 Then
>     pos = InStr(Position, Source, Find)
>     If pos = Position Then
>       Repeat = 1
>       begin = pos
>     Else
>       Repeat = 0
>     End If
>   End If
>
>   Do While Repeat > 0
>
>      pos = InStr(begin, Source, Find)
>
>     If pos > 0 Then
>       tmp = Space$(Len(Source) + diff)
>       Mid(tmp, 1) = Mid$(Source, 1, pos - 1)
>       Mid(tmp, pos + Len(Insert)) = Mid$(Source, pos + Len(Find))
>       Mid(tmp, pos) = Insert
>       begin = pos + Len(Insert)
>       Repeat = Repeat - 1
>       If all Then Repeat = 2
>       Source = tmp
>     Else
>       Repeat = 0
>     End If
>   Loop
>   Replace = Source
>
> End Function
>
>
>
>
Author
27 Mar 2009 12:47 AM
Larry Serflaten
"RB Smissaert" <bartsmissa***@blueyonder.co.uk> wrote
> Thanks, will have a look at that.
> Will it work if the replacing string is longer than the string to be
> replaced?

Yes, look at the debug examples to see it in action.

One test that I did not include in the post is the case where the
inserted text contains the search text, for example:

Debug.Print Replace("123345", "3", "A3B", -1)

There, the insert text (A3B) contains the find text (3), but the
function will not loop forever, once the find text has been replaced,
it moves on....  The result will be "12A3BA3B45"

LFS
Author
27 Mar 2009 12:57 AM
Larry Serflaten
"Larry Serflaten" <serfla***@usinternet.com> wrote

> Here is one that will get the job done.  You'd have to run timed tests to
> see if its faster than concatenation....  (it should be...)

It will have to be amended to catch the case where the find text is at
the very end of the source string.  The earlier version errors, this version
catches that condition before it occurs:

LFS

Function Replace(ByVal Source$, _
                 ByRef Find$, _
                 ByRef Insert$, _
                 Optional Repeat As Long = 1, _
                 Optional Position As Long = 0) As String
Dim tmp As String
Dim diff As Long
Dim begin As Long
Dim pos As Long
Dim all As Boolean

   begin = 1
   diff = Len(Insert) - Len(Find)

   If Repeat < 0 Then
     all = True
     Repeat = 2
   End If

   If Position > 0 Then
     pos = InStr(Position, Source, Find)
     If pos = Position Then
       Repeat = 1
       begin = pos
     Else
       Repeat = 0
     End If
   End If

   Do While Repeat > 0

      pos = InStr(begin, Source, Find)

     If pos > 0 Then
       tmp = Space$(Len(Source) + diff)
       Mid(tmp, 1) = Mid$(Source, 1, pos - 1)
       If pos < Len(Source) Then
         Mid(tmp, pos + Len(Insert)) = Mid$(Source, pos + Len(Find))
       End If
       Mid(tmp, pos) = Insert
       begin = pos + Len(Insert)
       Repeat = Repeat - 1
       If all Then Repeat = 2
       Source = tmp
     Else
       Repeat = 0
     End If
   Loop
   Replace = Source

End Function

Bookmark and Share