Initializing Array in Structure in module outside of subroutine - arrays

I have the following declared in a module (simplified for example):
Public Structure ActiveDeviceInfo
Dim InStream As String
Dim InMsg() As String
Dim OutMsg() As String
Public Sub Initialize()
ReDim InMsg(30)
ReDim OutMsg(30)
End Sub
End Structure
then right after that I create the instance for the module. I need it to have the scope of the whole module instead of the individual subroutines.
Public ActiveRelay As New ActiveDeviceInfo
ActiveRelay.Initialize()
I'm getting the 'Declaration Expected' error on the Initialization call.
Any ideas on how to fix this?

You could add it in the static constructor for the module:
Public Module Module1
Public ActiveRelay As New ActiveDeviceInfo
Sub New()
ActiveRelay.Initialize()
End Sub
'Struct Here
End Module

Just inside the module definition I would put:
Dim ActiveRelay As New ActiveDeviceInfo
And then in individual subroutines just call:
ActiveRelay.Initialize()
If you want to call an initialized when an object is created one could switch to a Class with a constructor.Something like:
Dim ActiveRelay As New ActiveDeviceInfo
Public Class ActiveDeviceInfo
Dim InStream As String
Dim InMsg() As String
Dim OutMsg() As String
Public Sub Initialize()
ReDim InMsg(30)
ReDim OutMsg(30)
End Sub
Sub New()
Initialize()
End Sub
End Class
This would run New() when the class is instantiated.

Related

Can't figure out making an Array based off of a Class

What I'm trying to do is create an array from a Class that holds a list of information.
What I've tried so far is this - First, create the Class:
Public Class PowerArray
Public Name As String
Public Action As String
Public Cost As Integer
Public Pool1 As String
Public Pool2 As String
Public Range As String
Public Duration As String
Public Tags As ArrayList = New ArrayList
Public Desc As String
End Class
Then, define a new object that uses PowerArray as type, contained in a Public Class so it can be called in any sub:
Public Class GVar
Public Shared CharPowers(100) As PowerArray
Public Shared PCount As Integer = 0
End Class
But when I try to write to that object, it keeps throwing a Null Reference Exception.
Example:
Trying to write an entry to CharPowers(GVar.Pcount) (where PCount is currently 0, and "txt.PowerName.Text" is any string):
GVar.CharPowers(GVar.PCount).Name = txtPowerName.Text
...throws the exception. This happens no matter which value I try to write to.
I haven't had any major hangups going this route when defining a new object inside a sub using that type (not as an array, but just a simple object), so I'm guessing it's the object being an array that's throwing a fit. I just can't figure out how or why. It clearly exists, it's defined on startup.
Your array in GVar is an array of elements typed as PowerArray with a value of Nothing. You must create an instance of PowerArray and assign it to an element is the array before you can set a field of a PowerArray object.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim PA As New PowerArray
GVar.CharPowers(GVar.PCount) = PA
GVar.CharPowers(GVar.PCount).Name = TextBox1.Text
MessageBox.Show(GVar.CharPowers(GVar.PCount).Name)
End Sub
Are you planning on incrementing PCount? You would not need to keep track of where you are in the array if you used List(Of PowerArray).
EDIT
Public Class PowerArray
Public Property Name As String
Public Property Action As String
Public Property Cost As Integer
Public Property Pool1 As String
Public Property Pool2 As String
Public Property Range As String
Public Property Duration As String
Public Property Tags As New List(Of Object)
Public Property Desc As String
End Class
Public Class GVar
Public Shared Property CharPowers As New List(Of PowerArray)
End Class
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim PA As New PowerArray
PA.Name = TextBox1.Text
GVar.CharPowers.Add(PA)
For Each item As PowerArray In GVar.CharPowers
MessageBox.Show(item.Name)
Next
End Sub
Seems I tripped over an answer. In particular:
Public Class GVar
Public Shared CharPowers(100) As PowerArray
Public Shared PCount As Integer = 0
Shared Sub New()
For i = 0 To CharPowers.GetUpperBound(0)
CharPowers(i) = New PowerArray
Next
End Sub
End Class

I am getting error when accessing variable on another module?

