Random string picker (string names are exactly the same, except the number) - string

Dim rnd As New Random
Dim quote1, quote2, quote3 As String
Dim int As Integer
int = rnd.Next(1, 3)
quote1 = "never give up"
quote2 = "always believe in yourself"
quote3 = "always follow your dreams"
MessageBox.Show("quote" & int)
Hey, can somebody please tell me, how I can assign the int to the word quote, so every time it would pick a different quote?

With only 3 quotes you can do something like
Dim quoteIndex As Integer = Rnd.Next(1, 3)
Dim quote As String = ""
Select Case quoteIndex
Case 1
quote = quote1
Case 2
quote = quote2
Case 3
quote = quote3
End Select
MessageBox.Show(quote)
But in all honesty it's a quite lame solution, more akin to ninja code than to good practices. Instead, you should use an array or a list (which can be created inside this method or come from somewhere else like an overload or a modal variable):
Dim quoteList As New List(Of String)
quoteList.AddRange({"never give up", "always believe in yourself", "always follow your dreams", "something else"})
Dim quoteChoosen As Integer = Rnd.Next(0, quoteList.Count) 'this array start at zero
MessageBox.Show(quoteList(quoteChoosen)) '
If your list evolves over time (assuming that it's stored in a variable somewhere), your method won't need to be updated. Your user could add his own motivational quotes to the list without breaking your code, for an example.

As your code it written, you're showing a string value in the MessageBox. The string is being appended to, so it is dynamic and random, but it's still a string.
To get the affect I think you're looking for, you would need to use your random value as a pointer of some sort to reference a variable value. Using an array is probably the most straight-forward way to do that with this code. Instead of having 3 distinct quote strings values, you could create an array of strings...something like
quote = new string[]
where
quote[0] = "never give up"
then you could do something like MessageBox.Show(quote[int])

Related

Best formula/method to extract a standard set of numbers from a string?

I have the following strings from which I need to extract 6 digit numbers. Since these strings are generated by another software, they occur interchangeably and I cannot control it. Is there any one method that would extract both 6-digit numbers from each of these strings?
Branch '100235 to 100236 Ckt 1' specified in table 'East Contingency' for record with primary key = 21733 was not found in branch or transformer data.
Loadflow branch ID '256574_701027_1' defined in supplemental branch table was not found in branch or transformer input.
Transmission element from bus number 135415 to bus number 157062 circuit ID = 1 defined for corridor 'IESO-NYISO' was not found in input data
I don't know VBA, but I can learn it if it means I can get the 6 digit numbers using a single method.
thanks
I have been using LEFT(), RIGHT() & MID() previously, but it means manually applying the appropriate formula for individual string.
If you have Microsoft 365, you can use this formula:
=LET(arr,TEXTSPLIT(SUBSTITUTE(SUBSTITUTE(A1,"'"," "),"_"," ")," "),
FILTER(arr,ISNUMBER(-arr)*(LEN(arr)=6)))
Thanks to #TomSharpe for this shorter version, using an array constant within TEXTSPLIT to add on possible delimiters.
=LET(arr,TEXTSPLIT(A1,{"_"," ",","," ","'"}),FILTER(arr,(LEN(arr)=6)*ISNUMBER(-arr)))
Data
Output
An alternative is:
=LET(ζ,MID(A1,SEQUENCE(,LEN(A1)-5),6),ξ,MID(ζ,SEQUENCE(6),1),FILTER(ζ,MMULT(SEQUENCE(,6,,0),1-ISERR(0+ξ))=6))
A couple more suggestions (if you need them):
(1) Replacing all non-digit characters with a space then splitting the resulting string:
=LET(numbers,TEXTSPLIT(TRIM(REDUCE("",MID(A1,SEQUENCE(1,LEN(A1)),1),LAMBDA(a,c,IF(is.digit(c),a&c,a&" "))))," "),FILTER(numbers,LEN(numbers)=6))
Here I've defined a function is.digit as
=LAMBDA(c, IF(c = "", FALSE, AND(CODE(c) > 47, CODE(c) < 58)))
(tl;dr I quite like doing it this way because it hides the implementation details of is.digit and creates a rudimentary form of encapsulation)
(2) A UDF - based on the example here and called as
=RegexTest(A1)
Option Explicit
Function RegexTest(s As String) As Double()
Dim regexOne As Object
Dim theNumbers As Object
Dim Number As Object
Dim result() As Double
Dim i As Integer
Set regexOne = New RegExp
' Not sure how you would extract numbers of length 6 only, so extract all numbers...
regexOne.Pattern = "\d+"
regexOne.Global = True
regexOne.IgnoreCase = True
Set theNumbers = regexOne.Execute(s)
i = 1
For Each Number In theNumbers
'...Check the length of each number here
If Len(Number) = 6 Then
ReDim Preserve result(1 To i)
result(i) = CDbl(Number)
i = i + 1
End If
Next
RegexTest = result
End Function
Note - if you wanted to preserve leading zeroes you would need to omit the Cdbl() and return the numbers as strings. Returns an error if no 6-digit numbers are found.

VBA-Excel: How to get text enclosed in Quotation Mark from String

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

How do I evaluate a string mathematically? ("4*4+1/1" = 17 for example)

I've been stuck trying different methods of doing this for a while, usually not getting anywhere productive. I've tried going down each operator and splitting the string and evaluating there, I've tried looping through each character and then checking the next character but nothing seems to work very well and efficiently.
Is there a way to do this easily? I'd want to input a string, for example, "4*4+1/1" and receive an output of 17. Or, "4^2*2" = 14
The following will compute a string.
Private Sub CompteString()
Dim equation As String = "2+3"
Dim result = New DataTable().Compute(equation, Nothing)
Debug.Print(result.ToString)
End Sub

VBA: assign string character by character

Most people ask how to get the characters from a string, which can be done by Mid(). I am trying to assign a string character by character in VBA code. The characters to be assigned depend on some calculated results.
I do not want to use string concatenation to form the string.
I have searched the web, but the posted solution, strName.Chars(i) (e.g., at MS development network), is not recognized in my 2007 Access VBA.
Thanks
You can use Mid to set values, too.
Sub showMidExample()
Dim s As String
s = "aaaaa"
Dim i As Integer
For i = 1 To Len(s)
Mid(s, i) = "n"
Debug.Print s
Next i
End Sub
This prints out
naaaa
nnaaa
nnnaa
nnnna
nnnnn
Which is what you are looking for.
Since no working answer is posted. I assume that cannot be done in VBA and I have to use concatenation to form the string although that is cumbersome in my case.

VB 2010 chop off part of string and get string up to next '\' in filepath

I cannot find a solution as how to chop off part of a string(filepath) and use what's left to get another string.
For example: if I have filepath: Q:\2456_blah_blah\file.txt and I want to put this entire filepath into an array and delete from left characters 0 through 8 (which is consistent for my application) so I'd have 'blah_blah\file.txt' left for my array.
(The blah_blah portion is going to be a dynamic length, but it will always be letters.)
So then I'd like to take the 'blah_blah\file.txt' and pull just from that beginning up to the next '\' symbol, getting "blah_blah" as a string. I'm not too savy with VB strings at this point, so any help would be much appreciated. This is just my thinking how it could be done, if there's a simpler solution, I'm all ears.
Thanks,
Two Substring calls should do it.
Dim str As String = "Q:\2456_blah_blah\file.txt"
str = str.Substring(8, str.Length - 8)
Dim blah As String = str.Substring(0, str.IndexOf("\"))
Are you looking for something like this. Not knowing all the details makes it difficult to create something that fits your needs but I'll give it a shot. This will return back the blah_blah portion of your strings no matter how large "blah_blah" is, no matter how long the filename is, no matter how long the first portion of your string is and no matter how deep the path goes.
Dim test As String = "c:\34242_blah_blah\test.txt"
Dim startPos As Integer = test.IndexOf("_") + 1
Dim endPos As Integer = test.IndexOf("\", startPos)
Dim result As String = test.Substring(startPos, endPos - startPos)

Resources