Using Linq for select row from DataTableA where id not in DataTableB - vb.net

I have two dataTables ,and i want select all rows from DataTable1 where id is not in DataTable2.below what i have tried :
Sql = "select *,N°Reçu as NumRecu from V_Sit_J_Vente,V_Bien where V_Sit_J_Vente.Code_bien=V_Bien.Code_bien and date_situation <= '" + dt2 + "' and date_situation >= '" + dt1 + "'"
Dim GlobalDataVente As DataTable = utilitaire.getDataSet(Sql).Tables(0)
Sql = "select * from V_Reserv_Annule"
Dim GlobalDataAnnule As DataTable = utilitaire.getDataSet(Sql).Tables(0)
Dim query = (From order In GlobalDataVente.AsEnumerable() _
Where order!code_projet = tab.Rows(i).Item("code_projet")).ToList
Dim bannedCCList = From c In GlobalDataAnnule.AsEnumerable() _
Where c!type.Equals("Transfert acompte") = False And c!date_annule <= dt2
Dim exceptBanned = From c In query Group Join b In bannedCCList On c.Field(Of String)("N°Reçu") Equals b.Field(Of String)("num_reserv_remplace")
Into j() From x In j.DefaultIfEmpty() Where x Is Nothing Select c
What i want that "exceptBanned " containt all rows of "query" except row exist in "bannedCCList "
Thanks in advance

You can use Contains for this:
Dim query = (From order In GlobalDataVente.AsEnumerable() _
Where order!code_projet = tab.Rows(i).Item("code_projet")).ToList
Dim bannedCCList = From c In GlobalDataAnnule.AsEnumerable() _
Where c.type.Equals("Transfert acompte") = False And c.date_annule <= dt2
Select c.Field(Of String)("num_reserv_remplace")
Dim exceptBanned = From c In query
Where Not bannedCCList.Contains(c.Field(Of String)("N°Reçu"))
Select c
bannedCCList defines a query that produces the Id values you want to exclude; exceptBanned combines query with this list of Ids into a query that only runs once to return the final results. It works this way because bannedCCList is an IEnumerable. It isn't executed when it's defined, only when it's actually used.

Related

Why is this dropdown not populating?

I have three dropdowns; the second one (Members) populates based on what's in the first (Units), and the third one (Customers) SHOULD populate based on what's in the second; but it doesn't.
Here's the query that works in LINQPad (returns a list of Company names):
select distinct companyname from customers C left join members M on M.MemberNo = C.MemberNo where M.MemberNo = '052' order by companyname
...but does not work in the following code:
'Populate the Members dropdown
Dim selectedUnit As String = DropDownListUnits.Text
Dim membersDT As DataTable
sql = "select distinct shortname, M.memberno from members M left join memberunitproducts mup on M.MemberNo = mup.MemberNo where unit = '" + selectedUnit + "' order by shortname"
retDS = sqlDAL.runSQLDataSet(sql)
membersDT = retDS.Tables(0)
DropDownListMembers.DataSource = membersDT
DropDownListMembers.DataTextField = "shortname"
DropDownListMembers.DataValueField = "memberno"
DropDownListMembers.DataBind()
'Populate the Customers dropdown
Dim selectedMember As String = DropDownListMembers.DataValueField
Dim customersDT As DataTable
sql = "select distinct companyname from customers C left join members M on M.MemberNo = C.MemberNo where M.MemberNo = '" + selectedMember + "' order by companyname"
retDS = sqlDAL.runSQLDataSet(sql)
customersDT = retDS.Tables(0)
DropDownListCustomers.DataSource = customersDT
DropDownListCustomers.DataTextField = "companyname"
DropDownListCustomers.DataValueField = "companyname"
DropDownListCustomers.DataBind()
The third (Customers) dropdown remains unpopulated when this runs - why?
It's probably not needed, but here is the code for the first ("Units") dropdown:
'Populate the Units dropdown
Dim unitsDT As DataTable
sql = "Select distinct unit from masterunits where abs(active) = 1"
retDS = sqlDAL.runSQLDataSet(sql)
unitsDT = retDS.Tables(0)
DropDownListUnits.DataSource = unitsDT
DropDownListUnits.DataTextField = "unit"
DropDownListUnits.DataValueField = "unit"
DropDownListUnits.DataBind()
What am I missing or doing wrong?
I had to change this:
Dim selectedMember As String = DropDownListMembers.DataValueField
...to this:
Dim selectedMember As String = DropDownListMembers.SelectedItem.Value

