Index and length must refer to a location within the string." & vbCrLf & "Parameter name: length vb.net - vb.net

Public Sub Main(temp As String)
Dim AccNo As String = temp.Substring(0, 18)
Dim Identifier As String = temp.Substring(36, 46)
Dim Expected As String = temp.Substring(45, 98)
Dim Received As String = temp.Substring(100, 105)
Dim Length As String = temp.Length.ToString
lbLength.Text = Length.ToString
lbAcc.Text = AccNo.ToString
lbIdentifier.Text = Identifier.ToString
lbExpected.Text = Expected.ToString
lbReceived.Text = Received.ToString
End Sub
I'm trying to extract a section from a String line. It's working correctly first two times but then it generates
Index and length must refer to a location within the string." & vbCrLf & "Parameter name: length vb.net"
Please help me to solve this.

At the beginning of your Sub check the length of the temp string.
Dim temp As String = ""
If temp.Length < 205 Then
MessageBox.Show("String is too short to process")
Exit Sub
End If

Substring(StartPosition,length) length is number of characters from starting position.
If you want to do it like Substring(start_position,end_position) end position has to be replaced with (98-45), because end-start=length

Related

Index and length should refer to a location within the sequence

I need to break a variable to get the value of the database. Today my full return would be "2017-09-15T14: 01: 46" I only need 2017-09-15 and 14:01, I tried to do
.Substring (0.10) for the date and worked, already for the time I tried Substring (11,16) and the error that is in the title of the question occurs.
Assuming you always have the capital T in your result string
dim xValue as string = "2017-09-15T14: 01: 46"
dim xStr() as string = xValue.split("T")
dim xDate as string = ""
dim xTime as string = ""
if xstr.count>0 then
xDate = xStr(0)
xTime = xStr(1)
end if
or
dim xValue as string = "2017-09-15T14: 01: 46"
dim xDate as string = strings.left(xValue, 10)
dim xTime as string = strings.mid(xValue, 12)
So with VB.NET, you can use the DateTime method. From the DateTime, you can do something like DateTime.Date or DateTime.ToShortDateString for just the date and DateTime.ToShortTimeString for the time.
Your arguments to the function Substring are wrong.
The second argument to the function Substring (in your case 16) needs to be the amount of letters that the function will return and NOT the index it needs to end in.
It will work with something like Substring(11, 5), where the 5 is the length of the returned substring.
Dim temp_date As String = "2017-09-15T14: 01: 46"
Dim main_date As String = temp_date.Substring(0, 10)
Dim main_time As String = temp_date.Substring(11, 6)
OR
a better approach using the datetime object proposed by AustinS90 (this will support alot of time formatted strings):
Dim temp_date As DateTime = DateTime.Parse("2017-09-15T14: 01: 46")
Dim main_date As String = temp_date.Year() & "-" & temp_date.Month() & "-" & temp_date.Day
Dim main_time As String = temp_date.Hour & ":" & temp_date.Minute

reverse some text in cell selected - VBA

I'm rooky for VBA. I have some problem about reversing my data on VBA-Excel. My data is "3>8 , 6>15 , 26>41 (each data on difference cells)" that i could reverse "3>8" to "8>3" follow my requirement by using function reverse. But i couldn't reverse "6>15" and "26>41" to "15>6" and "41>26". It will be "51>6" and "14>62" that failure, I want to be "15>6" and "41>26".
Reverse = StrReverse(Trim(str))
Help me for solve my issue please and thank for comment.
You first need to find the position of the ">" in the cell. you do this by taking the contents of the cell and treating it as a String and finding the ">"
This is done in the line beginning arrowPosition. This is the integer value of the position of the ">" in you original string
Next use Left to extract the text up to the ">" and Right to extract the text after the ">"
Then build a new String of rightstr & ">" & leftStr.
Note I input my data from Sheet1 B5 but you can just use any source as long as it is a String in the correct format.
Sub Test()
Dim myString As String
myString = Sheets("Sheet1").Range("B5")
Debug.Print myString
Debug.Print reverseString(myString)
End Sub
Function reverseString(inputString As String) As String
Dim leftStr As String
Dim rightStr As String
Dim arrowPosition As Integer
arrowPosition = InStr(1, inputString, ">")
leftStr = Left(inputString, arrowPosition - 1)
rightStr = Right(inputString, Len(inputString) - arrowPosition)
reverseString = rightStr & ">" & leftStr
End Function
just because you look for a VBA, you can add this function into your code:
Function rev(t As String) As String
s = Split(t, ">", 2)
rev = s(1) & ">" & s(0)
End Function
of course only if you have to reverse 2 number, otherwise you'll loop the "s", but the function would lose its usefulness

Parsing numbers containing commas or periods

