Fastest way to get a row using TableAdapter - sql

From my TableAdapter SELECT statement, I do a
SELECT StudentID FROM dbo.Student WHERE Email = #Email
And in my .vb code, I call the function out and do a for each loop like this:
Dim myStudentID As Integer
Dim myTable = StudentTableAdapter1.GetStudentID("myEmail#mail.com")
For Each myRow As DataRow In myTable.Rows
myStudentID = myRow.Item("StudentID")
MessageBox.Show(myStudentID)
Next
However I wish to shorten this further. Is there a way to get the row faster?

If you're absolutely sure that you will only return a row, you can do as follows:
Dim myStudentID As Integer
Dim myTable = StudentTableAdapter1.GetStudentID("myEmail#mail.com")
myStudentID = myTable(0)("StudentID")
MessageBox.Show(myStudentID)

Related

how to sum values of same id in datagridview?

i am trying to sum values of same id in datagridview and trying to update sql database table. how to do it?
For i As Integer = 0 To DataGridView2.Rows.Count - 1
If Convert.ToInt32(DataGridView2.Rows(i).Cells(0).Value) = Convert.ToInt32(DataGridView2.Rows(i).Cells(0).Value) Then
y += Convert.ToInt32(DataGridView2.Rows(i).Cells(3).Value)
End If
Next
As you have been already told, the if statement you are coding is comparing a cell with itself, which doesn't make sense, because it Will always return true.
I'm guessing that you need to compare all cells that share the same id and sum the result, but you would need to elaborate the question better, so we can understand what your actuall purpose is.
you can use Dictionary to check and group id with sum values
Dim totals As Dictionary(Of String, Integer) = New Dictionary(Of String, Integer)()
For i As Integer = 0 To DataGridView2.Rows.Count - 1
Dim group As String = Convert.ToInt32(DataGridView2.Rows(i).Cells("id").Value)
Dim qty As Integer = Convert.ToInt32(DataGridView2.Rows(i).Cells("value").Value)
If totals.ContainsKey(group) = False Then
totals.Add(group, qty)
Else
totals(group) += qty
End If
Next
or use group with LINQ:
Dim totals = DataGridView2.Rows.Cast(Of DataGridViewRow)().GroupBy(Function(row) row.Cells("id").Value.ToString()).[Select](Function(g) New With {Key
.id= g.Key, Key
.SumValues = g.Sum(Function(row) Convert.ToInt32(row.Cells("value").Value))
})

linq to strongly typed datatable with nested query using vb.net

I am trying to convert following sql select * from tblPBRule where PBRuleId = 123 and StartDate < = '20140902' and finishdate is null and PBCodeid in (select PBCodeid from tblpbrule where PBHourstypeid IN (3,4,5,6)) into linq query within application
Dim query As IEnumerable(Of PBRuleData.PBRuleRow) = From s In Me.PBRule.PBRule.AsEnumerable() _
Where s.PBRuleId = .PBRuleId And s.StartDate <= .PBDate _
And ((s.IsFinishDateNull) OrElse (s.FinishDate > .PBDate)) Select s
can anyone help me to complete this query
Have just gone through the same search and found Brad's Blog which works for me as in my function below.
http://www.gorgando.com/blog/technology/asp-net/not-in-subquery-with-asp-net-linq-in-vb
Hope this helps. The only difference between the 2 queries of the second table is the "Where Not" for the not in condition.
Private Enum InOrNotInSelect
None = 0
InTable = 1
NotInTable = 2
End Enum
Private Function getNotInData(firstTable As DataTable,
secondTable As DataTable,
inOrNotIn As InOrNotInSelect,
keyField As String) As DataTable
' TODO: make keyField a ParamArray
' (don't know how to write dynamic LINQ code yet)
Dim loTable As DataTable = Nothing
' first of all do a query on the first table
Dim firstQuery = From dt1 In firstTable.AsEnumerable()
Select dt1.Field(Of String)(keyField)
If inOrNotIn = InOrNotInSelect.NotInTable Then
' next do a query on the second table returning the rows NOT IN the first table
Dim inNotInQuery = From dt2 In secondTable.AsEnumerable()
Where Not firstQuery.Contains(dt2.Field(Of String)(keyField))
Select dt2
' convert the rows to a table
loTable = inNotInQuery.CopyToDataTable()
ElseIf inOrNotIn = InOrNotInSelect.InTable Then
' next do a query on the second table returning the rows IN the first table
Dim inNotInQuery = From dt2 In secondTable.AsEnumerable()
Where firstQuery.Contains(dt2.Field(Of String)(keyField))
Select dt2
' convert the rows to a table
loTable = inNotInQuery.CopyToDataTable()
End If
' remove debug code in production build
For Each dRow As DataRow In loTable.Rows
Debug.Print(dRow(keyField) & " - " & dRow("FullName"))
Next
Return loTable
End Function

