I have Multiple Rows of same product with different Qty.
I want single row of each product by doing some of Qty in datatable in vb.net
So you want to group by the product and sum the quantity per group?
You could use LINQ's GroupBy + Sum and fill a second table with the same schema:
Dim productGroups = dt.AsEnumerable().GroupBy(Function(row) row.Field(Of String)("Product"))
Dim aggregatedTable As DataTable = dt.Clone() ' empty table, same columns
For Each grp In productGroups
Dim newRow = aggregatedTable.Rows.Add()
Dim sumOfQuantity As Int32 = grp.Sum(Function(row) row.Field(Of Int32)("Qty"))
newRow.SetField("Product", grp.Key)
newRow.SetField("Qty", sumOfQuantity)
Next
The same with query syntax if you prefer it:
Dim productGroups = From row In dt.AsEnumerable()
Group row By Product = row.Field(Of String)("Product") Into Group
Related
I have list of all days in a month (as GridView header) refer to which month is selected by user which then be displayed in GridView.
Display list of Days in a month
Dim dt As New DataTable
Dim col As New DataColumn
dt.Columns.AddRange(New DataColumn(0) {New DataColumn("Date")})
For i As Integer = 1 To gsTotalDD 'gsTotalDD is total of days in a month
dt.Columns.Add(i)
Next
dt.Rows.Add("Status")
gvRptStatus.DataSource = dt
gvRptStatus.DataBind()
I had a table named tblUpload inside the database which storing data that been uploaded together with date of data uploaded.
What I am trying to do is looping through all the header value (list of days) and check either there is day matching with the date of data uploaded. When there is matching value, the status row on the code dt.Rows.Add("Status") will show status done and leave cell empty if no matching days found.
Example : GridView date (fist row), second header column is 1 and check with database has matching value or not. If yes then on (second row) status, at second column will display done.
EDIT
So I came up with checking the matching value like this :
Dim lCnn As New SqlConnection(gsConnString)
Dim lCmd As New SqlCommand
Dim lsCmd As String
Dim dt As New DataTable
Dim newDt As New DataTable
Dim sda As New SqlDataAdapter
Dim dtrow As DataRow = newDt.NewRow()
lCnn.Open()
lCmd.Connection = lCnn
lsCmd = "SELECT DISTINCT DATEPART (d, [date])"
lsCmd &= " FROM dbUpload..tblUpload"
lCmd.CommandText = lsCmd
sda.SelectCommand = lCmd
sda.Fill(newDt)
dt.Columns.AddRange(New DataColumn(0) {New DataColumn("Date")})
For i As Integer = 1 To gsTotalDD 'gsTotalDD is total of days in a month
dt.Columns.Add(i)
value2 = i
For Each col As DataColumn In newDt.Columns
value = newDt.Rows(i - 1).Item(col)
If value = value2 Then
MsgBox("Same value")
End If
Next
Next
By doing this, I manage to check the value but it's not the right way to do it since I wanted to set the status as done if got matching value or leave status empty if vice versa.
Thank you.
I have 2 datatable objects (dt1,dt2), which have a common filed called "File_Name". I want to create a datatable (dtFinal), combining the two datatables to be used in gridview of asp.net
Each of the tables (dt1,dt2) can have overlapping column header names, meaning if dt1 has a header as "plant_code" dt2 can also have the header as "plant_Code" but not mandatory.
My objective is to have a common datatable (dtFinal) with all the headers from all the individual datatables.
I tried something like this
Dt1.PrimaryKey = New DataColumn() {Dt1.Columns(System.AppDomain.CurrentDomain.BaseDirectory & "\resources\files\" & "GRN" & ".csv")}
Dt2.PrimaryKey = New DataColumn() {Dt1.Columns(System.AppDomain.CurrentDomain.BaseDirectory & "\resources\files\" & "Payment Data" & ".csv")}
Dt1 = CsvToDataTable(System.AppDomain.CurrentDomain.BaseDirectory & "\resources\files\" & "GRN" & ".csv")
Dt2 = CsvToDataTable(System.AppDomain.CurrentDomain.BaseDirectory & "\resources\files\" & "Payment Data" & ".csv")
ds.Tables.Add(Dt1)
ds.Tables.Add(Dt2)
Dim drel As New DataRelation("EquiJoin", Dt2.Columns("File_Name"), Dt1.Columns("File_Name"))
ds.Relations.Add(drel)
Dim jt As New DataTable("Joinedtable")
ds.Tables.Add(jt)
For Each dr As DataRow In ds.Tables("Table1").Rows
Dim parent As DataRow = dr.GetParentRow("EquiJoin")
Dim current As DataRow = jt.NewRow()
' Just add all the columns' data in "dr" to the New table.
For i As Integer = 0 To ds.Tables("Table1").Columns.Count - 1
current(i) = dr(i)
Next
' Add the column that is not present in the child, which is present in the parent.
current("Dname") = parent("Dname")
jt.Rows.Add(current)
Next
DtFinal = ds.Tables("Joinedtable")
Creating a dataset and a relation between dt1 and dt2 ...But this doesn't seem to work and giving me an error in line 1 instance of object to be declared using New.
Has someone tried something like this in Vb ? Or can my code be edited to make it work.
Further info: each datatable tb1 and tb2 have unique values in the File_Name column which is the first column. and hence can be selected as the primary key.
When you say, "Merge" it may mean one thing or another. For example, I may think of this method.
This is Working Code:
Public Sub MergeTables()
Dim t1 As New DataTable("T1")
t1.Columns.Add("C1", GetType(String))
t1.Columns.Add("C2", GetType(String))
t1.Columns.Add("C3", GetType(String))
Dim t2 As New DataTable("T2")
t2.Columns.Add("C1", GetType(String)) 'same column
t2.Columns.Add("C2", GetType(Integer)) ' same column, different data type
t2.Columns.Add("C4", GetType(String)) ' different column
Dim map As New Dictionary(Of String, String)
Dim t3 As New DataTable("T4")
MergeColumns(t3, t1, map)
MergeColumns(t3, t2, map)
Debug.WriteLine("Should be 5 columns and reality is: " & t3.Columns.Count)
' Add some data
t1.Rows.Add({"data from t1 c1", "data from t1 c2", "data from t1 c3"})
t2.Rows.Add({"data from t2 c1", 55, "data from t2 c3"})
MergeRows(t3, t1, map)
MergeRows(t3, t2, map)
t3.AcceptChanges()
For Each row As DataRow In t3.Rows
Debug.WriteLine(String.Join(";", row.ItemArray.Select(Function(o) o.ToString()).ToArray()))
Next
End Sub
Private Sub MergeColumns(totbl As DataTable, fromtbl As DataTable, map As Dictionary(Of String, String))
For Each c As DataColumn In fromtbl.Columns
If Not totbl.Columns.Contains(c.ColumnName) Then
totbl.Columns.Add(c.ColumnName, c.DataType)
map.Add(c.Table.TableName & "_" & c.ColumnName, c.ColumnName)
ElseIf Not totbl.Columns(c.ColumnName).DataType.Equals(c.DataType) Then
totbl.Columns.Add(c.Table.TableName & "_" & c.ColumnName, c.DataType)
map.Add(c.Table.TableName & "_" & c.ColumnName, c.Table.TableName & "_" & c.ColumnName)
Else
map.Add(c.Table.TableName & "_" & c.ColumnName, c.ColumnName)
End If
Next
End Sub
Private Sub MergeRows(totbl As DataTable, fromtbl As DataTable, map As Dictionary(Of String, String))
For Each row As DataRow In fromtbl.Rows
Dim newRow As DataRow = totbl.NewRow()
For Each c As DataColumn In fromtbl.Columns
newRow(map(fromtbl.TableName & "_" & c.ColumnName)) = row(c.ColumnName)
Next
totbl.Rows.Add (newRow)
Next
End Sub
Result:
data from t1 c1 ; data from t1 c2 ; data from t1 c3 ; ;
data from t2 c1 ; ; ; 55 ; data from t2 c3
But may be, you need something else. However, this is good example how to do thing like this
You could try the DataTable Merge.
dt3 = new DataTable();
dt3 .Merge(dtOne);
dt3 .Merge(dtTwo);
Look at this post for more info/solutions. Merge 2 DataTables and store in a new one
i have 2 table in my dataset, what i trying to achieve is convert 2 table item into string
Public Shared Function mtdCDsToStr(ByVal pDataSet As DataSet) As String
Dim sDs As String
Dim sb As New System.Text.StringBuilder
Dim drRow As DataRow
Dim dcColumn As DataColumn
Dim dtTable As DataTable
Dim x As Integer = 0
For Each dtTable In pDataSet.Tables
For Each drRow In pDataSet.Tables(x).Rows
Dim colName(pDataSet.Tables(x).Columns.Count) As String
Dim i As Integer = 0
For Each dcColumn In pDataSet.Tables(0).Columns
colName(i) = dcColumn.ColumnName
sb.Append(colName(i) + "," + drRow(colName(i)).ToString + ",")
i += 1
Next
sb.Append("|")
Next
x += 1
sb.Append("$")
Next
sDs = sb.ToString
Return sDs
End Function
code explanation
the function is to pass in a dataset and convert the dataset into a string
what i trying to achieve is convert multiple datatable into a string but i can only loop one table in my code above, what should i do in order to loop multi table? =(
change as below
For Each dtTable As DataTable In dataSet.Tables
For Each dr As DataRow In dtTable.Rows
For Each column As DataColumn In dtTable.Columns
sb.Append(column.ColumnName + "," & dr(column.ColumnName).ToString() & ",")
Next
sb.Append("|")
Next
sb.Append("$")
Next
But rather than converting DataSet to string you may try to get XML from DataSet. I'm Not sure What is the exact requirement you converting to sting, but XML will be good way to communicate Data.
xmlString =lpDataSet.GetXml()
I have three select statements,
select 1 from tbl1;
select 2 from tbl2;
select 3 from tbl3;
and in my front end i use a Datatable to retrieve the value from sql.
datatable dt = new datatable(); dt = obj.funcgetval();
gridview.DataSource = dt; gridview.Databind();
I want to select a particular data from the datatable like in a dataset we use ds.tables[0], how can we apply the same in a datatable?
You can use combination of Rows and Columns to read / write particular cell of datatable.
dataTable.Rows[rowsIndex].Column["ColumnName"] = "SomeValue";
string strValue = dataTable.Rows[rowsIndex].Column["ColumnName"].ToString();
To iterate through dataTable
foreach(DataRow row in dt.Rows)
{
string name = row["name"].ToString();
string description = row["description"].ToString();
}
If you want to select any row then use
DataRow dr=dt.Rows[Rowindex];
If you want to get any column value then
object obj=dt.Rows[Rowindex][columnindex];
or
object obj=dt.Rows[Rowindex]["ColumnName"];
This should work for you:
dt.Rows[rowindex]["ColumnName"].ToString();
If you want select specific cell value from Datatable,you can use..
dt.Rows[row index]["Column name"].TOString();
like if you want to select 1st row value from column say Name then use
dt.Rows[1]["Name"].TOString();
if u want select particular row itself you can use Select with filtercondition.
string FilterCond = ur condition;
DataRow[] myrow = dt.Select(FilterCond);
I have a set of asp hidden field controls which I wish to set the values according to my data tables column names, the amount of columns returned differ, so I am setting the unused hidden fields to 0 if not used. Below is what I've attempted so far just struggling to set the correct hidden field accordingly.
VB-
Dim dt As DataTable
Dim ds As New DataSet()
ds = Getdata(4)
dt = ds.Tables(0)
Dim ColCnt As String = dt.Columns.Count 'Current ColCnt is 3
For Each column As DataColumn In dt.Columns
Select Case ColCnt
Case 2
hxValue.Value = column.ColumnName 'set to 1st Column Name
hxValue1.Value = 0 'Not used
hyValue.Value = column.ColumnName 'Set To 2nd Column Name
Case 3
hxValue.Value = column.ColumnName 'set to 1st Column Name
hxValue1.Value = column.ColumnName 'set to 2nd Column Name
hyValue.Value = column.ColumnName 'set to 3rd Column Name
End Select
Next
Try this, I don't think you need a For Each loop :
Dim ColCnt As Int = dt.Columns.Count 'Current ColCnt is 3
Select Case ColCnt
Case 2
hxValue.Value = dt.Columns[0].ColumnName 'set to 1st Column Name
hxValue1.Value = 0 'Not used
hyValue.Value = dt.Columns[1].ColumnName 'Set To 2nd Column Name
Case 3
hxValue.Value = dt.Columns[0].ColumnName 'set to 1st Column Name
hxValue1.Value = dt.Columns[1].ColumnName 'set to 2nd Column Name
hyValue.Value = dt.Columns[2].ColumnName 'set to 3rd Column Name
End Select