Using Class Properties to return ODBC calls to another class - vb.net

I have this class - CompLoc it returns two fields from a ODBC call.
I want to call the class like this.
dim myCompLoc as New CompLoc(company,location)
newCompany = mycompLoc.Company
newLocation = mycompLoc.Location
my Class.
Private _company As String
Public Property Company() As String
Get
Return _company
End Get
Set(ByVal value As String)
_company = value
End Set
End Property
Private _location As String
Public Property Location() As String
Get
Return _location
End Get
Set(ByVal value As String)
_location = value
End Set
End Property
Public Sub New(ByVal loc As String, ByVal comp As String)
'select company,location from mysqlTable Where location = loc and company = comp'
_company = 'field from ODBC'
_location = 'field from ODBC'
End Sub
I need to pass to the ODBC company and location, to return company and location (I know...not always in our hands). I have this class that I want to populate from the ODBC call.
corp.EmpId = currentRecord(0).ToString
corp.FirstName = currentRecord(1).ToString
corp.LastName = currentRecord(2).ToString
corp.BasePay = Decimal.Parse(currentRecord(3).ToString)
corp.corpCompany = currentRecord(4).ToString
corp.corpLocation = currentRecord(5).ToString
I need to add to the end of this class ---
corp.newCompany = myCompLoc.Company
corp.newLocation = myCompLoc.Location
Can I have some quidance to build my myCompLoc class properly so that I can call it from corp and receive both properties with values. I can pass this around as an array or other method, but i want to do it a better way.

Here is how I solved this. corpSQL inherits company and location from a properties class
corp inherits from corpMySql
Dim corporation as New Corporation
Dim corp As New corpMySql
Dim newcorp = corp.Getcorp(corp.Company, corp.Location)
corporation.Company = newcorp.NewCompany
corporation.Plant = newcorp.NewLocation
I hope this makes sense. I was able to do what I set out to acheive, but I think another way is more fluid. Maybe using inheritence?

Related

Creating a property as a list or array with properties

I would like to create a array or list property with theses results:
team(1).name = "Falcons"
team(1).totalPoints = 167
team(2).name = "Jets"
team(2).totalPoints = 121
and so on....
I know how to make properties, but not as an array or list. Thanks.
There is no sub-properties in .net, but you can achieve your target by creating a List of objects of a class that having properties. try the following:
Public Class Team
Private _Name As String
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
Private _TotalPoints As Integer
Public Property TotalPoints() As Integer
Get
Return _TotalPoints
End Get
Set(ByVal value As Integer)
_TotalPoints = value
End Set
End Property
End Class
Then you can create a list of objects of the class Team as follows:
Dim TeamList As New List(Of Team)
TeamList.Add(New Team() With {.Name = "Falcons", .TotalPoints = 167})
TeamList.Add(New Team() With {.Name = "Jets", .TotalPoints = 121})
So that ;
TeamList(0).Name Gives "Falcons"
TeamList(0).TotalPoints Gives 167
TeamList(1).Name Gives "Jets"
TeamList(1).TotalPoints Gives 121

"Expression of type "" is not queryable" error