VB.Net Linq with datatables - select from one table what does not exist in the other

I have two data on which I have applied the linq to select some lines :
csql = "select * from V_Vente where code_projet=" & ComProjet.GetColumnValue("code_projet") & " "
Dim tabVnt as Datatable = utilitaire.getDatatable(csql)
Dim query1 = tabVnt.AsEnumerable().Where(Function(r) DirectCast(r("date"), Date) >= dtDu And DirectCast(r("date"), Date) <= dtAu)
Dim tabAnnule As DataTable = utilitaire.getDatatable("select * from V_Reserv_Annule")
Dim query2 = From cust In tabAnnule.AsEnumerable() Where (cust.type = "définitif" Or cust.type = "Transfert") And cust.date_annule <= dtAu
now what i want is to select rows from "query1" where "Num_R" not exist in "query2".
The column "Num_r" exist in both datatable "tabVnt" and "tabAnnule"
I've tried this code but he doesn't work,please help me to find the error :
dim rows = from t1 in query1 .AsEnumerable() join t2 in query2.AsEnumerable() on t1.Field(Of String)("Num_r") equals t2.Field(Of String)("Num_r") Into tg
From tcheck In tg.DefaultIfEmpty()
Where tcheck = null
Select t1()
If I have understood your code right, you can check if second table's Num_rs does not contain the table one Num_r:
Dim rows = t1.Where(x=> !t2.Select(y=> y.Num_r).Contains(x.Num_r));
I have find the solution for my issus ,and i'd like to share it here with you :
Dim csql = "select * from V_Vente where code_projet=" & ComProjet.GetColumnValue("code_projet") & " "
Dim tabVnt As DataTable = utilitaire.getDatatable(csql)
Dim query1 = tabVnt.AsEnumerable().Where(Function(r) DirectCast(r("date"), Date) >= dt1 And DirectCast(r("date"), Date) <= dt2).ToList
Dim tabAnnule As DataTable = utilitaire.getDatatable("select * from V_Reserv_Annule")
bannedCCList = From c In tabAnnule.AsEnumerable() _
Where (c!type.Equals("définitif") = True Or c!type.Equals("Transfert") = True) And c!date_annule <= dt2
Select c.Field(Of String)("num_recu")
Dim exceptData = (From c In query1.AsEnumerable() _
Where Not bannedCCList.Contains(c.Field(Of String)("num_recu")) _
).ToList

how to use an in clause to check if a column is a certain string or not when referencing 3 tables

