initialize a class from datarow - vb.net

I'm trying to initialize a class using a DataRow, But when the DataRow item "LOCATION" is a Null value I receive an error. How can I load these variables with their appropriate datatype values when the row item is null?
Public Sub New(ByVal row As DataRow)
intID = row.Item("ID")
strDepartmentCode = row.Item("DEPARTMENT_CODE")
strDepartmentName = row.Item("DEPARTMENT_NAME")
intLocation = row.Item("LOCATION")
End Sub

Something like this:
Dim location As Object = row.Item("LOCATION")
If location Is Convert.DBNull
intLocation = -1
Else
intLocation = Convert.ToInt32(location)
End If

Related

VB.net - Sorting only one column in datagridview

I'm populating a DataGridView from an Excel file, and trying to sort only ONE column of my choice, other columns should remain as-is. How can it be achieved? Should the component be changed to something else, in case it is not possible in DataGridView?
I Created a List of my custom class, and this class will handle the sorting based on my preference (Randomization in this case)
Public Class Mylist
Implements IComparable(Of Mylist)
Private p_name As String
Private r_id As Integer
Public Property Pname() As String 'This will hold the contents of DGV that I want sorted
Get
Return p_name
End Get
Set(value As String)
p_name = value
End Set
End Property
Public Property Rid() As Integer 'This will be the basis of sort
Get
Return r_id
End Get
Set(value As Integer)
r_id = value
End Set
End Property
Private Function IComparable_CompareTo(other As Mylist) As Integer Implements IComparable(Of Mylist).CompareTo
If other Is Nothing Then
Return 1
Else
Return Me.Rid.CompareTo(other.Rid)
End If
End Function
End Class
Then a Button which will sort the contents:
Dim selcol = xlView.CurrentCell.ColumnIndex
Dim rand = New Random()
Dim x As Integer = 0
Dim plist As New List(Of Mylist)
Do While x < xlView.Rows.Count
plist.Add(New Mylist() With {
.Pname = xlView.Rows(x).Cells(selcol).Value,
.Rid = rand.Next()
})
x += 1
Loop
plist.Sort()
x = 0
Do While x < xlView.Rows.Count
xlView.Rows(x).Cells(selcol).Value = plist.ElementAt(x).Pname
x += 1
Loop
xlView.Update()
plist.Clear()
I'm open to any changes to code, as long as it achieves the same result.
Here is the simpler version. Pass the column index will do like Call SortSingleColum(0)
Private Sub SortSingleColumn(x As Integer)
Dim DataCollection As New List(Of String)
For i = 0 To dgvImport.RowCount - 2
DataCollection.Add(dgvImport.Item(x, i).Value)
Next
Dim t As Integer = 0
For Each item As String In DataCollection.OrderBy(Function(z) z.ToString)
dgvImport.Item(x, t).Value = item
t = t + 1
Next
End Sub

How to find blank value from all member of class in vb.net

I have third party object which contain so many member with integer, string and Boolean. I want to update that record whose value is not null or blank
You can use reflection to achieve what you want:
Sub Main()
Dim obj As Test = new Test()
Dim type As Type = GetType(Test)
Dim info As PropertyInfo() = type.GetProperties()
For Each propertyInfo As PropertyInfo In info
Dim value As String = propertyInfo.GetValue(obj)
If propertyInfo.PropertyType = GetType(String) And String.IsNullOrEmpty(value)
' empty value for this string property
End If
Next
End Sub
public Class Test
Public Property Test As String
End Class

Why does this implementation of move corresponding work?

Since three is read only and depends on a non property (four). Three should be undefined.
How does props, which does not set four, set three to the correct value?
public sub main
Dim x1 = New one, x2 = New two
x1.one = 3
MoveCorresponding(x1, x2)
end sub
Public Sub MoveCorresponding(a As Object, b As Object, Optional ignoreList As List(Of String) = Nothing)
Dim oType As Type = b.GetType
Dim iType = a.GetType
Dim props = iType.GetProperties()
For Each pInf As PropertyInfo In props
Dim parName = pInf.Name
If pInf.CanWrite Then
Try
Dim val = pInf.GetValue(a, Nothing)
pInf.SetValue(b, val)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If
Next
End Sub
End Class
Class one
Public Property one As String = "1"
Dim four As Integer = 1
Public ReadOnly Property three As Integer
Get
Return four * 10
End Get
End Property
End Class
You set four on the same line that you declare it:
Dim four As Integer = 1 '<-- see? it's set to "1".
The property three is simply computed from four:
Return four * 10
Am I not understanding your question?

How to access class properties outside the constructor

