Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Replace one occurence of string within string at certain position

1 view
Skip to first unread message

RB Smissaert

unread,
Mar 26, 2009, 5:17:14 PM3/26/09
to
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

Michael Williams

unread,
Mar 26, 2009, 5:36:45 PM3/26/09
to
"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message
news:OH6t2flr...@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


RB Smissaert

unread,
Mar 26, 2009, 5:57:51 PM3/26/09
to
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


"Michael Williams" <Mi...@WhiskeyAndCoke.com> wrote in message
news:uFyDEslr...@TK2MSFTNGP02.phx.gbl...

RB Smissaert

unread,
Mar 26, 2009, 6:05:04 PM3/26/09
to
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" <Mi...@WhiskeyAndCoke.com> wrote in message
news:uFyDEslr...@TK2MSFTNGP02.phx.gbl...

RB Smissaert

unread,
Mar 26, 2009, 6:34:36 PM3/26/09
to
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


"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message

news:O72am6lr...@TK2MSFTNGP05.phx.gbl...

Karl E. Peterson

unread,
Mar 26, 2009, 7:00:48 PM3/26/09
to
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


RB Smissaert

unread,
Mar 26, 2009, 7:24:27 PM3/26/09
to
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


"Karl E. Peterson" <ka...@mvps.org> wrote in message
news:eFSc1amr...@TK2MSFTNGP04.phx.gbl...

Karl E. Peterson

unread,
Mar 26, 2009, 8:11:15 PM3/26/09
to
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?

RB Smissaert

unread,
Mar 26, 2009, 8:27:12 PM3/26/09
to
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


"Karl E. Peterson" <ka...@exmvps.org> wrote in message
news:%23Xc9MCn...@TK2MSFTNGP03.phx.gbl...

Larry Serflaten

unread,
Mar 26, 2009, 8:34:15 PM3/26/09
to

"RB Smissaert" <bartsm...@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


RB Smissaert

unread,
Mar 26, 2009, 8:41:09 PM3/26/09
to
Thanks, will have a look at that.
Will it work if the replacing string is longer than the string to be
replaced?

RBS


"Larry Serflaten" <serf...@usinternet.com> wrote in message
news:%23MNOaOn...@TK2MSFTNGP06.phx.gbl...

Larry Serflaten

unread,
Mar 26, 2009, 8:47:08 PM3/26/09
to

"RB Smissaert" <bartsm...@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

Larry Serflaten

unread,
Mar 26, 2009, 8:57:45 PM3/26/09
to

"Larry Serflaten" <serf...@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

Do While Repeat > 0

If pos < Len(Source) Then


Mid(tmp, pos + Len(Insert)) = Mid$(Source, pos + Len(Find))

End If

Rick Rothstein

unread,
Mar 26, 2009, 11:12:35 PM3/26/09
to
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" <ka...@exmvps.org> wrote in message
news:%23Xc9MCn...@TK2MSFTNGP03.phx.gbl...

Rick Rothstein

unread,
Mar 26, 2009, 11:20:39 PM3/26/09
to
Oh, I meant to add "... without using concatenation" to the opening
sentence.

--
Rick (MVP - Excel)


"Rick Rothstein" <rick.new...@NO.SPAMverizon.net> wrote in message
news:O9l2hnor...@TK2MSFTNGP02.phx.gbl...

Rick Rothstein

unread,
Mar 26, 2009, 11:28:56 PM3/26/09
to
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)


"Rick Rothstein" <rick.new...@NO.SPAMverizon.net> wrote in message

news:uuTHCsor...@TK2MSFTNGP05.phx.gbl...

Eduardo

unread,
Mar 27, 2009, 4:40:38 AM3/27/09
to
"Karl E. Peterson" <ka...@exmvps.org> escribió en el mensaje
news:%23Xc9MCn...@TK2MSFTNGP03.phx.gbl...

Karl,

You get 123XX56789 if you use your implementation of the Replace function
for VB5, but if you use the buit in Replace function of VB6, strangely you
get XX56789 (it discards all the characters to the left of the Start
parameter).
I don't think the VB6 function should work in this way, and I think it's
most likely a bug.
I would had swear that the VB6 function worked as your VB5 implementation
does, but I see it's not the case.