I have this SQL statement and it joining 2 tables...
SELECT TRIDENT.Maintenance.RCFAs.*, TRIDENT.Maintenance.Equipment.EquipmentName
FROM TRIDENT.Maintenance.RCFAs
LEFT JOIN TRIDENT.Maintenance.Equipment
ON TRIDENT.Maintenance.Equipment.EquipmentId = TRIDENT.Maintenance.RCFAs.EquipmentId
WHERE 1 = 1
Now I have to reference a third table because I have a dropdown by the name of components that we will use to lookup stuff on the table named TRIDENT.Maintenance.RCFAXrefComponents. So if "bolts" is selected from the dropdown it will look up the YEAR and RCFAID which makes a unqiue key for both RCFAXrefComponents and RCFAs and checks if there are any rows in RCFAs that had "bolts" in the component column when looking up that YEAR and RCFAId. A coworker suggested I use an IN clause to check if the YEAR and RCFAId is in that RCFAXrefComponents. He said it might be tricky, but I'm a little lost on how to do this.
Below is the RCFAs table that I want to grab the YEAR and RCFAId values together and lookup on the other to see if that bolt is also there. Then it should bring up the line item on RCFAs table to output to user
this is RCFAXrefComponents table below
Public Shared Function GetRCFAList(rcfaNumber As Integer?, description As String,
failureType As String, equipmentDescription As String, componentSelection As String) As List(Of RCFA)
Dim sql = "SELECT r.*, e.EquipmentName FROM TRIDENT.Maintenance.RCFAs AS r LEFT JOIN TRIDENT.Maintenance.Equipment AS e ON e.EquipmentId = r.EquipmentId JOIN TRIDENT. Maintenance.RCFAXrefComponents AS c ON c.Year = r.Year AND c.RCFAId = r.RCFAId WHERE"
If failureType <> "" Then
sql += " AND RCFAs.FailureType = '" & failureType.ToUpper & "'"
End If
If description <> "" Then
sql += " AND RCFAs.ShortDesc LIKE '%" & description.ToUpper & "%'"
End If
If equipmentDescription <> "" Then
sql += " AND Equipment.EquipmentName LIKE '%" & equipmentDescription.ToUpper & "%'"
End If
If componentSelection <> "" Then
sql += " c.ComponentId = '%" & componentSelection.ToUpper & "%'"
End If
Dim dbConn As New Trident.Core.DBConnection
Dim ds = dbConn.FillDataSet(sql)
Dim tmpList As New List(Of RCFA)
For Each dr As DataRow In ds.Tables(0).Rows
tmpList.Add(New RCFA(New Trident.Objects.Maintenance.RCFA.RCFA(dr)))
Next
Return tmpList
End Function
Just use a simple JOIN with the RFCAXrefComponents table, and a WHERE clause that filters the component ID.
SELECT r.*, e.EquipmentName
FROM TRIDENT.Maintenance.RCFAs AS r
LEFT JOIN TRIDENT.Maintenance.Equipment AS e
ON e.EquipmentId = r.EquipmentId
JOIN TRIDENT.Maintenance.RCFAXrefComponents AS c
ON c.Year = r.Year
AND c.RCFAId = r.RCFAId
WHERE c.ComponentID = 'BOLTS'
I may be confused but it sounds like you need to use EXISTS.
SELECT r.*,
e.EquipmentName
FROM TRIDENT.Maintenance.RCFAs r
LEFT JOIN TRIDENT.Maintenance.Equipment e ON e.EquipmentId = r.EquipmentId
WHERE EXISTS ( SELECT 1
FROM TRIDENT.Maintenance.RCFAXrefComponents c
WHERE c.Year = r.Year
AND c.RCFAId = r.RCFAId
AND c.ComponentId LIKE '%BOLTS%' )
you may not need the c.ComponentId LIKE '%BOLTS%' you might just want c.ComponentId = 'BOLTS'

Identical datatable 2 columns merging and summing one column in vb.net