I'm trying to retrieve my other football attributes (crossing, dribbling, finishing, ball control) that haven't been requested as arguments in the constructor- reportID, playerID and comments are all that are required.
There are over 20 football attributes, so I've just included the first few for readability.
Report Class:
Public Class Report
Public Sub New(ByVal reportID As Integer, ByVal playerID As Integer, ByVal comments As String)
_ReportID = reportID
_PlayerID = playerID
_Comments = comments
End Sub
Private _ReportID As Integer = 0
Private _PlayerID As Integer = 0
Private _Comments As String = ""
Private _Crossing As Integer = 0
Private _Dribbling As Integer = 0
Private _Finishing As Integer = 0
Private _BallControl As Integer = 0
Public Property ReportID() As Integer
Get
Return _ReportID
End Get
Set(ByVal value As Integer)
_ReportID = value
End Set
End Property
Public Property PlayerID() As Integer
Get
Return _PlayerID
End Get
Set(ByVal value As Integer)
_PlayerID = value
End Set
End Property
Public Property Comments() As String
Get
Return _Comments
End Get
Set(ByVal value As String)
_Comments = value
End Set
End Property
Public Property Crossing() As Integer
Get
Return _Crossing
End Get
Set(ByVal value As Integer)
_Crossing = value
End Set
End Property
Public Property Dribbling() As Integer
Get
Return _Dribbling
End Get
Set(ByVal value As Integer)
_Dribbling = value
End Set
End Property
Public Property Finishing() As Integer
Get
Return _Finishing
End Get
Set(ByVal value As Integer)
_Finishing = value
End Set
End Property
Public Property BallControl() As Integer
Get
Return _BallControl
End Get
Set(ByVal value As Integer)
_BallControl = value
End Set
End Property
End Class
Below I realise I'm only adding reportID, playerID and comments to my typeList, which is why I'm getting all 0's for my other attributes. How do access the attributes as well?
Retrieving the data:
Private Function retrieveReport() As List(Of Report)
Dim typeList As New List(Of Report)
Dim Str As String = "SELECT * FROM Report ORDER BY PlayerID"
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 Report(drResult("ReportID"), drResult("PlayerID"), drResult("Comments")))
End While
End Using 'Automatically closes connection
End Using
End Using
Catch ex As Exception
MsgBox("Report Exception: " & ex.Message & vbNewLine & Str)
End Try
Return typeList
End Function
Private Sub setReport()
For Each rpt As Report In retrieveReport()
'*****General Information
UC_Menu_Scout1.txtComments.Text = rpt.Comments
'*****Technical
UC_Menu_Scout1.UcAttributes1.lblXCrossing.Text = rpt.Crossing
UC_Menu_Scout1.UcAttributes1.lblXDribbling.Text = rpt.Dribbling
UC_Menu_Scout1.UcAttributes1.lblXFinishing.Text = rpt.Finishing
UC_Menu_Scout1.UcAttributes1.lblXBallControl.Text = rpt.BallControl
UC_Menu_Scout1.UcAttributes1.lblXPassing.Text = rpt.Passing
UC_Menu_Scout1.UcAttributes1.lblXHeadingAccuracy.Text = rpt.HeadingAccuracy
UC_Menu_Scout1.UcAttributes1.lblXMarking.Text = rpt.Marking
UC_Menu_Scout1.UcAttributes1.lblXTackling.Text = rpt.Tackling
'*****Mental
UC_Menu_Scout1.UcAttributes1.lblXAggression.Text = rpt.Aggression
UC_Menu_Scout1.UcAttributes1.lblXPositioning.Text = rpt.Positioning
UC_Menu_Scout1.UcAttributes1.lblXAnticipation.Text = rpt.Anticipation
UC_Menu_Scout1.UcAttributes1.lblXComposure.Text = rpt.Composure
UC_Menu_Scout1.UcAttributes1.lblXVision.Text = rpt.Vision
UC_Menu_Scout1.UcAttributes1.lblXTeamwork.Text = rpt.Teamwork
UC_Menu_Scout1.UcAttributes1.lblXWorkRate.Text = rpt.WorkRate
'*****Physical
UC_Menu_Scout1.UcAttributes1.lblXPace.Text = rpt.Pace
UC_Menu_Scout1.UcAttributes1.lblXBalance.Text = rpt.Balance
UC_Menu_Scout1.UcAttributes1.lblXJumping.Text = rpt.Jumping
UC_Menu_Scout1.UcAttributes1.lblXStrength.Text = rpt.Strength
UC_Menu_Scout1.UcAttributes1.lblXStamina.Text = rpt.Stamina
Next
End Sub
I imagine it's not that hard, so any help would be appreciated please!
To add values to the properties, use With:
typeList.Add(New Report(drResult("ReportID"), drResult("PlayerID"), drResult("Comments")) With {.BallControl = drResult("BallControl"), .Dribbling = drResult("Dribbling")})
You need to assign the property values that you aren't providing to the constructor as arguments, or you can add arguments to the constructor. Try this -- instead of calling the constructor like this:
typeList.Add(New Report(drResult("ReportID"), drResult("PlayerID"), drResult("Comments")))
instead, do this:
dim rep = New Report(drResult("ReportID"), drResult("PlayerID"), drResult("Comments"))
.Crossing = drResult("Crossing")
'additional property assignments
With rep
End With
typeList.Add(rep)

Use structure or 2 dimensional array as source for RDLC

