Skip to content

Commit 7c5eb31

Browse files
committed
Improvement: ability to compare literal strings given in expressions.
1 parent 410d694 commit 7c5eb31

File tree

2 files changed

+70
-18
lines changed

2 files changed

+70
-18
lines changed

src/VBAexpressions.cls

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ Private Const d_lCurly As String = "{"
143143
Private Const d_rCurly As String = "}"
144144
Private Const d_lParenthesis As String = "("
145145
Private Const d_rParenthesis As String = ")"
146+
Private Const d_Apostrophe As String = "'"
146147
'#
147148
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
148149
' VARIABLES:
@@ -804,14 +805,18 @@ Private Sub CastCase(ByRef Expression As String, ByRef outStr As String)
804805
End If
805806
End Sub
806807

807-
Private Function CastOPtype(ByRef strOperand As String, ByRef Negate As Boolean) As Double
808-
If AscW(strOperand) < 58 Then
809-
CastOPtype = CDbl(strOperand)
808+
Private Function CastOPtype(ByRef strOperand As String, ByRef Negate As Boolean) As Variant
809+
If InStrB(1, strOperand, d_Apostrophe) Then 'Literal strings like ['string']
810+
CastOPtype = strOperand
810811
Else
811-
If Not Negate Then
812-
CastOPtype = -1 * CBool(strOperand)
812+
If AscW(strOperand) < 58 Then
813+
CastOPtype = CDbl(strOperand)
813814
Else
814-
CastOPtype = -1 * (Not CBool(strOperand))
815+
If Not Negate Then
816+
CastOPtype = -1 * CBool(strOperand)
817+
Else
818+
CastOPtype = -1 * (Not CBool(strOperand))
819+
End If
815820
End If
816821
End If
817822
End Function
@@ -933,8 +938,8 @@ End Function
933938

934939
Public Function Create(ByRef aExpression As Variant) As VBAexpressions
935940
If aExpression <> vbNullString Then
936-
ExprToEval = RemoveDupNegation(ApplyLawOfSigns(Join$(Split(aExpression, " "), vbNullString)))
937-
If ExprToEval <> RemoveDupNegation(ApplyLawOfSigns(Join$(Split(P_EXPRESSION, " "), vbNullString))) Then
941+
ExprToEval = RemoveDupNegation(ApplyLawOfSigns(ReconstructLiteralStrings(CStr(aExpression), Join$(Split(aExpression, " "), vbNullString))))
942+
If ExprToEval <> RemoveDupNegation(ApplyLawOfSigns(ReconstructLiteralStrings(CStr(P_EXPRESSION), Join$(Split(P_EXPRESSION, " "), vbNullString)))) Then
938943
P_EXPRESSION = aExpression
939944
VariablesInit ExprToEval
940945
Parse ExprToEval
@@ -2079,6 +2084,16 @@ Private Function IsLikeSciNot(ByRef Chars As String) As Boolean
20792084
End If
20802085
End Function
20812086

2087+
Private Function IsLiteralString(ByRef aString As String) As Boolean
2088+
If LenB(aString) Then
2089+
If AscW(aString) = 39 Then 'Apostrophe
2090+
IsLiteralString = (InStrB(3, aString, d_Apostrophe) = LenB(aString) - 1)
2091+
Else
2092+
IsLiteralString = False
2093+
End If
2094+
End If
2095+
End Function
2096+
20822097
Private Function IsPlusOrMinus(ByRef Char As String) As Boolean
20832098
If LenB(Char) Then
20842099
Select Case AscW(Char)
@@ -2310,13 +2325,18 @@ Private Sub ParseVariables(ByRef Expression As String)
23102325
Do
23112326
tmpChr = MidB$(Expression, curPos, 2)
23122327
varLen = 0
2313-
If IsLetter(tmpChr) Then
2328+
If IsLetter(tmpChr) Or tmpChr = d_Apostrophe Then
23142329
varInitPos = curPos
2315-
Do
2316-
varLen = varLen + 2
2317-
curPos = curPos + 2
2318-
tmpChr = MidB$(Expression, curPos, 2)
2319-
Loop While IsExtAlphaNumeric(tmpChr) And curPos < lenExpr
2330+
If tmpChr <> d_Apostrophe Then
2331+
Do
2332+
varLen = varLen + 2
2333+
curPos = curPos + 2
2334+
tmpChr = MidB$(Expression, curPos, 2)
2335+
Loop While IsExtAlphaNumeric(tmpChr) And curPos < lenExpr
2336+
Else
2337+
curPos = InStrB(varInitPos + 2, Expression, d_Apostrophe)
2338+
varLen = curPos - varInitPos + 2
2339+
End If
23202340
If varInitPos > 2 Then
23212341
tmpPos = varInitPos - 2
23222342
Else
@@ -2326,7 +2346,9 @@ Private Sub ParseVariables(ByRef Expression As String)
23262346
tmpVar = MidB$(Expression, varInitPos, varLen)
23272347
If Not ReservedToken(tmpVar) Then
23282348
If GetFunctionName(LCase$(tmpVar)) = vbNullString Then
2329-
AddVariable tmpVar, ConstantKey
2349+
If Not IsLiteralString(tmpVar) Then 'Exclude literal strings
2350+
AddVariable tmpVar, ConstantKey
2351+
End If
23302352
End If
23312353
End If
23322354
Else
@@ -2336,7 +2358,9 @@ Private Sub ParseVariables(ByRef Expression As String)
23362358
charsBefore = MidB$(Expression, tmpPos + 1, varInitPos - (tmpPos + 1)) 'Chars before variable
23372359
If IsNumeric(charsBefore) Then 'implied multiplication found
23382360
If GetFunctionName(LCase$(tmpVar)) = vbNullString Then
2339-
AddVariable tmpVar, ConstantKey
2361+
If Not IsLiteralString(tmpVar) Then
2362+
AddVariable tmpVar, ConstantKey
2363+
End If
23402364
End If
23412365
Expression = MidB$(Expression, 1, varInitPos - LenB(charsBefore) - 1) & _
23422366
charsBefore & op_mult & tmpVar & _
@@ -2373,6 +2397,34 @@ Private Function Power(ByRef Expression As String) As Double
23732397
Power = tmpEval
23742398
End Function
23752399