I have 5 datatables which having each 3 columns (ID, Brand, Quanitiy) to derive the opening, purchase, sales and closing stock. The First 3 datatables should be merged and sum up to derive the opening stock as on given period. 4 th datatable is for Purchases done for the given period. The last one Datatable is for Sales done for the given period.
Here is my question:
How can i merge the 3 datatables and using the first 2 columns and summing the values?
How can i use the tables in crystal reports?
My code is :
Dim con As New ClassConnection
If con.Conn.State = ConnectionState.Closed Then con.Conn.Open()
'To get Opening Stock in Full Quantity
Dim sql As String = "SELECT tblBrand.B_ID AS ID, tblBrand.B_Name AS Brand," & _
" Sum (tblOp_Details.Net_Qty) AS Quantity FROM tblOp_Stock INNER JOIN (tblBrand INNER JOIN" & _
" tblOp_Details ON tblBrand.B_ID = tblOp_Details.B_ID) ON tblOp_Stock.Stk_ID = tblOp_Details.Stk_ID" & _
" WHERE tblOp_Stock.God_ID = #GID GROUP BY tblBrand.B_ID, tblBrand.B_Name"
'To get Purchases < start date and adding to the opening stock
Dim sql1 As String = "SELECT tblBrand.B_ID AS ID, tblBrand.B_Name AS Brand," & _
" Sum (tblPur_Details.Net_Qty) AS Quantity FROM tblPurchase INNER JOIN (tblBrand INNER JOIN" & _
" tblPur_Details ON tblBrand.B_ID = tblPur_Details.B_ID) ON tblPurchase.Pur_ID = tblPur_Details.Pur_ID" & _
" WHERE tblPurchase.God_ID = #GID AND tblPurchase.Rec_Date < #SDate GROUP BY tblBrand.B_ID, tblBrand.B_Name"
'To get Sales < Start date and subtracting to the above
Dim sql2 As String = "SELECT tblBrand.B_ID AS ID, tblBrand.B_Name AS Brand," & _
" Sum (tblSales_Details.Net_Qty) AS Quantity FROM tblSales INNER JOIN (tblBrand INNER JOIN" & _
" tblSales_Details ON tblBrand.B_ID = tblSales_Details.B_ID) ON tblSales.Sale_ID = tblSales_Details.Sale_ID" & _
" WHERE tblSales.God_ID = #GID AND tblSales.Sale_Date < #SDate GROUP BY tblBrand.B_ID, tblBrand.B_Name"
'The above 3 condition is for deriving opening stock as on given date
'To get Purchases >= Start Date and <= Start Date
Dim sql3 As String = "SELECT tblBrand.B_ID AS ID, tblBrand.B_Name AS Brand," & _
" Sum(tblPur_Details.Net_Qty) AS Quantity FROM tblBrand INNER JOIN (tblPurchase INNER JOIN" & _
" tblPur_Details ON tblPurchase.Pur_ID = tblPur_Details.Pur_ID) ON tblBrand.B_ID = tblPur_Details.B_ID" & _
" WHERE tblPurchase.God_ID = #GID And tblPurchase.Rec_Date >= #SDate And tblPurchase.Rec_Date" & _
" <= #EDate GROUP BY tblBrand.B_ID, tblBrand.B_Name"
'The above condition is for deriving Purchases as on given date
'To get Sales >= Start Date and <= Start Date
Dim sql4 As String = "SELECT tblBrand.B_ID AS ID, tblBrand.B_Name AS Brand," & _
" Sum(tblSales_Details.Net_Qty) AS Quantity FROM tblBrand INNER JOIN (tblSales INNER JOIN" & _
" tblSales_Details ON tblSales.Sale_ID = tblSales_Details.Sale_ID) ON tblBrand.B_ID = tblSales_Details.B_ID" & _
" WHERE tblSales.God_ID = #GID And tblSales.Sale_Date >= #SDate And tblSales.Sale_Date <= #EDate" & _
" And tblSales_Details.S_Active = #SAct GROUP BY tblBrand.B_ID, tblBrand.B_Name"
'The above condition is for deriving Sales as on given date
Dim da As New OleDb.OleDbDataAdapter(sql, con.Conn)
Dim da1 As New OleDb.OleDbDataAdapter(sql1, con.Conn)
Dim da2 As New OleDb.OleDbDataAdapter(sql2, con.Conn)
Dim da3 As New OleDb.OleDbDataAdapter(sql3, con.Conn)
Dim da4 As New OleDb.OleDbDataAdapter(sql4, con.Conn)
da.SelectCommand.Parameters.AddWithValue("#GID", Me.stBar_G_ID.Text)
da1.SelectCommand.Parameters.AddWithValue("#GID", Me.stBar_G_ID.Text)
da1.SelectCommand.Parameters.AddWithValue("#SDate", Me.dtpStart.ToString)
da2.SelectCommand.Parameters.AddWithValue("#GID", Me.stBar_G_ID.Text)
da2.SelectCommand.Parameters.AddWithValue("#SDate", Me.dtpStart.ToString)
da3.SelectCommand.Parameters.AddWithValue("#GID", Me.stBar_G_ID.Text)
da3.SelectCommand.Parameters.AddWithValue("#SDate", Me.dtpStart.ToString)
da3.SelectCommand.Parameters.AddWithValue("#EDate", Me.dtpEnd.ToString)
da4.SelectCommand.Parameters.AddWithValue("#GID", Me.stBar_G_ID.Text)
da4.SelectCommand.Parameters.AddWithValue("#SDate", Me.dtpStart.ToString)
da4.SelectCommand.Parameters.AddWithValue("#EDate", Me.dtpEnd.ToString)
da4.SelectCommand.Parameters.AddWithValue("#SAct", "Yes")
Dim dt As New DataTable
Dim dt1 As New DataTable
Dim dt2 As New DataTable
Dim dt3 As New DataTable
Dim dt4 As New DataTable
Ignoring the fact that such operations should be done in the database instead of memory, you can use Linq-To-DataSet which is a subset of Linq-To-Objects.
If you want to concatenate the three tables, group by ID + Brand to get the sum of Quantity:
Dim allRows = dt1.AsEnumerable().Concat(dt2.AsEnumerable()).Concat(dt3.AsEnumerable())
Dim query = From row In allRows
Let GroupColumns = New With {
.Id = row.Field(Of Int32)("Id"),
.Brand = row.Field(Of String)("Brand")
}
Group row By GroupColumns Into Group
Select New With {
.Id = GroupColumns.Id,
.Brand = GroupColumns.Brand,
.SumQuantity = Group.Sum(Function(row) row.Field(Of Int32)("Quantity"))
}
Fill the merged table from the query:
Dim dt As DataTable = dt1.Clone() ' empty, same columns
For Each x In query
Dim row = dt.Rows.Add()
row.SetField("Id", x.Id)
row.SetField("Brand", x.Brand)
row.SetField("Quantity", x.SumQuantity)
Next

