How to search result set from a result set - vb.net

I have a problem to search result from a result set.
I search order based on customer id and store in rs, then I want to search payment based on order id from rs and store in rs2.
This rs2 will then bind in datagridview.
But I found that rs2 will keep reassign the previous data once new data found, so the final result always show the one result which is the last result found. I try use Static rs2 but it still not work.
Hope some expert can provide solution. Thank you.
Private Sub BindCard()
Dim name As String = cboCreditType.Text
Dim db As New ConcertDataContext()
Dim rs = From o In db.orders Where (o.customer_id = MemberLogin.id)
Dim allOrders = From id In rs Select id.order_id
Dim rs2 = From o In db.payments
Where (name = "All" Or o.creditType = name) And
allOrders.Contains(o.order_id)
Select o.payment_id, o.total_payment, o.creditNumber, o.creditType, o.order_id
dgv.DataSource = rs2 'Error occurs here'
End Sub

You have correctly identified the problem in your code, the solution is pretty simple.
Remove the loop, extract a list of orderid to process and then use that list as a condition with Contains against the payments data
' First extract a list of all orders ID present in the orders selected
Dim allOrders = from id in rs select id.orderid
' Then use that list and select only the payments for those orders
rs2 = From o In db.payments
Where (name = "All" Or o.creditType = name) And
(allOrders.Contains(o.order_id))
Select o.payment_id, o.total_payment, o.creditNumber, o.creditType, o.order_id
If you don't need all the data in rs then you can replace the initial query with
Dim allOrders = From o In db.orders
Where (o.customer_id = MemberLogin.id)
Select o.order_Id

Related

Assign Value from Query with sum to Textbox

I am trying to assign the value from a SQL Query to a text box.
I have the function tied to a ComboBox After update.
I tested the SQL by running it.
How do I assign the result to the Txtbox named prepoffEIC?
Dim MyVar2 As Integer
MyVar2 = Me.SelectedExam.Column(0)
ExamViewQry = "SELECT Sum(tblentrys.entryhours) AS TotalHoursPerFunction FROM tBleExams INNER JOIN (tBlBankList INNER JOIN (tBlExaminers INNER JOIN (tBlEntrys INNER JOIN tBlActivity ON tBlEntrys.EntryActivityID = tBlActivity.FunctionKey) ON tBlExaminers.ExaminersKey = tBlEntrys.EntryExaminerID) ON tBlBankList.BankID = tBlEntrys.EntryInstitutionID) ON (tBlBankList.BankID = tBleExams.ExamBankID) AND (tBleExams.ExamID = tBlEntrys.EntryExamID) WHERE tBlEntrys.EntryActivityID=1 AND tblEntrys.EntryExamStageID=1 AND tBleExams.ExamID=" & MyVar2
Me.prepoffEIC.ControlSource = "ExamViewQry"
Me.prepoffEIC.Requery
Create a query using the sql you have, but slightly modded paste it here:
PARAMETERS eid long;
SELECT Sum(tblentrys.entryhours) AS TotalHoursPerFunction
FROM tBleExams
INNER JOIN (
tBlBankList INNER JOIN (
tBlExaminers INNER JOIN (
tBlEntrys INNER JOIN tBlActivity ON tBlEntrys.EntryActivityID = tBlActivity.FunctionKey
) ON tBlExaminers.ExaminersKey = tBlEntrys.EntryExaminerID
) ON tBlBankList.BankID = tBlEntrys.EntryInstitutionID
) ON (tBlBankList.BankID = tBleExams.ExamBankID)
AND (tBleExams.ExamID = tBlEntrys.EntryExamID)
WHERE tBlEntrys.EntryActivityID = 1
AND tblEntrys.EntryExamStageID = 1
AND tBleExams.ExamID = [eid]
lets call it qryGetHours (since i dont know what you need it for.)
in the after update event (also use better naming, this is quick and dirty)
dim db as DAO.Database
dim qry as QueryDef
dim rs as DAO.Recordset
set db = currentdb
set qry = db.querydefs("qryGetHours")
'this is the name of the query you made above
qry.parameters("eid").value = me.SelectedExam.Column(0)
set rs = qry.openrecordset(dbopendynaset,dbseechanges)
'dbseechanges is more for if you have a sql server backend, but i usually do
if not ( rs.eof and rs.bof) then
rs.movefirst
me.prepoffEIC = rs.fields("TotalHoursPerFunction").value
'This portion assumes that you only get one record back,
'or if you do end up with more than one, it only goes
'after the first one.
else
msgbox "Errors... Errors everywhere."
'You will definitely want to put something meaningful
'here relating to it not being able to find the data you
'were looking for.
end if
if not rs is nothing then
rs.close
set rs = nothing
end if
set qry = nothing
set db = nothing
'you will always want to do this portion where you properly
'check if a recordset exists and then close it when you are
'done, along with closing out the querydef and database variables.