I have three values which need to be sorted from highest to lowest value. I use the following code which works like a charm until I want to use periods "." and commas ",". If I type "1,3" it displays as I like, but if I type "1.3" it changes to 13. My end users need to be able to use both commas and periods.
How can I fix this?
Dim IntArr(2) As Decimal
IntArr(0) = TextBox1.Text
IntArr(1) = TextBox2.Text
IntArr(2) = TextBox3.Text
Array.Sort(IntArr)
Dim highestNum As Decimal
Dim Midelnum As Decimal
Dim lowestNum As Decimal
lowestNum = IntArr(0)
Midelnum = IntArr(1)
highestNum = IntArr(2)
MsgBox("Highest " & highestNum)
MsgBox("lowest " & lowestNum)
MsgBox("middel " & Midelnum)
The problem is that it's based on culture. I say this because if I enter numbers as you described, I get the opposite effect ("1,3" -> "13", etc).
Here's a quick way to change the values to match the current culture.
At the top of your class, put this:
Imports System.Globalization
Then, you can do this:
Dim IntArr(2) As Decimal
Dim nfi As NumberFormatInfo = CultureInfo.CurrentCulture.NumberFormat
Dim sep1 As String = nfi.NumberDecimalSeparator
Dim sep2 As String = If(sep1.Equals("."), ",", ".")
Dim useComma As Boolean = (TextBox1.Text.Contains(",") Or TextBox2.Text.Contains(",") Or TextBox3.Text.Contains(","))
'Replace the separator to match the current culture for parsing
Decimal.TryParse(TextBox1.Text.Replace(sep2, sep1), IntArr(0))
Decimal.TryParse(TextBox2.Text.Replace(sep2, sep1), IntArr(1))
Decimal.TryParse(TextBox3.Text.Replace(sep2, sep1), IntArr(2))
Array.Sort(IntArr)
sep1 = If(useComma, ",", ".")
sep2 = If(useComma, ".", ",")
'Reformat the results to match the user's input
Dim lowestNum As String = IntArr(0).ToString().Replace(sep2, sep1)
Dim middleNum As String = IntArr(1).ToString().Replace(sep2, sep1)
Dim highestNum As String = IntArr(2).ToString().Replace(sep2, sep1)
Dim msg As String = "Highest: {0}" & Environment.NewLine & _
"Lowest: {1}" & Environment.NewLine & _
"Middle: {2}"
msg = String.Format(msg, highestNum, lowestNum, middleNum)
MessageBox.Show(msg)
Also, since you are using .NET, you may want to skip the VB6 way of doing things. Refer to my example to see what I've used.
You could use the hack of altering the string before saving it:
TextBox.Text.Replace(".",",")
But if you want to show the original input you could have a variable to detect the entered character:
Dim isDot As Boolean = False
Dim number As String = TextBox.Text
If number.Contains(".") Then
isDot = True
End If
And in the end replace it just for purposes of displaying
If isDot Then
number.Replace(",",".")
End If
The accepted answer uses too much unnecessary string manipulation. You can use the CultureInfo object to get what you need:
Sub Main
Dim DecArr(2) As Decimal
'Select the input culture (German in this case)
Dim inputCulture As CultureInfo = CultureInfo.GetCultureInfo("de-DE")
Dim text1 As String = "1,2"
Dim text2 As String = "5,8"
Dim text3 As String = "4,567"
'Use the input culture to parse the strings.
'Side Note: It is best practice to check the return value from TryParse
' to make sure the parsing actually succeeded.
Decimal.TryParse(text1, NumberStyles.Number, inputCulture, DecArr(0))
Decimal.TryParse(text2, NumberStyles.Number, inputCulture, DecArr(1))
Decimal.TryParse(text3, NumberStyles.Number, inputCulture, DecArr(2))
Array.Sort(DecArr)
Dim format As String = "Highest: {0}" & Environment.NewLine & _
"Lowest: {1}" & Environment.NewLine & _
"Middle: {2}"
'Select the output culture (US english in this case)
Dim ouputCulture As CultureInfo = CultureInfo.GetCultureInfo("en-US")
Dim msg As String = String.Format(ouputCulture, format, DecArr(2), DecArr(1), DecArr(0))
Console.WriteLine(msg)
End Sub
This code outputs:
Highest: 5.8
Lowest: 4.567
Middle: 1.2

Delete specific symbol and number at the end of filename if exist

