I need quotes in a string in VB Net.
c = C:\test.doc
How can I realize that the string looks like:
PrintFile /File="C:\test.doc" /OutputFile="C:\test.pdf"
online I read that I have to double the quotes...
but this doesn't work:
" PrintFile /File=""" & c & """ /OutputFile=""" & pfadFertig & pdfName & ".pdf"""
How can I get c and pfadFertig & pdfName & .pdf appear in quotes?
You do indeed have to double the quotes. This is a great example of why you should use String.Format or, even better, string interpolation. Using concatenation operators (&) already makes your code harder to read but with all the extra quotes, it's harder still. Do this:
Dim str = $"PrintFile /File=""{c}"" /OutputFile=""{pfadFertig}{pdfName}.pdf"""
It's obviously much easier to read.
Also I suspect that pfadFertig is a folder path, in which case you should be using Path.Combine to create the file path:
Dim str = $"PrintFile /File=""{c}"" /OutputFile=""{Path.Combine(pfadFertig, pdfName)}.pdf"""
Path.Combine will ensure the correct number of slashes regardless of what trailing or leading slashes are included in the inputs, so you can never make a mistake. In this case, I could probably excuse one concatenation operator as it may seem more natural:
Dim str = $"PrintFile /File=""{c}"" /OutputFile=""{Path.Combine(pfadFertig, pdfName & ".pdf")}"""
Related
I have a String in VBA with this text: < History Version="1.10" Client="TestClient001" >
I want to get this TestClient001 or anything that's inside Client="xxxx"
I made this code but it's not working
Client = MID(text,FIND("Client=""",text)+1,FIND("""",text)-FIND("Client=""",text)-1)
Is there a way to specifically get the text inside Client="xxxx"?
There's no such function as Find in VBA - that's a worksheet function. The VBA equivalent is InStr, but I don't think you need to use it here.
The best tool for extracting one string from another in VBA is often Split. It takes one string and splits it into an array based on a delimiting string. The best part is that the delimiter doesn't have to be a single character - you can make it an entire string. In this case, we'd probably do well with two nested Split functions.
Client = Split(Split(text,"Client=""")(1),Chr(34))(0)
The inner Split breaks your text string where it finds "Client="". The (1) returns array element 1. Then the outer Split breaks that returned text where it finds a " character, and returns array element 0 as the final result.
For better maintainability, you may want to use constants for your delimiters as well.
Sub EnclosedTextTest()
Const csFlag1 As String = "Client="""
Const csFlag2 As String = """"
Const csSource As String = "< History Version=""1.10"" Client=""TestClient001"" >"
Dim strClient As String
strClient = Split(Split(csSource, csFlag1)(1), csFlag2)(0)
Debug.Print strClient
End Sub
However, if the Split method doesn't work for you, we can use a method similar to the one you were using, with InStr. There are a couple of options here as well.
InStr will return the position in a string that it finds a matching value. Like Split, it can be given an entire string as its delimiter; however, if you use more than one character you need to account for the fact that it will return where it finds the start of that string.
InStr(1,text,"Client=""")
will return 26, the start of the string "Client="" in the text. This is one of the places where it's helpful to have your delimiter stored in a constant.
intStart = InStr(1,text,csFlag1)+len(csFlag1)
This will return the location it finds the start of the delimiter, plus the length of the delimiter, which positions you at the beginning of the text.
If you store this position in a variable, it makes the next part easier as well. You can use that position to run a second InStr and find the next occurrence of the " character.
intEnd = InStr(intStart,text,csFlag2)
With those values, you can perform your mid. You code overall will look something like this:
Sub InstrTextTest()
Const csFlag1 As String = "Client="""
Const csFlag2 As String = """"
Const csSource As String = "< History Version=""1.10"" Client=""TestClient001"" >"
Dim strClient As String
Dim intPos(0 To 1) As Integer
intPos(0) = InStr(1, csSource, csFlag1) + Len(csFlag1)
intPos(1) = InStr(intPos(0), csSource, csFlag2)
strClient = Mid(csSource, intPos(0), intPos(1) - intPos(0))
Debug.Print strClient
End Sub
This will work, but I prefer the Split method for ease of reading and reuse.
You can make use of Split function to split at character = then with last element of the resulting array remove character quotes and > with help of replace function and you will get the required output.
In the end I got it thanks to the idea given by #alok and #Bigben
Dim cl() As String
Dim ClientCode As String
If (InStr(1, temp, "Client=", vbTextCompare) > 0) Then
cl = Split(temp, "=")
ClientCode = cl(UBound(cl))
ClientCode = Replace(ClientCode, """", "")
ClientCode = Replace(ClientCode, ">", "")
It's XML, so you could do this:
Dim sXML As String
sXML = "<History Version=""1.10"" Client=""TestClient001"">"
With CreateObject("MSXML.Domdocument")
.LoadXML Replace(sXML, ">", "/>") 'close the element
Debug.Print .FirstChild.Attributes.getnameditem("Client").Value
End With
Dear all i want to format my cell based on the Cell value. There are 3 possible Conditions:
Cell is larger than 0.05 -> the Value should stay the same but be fromated to 0.0
Cell is smaller than a variable (called Threshold) -> the Value should be replaced with a String "a.C."
Cell is Zero -> the Value should be replaced with a Dash"
I figured out how to do this without a vavriable in here. How to add a text string .numberformat in vba is discussed here!
This:
.NumberFormat = "[=0]---;[<0.05] ""a.C."";0.0 "
Does work, while this:
Dim threshold as Double
threshold = 0.05
.NumberFormat = "[=0]---;[<threshold] ""a.C."";0.0 "
Does not work. I guess i nedd to either pass a special variable typoe to the "<" comperator or i need to escape the variable somehow?
A hint would be really appreciated!
Thank you in advance
That's because threshold is part of your number format string. Basically everything that is within quotes is not touched by VBA - except for the double double quotes that tells VBA to use a quote character within the string rather than end the string.
To put the content of the variable into a string, use string concatenation. This is done in VBA using the "&" operator:
.NumberFormat = "[=0]---;[<" & threshold & "] ""a.C."";0.0 "
However, as Double can be a little bit nasty because of rounding, it's maybe better to use the format command to output it in the wanted form (eg 2 digits after the decimal). And it's usually a good idea to use an intermediate variable that you can easily check with the debugger:
Dim myNumberFormat as string
myNumberFormat = "[=0]---;[<" _
& format(threshold, "0.00") _
& "] ""a.C."";0.0 "
.NumberFormat = myNumberFormat
is there a way to check if the string begins with any 4 letters. I am looking for something like this:
If string like "####*" then
'DO STUFF
end if
"#" is for digits, I need the same thing but for letters only.
Can this be done without regEx?
I don't know a way to do this without using regular expressions. We can try using regex Test along with the pattern ^[A-Z]{4}.*$:
Dim input As String
Dim regex As Object
Set regex = New RegExp
regex.Pattern = "^[A-Z]{4}.*$"
input = "ABCD blah"
If regex.Test(input) Then
'DO STUFF
End If
You can do it with Like almost the same as with RegEx.
"{#}" - doesn't exist in Like operators, but "[A-Z]" absolutely valid
if string like "[A-Z][A-Z][A-Z][A-Z]*" then
'DO STUFF
end if
Can this be done without regEx?
Yes, there is no specific need for Regular Expressions since the Like operator is quite capable as some sort of last resort to handle the situation, just like the writer of this article explains. Also, RegEx is sort of slow on a larger database. Nonetheless, RegEX is a great tool to use!
The solution provided by #AlexandruHapco would tell you if the string starts with 4 capital letters. But to account for lower OR upper, you can extend this logic:
If str Like "[a-zA-Z][a-zA-Z][a-zA-Z][a-zA-Z]*" Then
However, to shorten this a bit we can use [!charlist] to tell the operator we are looking for something that is NOT in the provided range. In other words, we could use:
If str Like "[!0-9][!0-9][!0-9][!0-9]*" Then
This last solution won't work when your string has any other characters than alphanumeric ones.
Approach using the FilterXML function
The WorksheetFunction FilterXML() has been added in ►Excel 2013 and allows to specify any XPath search string for a given XML document, which hasn't to be a locally saved file (needing WebService() function), but can be a string within well formed opening and closing nodes, i.e. our test string with some easy node additions (partly comparable to a html structure).
Example call
Sub TextXML()
Dim myString As String
myString = "ABCD blah"
If check(myString) Then
'DO STUFF
Debug.Print "okay"
Else
Debug.Print "oh no"
End If
End Sub
Help function
Function check(ByVal teststring As String) As Boolean
Const s As String = Chr(185) ' unusual character, e.g. Chr(185): "¹"
On Error GoTo oops
If Len(WorksheetFunction.FilterXML("<all><i>" & teststring & "</i></all>", "//i[substring(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','" & _
String(26, s) & "'),1,4)='" & String(4, s) & "']")) > 0 Then check = True
Exit Function
oops:
Err.Clear
End Function
tl;tr - how to use VBA in Excel versions before 2013
For the sake of the art the classic way to use XPath via XMLDOM methods:
Example call
Sub TextXML2()
Dim myString As String
myString = "ABCD blah"
If check2(myString) Then
'DO STUFF
Debug.Print "okay"
Else
Debug.Print "oh no"
End If
End Sub
Help functions
Function check2(ByVal teststring As String) As Boolean
' Purpose: check if first 4 characters of a test string are upper case letters A-Z
' [0] late bind XML document
Dim xDoc As Object
Set xDoc = CreateObject("MSXML2.DOMDocument.6.0")
' [1] form XML string by adding opening and closing node names ("tags")
teststring = "<all><i>" & teststring & "</i></all>"
' [2] load XML
If xDoc.LoadXML(teststring) Then
' [3a] list matching item(s) via XPath
Dim myNodeList As Object
Set myNodeList = xDoc.SelectNodes(XPath())
'Debug.Print teststring, " found: " & myNodeList.Length
' [3b] return true if the item matches, i.e. the list length is greater than zero
If myNodeList.Length > 0 Then check2 = True
End If
End Function
Function XPath() As String
' Purpose: create XPath string to get nodes where the first 4 characters are upper case letters A-Z
' Result: //i[substring(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹'),1,4)="¹¹¹¹"]
' get UPPER case alphabet
Const ABC As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
' define replacement string consisting of an unusual character repeated 26 times
Const UNUSUAL As String = "¹" ' << replace by your preferenced character
Dim replacement As String: replacement = String(Len(ABC), UNUSUAL)
'return XPath string
XPath = "//i[substring(translate(.,'" & ABC & "','" & replacement & "'),1,4)=""" & String(4, UNUSUAL) & """]"
End Function
To test a few characters -- the first 4 letters in this case -- you can always do the following:
If Not (Mid(string, 1, 1) Like "#" And Mid(string, 2, 1) Like "#" _
And Mid(string, 3, 1) Like "#" And Mid(string, 4, 1) Like "#") Then
' DO STUFF
End If
It's a bit more to type then when using the Like operator, but so what? Also, you can use Select Case in a loop...
Another option is to use IsNumeric(Mid(string, i, 1)) instead of Mid(string, i, 1) Like "#", etc.
Granted, this approach is still quite practical with 4 characters, but is not as flexible and very much not scalable like RegEx is.
I'm trying to prepare my data to be inserted in a SQL database, so certain pieces need to be surrounded by quotes.
For Each r In Range("A2", last_data)
r.Value2 = """ & r.Value2 & """
Next r
This just populates everything with 'r.value2'. Using a single quote makes it only appear on the right side of the word.
Essentially, the sheet needs to be modified so every word is surrounded by double quotes. I had a custom code in Excel that surrounded everything with quotes but when VBA reads the cells it ignores the custom formatting.
I think you need to escape the single, double quote within the ... er... quotes:
For Each r In Range("A2", last_data)
r.Value2 = """" & r.Value2 & """"
Next r
The fact that the escape character is, unfortunately, yet another double quote character, makes things a bit confusing.
So for each double quote that you want to add, you have an escape character ("), followed by the actual double quote that you want to add. These are then surrounded by two more double quotes, denoting that it is a string value.
I'm sorry if I haven't explained this well, but I hope you get the idea.
Although, as #Comintern suggests in comments, there is most likely a better way of doing what you want.
am exporting data from access to excel using vba , and i want to excel to receive these lines:-
=COUNTIF('Sheet1'!G2:G68,"1/1")
=COUNTIF('Sheet1'!G2:G68,"1/2")
etc...
my problem is that i can't add these double quotations right,i know that to print this symbol i should put it twice like this "" but still no luck,am getting all kinds of error,can you please modify my code:=
For r = 6 To 16
.Range("B" & r).Value = "=COUNTIF('Sheet1'!C1:C67,1/" & r - 5 & ")"
Next
thanks
If you wish to embed double quotes into the string you are building you can either do it by (as you mentioned) using two pairs of double quotes to 'escape' the double quote you are attempting to add, as follows:
"=COUNTIF('Sheet1'!C1:C67,""1/" & r - 5 & """)"
...which will return:
=COUNTIF('Sheet1'!C1:C67,"1/-5")
An important point to remember is that in order to properly escape the double quote you are inserting, you dont count the double quotes that are defining the string itself as one of the two pairs; That is why in the above example there are 4 pairs at the end:
""")"
The outer two define the string itself; the inner two represent the escaped double quote character.
I always found this form somewhat confusing, and would often opt to instead insert the double quotes by using the chr function, passing in the ascii value for the double quotes character, which is 34;
"=COUNTIF('Sheet1'!C1:C67," & chr(34) & "1/" & r - 5 & chr(34) & ")"
...which will return the same result as the first example:
=COUNTIF('Sheet1'!C1:C67,"1/-5")
Hope this helps,
nim