LinQ DataTable Group By

I have a datatable in vb.net application. the data table is looking like this:
State Level City
AL T Arlton
AL T Brton
AL T Rurton
CO T Dver
CO T Crodo
WA T Blain
WA T Bwelham
I would like to group the state and do a loop
I tried the following but is not working as expected.
please help
what I tried so far:
Dim result = From r In dt Group r By state = r(0) Into Group Select Group
For Each r In result
Console.WriteLine(r("State"))
Next
The output from the loop should be
AL
CO
WA
Thank you
You cannot call GroupBy on a datatable. So you may first convert the datatable to a collection using the AsEnumerable() method and then apply your group by
Dim itms = dt.AsEnumerable().[Select](Function(x) New With {
Key .City = x.Field(Of String)("City"),
Key .State = x.Field(Of String)("State"),
Key .Level = x.Field(Of String)("Level")
})
Dim uniqueStatesgroupedStates = itms.GroupBy(Function(s) s.State, Function(p) p,
Function(k, v) New With {
Key .State = k,
Key .Item = v
})
' IF you want group records based in State
For Each r In uniqueStatesgroupedStates
Console.WriteLine(r.State)
Next
' IF you want only Unique states from your data table
Dim uniqueStates = itms.[Select](Function(s) s.State).Distinct().ToList()
For Each r In uniqueStates
Console.WriteLine(r)
Next
Your expected output looks like you want only the unique State names, In that case you simply need to do a Select on State property and call Distinct() on that.
I guess you need distinct instead of a group by, If I understood your question correctly following method will work for you.
Dim resultdt As DataTable = dt.DefaultView.ToTable(True, "state")
For Each row In newdt.Rows
Console.WriteLine(row(0).ToString)
Next
DataView.ToTable Method (): Creates and returns a new DataTable based on rows in an existing DataView

Dynamic Where in Linq query to get all results or limit by one

I have a linq query that gets me the data I need. Then I use For Each loop to process it.
Dim PickCustomer as string = "Some Customer"
Dim CustQuery = From Cust In myCustTable _
Select CustomerID = Cust.CustomerID, _
CustName = Cust.Name, _
Order By CustomerID Ascending
For Each MyCust In CustQuery
Next
How can I dynamically change the query? If PickCustomer = "" then I want all the results. But if PickCustomer has a name (any length > 0) then I want to limit my linq query to only that customer. Like Where (CustName = PickCustomer)
I've been checking out dynamic Linq queries but I can't quite make it work.
Since LINQ queries are lazy evaluated, you can build then up in stages, so you don't really need anything dynamic in this case, just an If.
e.g. Something like this (untested):
Dim PickCustomer As String = ""
Dim CustQuery = From Cust In myCustTable
If Not String.IsNullOrWhiteSpace(PickCustomer) Then
CustQuery = From Cust In CustQuery
Where Cust.Name = PickCustomer
End If
CustQuery = From Cust In CustQuery
Select
CustomerID = Cust.CustomerID,
CustName = Cust.Name
Order By CustomerID Ascending
For Each MyCust In CustQuery
Next
I don't think you need dynamic Linq for this. Just add a where clause that deals with both cases. Something like:
Where String.IsNullOrEmpty(PickCustomer) or (CustName = PickCustomer)
Yes, I agree that there's no need to use dynamic LINQ for this.
You can also try logic even outside of the query, like this:
Dim MyCompany as string = "Consolidated Messenger"
Dim companies =
{"Consolidated Messenger", "Alpine Ski House", "Southridge Video", "City Power & Light",
"Coho Winery", "Wide World Importers", "Graphic Design Institute", "Adventure Works",
"Humongous Insurance", "Woodgrove Bank", "Margie's Travel", "Northwind Traders",
"Blue Yonder Airlines", "Trey Research", "The Phone Company",
"Wingtip Toys", "Lucerne Publishing", "Fourth Coffee"}
If MyCompany.length = 0 then
For Each company As String In companies
Console.WriteLine(company)
Next
Else
Dim CompanyResult =
From company In companies where String.IsNullOrEmpty(company) or company.ToLower() = MyCompany.ToLower() select company
For Each comp as String in CompanyResult
Console.WriteLine(comp)
Next
End If

