Reputation: 870
In VBA and VB6 I can assign something to mid
for Example mid(str,1,1)="A"
in VBS this doesn't work.
I need this because String concatenation is freakin' slow
Here is the actual code i hacked together real quick
Function fastXMLencode(str)
Dim strlen
strlen = Len(str)
Dim buf
Dim varptr
Dim i
Dim j
Dim charlen
varptr = 1
buf = Space(strlen * 7)
Dim char
For i = 1 To strlen
char = CStr(Asc(Mid(str, i, 1)))
charlen = Len(char)
Mid(buf, varptr, 2) = "&#"
varptr = varptr + 2
Mid(buf, varptr, charlen) = char
varptr = varptr + charlen
Mid(buf, varptr, 1) = ";"
varptr = varptr + 1
Next
fastXMLencode = Trim(buf)
End Function
How can i get this to work in VBS?
Upvotes: 1
Views: 782
Reputation: 1134
It's never too late to suggest an answer, even to a decade-old question...
One great thing about VBScript is that even though it's a subset of VB/VBA it still lets you declare (and use) classes. And having classes implies them having properties, with getters and/or setters... if you can guess where I'm going...
So if you wrap a class around a VBA-compatible implementation of Mid()
, it's actually possible to emulate Mid() statements with a Let property. Consider the following code:
Class CVBACompat
' VB6/VBA-Like Mid() Statement
Public Property Let LetMid(ByRef Expression, ByVal StartPos, ByVal Length, ByRef NewValue) ' ( As String, As Long, As Long, As String)
Dim sInsert ' As String
sInsert = Mid(NewValue, 1, Length)
Expression = Mid(Expression, 1, StartPos - 1) & sInsert & Mid(Expression, StartPos + Len(sInsert))
End Property
' VB6/VBA-Like IIf() Function
Public Function IIf(Expression, TruePart, FalsePart)
If CBool(Expression) Then
IIf = TruePart
Else
IIf = FalsePart
End If
End Function
End Class: Public VBACompat: Set VBACompat = New CVBACompat: Public Function IIf(X, Y, Z): IIf = VBACompat.IIf(X, Y, Z): End Function
VBA's language specification says that when Mid( <string-expression>, <start> [, <length> ] )
is used as a statement, what's to be replaced in the source string <string-expression>
is the lowest number of characters given the entire RHS expression or as limited by the <lenght>
argument, when provided. Now, you can't have optional arguments in VBScript, so if you want to be able to also use statements of the sort Mid( <string-expression>, <start> ) = <expression>
you'll have to have two separate implementations.
The implementation proposed above can be checked with the following code (not including checks for error-throwing conditions, which are the same as for the Mid()
function anyway) :
Dim f ' As String
Dim g ' As String
f = "1234567890"
g = f
' VB6 / VBA: Mid(f, 5, 2) = "abc"
VBACompat.LetMid(f, 5, 2) = "abc"
' VB6 / VBA: Mid(g, 5, 4) = "abc"
VBACompat.LetMid(g, 5, 4) = "abc"
WScript.Echo "First call " & IIf(f = "1234ab7890", "passes", "fails")
WScript.Echo "Second call " & IIf(g = "1234abc890", "passes", "fails")
In any case, since the proposed solution is just an emulation of otherwise native code implementations (in VB6, VBA), and still implies string concatenation anyway with the overhead of class instantiation + VTable translations, the OP'd be better off creating and making available an ActiveX component (OCX) to do concatenations in series.
Upvotes: 0
Reputation: 24227
Authoritative source explicitly stating it's not available in VBScript:
Visual Basic for Applications Features Not In VBScript:
Strings: Fixed-length strings LSet, RSet Mid Statement StrConv
VBA has both a Mid Statement and a Mid Function. VBScript only has the Mid Function.
The one other option you have if you are stuck doing this in VBScript is to make API calls. Since you are already comfortable working directly with the string buffer this might not be too big a jump for you. This page should get you started: String Functions
Sorry, it looks like API calls are out, too: Rube Goldberg Memorial Scripting Page: Direct API Calls Unless you want to write an ActiveX wrapper for your calls, but we're starting to get into an awful lot of work (and additional maintenance requirements) now.
Upvotes: 2
Reputation: 2251
This is not possible, mid(str,1,1)
is a function which just returns a number (str is not passed 'by reference' and is not altered).
Upvotes: 0
Reputation: 190943
You can't do that. You will have to rebuild the string from scratch.
Upvotes: 1