I am writing a function that will allow me to input some values and then this will return this as a list. This is my code currently.
Structure question
Dim asking As String
Dim answers As List(Of String)
End Structure
Private Function addQuestionToList(toAsk As String, answers() As String) As question
addQuestionToList.asking = toAsk
Dim listTemp As List(Of String)
For i As Integer = 0 To answers.Count - 1
listTemp.Add(answers(i))
Next
addQuestionToList.answers = listTemp
End Function
#Region "Quiz Questions"
Dim GTAQuestions As List(Of question)
Sub initializeGTAQuestions()
GTAQuestions.Add(addQuestionToList("Some Question", {"answer1", "answer2"}))
End Sub
#End Region
Change your code:
Dim GTAQuestions As List(Of question)
Sub initializeGTAQuestions()
GTAQuestions.Add(addQuestionToList("Some Question", {"answer1", "answer2"}))
End Sub
with this:
Dim GTAQuestions As New List(Of question)
Sub initializeGTAQuestions()
GTAQuestions.Add(addQuestionToList("Some Question", {"answer1", "answer2"}))
End Sub
You need to initialize each instance of the structure. One option is to include a custom new method in your structure, so your structure and function will look like this:
Structure question
Dim asking as String
Dim answers as List(Of String)
Public Sub New (ByVal _asking as String, ByVal _answers as List(Of String))
asking = _asking
answers = _answers
End Sub
End Structure
Private Function addQuestionToList(ByVal asking as String, ByVal answers() as String) as question
Dim lstAnswers as New List(Of String)
For Each answer As String in answers
lstAnswers.Add(answer)
Next
Return New question(asking, lstAnswers)
End Function
Related
I have following json data:
{
"cgFinishing": {
"a3colorfn": [{
"type": "Cacah",
"kode": "CCH"
},
{
"type": "Cutting",
"kode": "CUT"
}
]
}
}
And my JSON Class:
Public Class A3colorfn
Public Property type As String
Public Property kode As String
End Class
Public Class CgFinishing
Public Property a3colorfn As A3colorfn()
End Class
Public Class CGSave
Public Property cgFinishing As CgFinishing
End Class
I want to write a method in VB.NET that pull values from this JSON array using JSON.NET. This code works for me:
Public Sub fillCBfromJson(ByVal cb As ComboBox, json As Object, Optional ByVal value As String = "", Optional display As String = "")
....
End Sub
But I'd like to replace json As Object with something that are more specific, because I'd like to retrieve the count of items in the array (something like Count or GetLength, I cannot expose those property with Object type)
For your reference this code works for me...
Dim count As Integer = jsonObj.cgFinishing.a3colorfn.GetLength(0)
But I have no idea to turn it as a method.
Any help is appreciated.
More code listing:
Private Sub PublishDigital_Load(sender As Object, e As System.EventArgs) Handles MyBase.Load
jsonPath = Application.StartupPath + "\Addons\CG_Tools\cgSave.json"
jsonObj = JsonConvert.DeserializeObject(Of CGSave)(File.ReadAllText(jsonPath))
initfinishingA3()
End Sub
Public Sub initfinishingA3() 'I want to make this as a method, so I'll only need to input the Array object as argument.
Dim cbdata As Object = jsonObj.cgFinishing.a3colorfn '<- I want to put this line as argument instead
Dim count As Integer = jsonObj.cgFinishing.a3colorfn.GetLength(0)
Dim myCb As New List(Of CheckBox)
For Each cur In cbdata
Dim cb = New CheckBox()
tb_finishinga3.Controls.Add(cb)
Dim txt As JObject = JsonConvert.DeserializeObject(Of JObject)(JsonConvert.SerializeObject(cur))
...
cb.Text = txt("type")
...
Next
End Sub
Following method I wrote does not work..
Public Sub fillTabwithCB(ByVal cbdata As JArray, XOffset As Integer, YOffset As Integer, maxRow As Integer)
Dim count As Integer = cbdata.Count
Dim loopIndex As Integer
Dim i As Integer = 0
Dim myCb As New List(Of CheckBox)
For Each cur In cbdata
Dim cb = New CheckBox()
tb_finishinga3.Controls.Add(cb)
Dim txt As JObject = JsonConvert.DeserializeObject(Of JObject)(JsonConvert.SerializeObject(cur))
.........
cb.Text = txt("type")
..........
Next
End Sub
Then I tried it in this line...
fillTabwithCB(jsonObj.cgFinishing.a3colorfn, 7, 7, 5)
It generates following error:
Value of type '1-dimensional array of
CG_FileManagement.A3colorfn' cannot be converted to
'Newtonsoft.Json.Linq.JArray'.
I'm trying to make an array of string, but can't get it to run correctly. Here is what I have.
Public Class Form1
Dim wordArray() As String
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'increase the size of string array by one, by setting the new upperBound at the current Length
'use Preserve so that string currently in the array are not overwritten with Nothing
ReDim Preserve wordArray(wordArray.Length)
'use an TextBox to get the name of the new string from the user
'assign this name (which is a String) to the last element of the string array
wordArray(wordArray.GetUpperBound(0)) = TextBox2.Text
End Sub
End Class
Any help will be appreciated, thank you.
How about a List(Of String)? No ReDim required here.
Private wordList As New List(Of String)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
wordList.Add(textbox2.Text)
End Sub
For Fixed-size array:
Dim strCDRack(0 to 2) As String
strCDRack(0) = "Deftones"
strCDRack(1) = "Tool"
strCDRack(2) = "Disturbed"
For Dynamic array:
Dim strCDRack() As String
ReDim strCDRack(0 to 2) As String
strCDRack(0) = "Deftones"
strCDRack(1) = "Tool"
strCDRack(2) = "Disturbed"
For expanding the Dynamic array:
Dim strCDRack() As String
ReDim strCDRack(0 to 2) As String
strCDRack(0) = "Deftones"
strCDRack(1) = "Tool"
strCDRack(2) = "Disturbed"
ReDim Preserve strCDRack(0 to 3) As String
strCDRack(3) = "Charlotte Church"
For more info about VB arrays checkout this link..
Use a list!
Dim StringArray As New List(Of [String])()
And in the click handler:
StringArray.Add(TextBox1.Text)
You should use Collections here like List(Of String), it grows as the number of element grows. No need to maintain size yourself. Also the problem might at your end is, when you ReDim try to increase your array size.
ReDim Preserve wordArray(wordArray.Length + 1)
Upon selecting a Question ID in the combo box the relating question should then appear in the text box. I am unsure how to get this to work though. I receive an error "Value of type......cannot be converted to string" on retrieveQuestion(). Any help is appreciated, thankyou.
Private Sub cmbQuestion_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbQuestion.SelectedIndexChanged
txtExistingQuestion.Text = retrieveQuestion() 'Add question, relevant to Question ID, to text box, DO I NEED .ToString?????????????????
loaded = True
End Sub
Public Function retrieveQuestion() As List(Of Question) 'Retrieves selected question into text box
Dim typeList As New List(Of Question)
Dim Str As String = "SELECT Question_ID, Question_Text FROM Question WHERE Question_ID =" & cmbQuestion.SelectedValue
Try
Using conn As New SqlClient.SqlConnection(DBConnection)
conn.Open()
Using cmdQuery As New SqlClient.SqlCommand(Str, conn)
Using drResult As SqlClient.SqlDataReader = cmdQuery.ExecuteReader()
While drResult.Read
typeList.Add(New Question(drResult("Question_ID"), drResult("Question_Text")))
End While
End Using 'Automatically closes connection
End Using
End Using
Catch ex As Exception
MsgBox("Question List Exception: " & ex.Message & vbNewLine & Str)
End Try
Return typeList
End Function
Public Class Question 'defining one club within class
Public Sub New(ByVal questionID As Integer, ByVal questionText As String)
mQuestionID = questionID 'm is for member of the class
mQuestionText = questionText
End Sub
Private mQuestionID As String = ""
Private mQuestionText As String = ""
Public Property QuestionID() As String
Get
Return mQuestionID
End Get
Set(ByVal value As String)
mQuestionID = value
End Set
End Property
Public Property QuestionText() As String
Get
Return mQuestionText
End Get
Set(ByVal value As String)
mQuestionText = value
End Set
End Property
End Class
Your issue is this line:
mQuestionID = questionID
In your class you have defined this:
Private mQuestionID As String = ""
But in your constructor, you are saying that questionID should be an Integer, like this:
Public Sub New(ByVal questionID As Integer, ByVal questionText As String)
You need to change your backing variable in your class (mQuestionID) to be an Integer, like this:
Private mQuestionID As Integer
This will also necessitate a change to the property syntax for QuestionID, like this:
Public Property QuestionID() As Integer
Get
Return mQuestionID
End Get
Set(ByVal value As Integer)
mQuestionID = value
End Set
End Property
Your error is originated by the return value of retrieveQuestion declared as a List(Of Question) but then you try to set the text property of a TextBox (and there is no way to convert automatically a List(Of Question) to a string)
So you could write something like this to extract the text of the first question in the list
Dim qList = retrieveQuestion()
if qList.Count > 0 then
txtExistingQuestion.Text = qList(0).QuestionText
loaded = True
End If
Of course, if your query returns zero or just one question, then there is no need to return a List(Of Question) and you can change the retrieveQuestion method to return just a Question or Nothing
Public Function retrieveQuestion() As Question
Dim questionResult As Question = Nothing
......
Using drResult As SqlClient.SqlDataReader = cmdQuery.ExecuteReader()
if drResult.Read() then
questionResult = New Question(drResult("Question_ID"), _
drResult("Question_Text")))
End if
End Using
....
return questionResult
End Function
Dim question = retrieveQuestion()
if question IsNot Nothing then
txtExistingQuestion.Text = question.QuestionText
loaded = True
End If
However, all the comments about string and integer conversion happening automatically on your code are really an alarm bell. You should strive to avoid this kind of conversion because they render your code weak and prone to misterious errors. Switch to Option Strinct On on your project properties and prepare yourself to a lot of conversion fixing.
I wrote the following code:
Public Class Form1
Private Structure udtThing
Dim SomeText As String
Dim SomeElements() As String
Public Shared Function CreateInstance() As udtThing
Dim result As New udtThing
result.SomeText = String.Empty
ReDim result.SomeElements(2)
result.SomeElements(0) = String.Empty
result.SomeElements(1) = String.Empty
result.SomeElements(2) = String.Empty
Return result
End Function
End Structure
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim nThings() As udtThing
nThings = Array.CreateInstance(GetType(udtThing), 10)
End Sub
End Class
I partly works, nThings becomes an array of 11 udtThings.
But .SomeElements is not redimmed to 3 strings of String.Empty, but it is "Nothing" instead.
Does anybody see where I went wrong?
Thank you very much!
By design, a Redim is required. Array.CreateInstance() isn't going to perform that operation, it can't guess what size is required. You'll have to help:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim nThings(10) As udtThing
For ix As Integer = 0 To UBound(nThings)
nThings(ix) = udtThing.CreateInstance()
Next
End Sub
I have to code a WPF application for college which reads from a csv file. I get a null reference exception when I want to output the parts of the CSV lines into arrays. You can find the line where the error happens in commentary. Here is the code.
Imports System.Windows.Forms
Imports System.IO
Imports System.Globalization
Class MainWindow
Private foldername As String
Private arrGemeenten As String()
Private arrOppervlakte As Double()
Private arrInwoners As Integer()
Private arrDeelgemeenten As Integer()
Private Sub cboProvincie_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles cboProvincie.SelectionChanged
CSVInlezen()
End Sub
Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
FileBrowserAanmaken()
comboBoxVullen()
End Sub
Private Sub comboBoxVullen()
For Each file As String In IO.Directory.GetFiles(foldername)
If file.EndsWith(".csv") Then
Dim filenaam As String = System.IO.Path.GetFileNameWithoutExtension(file)
cboProvincie.Items.Add(filenaam)
End If
Next
End Sub
Private Sub FileBrowserAanmaken()
'folderbrowserdialog aanmaken
Dim fbd As New FolderBrowserDialog
fbd.SelectedPath = AppDomain.CurrentDomain.BaseDirectory
' Show the FolderBrowserDialog.
Dim result As DialogResult = fbd.ShowDialog()
If (result = Forms.DialogResult.OK) Then
foldername = fbd.SelectedPath
End If
End Sub
Private Sub CSVInlezen()
Dim filepath As String = foldername & "\" & cboProvincie.SelectedValue & ".csv"
If File.Exists(filepath) Then
fileInlezenHulpMethode(filepath)
End If
End Sub
Private Sub fileInlezenHulpMethode(ByVal path As String)
'declarations
Dim sr As New StreamReader(path)
Dim iTeller As Integer = 0
Dim arrLijn As String()
Dim culture As New System.Globalization.CultureInfo("nl-BE")
'eerste lijn meteen uitlezen, dit zijn kolomkoppen en hebben we niet nodig
'read out first line, these are titles and we don't need them
sr.ReadLine()
Do While sr.Peek <> -1
Dim lijn As String = sr.ReadLine()
arrLijn = lijn.Split(";")
arrGemeenten(iTeller) = Convert.ToString(arrLijn(0)) 'HERE I GET THE ERROR!
arrOppervlakte(iTeller) = Double.Parse(arrLijn(2), NumberStyles.AllowDecimalPoint, culture.NumberFormat)
arrInwoners(iTeller) = Integer.Parse(arrLijn(3), NumberStyles.Integer Or NumberStyles.AllowThousands, culture.NumberFormat)
arrDeelgemeenten(iTeller) = Convert.ToString(arrLijn(4))
Loop
End Sub
End Class
You haven't created the array, you have only created a reference for it. To create the array you need to specify a size, for example:
Private arrGemeenten As String(100)
However, to specify the size, you need to know the size when you create the array. (Well, actually you put all data in the first item, so just the size 1 would keep it from crashing, but I don't thing that's what you intended.) You probably want to use lists instead:
Private gemeenten As New List(Of String)()
Then you use the Add method to add items to the list:
gemeenten.Add(Convert.ToString(arrLijn(0)))
Also, consider putting the data in a single list of a custom object, instead of having several lists of loosely coupled data.