How to merge cells and remove blank spaces in my DataGrid using proper loop

My title is still broad so i'll explain here further.
This is my current output using my code:
.
But I want to make it look like this..
As you can see on the pictures, i want to remove the blank spaces. Because if I selected MORE data, let's say I selected 7 more days, it will go DIAGONALLY not horizontally.
I think I have a problem regarding my loops. Hope you can help me trace because I've been stuck here for a week debugging. (nevermind my long query, i just want to post all my code. I've also added comments for easier debugging.)
Here's my code:
Private Sub LoadDateAndUser()
Dim SqlStr As String = ""
Dim sqlConn As New SqlConnection(DataSource.ConnectionString)
Dim sqlComm As New SqlCommand(SqlStr, sqlConn)
Dim sqlAdapter As New SqlDataAdapter(sqlComm)
Dim o_Dataset As New DataSet()
SqlStr = " SELECT convert(varchar(10), A.TransDate, 101) as TransDate,ADMMED.TransNum, ADMMED.AdministeredDate, D.Dosage [Dosage], ISNULL(C.GenericName, ' ') + ' (' + IsNull(B.ItemName,'') + ' ' + IsNull(B.ItemDesc,'') + ')' [Medication], ADMMED.UserID" & _
" FROM INVENTORY..tbInvStockCard as A" & _
" LEFT OUTER JOIN INVENTORY..tbInvMaster as B On A.ItemID = B.ItemID " & _
" LEFT OUTER JOIN Inventory.dbo.tbForGeneric as C On B.GenericID = C.GenericID" & _
" LEFT OUTER JOIN Station..tbNurse_AdministeredMedicines ADMMED on a.idnum= ADMMED.idnum " & _
" LEFT OUTER JOIN build_file.dbo.tbCoDosage as D on A.DosageID = D.DosageID" & _
" LEFT OUTER JOIN Station.dbo.tbNurseCommunicationFile as E on A.IdNum = E.IDnum and E.ReferenceNum = A.RefNum" & _
" WHERE A.IdNum = '" & Session.Item("IDNum") & "' and ( A.RevenueID = 'PH' or A.RevenueID = 'PC' ) " & _
" AND A.LocationID = '20' and Not IsNull(ADMMED.AdministeredDate, '') = ''" & _
" AND A.RefNum = ADMMED.ReferenceNum and ADMMED.ItemID = A.itemid" & _
" AND (B.ItemClassificationID = '1' or B.ItemClassificationID = '10' or B.ItemClassificationID = '11' or B.ItemClassificationID = '16' or B.ItemClassificationID = '2' or B.ItemClassificationID = '9')" & _
" order by TransDate desc,ADMMED.AdministeredDate desc"
sqlComm.CommandText = SqlStr
sqlAdapter.Fill(o_Dataset, "Table")
Dim o_Row As DataRow
Dim o_AdmDates As New Collection()
Dim s_FormattedLastAdmDate As String = ""
Dim s_FormattedAdmDate As String = ""
Dim o_DerivedTable As New DataTable()
With o_DerivedTable
.Columns.Add("TransDate")
.Columns.Add("Medication")
.Columns.Add("Dosage")
.Columns.Add("TransNum")
End With
'Select all unformatted administered dates from the query
Dim o_UnformattedAdmDates As DataRow() = o_Dataset.Tables(0).Select("", "AdministeredDate Desc")
'Extract distinct administered dates and change its format
For Each o_Row In o_UnformattedAdmDates
s_FormattedAdmDate = Format(CDate(o_Row.Item("AdministeredDate")), KC_Date_Format) 'eg. Jan 01 15
If s_FormattedLastAdmDate <> s_FormattedAdmDate Then
s_FormattedLastAdmDate = s_FormattedAdmDate
o_AdmDates.Add(s_FormattedLastAdmDate) 'add all formatted dates in o_AdmDates
End If
Next
'Add formatted administred dates to derived table
Dim o_Item As String
For Each o_Item In o_AdmDates
o_DerivedTable.Columns.Add(o_Item)
Next
'Loop through the administred date
Dim o_NewRow As DataRow
Dim o_NextRow As DataRow
Dim i_Ctr As Integer
Dim x_isNewRow As Boolean = True
Dim i_MaxRec As Integer
i_MaxRec = o_Dataset.Tables(0).Rows.Count - 1
For i_Ctr = 0 To i_MaxRec
o_Row = o_Dataset.Tables(0).Rows(i_Ctr)
If i_Ctr <> i_MaxRec Then
o_NextRow = o_Dataset.Tables(0).Rows(i_Ctr + 1)
End If
If x_isNewRow Then
o_NewRow = o_DerivedTable.NewRow()
End If
o_NewRow("TransDate") = o_Row("TransDate")
o_NewRow("Medication") = o_Row("Medication")
o_NewRow("Dosage") = o_Row("Dosage")
o_NewRow("TransNum") = o_Row("TransNum")
'Fill approriate result date column based on query
For Each o_Item In o_AdmDates
s_FormattedAdmDate = Format(CDate(o_Row.Item("AdministeredDate")), KC_Date_Format)
Dim AdmTim As DateTime = DateTime.Parse(o_Row("AdministeredDate"))
If s_FormattedAdmDate = o_Item Then
o_NewRow(s_FormattedAdmDate) = AdmTim.ToString("hh:mm tt") + " - " + o_Row("UserID")
End If
Next
If i_Ctr < i_MaxRec _
And Not o_NextRow Is Nothing _
And o_Row("TransDate") = o_NextRow("TransDate") _
And o_Row("Medication") = o_NextRow("Medication") _
And o_Row("Dosage") = o_NextRow("Dosage") _
And o_Row("AdministeredDate") = o_NextRow("AdministeredDate") Then
x_isNewRow = False
Else
o_DerivedTable.Rows.Add(o_NewRow)
x_isNewRow = True
End If
Next
'Bind derived table
dgSheet.DataSource = o_DerivedTable
dgSheet.DataBind()
If o_Dataset.Tables(0).Rows.Count > 0 Then
GroupGridView(dgSheet.Items, 0, 3)
Else
End If
End Sub
I think you must review your programming logic:
After that huge ugly SqlStr : you will have a DataSet, with a Table with all rows mixed !?
Let's try a pseudo-code:
I think is better to create in that DataSet, 2 Tables:<br>
**first** table with: id, DateOrder, Medication, Dosage <br>
and **second** table with: idDate, FirstTable.id, AdministeredDate
after that you know how many ADMMED.AdministeredDate.Count are, because you must know how manny columns you need to add
create a 3-rd table from iteration of first table, nested with second by ID.
Set as Datasource for DataGridView the Third DataTable.
So you have 2 datasets, and generate this one .. one to many ..
.. I have no time now, if you don't get the ideea .. forget it !