I'm attempting to get an assignment done for class and have hit this error:
Error 1 Expression of type 'Homework_Code_Examples.Form1.State' is not queryable. Make sure you are not missing an assembly reference and/or namespace import for the LINQ provider. D:\Users\Stryke\Documents\Visual Studio 2013\Projects\Homework Code Examples\Homework Code Examples\Form1.vb 11 32 Homework Code Examples
I've never encountered this before and searching via Google, MSDN and these forums all tell me that I must target the correct .NET framework for my program, however I am completely lost as to which framework I should target as the recommended answers all give the same error upon being recompiled. Currently, I am using .NET Framework 4.5 in Visual Studio 2013.
I don't know if it helps at all or not, but here is my code so that you may see what it is I'm trying to achieve...
Public Class Form1
Dim states As State
Private Sub btnDisplay_Click(sender As Object, e As EventArgs) Handles btnDisplay.Click
states = New State()
Dim query = From st In states
Let name = states.Name
Let density = states.Density()
Order By density Descending
Select name, density
End Sub
Private Sub stateInfo_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles stateInfo.CellContentClick
End Sub
Class State
Private m_name, m_abbr, m_date As String
Private m_area, m_pop As Integer
Public Property Name()
Get
Return m_name
End Get
Set(value)
m_name = value
End Set
End Property
Public Property Abbreviation()
Get
Return m_abbr
End Get
Set(value)
m_abbr = value
End Set
End Property
Public Property joinDate()
Get
Return m_date
End Get
Set(value)
m_date = value
End Set
End Property
Public Property landArea
Get
Return m_area
End Get
Set(value)
m_area = value
End Set
End Property
Public Property Population
Get
Return m_pop
End Get
Set(value)
m_pop = value
End Set
End Property
Public Function Density()
Dim popDensity As Integer
popDensity = Population / landArea
Return popDensity
End Function
End Class
End Class
Linq needs to iterate through multiple objects. In your case, it can be list or collection of State class.
Example with List(Of Type)
Change line
Dim states As State
to
Dim states As List(Of State)
and
states = New State()
into
states = New List(Of State)
Example with array
Change line
Dim states As State
to
Dim states() As State
and
states = New State()
into
ReDim states(10) 'or use a variable inside
Here's a sample of how to populate your data. I also fix some error in your query. Compare your query to mine to see what I changed.
' initialize a list with some values
Dim states = New List(Of State) From {
New State With {.Name = "Ohio", .Population = 10000, .landArea = 10},
New State With {.Name = "Texas", .Population = 20000, .landArea = 300},
New State With {.Name = "Florida", .Population = 5000, .landArea = 1000}
}
' query the list
Dim query = From st In states
Let name = st.Name
Let density = st.Density()
Order By density Descending
Select name, density
I also improve your State class to use proper data type instead of object.
Class State
Private m_name, m_abbr, m_date As String
Private m_area, m_pop As Integer
Public Property Name As String
Get
Return m_name
End Get
Set (value As String)
m_name = value
End Set
End Property
Public Property Abbreviation As String
Get
Return m_abbr
End Get
Set(value As String)
m_abbr = value
End Set
End Property
Public Property joinDate As String
Get
Return m_date
End Get
Set(value As String)
m_date = value
End Set
End Property
Public Property landArea As Integer
Get
Return m_area
End Get
Set(value As Integer)
m_area = value
End Set
End Property
Public Property Population As Integer
Get
Return m_pop
End Get
Set(value As Integer)
m_pop = value
End Set
End Property
Public Function Density() As Double
Dim popDensity As Double
popDensity = Population / landArea
Return popDensity
End Function
End Class

Casting from class to interface in Excel VBA

In Excel 2013, I have two classes: LoadCase and LoadCombination, which implement interface ILoadCase.
The declaration for ILoadCase is:
Option Explicit
'' Public properties
Public Property Get Name() As String
End Property
Public Property Let Name(ByVal value As String)
End Property
Public Property Get ID() As Long
End Property
Public Property Let ID(ByVal valus As Long)
End Property
And the (partial) implementations for both LoadCase and LoadCombination are:
Option Explicit
Implements ILoadCase
'' Public properties
Public Property Get ILoadCase_Name() As String
ILoadCase_Name = pName
End Property
Private Property Let ILoadCase_Name(ByVal value As String)
pName = value
End Property
Public Property Get ILoadCase_ID() As Long
ILoadCase_ID = pID
End Property
Private Property Let ILoadCase_ID(ByVal value As Long)
pID = value
End Property
I've omitted code which is irrelevant to the implementation of the interface.
I then have a class BeamForces, which contains results for a particular ILoadCase object:
Option Explicit
Public Fx As Double
Public Fy As Double
Public Fz As Double
Public Mx As Double
Public My As Double
Public Mz As Double
Public ParentLoadCase As ILoadCase
I thought that with this I'd be able to do something like this:
Set currentBeamForces = New BeamForces
With currentBeamForces
.Fx = forces(0)
.Fy = forces(1)
.Fz = forces(2)
.Mx = forces(3)
.My = forces(4)
.Mz = forces(5)
Set .ParentLoadCase = TargetLoadCase
End With
Where TargetLoadCase is either a LoadCase or a LoadCombination, but this gives me an error every time.
I've coded this like I would in .NET and just expected that it would work, but does casting to an interface not work in VBA? Or am I going wrong here somewhere?
EDIT
More details. I first call the following method:
Public Function LoadBeamForcesAtNode(ByVal TargetBeam As Beam, ByVal TargetNode As Node, Optional ByVal TargetLoadCases As Collection = Nothing) As Boolean
Dim i As Integer
Dim currentLoadCase As Variant
Dim targetBeamForces As BeamForces
If TargetLoadCases Is Nothing Then
For Each currentLoadCase In Me.LoadCases.Items
Call TargetLoadCases.Add(currentLoadCase)
Next
For Each currentLoadCase In Me.LoadCombinations.Items
Call TargetLoadCases.Add(currentLoadCase)
Next
End If
'On Error GoTo ExitPoint
For Each currentLoadCase In TargetLoadCases
Set targetBeamForces = InstantiateBeamForces(TargetBeam, TargetNode, currentLoadCase)
If TargetNode Is TargetBeam.Node1 Then
Set TargetBeam.Forces1 = targetBeamForces
Else
Set TargetBeam.Forces2 = targetBeamForces
End If
Next
LoadBeamForcesAtNode = True
ExitPoint:
End Function
Where TargetLoadCases is a collection which can contain both LoadCase and LoadCombination objects.
The problem occurs in InstantiateBeamForces, the code for which is
Private Function InstantiateBeamForces(ByVal TargetBeam As Beam, ByVal TargetNode As Node, ByVal TargetLoadCase As Variant) As BeamForces
Dim forces(5) As Double
Dim currentBeamForces As BeamForces
Call Me.output.GetMemberEndForces(TargetBeam.ID, IIf(TargetNode Is TargetBeam.Node1, 0, 1), TargetLoadCase.ILoadCase_ID, forces, 0)
Set currentBeamForces = New BeamForces
With currentBeamForces
.Fx = forces(0)
.Fy = forces(1)
.Fz = forces(2)
.Mx = forces(3)
.My = forces(4)
.Mz = forces(5)
Set .ParentLoadCase = TargetLoadCase
End With
Set InstantiateBeamForces = currentBeamForces
End Function
Which creates a new BeamForces object and populates it with the values returned by the ...GetMemberEndForces(...) API COM call.
The problem is that the .ParentLoadCase property is nothing after the assignment, so I'm assuming an invalid cast...
** EDIT 2 **
Here is a screenshot of TargetLoadCase when I put a breakpoint in InstantiateBeamForces.
The ILoadCase member is Nothing, but I don't get why. Could this be the cause of the problem?