Michael Williams

unread,
Mar 27, 2009, 6:50:07 AM3/27/09
to
"Eduardo" <m...@mm.com> wrote in message news:gqi3c8$cev$1...@aioe.org...

> You get 123XX56789 if you use your implementation of the
> Replace function for VB5, but if you use the buit in Replace
> function of VB6, strangely you get XX56789 (it discards all
> the characters to the left of the Start parameter). I don't think
> the VB6 function should work in this way, and I think it's most likely a
> bug.

Actually that's the way the VB6 Replace function is supposed to work. Here's
the appropriate extract from the help files:

"The return value of the Replace function is a string, with
substitutions made, that begins at the position specified by
start and and concludes at the end of the expression string.
It is not a copy of the original string from start to finish."

Mike


Eduardo

unread,
Mar 27, 2009, 10:23:23 AM3/27/09
to
"Michael Williams" <Mi...@WhiskeyAndCoke.com> escribió en el mensaje
news:OHD7Ynsr...@TK2MSFTNGP05.phx.gbl...

A little counterintuitive to me.
Do you understand the reason?

PS: I rather would call it CutAndReplace.


RB Smissaert

unread,
Mar 27, 2009, 10:39:09 AM3/27/09
to
> I rather would call it CutAndReplace

Yes. Never was aware of this behaviour and I will need to check all my code
to make sure it isn't causing a problem somewhere. I always thought that the
Start argument meant that it would start looking for the Find argument from
the Start position. Strange one that.

RBS


"Eduardo" <m...@mm.com> wrote in message news:gqinet$3sa$1...@aioe.org...

RB Smissaert

unread,
Mar 27, 2009, 11:34:38 AM3/27/09
to
Have tested this now and it looks it is about 2 times slower.
This is compared with this:

Function ReplaceAt(strToSearch As String, _
strToFind As String, _
strReplace As String, _
lPos As Long, _
Optional bOnlyWithFind As Boolean = True) As String

'will replace strToFind in strToSearch with strReplace,

'but only if strToFind appears at position lPos if bOnlyWithFind = True
'or replace in any case, no matter what is at that position
'----------------------------------------------------------------------
If bOnlyWithFind Then
If Mid$(strToSearch, lPos, Len(strToFind)) <> strToFind Then
ReplaceAt = strToSearch
Exit Function
End If
End If

If Len(strToFind) = Len(strReplace) Then
'this is a lot faster that concatenation
'note though that this will alter strToSearch and
'and passing that ByVal will make it about 50% slower
'----------------------------------------------------
Mid$(strToSearch, lPos, Len(strToFind)) = strReplace
ReplaceAt = strToSearch
Else


ReplaceAt = Left$(strToSearch, lPos - 1) & _
strReplace & _
Right$(strToSearch, Len(strToSearch) - (lPos +
(Len(strToFind) - 1)))

End If

End Function


And tested like this:

Sub test()

Dim i As Long


Dim str1 As String
Dim str2 As String

Dim str3 As String

str1 = String(100, "A")
str2 = "123"

StartSW

For i = 1 To 100000
str3 = ReplaceX(str1, "A", str2, 1, 50)
'str3 = ReplaceAt(str1, "A", str2, 50)
Next i

StopSW

MsgBox str3, , Len(str3)

End Sub


I suppose it could be made faster by using one of the fast string concat
routines that are available.


RBS

"Larry Serflaten" <serf...@usinternet.com> wrote in message

news:erjJjbnr...@TK2MSFTNGP04.phx.gbl...

Dave O.

unread,
Mar 27, 2009, 11:59:32 AM3/27/09
to

"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message
news:e3hHHFvr...@TK2MSFTNGP02.phx.gbl...

> Have tested this now and it looks it is about 2 times slower.

You seem to be making a big meal out of it.
Firstly let's see if I have the problem correctly:
You have a string and at a given position you want to remove some characters
and insert some others, the number of inserted and removed characters need
not be equal and there will only be one set of characters to replace.
If that's the case a quick method would be firstly calculate the length of
the final string then make a new string of that length. Then using Mid copy
the bits you want from the source string to the result string then again
using Mid plonk the new text in the gap that's waiting for it. All done -
Easy.