2400+
Private Function ReconstructLiteralStrings(InputExpr As String, StoredExp As String) As String
2401+
Dim curPosInput As Long
2402+
Dim lastPosInput As Long
2403+
Dim curPosStored As Long
2404+
Dim lastPosStored As Long
2405+
Dim closingMarkInput As Long
2406+
Dim closingMarkStored As Long
2407+
Dim tmpResult As String
2408+
2409+
lastPosInput = 1
2410+
lastPosStored = -1
2411+
curPosInput = InStrB(lastPosInput, InputExpr, d_Apostrophe)
2412+
tmpResult = StoredExp
2413+
Do While curPosInput 'Found literal string
2414+
lastPosStored = lastPosStored + 2
2415+
curPosStored = InStrB(lastPosStored, tmpResult, d_Apostrophe)
2416+
closingMarkInput = InStrB(curPosInput + 2, InputExpr, d_Apostrophe)
2417+
closingMarkStored = InStrB(curPosStored + 2, tmpResult, d_Apostrophe)
2418+
tmpResult = MidB$(tmpResult, 1, curPosStored - 1) _
2419+
& MidB$(InputExpr, curPosInput, closingMarkInput - curPosInput + 2) _
2420+
& MidB$(tmpResult, closingMarkStored + 2)
2421+
lastPosStored = closingMarkStored + 2
2422+
lastPosInput = closingMarkInput + 2
2423+
curPosInput = InStrB(lastPosInput, InputExpr, d_Apostrophe)
2424+
Loop
2425+
ReconstructLiteralStrings = tmpResult
2426+
End Function
2427+
23762428
Private Function RemoveDupNegation(ByRef Expression As String) As String
23772429
Dim tmpResult As String
23782430

@@ -2680,11 +2732,11 @@ Private Sub VariableAssignment(ByRef vString As String)
26802732
Dim avIcounter As Long
26812733
Dim VarIdx As Long
26822734

2683-
tmpAssignment() = Split(Join(Split(vString, " "), vbNullString), P_SEPARATORCHAR)
2735+
tmpAssignment() = Split(ReconstructLiteralStrings(vString, Join(Split(vString, " "), vbNullString)), P_SEPARATORCHAR)
26842736
For avIcounter = LBound(tmpAssignment) To UBound(tmpAssignment)
26852737
tmpValues() = Split(tmpAssignment(avIcounter), "=")
26862738
If tmpValues(UBound(tmpValues)) <> vbNullString Then
2687-
If IsNumeric(tmpValues(UBound(tmpValues))) Then
2739+
If IsNumeric(tmpValues(UBound(tmpValues))) Or IsLiteralString(tmpValues(UBound(tmpValues))) Then
26882740
VarIdx = GetCBItemIdx(ExprVariables, tmpValues(LBound(tmpValues)))
26892741
If VarIdx > -1 Then
26902742
ExprVariables.Storage(VarIdx).value = tmpValues(UBound(tmpValues))

testing/tests/Test runner.xlsm

9.03 KB
Binary file not shown.

0 commit comments

Comments
 (0)