How to create a compound object in VBA?

I cannot make my way through the Microsoft help, which is great provided you know what the answer is already, so I'm stuck.
Is it possible for me to create my own compound object (I assume that this is the term) such that, for example, the object could be a person and would have the following sub-classes:
Firstname - String
Surname - String
Date of birth - Datetime
Gender - String (M/F accepted)
Height - Real number
Sorry if it seems like a very basic question (no pun intended) but I haven't used Visual Basic for a long time, and Microsoft Visual Basic was never my forté.
You should consider using class modules instead of types. Types are fine, but they're limited in what they can do. I usually end up converting my types to classes as soon as I need some more function than a type can provide.
You could create a CPerson class with the properties you want. Now if you want to return a FullName property, you can write a Property Get to return it - something you can't do with a type.
Private mlPersonID As Long
Private msFirstName As String
Private msSurname As String
Private mdtDOB As Date
Private msGender As String
Private mdHeight As Double
Private mlParentPtr As Long
Public Property Let PersonID(ByVal lPersonID As Long): mlPersonID = lPersonID: End Property
Public Property Get PersonID() As Long: PersonID = mlPersonID: End Property
Public Property Let FirstName(ByVal sFirstName As String): msFirstName = sFirstName: End Property
Public Property Get FirstName() As String: FirstName = msFirstName: End Property
Public Property Let Surname(ByVal sSurname As String): msSurname = sSurname: End Property
Public Property Get Surname() As String: Surname = msSurname: End Property
Public Property Let DOB(ByVal dtDOB As Date): mdtDOB = dtDOB: End Property
Public Property Get DOB() As Date: DOB = mdtDOB: End Property
Public Property Let Gender(ByVal sGender As String): msGender = sGender: End Property
Public Property Get Gender() As String: Gender = msGender: End Property
Public Property Let Height(ByVal dHeight As Double): mdHeight = dHeight: End Property
Public Property Get Height() As Double: Height = mdHeight: End Property
Public Property Get FullName() As String
FullName = Me.FirstName & Space(1) & Me.Surname
End Property
Then you can create a CPeople class to hold all of your CPerson instances.
Private mcolPeople As Collection
Private Sub Class_Initialize()
Set mcolPeople = New Collection
End Sub
Private Sub Class_Terminate()
Set mcolPeople = Nothing
End Sub
Public Property Get NewEnum() As IUnknown
Set NewEnum = mcolPeople.[_NewEnum]
End Property
Public Sub Add(clsPerson As CPerson)
If clsPerson.PersonID = 0 Then
clsPerson.PersonID = Me.Count + 1
End If
mcolPeople.Add clsPerson, CStr(clsPerson.PersonID)
End Sub
Public Property Get Person(vItem As Variant) As CPerson
Set Person = mcolPeople.Item(vItem)
End Property
Public Property Get Count() As Long
Count = mcolPeople.Count
End Property
Public Property Get FilterByGender(ByVal sGender As String) As CPeople
Dim clsReturn As CPeople
Dim clsPerson As CPerson
Set clsReturn = New CPeople
For Each clsPerson In Me
If clsPerson.Gender = sGender Then
clsReturn.Add clsPerson
End If
Next clsPerson
Set FilterByGender = clsReturn
End Property
With this class, you can For Each through all the instances (google custom class and NewEnum to see how to do that). You can also use a Property Get to return a subset of the CPerson instances (females in this case).
Now in a standard module, you can create a couple of CPerson instances, add them to your CPeople instance, filter them, and loop through them.
Public Sub FillPeople()
Dim clsPerson As CPerson
Dim clsPeople As CPeople
Dim clsFemales As CPeople
Set clsPeople = New CPeople
Set clsPerson = New CPerson
With clsPerson
.FirstName = "Joe"
.Surname = "Blow"
.Gender = "M"
.Height = 72
.DOB = #1/1/1980#
End With
clsPeople.Add clsPerson
Set clsPerson = New CPerson
With clsPerson
.FirstName = "Jane"
.Surname = "Doe"
.Gender = "F"
.Height = 62
.DOB = #1/1/1979#
End With
clsPeople.Add clsPerson
Set clsFemales = clsPeople.FilterByGender("F")
For Each clsPerson In clsFemales
Debug.Print clsPerson.FullName
Next clsPerson
End Sub
There's defintely more learning curve to creating classes, but it's worth it in my opinion.
I think you need to use TYPE syntax, like this:
TYPE person
Firstname As String
Surname As String
Date_of_birth As Date ' instead of Datetime
Gender As String '(M/F accepted)
Height As Single 'instead of Real number
END TYPE
Sub Test()
Dim aTest As person
End Sub