Good Luck
Dave O.


RB Smissaert

unread,
Mar 27, 2009, 12:21:50 PM3/27/09
to
> You seem to be making a big meal out of it.

Not sure what gives you that idea. I am just saying that the suggested code
is not
faster than what I posted. You are probably right in that prefixing a string
and doing Mid etc.
is faster than doing the concatenation as posted. Will test that now.

RBS


"Dave O." <nob...@nowhere.com> wrote in message
news:%237dbwUv...@TK2MSFTNGP06.phx.gbl...

Larry Serflaten

unread,
Mar 27, 2009, 1:35:48 PM3/27/09
to

"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote

> > You seem to be making a big meal out of it.
>
> Not sure what gives you that idea. I am just saying that the suggested code
> is not
> faster than what I posted. You are probably right in that prefixing a string
> and doing Mid etc.
> is faster than doing the concatenation as posted. Will test that now.
>

My example may be slower due to all the extra conditions it covered.
If you'll notice, the meat of the function did exactly as you indicate above;
allocate one large string and Mid copy the parts into it:

(Comments added)

' Allocate one large string


> tmp = Space$(Len(Source) + diff)

' Copy left side


> Mid(tmp, 1) = Mid$(Source, 1, pos - 1)

' Copy right side


> If pos < Len(Source) Then
> Mid(tmp, pos + Len(Insert)) = Mid$(Source, pos + Len(Find))
> End If

' Copy new text
> Mid(tmp, pos) = Insert

None the less, I think streamlining that approach would be your best
'all VB' approach....

Good luck!
LFS


Nobody

unread,
Mar 27, 2009, 1:53:51 PM3/27/09
to
"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message
news:e3hHHFvr...@TK2MSFTNGP02.phx.gbl...

> Have tested this now and it looks it is about 2 times slower.

Check these alternative Replace functions, modify as needed:

http://www.xbeat.net/vbspeed/c_Replace.htm


RB Smissaert

unread,
Mar 27, 2009, 4:56:08 PM3/27/09
to
Yes, thanks, I am aware of this site.
BTW, this is what they say about the Start argument
in the regular VB6 replace, and I agree:

VB6 Replace features a very bizarre interpretation of the Start parameter
that can be paraphrased as follows:
' *before* any replacements
Replace = Mid$(Expression, Start)
Until anybody reveals the deeper meaning of this, we will not care about it
in our emulations.

RBS


"Nobody" <nob...@nobody.com> wrote in message
news:%23L8YKUw...@TK2MSFTNGP05.phx.gbl...

Michael Williams

unread,
Mar 27, 2009, 5:17:50 PM3/27/09
to
"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message
news:%23JTww4x...@TK2MSFTNGP05.phx.gbl...

> BTW, this is what they say about the Start argument
> in the regular VB6 replace, and I agree:
> VB6 Replace features a very bizarre interpretation of the
> Start parameter that can be paraphrased as follows:
> ' *before* any replacements
> Replace = Mid$(Expression, Start)
> Until anybody reveals the deeper meaning of this, we
> will not care about it in our emulations.

Well, yes, I certainly do agree that it is rather stange behaviour. But is
/is/ documented and it /is/ the way it works, so if you do decide to use the
VB6 Replace function in your code then you must take that behaviour into
account, like it or not.

Mike


RB Smissaert

unread,
Mar 27, 2009, 5:32:31 PM3/27/09
to
> so if you do decide to use the VB6 Replace function in your code then you
> must take that behaviour into account, like it or not.

Hard to disagree with that one :-)

RBS


"Michael Williams" <Mi...@WhiskeyAndCoke.com> wrote in message

news:%23ngEAGy...@TK2MSFTNGP03.phx.gbl...

Eduardo

unread,
Mar 27, 2009, 11:02:14 PM3/27/09
to
"Michael Williams" <Mi...@WhiskeyAndCoke.com> escribió en el mensaje
news:%23ngEAGy...@TK2MSFTNGP03.phx.gbl...

