When I finally had figured out that I can use my own language with Range.FormulaLocal in stead of Range.Formula I was very excited!
The possibilities are endless. But, I am encountering a problem with textstrings in formulas.
This code works just fine:
Range("I5").FormulaLocal = "=ALS(A5=1;H5;0)"
But these codelines are not working:
Range("I5").FormulaLocal = "=ALS(A5="x";H5;0)"
Range("I6").FormulaLocal = "=ALS.FOUT(VERT.ZOEKEN(A2;'betaaltermijnen.xlsx'!tabel;3;ONWAAR);"")
Could somebody help me?
You're accidentally ending your strings early...
First line:
If you have a variable x which you want to include in the string, then use &
Range("I5").FormulaLocal = "=ALS(A5=" & x & ";H5;0)"
If instead you're trying to have the string "x" then you must use an additional quotation mark before each in-string quotation mark. This is called an escape character.
Range("I5").FormulaLocal = "=ALS(A5=""x"";H5;0)"
This way, when VBA sees "", it treats it as the start or end of a quote within a string
By the same reasoning, your second line becomes
Range("I6").FormulaLocal = _
"=ALS.FOUT(VERT.ZOEKEN(A2;'betaaltermijnen.xlsx'!tabel;3;ONWAAR);"" "") "
Where I've used the _ underscore to continue the line without it getting too long, because the last 6 characters are the important bit!
chk this code snippet
Please refer the below code.
rv = “Are you 56' taller ?”
If I pass 20 fields ie, until [rv = “ Are you 56' taller ? "].
It’s not working because ‘ – apostrophe is used to comment in QTP
How to handle ' ( apostrophe ) in Xpath using QTP ?
Code Snippet:
rv = Replace (rv,"'", "\'")
rv = LEFT(rv,50)
If SVAL = "Yes" Then
Set oobj = Browser("xyz").Page("abc").WebElement("xpath:=//div[contains(text(),'"& rv &"')]/../..//label[starts-with(text(),'Yes')]")
oobj.Click
oobj.Click
i = i+1
End If
I really appreciate your reply.
Try with the character code chr(39) for apostrophe as shown below:
"Are you 56" & chr(39) & " taller ?"
As others mentioned this is not because ' is a comment in vbscript (not just QTP) but because you're ending the string too early.
You use single quotes for the string to compare to in the XPath and then the apostrophe closes the string too early. You should instead use regular quotes there too so that the apostrophe doesn't end the string too early.
In order to get a double quote in a string in VBScript write it twice "Like ""this"" for example".
So your XPath should look like this:
"//div[contains(text(),""Are you 56' taller ?"")]"
Rather than this:
"//div[contains(text(),'Are you 56' taller ?')]"
Or using your example:
Browser("xyz").Page("abc").WebElement("xpath:=//div[contains(text(),"""& rv &""")]/../..//label[starts-with(text(),'Yes')]")
(Note this has been tested and works)
Use ' rather than (') so that the string can be properly processed.
Supporting evidence -> click here.
This has nothing to do with the ' being the comment character. This is normal working code:
Msgbox "'I love deadlines. I like the whooshing sound they make as they fly by.' Douglas Adams"
Your code results into an error because some characters needs to be escaped like <, >, & and your infamous '. To enter the line above correctly into an XML tag you need to do this:
htmlEscaped = "'I love deadlines. I like the whooshing sound they make as they fly by.&apos Douglas Adams"
Here you can find an overview to a set of the most common characters that needs escaping (while this is not totally true: if you are using Unicode/UTF-8 encoding, some characters will parse just fine).
Unfortunately VBScript does not have a native function that escapes HTML like the Escape function for urls. Only if you are on ASP Server, you can use Server.HtmlEncode but that is not the case with you
To generalize html escaping (treath everything as special except for the most commons) you can use a script like this:
Function HTMLEncode(ByVal sVal)
sReturn = ""
If ((TypeName(sVal)="String") And (Not IsNull(sVal)) And (sVal<>"")) Then
For i = 1 To Len(sVal)
ch = Mid(sVal, i, 1)
Set oRE = New RegExp : oRE.Pattern = "[ a-zA-Z0-9]"
If (Not oRE.Test(ch)) Then
ch = "&#" & Asc(ch) & ";"
End If
sReturn = sReturn & ch
Set oRE = Nothing
Next
End If
HTMLEncode = sReturn
End Function
It could be improved a bit (you'll notice passing objects into this function will result into an error) and made more specific: the regular expression could be matching more characters. I do also not know the performance of it, regular expressions can be slow if used incorrectly, but it proves as an example.
I have a section of code that writes to the header section of the page. The problem is that the string that is written to the header occasionally contains a '&' symbol. This interferes with the code because VBA automatically views & and the following character as a piece of code, even if its part of the string.
ActiveSheet.PageSetup.CenterHeader = "&B&14 Cool New Header for &16 &I" & vbNewLine & aString
Everything works great when aString has no '&' symbol in it. I get a bold, size 14 top line followed by the size 16, italicized aString text on a second line.
In the event that aString is something like 'B&S Company of Greatness' the header will come out with "Company of Greatness" stricken out because of the '&S' contained within the string.
How can I get around this? I'd do a search in string for '&S and compensate manually by inserting another &S to cancel it out but &S might not be the only occurance of the '&' symbol that occurs.
What's the best way to get around this? Would properly diming things help by telling excel to read aString ONLY as a string value and to not apply its contents improperly?
You need to escape the ampersand by adding a second ampersand to each instance in the string, like this:
aString = Replace(aString, "&", "&&")
ActiveSheet.PageSetup.CenterHeader = "&B&14 Cool New Header for &16 &I" & _
vbNewLine & aString
I'm looking into some legacy VB 6.0 code (an Access XP application) to solve a problem with a SQL statement by the Access app. I need to use replace single quotes with 2 single quotes for cases where a customer name has an apostrophe in the name (e.g. "Doctor's Surgery":
Replace(customerName, "'", "''")
Which will escape the single quote, so I get the valid SQL:
SELECT blah FROM blah WHERE customer = 'Doctor''s Surgery'
Unfortunately the Replace function causes an infinite loop and stack overflow, presumably because it replace function recursively converts each added quote with another 2 quotes. E.g. one quote is replaced by two, then that second quote is also replaced by two, and so on...
----------------EDIT---------------
I have noticed (thanks to posters) that the replace function used in this project is custom-written:
Public Function replace(ByVal StringToSearch As String, ByVal ToLookFor As String,
ByVal ToReplaceWith As String) As String
Dim found As Boolean
Dim position As Integer
Dim result As String
position = 0
position = InStr(StringToSearch, ToLookFor)
If position = 0 Then
found = False
replace = StringToSearch
Exit Function
Else
result = Left(StringToSearch, position - 1)
result = result & ToReplaceWith
result = result & Right(StringToSearch, Len(StringToSearch) - position - Len(ToLookFor) + 1)
result = replace(result, ToLookFor, ToReplaceWith)
End If
replace = result
End Function
Apparently, VB didn't always have a replace function of it's own. This implementation must be flawed. An going to follow folk's advice and remove it in favour of VB 6's implementation - if this doesn't work, I will write my own which works. Thanks everyone for your input!
Are you sure that it's not a proprietary implementation of the Replace function?
If so it can just be replaced by VB6's Replace.
I can't remember which version it appeared in (it wasn't in Vb3, but was in VB6) so if the original code base was vb3/4 it could be a hand coded version.
EDIT
I just saw your edit, I was Right!
Yes, you should be able to just remove that function, it'll then use the in build VB6 replace function.
We use an VB6 application that has the option of replacing ' with ` or removing them completely.
You could also walk through the letters, building a second string and inserting each ' as ''.
I just tried this in Access and it works fine (no stackoverflow):
Public Function ReplaceSingleQuote(tst As String) As String
ReplaceSingleQuote = Replace(tst, "'", "''")
End Function
Public Sub TestReplaceSingleQuote()
Debug.Print ReplaceSingleQuote("Doctor's Surgery")
End Sub
Is there a way to have multiline strings in VB.NET like Python
a = """
multi
line
string
"""
or PHP?
$a = <<<END
multi
line
string
END;
Of course something that is not
"multi" & _
"line
You can use XML Literals to achieve a similar effect:
Imports System.XML
Imports System.XML.Linq
Imports System.Core
Dim s As String = <a>Hello
World</a>.Value
Remember that if you have special characters, you should use a CDATA block:
Dim s As String = <![CDATA[Hello
World & Space]]>.Value
2015 UPDATE:
Multi-line string literals were introduced in Visual Basic 14 (in Visual Studio 2015). The above example can be now written as:
Dim s As String = "Hello
World & Space"
MSDN article isn't updated yet (as of 2015-08-01), so check some answers below for details.
Details are added to the Roslyn New-Language-Features-in-VB-14 Github repository.
VB.Net has no such feature and it will not be coming in Visual Studio 2010. The feature that jirwin is refering is called implicit line continuation. It has to do with removing the _ from a multi-line statement or expression. This does remove the need to terminate a multiline string with _ but there is still no mult-line string literal in VB.
Example for multiline string
Visual Studio 2008
Dim x = "line1" & vbCrlf & _
"line2"
Visual Studio 2010
Dim x = "line1" & vbCrlf &
"line2"
I used this variant:
Dim query As String = <![CDATA[
SELECT
a.QuestionID
FROM
CR_Answers a
INNER JOIN
CR_Class c ON c.ClassID = a.ClassID
INNER JOIN
CR_Questions q ON q.QuestionID = a.QuestionID
WHERE
a.CourseID = 1
AND
c.ActionPlan = 1
AND q.Q_Year = '11/12'
AND q.Q_Term <= (SELECT CurrentTerm FROM CR_Current_Term)
]]>.Value()
it allows < > in the string
Multi-line strings are available since the Visual Studio 2015.
Dim sql As String = "
SELECT ID, Description
FROM inventory
ORDER BY DateAdded
"
You can combine them with string interpolation to maximize usefullness:
Dim primaryKey As String = "ID"
Dim inventoryTable As String = "inventory"
Dim sql As String = $"
SELECT {primaryKey}, Description
FROM {inventoryTable}
ORDER BY DateAdded
"
Note that interpolated strings begin with $ and you need to take care of ", { and } contained inside – convert them into "", {{ or }} respectively.
Here you can see actual syntax highlighting of interpolated parts of the above code example:
If you wonder if their recognition by the Visual Studio editor also works with refactoring (e.g. mass-renaming the variables), then you are right, code refactoring works with these. Not mentioning that they also support IntelliSense, reference counting or code analysis.
Multiline string literals are introduced in Visual Basic 14.0 - https://roslyn.codeplex.com/discussions/571884
You can use then in the VS2015 Preview, out now - http://www.visualstudio.com/en-us/downloads/visual-studio-2015-downloads-vs (note that you can still use VS2015 even when targeting an older version of the .NET framework)
Dim multiline = "multi
line
string"
VB strings are basically now the same as C# verbatim strings - they don't support backslash escape sequences like \n, and they do allow newlines within the string, and you escape the quote symbol with double-quotes ""
this was a really helpful article for me, but nobody mentioned how to concatenate in case you want to send some variables, which is what you need to do 99% of the time.
... <%= variable %> ...
Here's how you do it:
<SQL>
SELECT * FROM MyTable WHERE FirstName='<%= EnteredName %>'
</SQL>.Value
Well, since you seem to be up on your python, may I suggest that you copy your text into python, like:
s="""this is gonna
last quite a
few lines"""
then do a:
for i in s.split('\n'):
print 'mySB.AppendLine("%s")' % i
# mySB.AppendLine("this is gonna")
# mySB.AppendLine("last quite a")
# mySB.AppendLine("few lines")
or
print ' & _ \n'.join(map(lambda s: '"%s"' % s, s.split('\n')))
# "this is gonna" & _
# "last quite a" & _
# "few lines"
then at least you can copy that out and put it in your VB code. Bonus points if you bind a hotkey
(fastest to get with:Autohotkey) to do this for for whatever is in your paste buffer. The same idea works well for a SQL formatter.
Multi-line string literals in vb.net using the XElement class.
Imports System.Xml.Linq
Public Sub Test()
dim sOderBy as string = ""
dim xe as XElement = <SQL>
SELECT * FROM <%= sTableName %>
<ORDER_BY> ORDER BY <%= sOrderBy %></ORDER_BY>
</SQL>
'** conditionally remove a section
if sOrderBy.Length = 0 then xe.<ORDER BY>.Remove
'** convert XElement value to a string
dim sSQL as String = xe.Value
End Sub
To me that is the most annoying thing about VB as a language.
Seriously, i once wrote the string in a file and wrote code something along the lines of:
Dim s as String = file_get_contents("filename.txt")
just so i could test the query directly on SQL server if i need to.
My current method is to use a stored procedure on the SQL Server and just call that so i can pass in parameters to the query, etc
I figured out how to use both <![CDATA[ along with <%= for variables, which allows you to code without worry.
You basically have to terminate the CDATA tags before the VB variable and then re-add it after so the CDATA does not capture the VB code. You need to wrap the entire code block in a tag because you will you have multiple CDATA blocks.
Dim script As String = <code><![CDATA[
<script type="text/javascript">
var URL = ']]><%= domain %><![CDATA[/mypage.html';
</script>]]>
</code>.value
You could (should?) put the string in a resource-file (e.g. "My Project"/Resources) and then get it with
Dim a = My.Resources.Whatever_you_chose
Disclaimer: I love python. It's multi-line strings are only one reason.
But I also do VB.Net, so here's my short-cut for more readable long strings.
Dim lines As String() = {
"Line 1",
"Line 2",
"Line 3"
}
Dim s As String = Join(lines, vbCrLf)
you can use XML for this like
dim vrstr as string = <s>
some words
some words
some
words
</s>
in Visual studio 2010 (VB NET)i try the following and works fine
Dim HtmlSample As String = <anything>what ever you want to type here with multiline strings</anything>
dim Test1 as string =<a>onother multiline example</a>
Available in Visual Basic 14 as part of Visual Studio 2015
https://msdn.microsoft.com/en-us/magazine/dn890368.aspx
But not yet supported by R#. The good news is they will be supported soon! Please vote on Youtrack to notify JetBrains you need them also.
If you need an XML literal in VB.Net with an line code variable, this is how you would do it:
<Tag><%= New XCData(T.Property) %></Tag>
Since this is a readability issue, I have used the following code:
MySql = ""
MySql = MySql & "SELECT myTable.id"
MySql = MySql & " FROM myTable"
MySql = MySql & " WHERE myTable.id_equipment = " & lblId.Text
You can also use System.Text.StringBuilder class in this way:
Dim sValue As New System.Text.StringBuilder
sValue.AppendLine("1st Line")
sValue.AppendLine("2nd Line")
sValue.AppendLine("3rd Line")
Then you get the multiline string using:
sValue.ToString()
Use vbCrLf or vbNewLine. It works with MessageBoxes and many other controls I tested.
Dim str As String
str = "First line" & vbCrLf & "Second line"
MsgBox(str)
str = "First line" & vbNewLine & "Second line"
MsgBox(str)
It will show two identical MessageBoxes with 2 lines.
No, VB.NET does not yet have such a feature. It will be available in the next iteration of VB (visual basic 10) however (link)
if it's like C# (I don't have VB.Net installed) you can prefix a string with #
foo = #"Multiline
String"
this is also useful for things like #"C:\Windows\System32\" - it essentially turns off escaping and turns on multiline.