I've done some Googling but can't find anything concrete enough to go forward with, so here I am.
I have date fields that I am running a WHERE clause against, and returning fields based on that. The date fields are encrypted, so I was forced to take an alternative approach.
Dim aEmpList(dt.Rows.Count, 5) As String
Try
lCount = 0
For i As Integer = 0 To dt.Rows.Count - 1
If clsEncrypt.DecryptData(dt.Rows(i)(3)) >= 19500101 Then
aEmpList(lCount, 0) = clsEncrypt.DecryptData(dt.Rows(i)(0))
aEmpList(lCount, 1) = clsEncrypt.DecryptData(dt.Rows(i)(1))
aEmpList(lCount, 2) = clsEncrypt.DecryptData(dt.Rows(i)(2))
aEmpList(lCount, 3) = clsEncrypt.DecryptData(dt.Rows(i)(3))
aEmpList(lCount, 4) = clsEncrypt.DecryptData(dt.Rows(i)(4))
lCount = lCount + 1
End If
Next
Catch ex As Exception
MessageBox.Show(e.ToString())
End Try
clsEncrypt is an encryption/decryption class.
The fields are Employee First Name, Last Name, and Date of Birth - and they are all encrypted.
I am trying to find all Employees born>= 19500101, and return that data as a report.
I created a Structure and put the data as an array into the structure myStructure
'Define a structure to be used as source for data grid view.
Structure mystructure
Private mDim1 As String
Private mDim2 As String
Private mDim3 As String
Private mDim4 As String
Private mDim5 As String
Public Property Dim1() As String
Get
Return mDim1
End Get
Set(ByVal value As String)
mDim1 = value
End Set
End Property
Public Property Dim2() As String
Get
Return mDim2
End Get
Set(ByVal value As String)
mDim2 = value
End Set
End Property
Public Property Dim3() As String
Get
Return mDim3
End Get
Set(ByVal value As String)
mDim3 = value
End Set
End Property
Public Property Dim4() As String
Get
Return mDim4
End Get
Set(ByVal value As String)
mDim4 = value
End Set
End Property
Public Property Dim5() As String
Get
Return mDim5
End Get
Set(ByVal value As String)
mDim5 = value
End Set
End Property
End Structure
I populate the structure to load into a DataGridView for visualization purposes:
'populate structure with aEmpList array
Dim myarr(dt.Rows.Count) As mystructure
Try
For i As Integer = 0 To lCount - 1
myarr(i) = New mystructure With {.Dim1 = aEmpList(i, 0).ToString, .Dim2 = aEmpList(i, 1).ToString, .Dim3 = aEmpList(i, 2).ToString, .Dim4 = aEmpList(i, 3).ToString, .Dim5 = aEmpList(i, 4).ToString}
Next
Catch ex As Exception
MessageBox.Show(e.ToString())
End Try
DataGridView1.DataSource = myarr
Now that I've provided sufficient background, does anyone know what my next move should be?
I'm not sure how, or if, I should load the structure into a DataSet() [if that's even possible] or something of that nature.
As I see it you're trying to create a business class, and thus should use a reference type (Class) instead of a value type (Structure). So, the "next move" would be to change your structure to a class, implement INotifyPropertyChanged, IEditableObject, IChangeTracking, IRevertibleChangeTracking, and create a BindingList(Of T) to hold your items.
So, this kind of sucked to figure out, but I got it. As the question title says - I actually ditched the array portion because all it did was confuse me, and I went with the following solution:
Dim dt As New DataTable
Dim dts As DataSet = New DataSet()
With comm
.CommandText = "SELECT EMPL_ID, EMPL_FIRST_NM, EMPL_LAST_NM, BEG_DT, END_DT FROM EMPL"
End With
Dim adapter As New SqlDataAdapter(comm)
adapter.Fill(dts) 'Fill DT with Query results
dt.Load(dts.CreateDataReader())
Me.reportViewer1.RefreshReport()
Dim dts2 As New DataSet()
dts2 = dts.Clone
Try
Dim m As Integer
m = 0
For i As Integer = 0 To dts.Tables(0).Rows.Count - 1
If clsEncrypt.DecryptData(dts.Tables(0).Rows(i)(3)) >= "20130101" Then
dts2.Tables(0).Rows.Add()
dts2.Tables(0).Rows(m)(0) = clsEncrypt.DecryptData(dts.Tables(0).Rows(i)(0))
dts2.Tables(0).Rows(m)(1) = clsEncrypt.DecryptData(dts.Tables(0).Rows(i)(1))
dts2.Tables(0).Rows(m)(2) = clsEncrypt.DecryptData(dts.Tables(0).Rows(i)(2))
dts2.Tables(0).Rows(m)(3) = clsEncrypt.DecryptData(dts.Tables(0).Rows(i)(3))
dts2.Tables(0).Rows(m)(4) = clsEncrypt.DecryptData(dts.Tables(0).Rows(i)(4))
'dts2.Tables(0).Rows.Add(dts.Tables(0).Rows(i).cl)
m = m + 1
End If
Next
Catch ex As Exception
MessageBox.Show(e.ToString())
End Try
Dim rds As ReportDataSource = New ReportDataSource("DataSetDateOfBirthTest", dts2.Tables(0))
With reportViewer1
.LocalReport.DataSources.Clear()
.LocalReport.DataSources.Add(rds)
.RefreshReport()
End With