VB: Problems with using variable from another class + what to do with not used interface`s functions

I have a problem with getting variable from another class and cannot understand what to do with interface`s functions which have already existed in another class.
What I have:
Form where clicking on a button I should see reversed string:
(I want to call pooraja.StringReverse which is below)
Private Sub btnPoora1_Click(sender As System.Object, e As System.EventArgs) _
Handles btnPoora1.Click
'Dim text As PrjTekstiPooraja.ITeisendused = New PrjTekstiPooraja.CtekstiPooraja
Dim text As PrjTekstiPooraja.ITeisendused = New PrjTekstiPooraja.CtekstiPooraja
Dim pooraja As PrjTekstiPooraja.ITeisendused = New PrjTekstiPooraja.CAlgrotimilinePooraja
text.strText = txtSisendTekst.Text
txtValjundTekst1.Text = pooraja.stringReverse
text.intStart = 1
text.intEnd = Len(txtSisendTekst.Text)
ascFSymbol.Text = text.ascFirstSymbol
ascLSymbol.Text = text.ascLastSymbol()
End Sub
CtekstiPooraja:
(Thiss class will be used to store data.Under data I mean strPooratavText. Data will be used in CAlgoritmilinePooraja)
Public Class CtekstiPooraja
Implements ITeisendused
Public intStartSymbol As Integer
Public intEndSymbol As Integer
Public strPooratavText As String
Private Property intEnd As Integer Implements ITeisendused.intEnd
Get
Return intEndSymbol
End Get
Set(ByVal value As Integer)
intEndSymbol = value
End Set
End Property
Private Property intStart As Integer Implements ITeisendused.intStart
Get
Return intStartSymbol
End Get
Set(ByVal value As Integer)
intStartSymbol = value
End Set
End Property
Public Function pooraText() As String Implements ITeisendused.pooraText
Return StrReverse(strPooratavText)
End Function
Public Property strText As String Implements ITeisendused.strText
Get
Return strPooratavText
End Get
Set(ByVal value As String)
strPooratavText = value
MsgBox(strPooratavText)
End Set
End Property
Public Sub teisendaText(ByRef strSisendText As String) Implements ITeisendused.teisendaText
strPooratavText = StrReverse(strSisendText)
End Sub
Public Function ascFirstSymbol() As String Implements ITeisendused.ascFirstSymbol
Return Asc(GetChar(strPooratavText, intStartSymbol))
End Function
Public Function ascLastSymbol() As String Implements ITeisendused.ascLastSymbol
Return Asc(GetChar(strPooratavText, intEndSymbol))
End Function
Public Function stringReverse() As String Implements ITeisendused.stringReverse
Return Nothing
End Function
End Class
CAlgrotimilinePooraja:
(This class will be called by form button. There I need to use stringReverse function with data from CtekstiPooraja. The problem is that everywhere is used the same interface and there is some functions and procedures from this interface which isnt necessary. I dont know what value should return these unused functions/procedures. Just using "return Nothing or return 0/ "" is bad idea, may be there is possible somehow referenceto to CTekstiPooraja functions/procedures variables")
Public Class CAlgrotimilinePooraja
Implements ITeisendused
Private x As New PrjTekstiPooraja.CtekstiPooraja
Public Function stringReverse() As String Implements ITeisendused.stringReverse
MsgBox(x.strPooratavText)
Dim i As Integer = 0
Dim j As Integer
Dim characters(j) As Char
Dim newString(j) As Char
characters = x.strPooratavText.ToCharArray()
newString = x.strPooratavText.ToCharArray()
Do While i <= j - 1
newString(i) = characters(j - 1)
newString(j - 1) = characters(i)
i += 1
j -= 1
Loop
Return newString
End Function
Public Function ascFirstSymbol() As String Implements ITeisendused.ascFirstSymbol
Return x.ascFirstSymbol()
End Function
Public Function ascLastSymbol() As String Implements ITeisendused.ascLastSymbol
Return Nothing
End Function
Public Property intEnd As Integer Implements ITeisendused.intEnd
Get
Return x.intEndSymbol
End Get
Set(ByVal value As Integer)
End Set
End Property
Public Property intStart As Integer Implements ITeisendused.intStart
Get
Return x.intStartSymbol
End Get
Set(ByVal value As Integer)
End Set
End Property
Public Function pooraText() As String Implements ITeisendused.pooraText
Return x.pooraText()
End Function
Public Property strText As String Implements ITeisendused.strText
Get
Return x.strPooratavText
End Get
Set(ByVal value As String)
End Set
End Property
Public Sub teisendaText(ByRef strSisendText As String) Implements ITeisendused.teisendaText
x.strPooratavText = StrReverse(strSisendText)
End Sub
End Class
MyInterface:
Public Interface ITeisendused
Property intStart As Integer
Property intEnd As Integer
Property strText As String
Function pooraText() As String
Function ascFirstSymbol() As String
Function ascLastSymbol() As String
Function stringReverse() As String
Sub teisendaText(ByRef strSisendText As String)
End Interface
I cannot understand how to get variable strPooratavText from CTekstiPooraja to CAlgrotimilinePooraja. Usually that instancewhich I create worked but not now. And I cannot understand what to do with already existed function and procedures in CAlgoritmilinePooraja when the same function and procedures has in another class. Maybe, it is possible to reference them somehow to existed functions/procedures in CTekstiPooraja? Could you explain me how to id, already tired to surf Internet to find a solution for it, have already try a lot.
Well, I think you have a fundamental problem with understanding interfaces. They describe data and behavior, it should be extremely rare to want to implement part of an interface.
That said, if you do want to implement part of an interface, instead of returning bogus data, throw an exception for behavior you don't implement.
Your specific problem is that CAlgoritmilinePooraja works on an instance of CtekstiPooraja, but it creates a new instance instead of using an existing one. Add
Sub New(incomingX as CtekstiPooraja)
x = incomingX
End Sub
to CAlgoritmilinePooraja. And then in your event, use....
Dim text As PrjTekstiPooraja.CtekstiPooraja = New PrjTekstiPooraja.CtekstiPooraja
text.strText = txtSisendTekst.Text
Dim pooraja As PrjTekstiPooraja.ITeisendused = New PrjTekstiPooraja.CAlgrotimilinePooraja(text)
That is the minimum change to your design that gets what you want to happen to happen but it's problably not what you should do. Other than implementing strReverse, CtekstiPooraja seems to be what you want, CAlgrotimilinePooraja looks to do just one thing, the actual string reversal.
I would move the implementation of strReverse into CtekstiPooraja, and then eliminate CAlgrotimilinePooraja.
PS I would try to stick to English for class names as well as functions and variables.