My application is downloading many diffrent files from network. There is possibility that some of the files could contain additional number within brackets like below:
report78-12-34-34_ex 'nothing to be removed
blabla3424dm_d334(7) '(7) - to be removed
erer3r3r3_2015_03_03-1945-user-_d334(31).xml '(31) - to be removed
group78-12-34-34_ex.html 'nothing to be removed
somereport5_6456 'nothing to be removed
As you see if (number) appear within filename it has to be removed. Do you have some nice secure method which could do the job?
I got some code from rakesh but it is not working when string doesn't contain (number):
string test="something(3)";
test=Regex.Replace(test, #"\d", "").Replace("()","");
Not working when e.g:
if i place file like this: UIPArt3MilaGroupUIAPO34mev1-mihe-2015_9_23-21_30_5_580.csv then it will show: UIPArtMilaGroupUIAPOmev-mihe--_.csv
And i would prefer not using regex.
Avoids Regex and checks the string inside the parentheses, only removing the substring if the enclosed string is a number.
Private Function NewFileName(ByVal FileName As String) As String
If FileName Like "*(*)*" Then
Try
Dim SubStrings() As String = Split(FileName, "(", 2)
NewFileName = SubStrings(0)
SubStrings = Split(SubStrings(1), ")", 2)
SubStrings(0) = NewFileName(SubStrings(0))
SubStrings(1) = NewFileName(SubStrings(1))
If IsNumeric(SubStrings(0)) Then
NewFileName &= SubStrings(1)
Else
Return FileName
End If
Catch
Return FileName
End Try
Else
Return FileName
End If
End Sub
I would do something like this:
Public Function GetFileName(ByVal fileName As String) As String
Dim lastOpenBracketPos As Integer = fileName.LastIndexOf("(")
Dim lastCloseBracketPos As Integer = fileName.LastIndexOf(")")
If lastOpenBracketPos <> -1 AndAlso lastCloseBracketPos <> -1 AndAlso lastCloseBracketPos > lastOpenBracketPos Then
Dim bracketsText As String = fileName.Substring(lastOpenBracketPos, lastCloseBracketPos-lastOpenBracketPos+1)
If IsNumeric(bracketsText.Trim("(",")")) Then
Return fileName.Replace(bracketsText,"")
End If
End If
Return fileName
End Function
Out of all code here i made out my own one because it has to be ensured that before every playing with filename first has to be checked how many brackets within filename - only if 1 for open and 1 for close bracket is there then go with checking. What do you think is there any issue i don;t see or something which could be tuned up?
Private Function DeleteBrackets(ByVal fn As String) As String
Dim countOpenBracket As Integer = fn.Split("(").Length - 1
Dim countCloseBracket As Integer = fn.Split(")").Length - 1
'-- If only one occurence of ( and one occurence of )
If countOpenBracket = 1 And countCloseBracket = 1 Then
Dim filextension = IO.Path.GetExtension(fn)
Dim filewithoutExtension As String = IO.Path.GetFileNameWithoutExtension(fn)
'Debug.Print("Oryginal file name = " & fn)
'Debug.Print("File name without extension = " & filewithoutExtension)
'Debug.Print("Extension = " & IO.Path.GetExtension(fn))
If filewithoutExtension.EndsWith(")") Then
fn = filewithoutExtension.Remove(filewithoutExtension.LastIndexOf("("))
'Debug.Print("After removing last index of ( = " & fn)
'Debug.Print("Adding again extension = " & fn & filextension)
End If
'Debug.Print(fn)
End If
Return fn
End Function

Variable truncates when using messagebox

I have a strange problem here. In my code, variable b string, has the value "Test Test Test". This value we can see while debugging the variable as well as in the text visualizer.
Now the problem is, if I show the same string using Messagebox, the value is just "Test". What can I do here to get the complete value.
I am converting from an ebcdic encoded bytes to corresponding utf8 string and doing the above operation. Any thoughts. below is my sample code.
Dim hex As String = "e385a2a300000000e385a2a3000000e385a2a3"
Dim raw As Byte() = New Byte((hex.Length / 2) - 1) {}
Dim i As Integer
For i = 0 To raw.Length - 1
raw(i) = Convert.ToByte(hex.Substring((i * 2), 2), &H10)
Next i
Dim w As String = System.Text.Encoding.GetEncoding(37).GetString(raw)
Dim raw1 As Byte() = Encoding.UTF8.GetBytes(w)
Dim b As String = Encoding.UTF8.GetString(raw1)
MessageBox.Show(b)
Look at the byte array. You have 4 ASCII 0's after each "Test". ASCII character code 0 corresponds to nul, which is a string termination sequence. If you want spaces instead of nulls there...
Dim b As String = Encoding.UTF8.GetString(raw1).Replace(Chr(0), " ")
It is possible that the string "b" might contains some control character.
To test a control char in string.
For Each p As Char In b
MsgBox(p & " " & Char.IsControl(p) & " " & AscW(p))
Next
Use String#Replace to replace control chars.
b = b.Replace(ChrW(0), " ")
MsgBox(b)