adding characters to string vb.net - arrays

The ending of the student name should read "2016". Is this the best way to modify the string:
Dim Student As String
If Student.Substring(0, 8) = "JoeBlogs" Then
stg = Student.Insert(0, 3)("2016")
End If
I want the string to read "Joe2016Blogs"

I recommend following the advice in Fabio's answer, however, to answer your specific question, you can do the following:
Dim Student As String = "JoeBlogs"
If Student.Substring(0) = "JoeBlogs" Then
Dim stg as string = Student.Insert(3, "2016")
console.WriteLine(stg)
End If
Which produces the following:
Joe2016Blogs

String concatenation should be avoided when done many thousands of times, but for something quick the following will do it: stg = Student & "2016"

String type is immutable, so in any case you need to create new string.
You can use concatenation
Dim newValue As String = stringVariable + "2016" + anotherStringVariable
or you can use String.Format method
Dim newValue As String = String.Format("{0}2016{1}", firstValue, secondValue);
In VB.NET 14 you can use more readable string interpolation feature
Dim newValue As String = $"{first}2016{second}"
And if you creating string in the loops with unknown amount of variables use StringBuilder
Dim builder As New StringBuilder()
For Each item As String in stringCollection
builder.Append(item)
builder.Append("2016")
End For
Dim allItems As String = builder.ToString()
In your case main problem is to split "JoeBlog" to the name and "blog" word and then put "2016" between

Related

How Do You Return True If A String Contains Any Item In An Array Of String With LINQ in VB.NET

I could not find this question on stack overflow but if it is here, please let me know and I will take it down.
Using LINQ in VB.NET, how do you return True if a string contains one of the items in an array of strings?
This is this is the code in multiple lines. How do you do this in one line with LINQ in VB.NET?
Sub Main
Dim endPointTimeoutText As Array = {"endpoint timeout", "endpoint is not available"}
Dim strResult As String = "endpoint is not available sample text."
Dim booleanResult As Boolean = False
For Each item As String In endPointTimeoutText
If strResult.Contains(item) Then
booleanResult = True
Exit For
End If
Next
Console.WriteLine(booleanResult) 'Only included this for the example
End Sub
The expected result would be 'True' or 'False' depending on if the string (strResult) contained one of the values in the Array Of Strings (endPointTimeoutText)
You turn it around, mentally - don't ask "for this string X, which of these things in this array are in that string", you ask "for this array of strings, which of them are in this one string X":
Dim whichStringsArePresent = endPointTimeoutText.Where(Function(ett) strResult.Contains(ett))
Dim firstImeoutStringFound = endPointTimeoutText.FirstOrDefault(Function(ett) strResult.Contains(ett))
Dim wasATimeout = endPointTimeoutText.Any(Function(ett) strResult.Contains(ett))
etc
By the way it would make your code read more nicely if you make it so that Collections of things have plural names. Consider something more like this:
Dim wasATimeout = endPointTimeoutTexts.Any(Function(ett) strResult.Contains(ett))
It's subtle, but significant in terms of readability
Thank you Caius Jard for your help on this. I am going to post the complete program for what I'm going to use as the answer below.
I needed to use a List instead of an Array so that I could use the 'Any()' method. Thanks again Caius, I really appreciate it!
Sub Main
Dim endPointTimeoutText As String = "endpoint timeout,endpoint is not available"
Dim endPointTimeoutList As New List(Of String)
Dim strResult As String = "endpoint is not available sample text."
endPointTimeoutList = endPointTimeoutText.Split(",").ToList()
Dim areAnyStringsPresent As Boolean
areAnyStringsPresent = endPointTimeoutList.Any(Function(itemInEndPointTimeoutList) strResult.Contains(itemInEndPointTimeoutList))
Console.WriteLine(areAnyStringsPresent)
'This code produces the following output:
'True
End Sub

VB.NET how to convert Object(,) to String()

i am currently ready data from excel per EPPlus interface. My Excel is a csv file.
I've already the data available in a object(,) property (for me a unknown format).
Which format is that? How can i convert it to a String Array?
If you mean like this...
Private Class TestIt
Dim strvar1 As String = Nothing
Dim strvar2 As String = Nothing
Dim Split As Object = MyFunc("A")
strvar1 = Split(0)
strvar2 = Split(1)
End Class
'Extra class or something
Public Function MyFunc(Test As String) As Object
Dim var1 As String = Nothing
Dim var2 As String = Nothing
Select Case (Test)
Case "A"
var1 = "one"
var2 = "two"
Case "B"
var = "three"
var2 = "four"
End Select
Return {var1, var2}
End Function
Sorry I didn't realized that it was a two-dimensional array.
The Problem was to find out the maximum number of each dimension.
I've found the following functions:
Array.getUpperBound(dimension)
So that solves my problem.
But many thanks for your fast answer!!