I don't agree on this point.
If you were going to distribute this Replace function to everybody as a
direct replacement of the built in VB6 one, I agree, but if you are going
to use it in your programs, I don't agree that you necessary have to emulate
the VB6 one in all and every aspects.
If you do it for yourself, you can do it as you like better.
Even if you were going to distribute it, you can write a note stating that
there is such a difference.


Eduardo

unread,
Mar 27, 2009, 11:15:21 PM3/27/09
to
"Eduardo" <m...@mm.com> escribió en el mensaje news:gqk3tr$jud$1...@aioe.org...

I want to add something:
Of course both options have advantages and disadvantages.
If you fully emulates the VB6 function, the advantage is that if you later
decide to remove the function replacement, all the code will remain working.
On the other hand, if you don't emulate it, you can use the replacement
function in situations like this one that "RB Smissaert" is posting about,
and that the VB6 one is not suited for.


RB Smissaert

unread,
Mar 28, 2009, 5:24:08 AM3/28/09
to
For now I have settled for a simple replacement for the standard VB Replace
and
this uses the same arguments and as far as I can see gives the same results,
but on the
whole about 3 times faster. As I run this in an ActiveX dll, mainly from VBA
all the
arguments are ByVal:

Public Function ReplaceX(ByVal strSource As String, _
ByVal strFind As String, _
ByVal strReplace As String, _
Optional ByVal lStart As Long = 1, _
Optional ByVal lCount As Long = -1, _
Optional ByVal bCompare As VbCompareMethod =
vbBinaryCompare) As String

'could make this a bit faster by making it a Sub and putting the result in
a ByRef argument
'------------------------------------------------------------------------------------------
Dim i As Long
Dim lPos As Long
Dim lLenFind As Long

lPos = InStr(lStart, strSource, strFind, bCompare)

If lPos = 0 Then
'strFind is not in strSource, so return strSource and get out
'------------------------------------------------------------
If lStart = 1 Then
ReplaceX = strSource
Else
'to make it consistent with the normal Replace function
'------------------------------------------------------
ReplaceX = Mid$(strSource, lStart)
End If
Exit Function
End If

lLenFind = Len(strFind)

If lStart < lPos And lLenFind = Len(strReplace) Then
If lCount = 1 Then
Mid$(strSource, lPos) = strReplace
Else
Do While lPos > 0
Mid$(strSource, lPos, lLenFind) = strReplace
lPos = InStr(lPos + lLenFind, strSource, strFind, bCompare)
Loop
End If
If lStart = 1 Then
ReplaceX = strSource
Else
'to make it consistent with the normal Replace function
'------------------------------------------------------
ReplaceX = Mid$(strSource, lStart)
End If
Else
ReplaceX = Replace(strSource, strFind, strReplace, lStart, lCount,
bCompare)
End If

End Function


RBS


"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message

news:OH6t2flr...@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:
>
> 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
>

Michael Williams

unread,
Mar 28, 2009, 6:46:03 AM3/28/09
to
"Eduardo" <m...@mm.com> wrote in message news:gqk3tr$jud$1...@aioe.org...

>> [Mike Williams said] Well, yes, I certainly do agree that it is


>> rather stange behaviour. But is /is/ documented and it /is/ the
>> way it works, so if you do decide to use the VB6 Replace
>> function in your code then you must take that behaviour into account,
>> like it or not.
>

> [Eduardo said] I don't agree on this point. If you were going to


> distribute this Replace function to everybody as a direct
> replacement of the built in VB6 one, I agree, but if you are
> going to use it in your programs, I don't agree that you
> necessary have to emulate the VB6 one in all and every aspects.

You have not read my post properly, Eduardo. I never said that a coded
function to replace parts of a string should behave in the same way as the
VB6 Replace function. I did NOT say that, or anything remotely like it. I
was simply commenting on RB Smissaert's observation that the author of some
specific code made the comment, "VB6 Replace features a very bizarre
interpretation of the Start parameter". I agreed with both the author of the
code and with RB Smissaert in that the VB6 Replace function's interpretation