Return matching named table in worksheet function VBA

Does anyone know how to return a values in a table with:
WorksheetFunction.Match
Or this there any other alternative function that could be used in order for it to be working.
rowNum = WorksheetFunction.Match(sum.Range("coverage").Table, temp.Range("A1:A200"), 0)
'colNum = WorksheetFunction.Match(sum.Range("Header").Value, temp.Range("CoverageT"), 0)
Above I tried to use WorksheetFunction to get it to work but that was a fail. I named tables 'coverage and 'header to get it to function but I did not succeed.
I hope my problem is clear enough to get some help!
If it's not clear enough please leave a comment!
WorksheetFunction.Match gets you the relative position of a value in a single column range or a single row range. If your item is third in the list it returns 3.
If you want the value from a table use WorksheetFunction.VLookup. You are looking up your item in the first column of a table or range. You specify which column you want the value from and it will return the cell value from the matching row.
Or use HLookup for a transposed table.
Try this if you really want to use Match:
dim KeyValue as string
KeyValue = "my item"
Dim rowNum as Variant
If Not VBA.IsError(Application.Match(KeyValue, temp.Range("A1:A200"), 0)) Then
rowNum = Application.Match(KeyValue, temp.Range("A1:A200"), 0)
End If
Try this if you want a vlookup:
Dim RetVal As Variant
Dim KeyValue As String 'or integer or date as appropriate
Dim LookupTable As Range
Dim ColumnNumber As Integer
KeyValue = "myItem"
LookupTable = Range("A1:A200")
ColumnNumber = 2
RetVal = WorksheetFunction.VLookup(KeyValue, LookupTable, ColumnNumber, False)

Adding two column values to listbox in vb.net