I have a module that is getting values from a datagrid and puts in the tags from each rows into the array of strings. I'm calling that array string on another module but i'm getting object not set to instance of an object. Why? What i'm trying to accomplish is combine all the tag into a array of strings or collection and be able to access it on another module.
'my main module
Public Class myMainModule
Public Shared myArray() As String
......
.......
Public sub doSomething()
Dim myArray As New List(Of String)
For Each row As DataGridViewRow In mydatagrid.Rows
If row.Cells("mycheckbox").Value = True Then
myArray.Add(row.Tag)
End If
Next
End Sub
End Class
'....then i'm calling it from another module:
Public Class myOtherModule
Public sub doit()
For Each value As String In myMainModule.myArray
Debug.Print(value)
Next
End Sub
End Class
You need to initialize your Array before you try to call it. Currently it is Nothing.
Public Class MyMainModule
Public Shared MyArray() As String
Public Shared Sub DoSomething()
Dim myList As New List(Of String)
For Each row As DataGridViewRow In mydatagrid.Rows
If row.Cells("mycheckbox").Value = True Then
myList.Add(row.Tag)
End If
Next
MyArray = myList.ToArray()
End Sub
End Class
Public Class MyOtherModule
Public Sub Foo()
MyMainModule.DoSomething()
For Each value As String In MyMainModule.MyArray
Debug.Print(value)
Next
End Sub
End Class
The other thing too is that you need to watch out for naming. I believe you got confused because you had a field called myArray, but also had a local variabled called myArray. You were working with the local variable that you newed up as List(Of T), not an array.

Unable to add item to a list

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

Accessing Public Variant Array from Module

Say I have two files Form1.frm and Module1.bas in a Visual Basic 6 project.
Form1.frm:
Public myArray As Variant
Private Sub Form_Load()
ReDim myArray(2)
Call PopulateArrays
End Sub
Module1.bas:
Public Sub PopulateArrays()
Form1.myArray(0) = Array(1, 2, 3)
Form1.myArray(1) = Array(4, 5, 6)
Form1.myArray(2) = Array(7, 8, 9)
End Sub
The issues is that once the code runs, 'myArray' remains empty.
If I put the PopulateArrays Sub within the main Form1.frm the arrays do populate.
Any thoughts?
There are certain things you can't declare in an object module (userforms are just special object modules) and one of them is arrays. If you had declared
Public myArray() As Variant
Then you would have got a compile error that said as much and would have known. But since you declared as Variant, the compiler didn't complain, but the assignment just doesn't work.
One option is to make the Variant array private and use property statements (this is VBA, but should be the same for VB6). In the userform
Private mmyArray() As Variant
Public Property Get myArray() As Variant
myArray = mmyArray
End Property
Public Property Let myArray(lmyArray As Variant)
mmyArray = lmyArray
End Property
Private Sub UserForm_Click()
MsgBox Join(Me.myArray(0), "_")
End Sub
Private Sub UserForm_Initialize()
ReDim mmyArray(2)
PopulateArrays
End Sub
And in a standard module
Public Sub PopulateArrays()
Dim ar(0 To 2) As Variant
ar(0) = Array(1, 2, 3)
UserForm1.myArray = ar
End Sub
I see you've used a workaround to let your Form1 hold a public array. However, I think a better solution would be: (A) move the array to the module and make it public (B) create accessor/mutator functions for it.
If you aren't keeping multiple instances of the form at the same time, then (A) is the simplest solution.
Here is the code I tested for (A),
Form:
Private Sub UserForm_Initialize()
Call PopulateArrays
Call displayArray
End Sub
Private Sub displayArray()
Dim v1 As Variant
Dim s As String
For Each v1 In myArray
s = s + Join(v1, ", ") + vbNewLine
Next v1
MsgBox s
End Sub
Module:
Dim form1 As UserForm1
Public myArray As Variant
Public Sub start()
Set form1 = New UserForm1
End Sub
Public Sub PopulateArrays()
ReDim myArray(2)
myArray(0) = Array(1, 2, 3)
myArray(1) = Array(4, 5, 6)
myArray(2) = Array(7, 8, 9)
End Sub

Null Reference Exception - Read from CSV

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.

Resources