of the Start parameter is indeed bizarre, and I said:

But is /is/ documented and it /is/ the way it works, so if you
do decide to use the VB6 Replace function in your code then
you must take that behaviour into account, like it or not

The above is /exactly/ what I said. I specifically mentioned the VB6 Replace
function, and I stand by my statement that if you are going to use the VB6
Replace function in your code then you must take its behaviour into account.

Naturally if you write your own code to perform a specific task and if you
are not offering it as a direct replacement for a native built in function
then you are free to write it so that it behaves in any way you wish, but I
never mentioned the behaviour of coded solutions in my post, I was
specifically talking about what you should accept if you /do/ decide to use
the VB6 Replace function. You have misinterpreted what I said, Eduardo.

Mike


Eduardo

unread,
Mar 28, 2009, 10:03:31 AM3/28/09
to
"Michael Williams" <Mi...@WhiskeyAndCoke.com> escribió en el mensaje

> You have not read my post properly, Eduardo. I never said that a coded


> function to replace parts of a string should behave in the same way as the
> VB6 Replace function. I did NOT say that, or anything remotely like it. I
> was simply commenting on RB Smissaert's observation that the author of
> some specific code made the comment, "VB6 Replace features a very bizarre
> interpretation of the Start parameter". I agreed with both the author of
> the code and with RB Smissaert in that the VB6 Replace function's
> interpretation of the Start parameter is indeed bizarre, and I said:
>
> But is /is/ documented and it /is/ the way it works, so if you
> do decide to use the VB6 Replace function in your code then
> you must take that behaviour into account, like it or not
>
> The above is /exactly/ what I said. I specifically mentioned the VB6
> Replace function, and I stand by my statement that if you are going to use
> the VB6 Replace function in your code then you must take its behaviour
> into account.
>
> Naturally if you write your own code to perform a specific task and if you
> are not offering it as a direct replacement for a native built in function
> then you are free to write it so that it behaves in any way you wish, but
> I never mentioned the behaviour of coded solutions in my post, I was
> specifically talking about what you should accept if you /do/ decide to
> use the VB6 Replace function. You have misinterpreted what I said,
> Eduardo.

Yep, I had read it too fast.

Karl E. Peterson

unread,
Mar 30, 2009, 5:49:22 PM3/30/09
to
Eduardo wrote:
>> 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?
>
> You get 123XX56789 if you use your implementation of the Replace function
> for VB5, but if you use the buit in Replace function of VB6, strangely you
> get XX56789 (it discards all the characters to the left of the Start
> parameter).

Wow. So, uh, well, that's just weird.

> I don't think the VB6 function should work in this way, and I think it's
> most likely a bug.
> I would had swear that the VB6 function worked as your VB5 implementation
> does, but I see it's not the case.

I thought I *was* using VB's replace, when I posted the above. I must've had the
replacement function in whatever application I had open in the IDE at the time. I
agree, it makes more sense the way I presented it. <G>

(Actually, "my" replacement has its roots over at vbSpeed, as I recall. Whaddaya
bet they're all "wrong" too?)

David Youngblood

unread,
Mar 31, 2009, 6:59:03 AM3/31/09
to
"Karl E. Peterson" <ka...@exmvps.org> wrote...

> Eduardo wrote:
>>> 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?
>>
>> You get 123XX56789 if you use your implementation of the Replace function
>> for VB5, but if you use the buit in Replace function of VB6, strangely
>> you
>> get XX56789 (it discards all the characters to the left of the Start
>> parameter).
>
> Wow. So, uh, well, that's just weird.

But documented, "The return value of the Replace function is a string, with

substitutions made, that begins at the position specified by start and and

concludes at the end of the expression string." Also If start >
Len(expression) Replace returns Zero-length string.

David


Karl E. Peterson

unread,
Mar 31, 2009, 3:38:30 PM3/31/09
to
David Youngblood wrote:
> "Karl E. Peterson" <ka...@exmvps.org> wrote...
>> Wow. So, uh, well, that's just weird.
>
> But documented,

Yeah, I saw that. Hadn't before. Weird. :-|

0 new messages