Split and Store a text file into an array using ArrayList

I have been developing a quiz application that uses a textfile to store questions.
The questions are formatted in this format "QUESTION##CHOICE_A##CHOICE_B##CHOICE_C##CHOICE_D##ANSWER"
I want it to read each line splits it into 6 different parts using "##" as the split string and store it into arrays such as Questions, CHOICE_A,CHOICE_B,CHOICE_C,CHOICE_D
My code does not loop. it just stores the first line
A graphical illustration is shown below of the questions
Here is my code
Dim sr As StringReader = New StringReader(My.Resources.ResourceManager.GetObject(globalVariables.currSubject))
Dim questions As String
Dim splitquestions(6) As String
Dim Unsplitquestions(6) As String
Dim i As Integer = 0
Do Until sr.Peek = -1
questions = sr.ReadLine
Unsplitquestions(i) = questions
splitquestions = Unsplitquestions(i).Split(New String() {"##"}, StringSplitOptions.RemoveEmptyEntries)
' Splits and Stores Into Various
'
'
globalVariables.ArrayQuestions.Add(splitquestions(0))
globalVariables.optionA.Add(splitquestions(1))
globalVariables.optionB.Add(splitquestions(2))
globalVariables.optionC.Add(splitquestions(3))
globalVariables.optionD.Add(splitquestions(4))
globalVariables.Answer.Add(splitquestions(5))
Loop
No, do not use an ArrayList for manipulating a set of objects like this. You should try to think in an Object Oriented way. A QuestionEntry is an entity that contains a QuestionText, 4 possible question answers and one QuestionAnswer.
So let's try this code
Public Class QuestionEntry
Public QuestionText as String
Public ChoiceA as String
Public ChoiceB as String
Public ChoiceC as String
Public ChoiceD as String
Public QuestionAnswer as String
End Class
Dim questions = new List(Of QuestionEntry)()
Dim line As String
Do While sr.Peek() >= 0
line = sr.ReadLine
Console.WriteLine(line)
Dim parts = line.Split(New String() {"##"}, StringSplitOptions.RemoveEmptyEntries)
Dim q = new QuestionEntry()
With q
.QuestionText = parts(0)
.ChoiceA = parts(1)
.ChoiceB = parts(2)
.ChoiceC = parts(3)
.ChoiceD = parts(4)
.QuestionAnswer = parts(5)
End With
questions.Add(q)
Loop
Of course this is just an example and a bit of error checking will be required to make the code more safe. For example before creating the new question entry you should check if the array returned by the split has effectively 6 elements. (parts.Length = 6)
Now all of your text is handled by an instance of a List(Of QuestionEntry) and you could use it like a normal array
Dim qe = questions(0)
Console.WriteLine("Question: " & qe.QuestionText)
Console.WriteLine("Choice A: " & qe.ChoiceA)
Console.WriteLine("Choice B: " & qe.ChoiceB)
Console.WriteLine("Choice C: " & qe.ChoiceC)
Console.WriteLine("Choice D: " & qe.ChoiceD)
Console.ReadLine("Enter your answer:")
The best way to do this is to rely on an existing delimited data parser. The .Split() method is very often horrible for this: performance is sub-par, and there are all kings of edge cases (more than you'd think) where it just doesn't work well. There is even a parser already built into .Net: Microsoft.VisualBasic.FileIO.TextFieldParser.
Additionally, ArrayLists really only exist for pre-.Net 2.0 compatibility. There's is no good reason to ever use one any more. At very least, use a generic List(Of String). In this case, though, your best option is to build a quick class:
Public Class Question
Public Property QuestionText As String
Public Property OptionA As String
Public Property OptionB As String
Public Property OptionC As String
Public Property OptionD As String
Public Property Answer As String
End Class
Now you read your file like this:
Dim results As New List(Of Question)()
Using rdr As New TextFieldParser(My.Resources.ResourceManager.GetObject(globalVariables.currSubject))
rdr.Delimiters = new String() {"##"}
Dim row() As String
While Not rdr.EndOfData
row = rdr.ReadFields()
results.Add(New Question() {
QuestionText = row(0),
OptionA = row(1),
OptionB = row(2),
OptionC = row(3),
OptionD = row(4),
Answer = row(5)
})
End While
End Using
Even with the class definition, that's a whole let less code than the original, and it's much easier to maintain, as well.
I'd also be tempted to write this as an Iterator:
Public Iterator Function ReadQuestions(ByVal FileName As String) As IEnumerable(Of Question)
Using rdr As New TextFieldParser(FileName)
rdr.Delimiters = new String() {"##"}
Dim row() As String
While Not rdr.EndOfData
row = rdr.ReadFields()
Yield New Question() {
QuestionText = row(0),
OptionA = row(1),
OptionB = row(2),
OptionC = row(3),
OptionD = row(4),
Answer = row(5)
}
End While
End Using
End Function
I have two final changes to suggest. The first to add a constructor to the Question type that accepts a string array. This would remove one bit of advanced syntax (the object initializer) from the code, and simplify reading through the portion of the code that actually reads the data. The second isto make the ReadQuestions() method a shared member of the Question type. The final result is this:
Public Class Question
Public Property QuestionText As String
Public Property OptionA As String
Public Property OptionB As String
Public Property OptionC As String
Public Property OptionD As String
Public Property Answer As String
Public Sub New(ByVal data() As String)
'Add error handling here
QuestionText = data(0),
OptionA = data(1),
OptionB = data(2),
OptionC = data(3),
OptionD = data(4),
Answer = data(5)
End Sub
Public Shared Iterator Function ReadFromFile(ByVal FileName As String) As IEnumerable(Of Question)
Using rdr As New TextFieldParser(FileName)
rdr.Delimiters = new String() {"##"}
While Not rdr.EndOfData
Yield New Question(rdr.ReadFields())
End While
End Using
End Function
End Class
And you call all this from your existing code like so:
Dim Questions = Question.ReadFromFile(My.Resources.ResourceManager.GetObject(globalVariables.currSubject))
For Each q As Question in Questions
'...
Next

VB.NET: Split string at everything except normal letters

I'm trying to split a string in VB.NET at everything except normal letters.
I tried to write a function using Char.IsLetter(...) but it didn't work too well for some reason (I put a comment where it crashed):
Private Function splitAtNonLetter(ByVal SplitString As String) As String()
Dim NonCharSplitArray As String() = {}
Dim ProcessValueTemp As String = String.Empty
For Each Letter As Char In SplitString
If Char.IsLetter(Letter) Then
ProcessValueTemp += Letter.ToString
Else
NonCharSplitArray(NonCharSplitArray.Length) = ProcessValueTemp
ProcessValueTemp = String.Empty
End If
Next
If ProcessValueTemp.Length > 0 Then
' Crashes in the next line: Index out of range exception...
NonCharSplitArray(NonCharSplitArray.Length) = ProcessValueTemp
End If
Return NonCharSplitArray
End Function
(I tried to use Regular Expressions but I've never used them before so I didn't really manage to get it to work either)
Is there a way to do it with RegExps or do you have to write a new function and how would it work?
Regex.Split is probably the way to go, using a negative character group.
For example:
Dim bits = Regex.Split(text, "[^a-zA-z]")
Or to cope with non-ASCII letters as well:
Dim bits = Regex.Split(text, "[^\p{L}]")

Pass stored procedure result to array

Quick question that I'm a bit unsure on how to proceed with an array issue.
Basically I have a stored procedure that outputs some course categories and I want to pass all of the rows to an array.
Subject SubjectCode
Applied Science F04
Access to HE F05
So basically the above is an example of what I get from the stored procedure and I'd like to pass the results of the subject to an array.
Dim num as Integer
Dim strNumResult as String
num = 0
Do While (rsData.Read())
num = num + 1
strNumResult = num.ToString()
Dim array(strNumResult) as String
loop
I'm assuming that I'd need to count the amount of rows in the procedure first, then put this result into the array? How would I then systematically pull all subjects in the procedure into the array?
Thanks!
The easiest would be to use a List(Of Subject) instead which can be resized. I would also create a class for the subject since you have two fields.
Dim subjects = New List(Of Subject)
Using con = New SqlConnection(connectionString)
Using cmd = New SqlCommand("StoredProcedureName", con)
cmd.CommandType = CommandType.StoredProcedure
Try
con.Open()
Using reader = cmd.ExecuteReader()
While reader.Read
Dim subject = reader.GetString(0)
Dim subjectCode = reader.GetString(1)
subjects.Add(New Subject() With {
.Subject = subject,
.SubjectCode = subjectCode
})
End While
End Using
Catch ex As Exception
' log exception
End Try
End Using
End Using
here's a simple implementation of that class:
Public Class Subject
Public Subject As String
Public SubjectCode As String
End Class
If you insist on an array, you can call subjects.ToArray().
You need GetRows method which will get your recordset data into an array:
array = recordset.GetRows(Rows, Start, Fields )
Basically execute your stored procedure and when you have the results use the GetRows method which returns a collection of rows from the result, given an array of unique column ID's.
You can see an example here.
In your case after making sure that you have some records returned you can do this:
arrData = rsData.GetRows()
Hope this helps.

Resources