DataSet Row Add / Imports Nothing

So I have a function when fired queries against the database (twice) and returns the results in a dataset. It checks the results (to make sure there are some) then loops through and grabs each row from the returned dataset and imports (copies) it to a different dataset.
I also add a primary key into a List so I do not add the same item twice (from the 2nd query) to the dataset.
I then return the dataset.
The problem? The query works and there is a returned value.. however the dataset in which I aim to import the row(s) to does not keep the imported row.
Please make any suggestions regarding my approach and the issue at hand; I'm always looking to improve!
Public Function GetClientsWithMonitors(ByVal argHost As FOO.Interfaces.BAR) As DataSet
Try
Dim localDataSet As New DataSet()
Dim clientsWithMonitors As New DataSet()
Dim tempList As New List(Of Integer)
clientsWithMonitors.Clear()
localDataSet.Clear()
tempList.Clear()
clientsWithMonitors.Tables.Add()
'SQL getting monitors applied to clients
Dim clientSQL As String = "SELECT DISTINCT c.ClientID, c.Name FROM agents a LEFT JOIN clients c ON c.ClientID = a.ClientID WHERE a.ClientID > 0"
'SQL getting monitors applied directly to an agent
Dim agentSQL As String = "SELECT DISTINCT c.ClientID, c.Name FROM clients c LEFT JOIN computers comp ON c.ClientID = comp.ClientID LEFT JOIN agents a ON comp.ComputerID = a.ComputerID WHERE a.LocID = 0 AND a.ClientID = 0 AND a.ComputerID > 0"
localDataSet = argHost.GetDataSet(clientSQL)
If localDataSet.Tables.Count > 0 AndAlso localDataSet.Tables(0).Rows.Count > 0 Then
For Each row As DataRow In localDataSet.Tables(0).Rows
If Not tempList.Contains(CInt(row("ClientID").ToString())) Then
Dim clientID As Integer = CInt(row("ClientID").ToString())
clientsWithMonitors.Tables(0).ImportRow(row)
tempList.Add(clientID)
End If
Next
End If
If localDataSet.Tables.Count > 0 AndAlso localDataSet.Tables(0).Rows.Count > 0 Then
localDataSet.Clear()
localDataSet = argHost.GetDataSet(agentSQL)
For Each row As DataRow In localDataSet.Tables(0).Rows
If Not tempList.Contains(CInt(row("ClientID").ToString())) Then
Dim clientID As Integer = CInt(row("ClientID").ToString())
clientsWithMonitors.Tables(0).ImportRow(row)
tempList.Add(clientID)
End If
Next
End If
Return clientsWithMonitors
Catch ex As Exception
LogEventViaHost(argHost, "Error Getting dataset of clients with a specified monitor" & ex.StackTrace & " " & ex.Message)
Return Nothing
End Try
Column names must be explicitly stated; for some reason I was thinking the dataset it would implicitly inherit the column names from the imported datarow row.
clientsWithMonitors.Tables(0).Columns.Add("Foo")
clientsWithMonitors.Tables(0).Columns.Add("Bar")

Get Query Results in a String

If I run a query to select three seperate fields from each record. Is it possible to get the results for each returned in three separate strings (one for each field) so that I can cycle through them in vba code?
Yes, you can try opening a Recordset and accessing the field values like a collection.
Dim d As DAO.Database
Dim r As DAO.Recordset
Set d = CurrentDb()
Set r = d.OpenRecordset("SQL or TableName")
While Not r.EOF
Debug.Print r!Field1, r!Field2, r!Field3
r.MoveNext
Wend
r.Close
Set r = Nothing
Set d = Nothing