So I am trying to run the following sub where I wish to split the string iden at the second occurrence of "_" But what I get instead is an array with the following elements "1-SWFEED-4.6.14", "10", "3_C" but what I want is an array with elements "1-SWFEED-4.6.14_10", "3_C". What am I doing wrong?
Sub check_split()
Dim iden As String
Dim element As Variant
iden = "1-SWFEED-4.6.14_10_3_C"
For Each element In Split(iden, "_", 3)
MsgBox element
Next element
End Sub
I also tried using the limit as UBound(split(iden, "_")) but it doesn't work either.
Came up with this sub which does what I need (Thanks #Maco for the comment)
Sub check_split()
Dim iden As String
Dim element As Variant
Dim indexCounter As Integer
Dim concIden As String
iden = "1-SWFEED-4.6.14_10_3_C"
indexCounter = 0
For Each element In Split(iden, "_")
If indexCounter < UBound(Split(iden, "_")) - 1 Then
If Not indexCounter + 1 = UBound(Split(iden, "_")) - 1 Then
concIden = concIden + element + "_"
Else
concIden = concIden + element
End If
End If
indexCounter = indexCounter + 1
Next element
MsgBox concIden
End Sub
How about this?
Sub check_split()
Dim iden As String, splitLocation As Integer, firstPart As String, secondPart As String
iden = "1-SWFEED-4.6.14_10_3_C"
splitLocation = WorksheetFunction.Find("_", iden, WorksheetFunction.Find("_", iden, 1) + 1)
firstPart = VBA.Left$(iden, splitLocation - 1) //prints 1-SWFEED-4.6.14_10
secondPart = VBA.Right$(iden, Len(iden) - splitLocation) // prints 3_C
End Sub
Related
I'm trying to obtain two codes from this string: "HL PNX-70[15200]"
But with this code, I obtain two times the same output: "HL PNX-70". So, the code is not properly done.
How to obtain the output '15200' from the above mentioned String?
Code:
Private Sub Comando221_Click()
MsgBox (Right(Split("HL PNX-70[15200]", "[")(0), 50))
MsgBox (Left(Split("HL PNX-70[15200]", "[")(0), 50))
End Sub
Are you looking for this ?
Sub Test()
MsgBox Split("HL PNX-70[15200]", "[")(0)
MsgBox Replace(Split("HL PNX-70[15200]", "[")(1), "]", "")
End Sub
Split returns a zero-based array so you are interested in the second element, index 1. Both lines of your code are extracting "HL PNX-70" and the leftmost and rightmost 50 characters will clearly be the same.
This code illustrates two ways of extracting the desired string for your specific example, but it is not necessarily ironclad if you are working with multiple different types of string. You could also use Instr, as per the other answer, or look at regular expressions if you need more complex pattern matching.
Sub y()
Dim s As String, v
s = "HL PNX-70[15200]"
v = Split(s, "[")
Debug.Print v(0) 'HL PNX-70
Debug.Print v(1) '15200]
MsgBox Left(v(1), Len(v(1)) - 1) '15200
v = Split(v(1), "]")
MsgBox v(0) '15200
End Sub
You could try:
Option Explicit
Sub Test()
Dim str As String, Result As String
Dim Start_Point As Long, No_Characters As Long
str = "HL PNX-70[15200]"
Start_Point = InStr(str, "[") + 1
No_Characters = Len(str) - Start_Point
Result = Mid(str, Start_Point, No_Characters)
Debug.Print Result
End Sub
Here is your code
Dim text, text1, text2 As String
text = "HL PNX-70[15200]"
text1 = Break_String(CStr(text), 0)
text2 = Break_String1(Break_String(CStr(text), 1))
Function Break_String(a As String, pos As Integer) As String
Dim WrdArray() As String
WrdArray() = Split(a, "[")
Break_String = WrdArray(pos)
End Function
Function Break_String1(a As String) As String
Dim WrdArray() As String
WrdArray() = Split(a, "]")
Break_String1 = WrdArray(0)
End Function
I am developing a program where you can input a sentence and then search for a word. The program will then tell you at which positions this word occurs. I have written some code but do not know how to continue.
Module Module1
Sub Main()
Dim Sentence As String
Dim SentenceLength As Integer
Dim L As Integer = 0
Dim LotsofText As String = Console.ReadLine
Console.WriteLine("Enter your word ") : Sentence = Console.ReadLine
For L = 1 To LotsofText.Length
If (Mid(LotsofText, L, 1)) = " " Then
End If
L = L + 1
Dim TextCounter As Integer = 0
Dim MainWord As String = Sentence
Dim CountChar As String = " "
Do While InStr(MainWord, CountChar) > 0
MainWord = Mid(MainWord, 1 + InStr(MainWord, CountChar), Len(MainWord))
TextCounter = TextCounter + 1
'Text = TextCounter + 2
' Console.WriteLine(Text)
Loop
Console.WriteLine(TextCounter)
Console.Write("Press Enter to Exit")
Console.ReadLine()
End Sub
End Module
Transform this piece of code from C# to Visual Basic. match.Index will indicate the position of the given word.
var rx = new Regex("your");
foreach (Match match in rx.Matches("This is your text! This is your text!"))
{
int i = match.Index;
}
To find only words and not sub-strings (for example to ignore "cat" in "catty"):
Dim LotsofText = "catty cat"
Dim Sentence = "cat"
Dim pattern = "\b" & Regex.Escape(Sentence) & "\b"
Dim matches = Regex.Matches(LotsofText, pattern)
For Each m As Match In matches
Debug.Print(m.Index & "") ' 6
Next
If you want to find sub-strings too, you can remove the "\b" parts.
If you add this function to your code:
Public Function GetIndexes(ByVal SearchWithinThis As String, ByVal SearchForThis As String) As List(Of Integer)
Dim Result As New List(Of Integer)
Dim i As Integer = SearchWithinThis.IndexOf(SearchForThis)
While (i <> -1)
Result.Add(i)
i = SearchWithinThis.IndexOf(SearchForThis, i + 1)
End While
Return Result
End Function
And call the function in your code:
Dim Indexes as list(of Integer) = GetIndexes(LotsofText, Sentence)
Now GetIndexes will find all indexes of the word you are searching for within the sentence and put them in the list Indexes.
I have a Note as stringBuilder with word and date: reval 41/50/50
I want to manipulate it, so I will have: reval 05/05/14.
(The date is only when I have the word reval before)
My function is:
Sub correctDateShowing(ByRef Note As StringBuilder)
Dim index, i, j As Integer
For index = 0 To Note.Length - 2
If (Note(index).ToString = "r" And Note(index + 1).ToString = "e") Then
For i = 6 To Note.Length - 1 'start from 6,because I want only the date to be reversed
'Here I am Stuck!!
Next
End If
Next
End Sub
I try to do some replacing with a tmp variable but it didn't work.
I will be glad to get some help.
Thanks All!!!
Sub CorrectDateShowing(ByRef Note As StringBuilder)
Dim str As String = Note.ToString()
Dim arr As String() = str.Split(" "c)
arr(1) = StrReverse(arr(1))
Note = New StringBuilder(arr(0) & " " & arr(1))
End Sub
Split the text into two parts, reverse the second part (the date) and then reconnect them.
Try this:
Dim tempCharArray As char[]
Dim dateStartIndex, dateLength As int
'' Here you need to calculate the date start index and date length (i guess the date length is always 8)
Note.CopyTo(dateStartIndex, tempCharArray, 0, dateLength)
Note.Replace(new String(tempCharArray), new String(Array.Reverse(tempCharArray)), dateStartIndex, dateLength)
I am developing a routine to calculate the proper futures contract front month
If i have a array of integers denoting month numbers ie, "1,4,7,10,12"
and I have a variable integer that is 2.
How do i test the variable against the array and change the variable to the next highest available in the array if the variable itself wasn't in the array? ie in this case the variable's value of 2 would become 4.
I've tried various ways but am stuck now
If datenum >= (targetdayofmonth + adjdays) Then
currentmonth = currentmonth + 1
Dim currmonthname As String = MonthName(currentmonth, True)
For x As Integer = 0 To contractmonths.Count - 1
If GetMonthNumberfromShortMonthName(contractmonths(x)) = currentmonth Then
currmonthname = currmonthname
Else
End If
Next
Else
Dim currmonthname As String = MonthName(currentmonth, True)
End If
So based on Tim's comments I've updated the code to;
Dim contractmonthNos As New List(Of Int32)
For Each childnode As XmlNode In From childnode1 As XmlNode In root Where childnode1.SelectSingleNode("futures/symbol/Code").InnerText = commodcode
'get the available contract months for this contract
Dim contractmonthnodes As XmlNode = childnode.SelectSingleNode("ContractMonths")
contractmonthNos.AddRange(From subnode As XmlNode In contractmonthnodes Select GetMonthNumberfromShortMonthName(subnode.Name))
Next
If datenum >= (targetdayofmonth + adjdays) Then
currentmonth = currentmonth + 1
Dim currmonthname As String = MonthName(currentmonth, True)
Else
Dim nextmonth = From month As Integer In contractmonthNos Where month > currentmonth
If nextmonth.Any() Then
currentmonth = nextmonth.First()
End If
Dim currmonthname As String = MonthName(currentmonth, True)
End If
but I am getting a VS2012 squiggly under nextmonth in the If Then Else warning of "Possible multiple enumeration of IEnumerable"
I think this is what you want:
Dim intVar = 2
Dim months = { 1,4,7,10,12 }
Dim higherMonths = months.Where(Function(month) month > intVar).ToArray()
If higherMonths.Any() Then
intVar = higherMonths.First()
End If
If you don't want the next available month in the array but the nearest you have to sort before:
Dim higherMonths = months.Where(Function(m) m> intVar).
OrderBy(Function(m) m).
ToArray()
If higherMonths.Any() Then
intVar = higherMonths.First()
End If
Something like
Module Module1
Sub Main()
' N.B. this needs to the array to be sorted.
Dim a() As Integer = {1, 4, 7, 10, 12}
Dim toFind As Integer = 2
Dim foundAt As Integer = -1
For i = 0 To a.Length() - 1
If a(i) >= toFind Then
foundAt = i
Exit For
End If
Next
If foundAt >= 0 Then
Console.WriteLine(String.Format("Looked for {0}, found {1}.", toFind, a(foundAt)))
Else
Console.WriteLine(String.Format("Did not find {0} or higher.", toFind))
End If
Console.ReadLine()
End Sub
End Module
Or you might want to look at using the Array.BinarySearch Method.
I have string "ololo123".
I need get position of first digit - 1.
How to set mask of search ?
Here is a lightweight and fast method that avoids regex/reference additions, thus helping with overhead and transportability should that be an advantage.
Public Function GetNumLoc(xValue As String) As Integer
For GetNumLoc = 1 To Len(xValue)
If Mid(xValue, GetNumLoc, 1) Like "#" Then Exit Function
Next
GetNumLoc = 0
End Function
Something like this should do the trick for you:
Public Function GetPositionOfFirstNumericCharacter(ByVal s As String) As Integer
For i = 1 To Len(s)
Dim currentCharacter As String
currentCharacter = Mid(s, i, 1)
If IsNumeric(currentCharacter) = True Then
GetPositionOfFirstNumericCharacter = i
Exit Function
End If
Next i
End Function
You can then call it like this:
Dim iPosition as Integer
iPosition = GetPositionOfFirstNumericCharacter("ololo123")
Not sure on your environment, but this worked in Excel 2010
'Added reference for Microsoft VBScript Regular Expressions 5.5
Const myString As String = "ololo123"
Dim regex As New RegExp
Dim regmatch As MatchCollection
regex.Pattern = "\d"
Set regmatch = regex.Execute(myString)
MsgBox (regmatch.Item(0).FirstIndex) ' Outputs 5
I actually have that function:
Public Function GetNumericPosition(ByVal s As String) As Integer
Dim result As Integer
Dim i As Integer
Dim ii As Integer
result = -1
ii = Len(s)
For i = 1 To ii
If IsNumeric(Mid$(s, i, 1)) Then
result = i
Exit For
End If
Next
GetNumericPosition = result
End Function
You could try regex, and then you'd have two problems. My VBAfu is not up to snuff, but I'll give it a go:
Function FirstDigit(strData As String) As Integer
Dim RE As Object REMatches As Object
Set RE = CreateObject("vbscript.regexp")
With RE
.Pattern = "[0-9]"
End With
Set REMatches = RE.Execute(strData)
FirstDigit = REMatches(0).FirstIndex
End Function
Then you just call it with FirstDigit("ololo123").
If speed is an issue, this will run a bit faster than Robs (noi Rob):
Public Sub Example()
Const myString As String = "ololo123"
Dim position As Long
position = GetFirstNumeric(myString)
If position > 0 Then
MsgBox "Found numeric at postion " & position & "."
Else
MsgBox "Numeric not found."
End If
End Sub
Public Function GetFirstNumeric(ByVal value As String) As Long
Dim i As Long
Dim bytValue() As Byte
Dim lngRtnVal As Long
bytValue = value
For i = 0 To UBound(bytValue) Step 2
Select Case bytValue(i)
Case vbKey0 To vbKey9
If bytValue(i + 1) = 0 Then
lngRtnVal = (i \ 2) + 1
Exit For
End If
End Select
Next
GetFirstNumeric = lngRtnVal
End Function
An improved version of spere's answer (can't edit his answer), which works for any pattern
Private Function GetNumLoc(textValue As String, pattern As String) As Integer
For GetNumLoc = 1 To (Len(textValue) - Len(pattern) + 1)
If Mid(textValue, GetNumLoc, Len(pattern)) Like pattern Then Exit Function
Next
GetNumLoc = 0
End Function
To get the pattern value you can use this:
Private Function GetTextByPattern(textValue As String, pattern As String) As String
Dim NumLoc As Integer
For NumLoc = 1 To (Len(textValue) - Len(pattern) + 1)
If Mid(textValue, NumLoc, Len(pattern)) Like pattern Then
GetTextByPattern = Mid(textValue, NumLoc, Len(pattern))
Exit Function
End If
Next
GetTextByPattern = ""
End Function
Example use:
dim bill as String
bill = "BILLNUMBER 2202/1132/1 PT2200136"
Debug.Print GetNumLoc(bill , "PT#######")
'Printed result:
'24
Debug.Print GetTextByPattern(bill , "PT#######")
'Printed result:
'PT2200136