I have a table named users which has the following columns in it
User_id,user_name,user_pwd,First_Name,Middle_Name,Last_Name and user_type.
I have dataset named dst and created a table called user in the dataset. Now I want to populate listbox with user_Name, First_Name, Last_name of each and every row in the table user.
I am able to add one column value at a time but not getting how to add multiple column values of each row to listbox
Dim dt As DataTable = Dst.Tables("user")
For Each row As DataRow In dt.Rows
lstUsers.Items.Add(row("User_Name"))
Next
Above code works perfectly but I also want to add First_name as well as last_name to the list box at the same time.
Use same approach as you have, but put all values you want in one string.
Dim dt As DataTable = Dst.Tables("user")
For Each row As DataRow In dt.Rows
Dim sItemTemp as String
sItemTemp = String.Format("{0},{1},{2}", row("User_Name"), row("First_Name"), row("Last_Name"))
lstUsers.Items.Add(sItemTemp)
Next
String.Format() function will call .ToString() on all parameters.
In this case if row(ColumnName) is NULL value then .ToString() return just empty string
You have 2 choices:
Using the ListBox:
To use the ListBox, set the font to one that is fixed width like courier new (so that the columns line up), and add the items like this:
For Each row As DataRow In dt.Rows
lstUsers.Items.Add(RPAD(row("User_Name"),16) & RPAD(row("First_Name"),16) & RPAD(row("Last_Name"),16))
Next
The RPAD function is defined like this:
Function RPAD(a As Object, LENGTH As Object) As String
Dim X As Object
X = Len(a)
If (X >= LENGTH) Then
RPAD = a : Exit Function
End If
RPAD = a & Space(LENGTH - X)
End Function
Adjust the LENGTH argument as desired in your case. Add one more for at least one space. This solution is less than ideal because you have to hard-code the column widths.
Use a DataGridView control instead of a ListBox. This is really the best option, and if you need, you can even have it behave like a ListBox by setting the option to select the full row and setting CellBorderStyle to SingleHorizontal. Define the columns in the designer, but no need to set the widths - the columns can auto-size, and I set that option in the code below. if you still prefer to set the widths, comment out the AutoSizeColumnsMode line.
The code to set up the grid and add the rows goes like this:
g.Rows.Clear() ' some of the below options are also cleared, so we set them again
g.AutoSizeColumnsMode = DataGridViewAutoSizeColumnMode.AllCells
g.CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal
g.SelectionMode = DataGridViewSelectionMode.FullRowSelect
g.AllowUserToAddRows = False
g.AllowUserToDeleteRows = False
g.AllowUserToOrderColumns = True
For Each row As DataRow In dt.Rows
g.Rows.Add(row("User_Name"), row("First_Name"), row("Last_Name"))
Next
You might solved your problem by now but other users like me might have issue with it.
Above answers given worked for me even but I found a same answer in a simple way according to what I want..
cmd = New SqlCommand("select User_Name, First_Name, Last_Name from User")
Dim dr As SqlDataReader = cmd.ExecuteReader(YourConnectionString)
If dr.HasRows Then
Do While dr.Read
lst.Items.Add(dr.Item(0).ToString & " " & dr.Item(1).ToString & " " & dr.Item(2).ToString)
Loop
End If
This worked for me, maybe wrong way but I found it simple :)
May I suggest you use a ListView control instead of Listbox?
If you make the switch, here's a sample subroutine you could use to fill it up with the data you said you want. Adapt it the way you like; there's much room for improvement but you get the general idea:
Public Sub FillUserListView(lstUsers As ListView, Dst As DataSet)
Dim columnsWanted As List(Of String) = New List(Of String)({"User_Name", "First_Name", "Last_Name"})
Dim dt As DataTable = Dst.Tables("user")
Dim columns As Integer = 0
Dim totalColumns = 0
Dim rows As Integer = dt.Rows.Count
'Set the column titles
For Each column As DataColumn In dt.Columns
If columnsWanted.Contains(column.ColumnName) Then
lstUsers.Columns.Add(column.ColumnName)
columns = columns + 1
End If
totalColumns = totalColumns + 1
Next
Dim rowObjects(columns - 1) As ListViewItem
Dim actualColumn As Integer = 0
'Load up the rows of actual data into the ListView
For row = 0 To rows - 1
For column = 0 To totalColumns - 1
If columnsWanted.Contains(dt.Columns(column).ColumnName) Then
If actualColumn = 0 Then
rowObjects(row) = New ListViewItem()
rowObjects(row).SubItems(actualColumn).Text = dt.Rows(row).Item(actualColumn)
Else
rowObjects(row).SubItems.Add(dt.Rows(row).Item(actualColumn))
End If
lstUsers.Columns.Item(actualColumn).Width = -2 'Set auto-width
actualColumn = actualColumn + 1
End If
Next
lstUsers.Items.Add(rowObjects(row))
Next
lstUsers.View = View.Details 'Causes each item to appear on a separate line arranged in columns
End Sub

Error on LINQ statement with enclosing variable

Trying to run the following LINQ statment:
Dim jobId As Integer = CInt(payment.ForJob)
Dim currentPaid = From a In db.Payments
Where a.ForJob = jobId
Select a.Amount
Get the following error on a.Amount though:
Range variable 'Amount' hides a variable in an enclosing block or a range variable previously defined in the query expression
Function RecordPaymentForJob(payment As Payment) As ActionResult
If ModelState.IsValid Then
Dim jobId As Integer = CInt(payment.ForJob)
Dim new currentPaid = From a In db.Payments
Where a.ForJob = jobId
Select a.Amount
Dim totalPaid As Double = currentPaid.Sum()
If (totalPaid + payment.Amount) > (db.Jobs.Find(payment.ForJob).JobAmount * -1) Then
db.Jobs.Find(payment.ForJob).JobStatus = "Paid"
Else
db.Jobs.Find(payment.ForJob).JobStatus = "Part Paid"
End If
Dim Id As Integer = payment.CustomerId
Dim amount As Double = db.Customers.Find(Id).AccBalance
amount += payment.Amount
db.Customers.Find(Id).AccBalance = amount
db.Payments.Add(payment)
db.SaveChanges()
Return Redirect("/Payment/PaymentSuccessful")
End If
Return View(payment)
End Function
I suspect this is the problem:
Dim amount As Double = db.Customers.Find(Id).AccBalance
I don't know VB very well, but I suspect the scope of this variable is the scope of the whole block, including that LINQ statement. In C# at least, that wouldn't be a problem... but the Select clause in VB works somewhat differently, I believe.
One alternative would be to compute the sum directly:
Dim totalPaid = db.Payments.Where(Function(a) a.ForJob = jobId).
Sum(Function(a) a.Amount)
My VB is pretty poor, but I think that should work.