Any ideas how to make this FOR LOOP? VB.NET - sql-server

Any Ideas on how to make this to "FOR LOOP" because the number of data that I want to show is not fixed or constant so I need to make it into for loop.
Public Sub ReportTransactionsLogs(ByVal LV As ListView)
Dim rReport As New ReportTransLog
Dim row As DataRow = Nothing
Dim ds As New DataSet
ds.Tables.Add("TransactionsLog")
With ds.Tables(0).Columns
.Add("Username")
.Add("ActionDate")
.Add("ActionTime")
.Add("Activity")
.Add("POInvoice")
End With
For Each LVI As ListViewItem In LV.Items
row = ds.Tables(0).NewRow
row(0) = LVI.Text
row(1) = LVI.SubItems(1).Text
row(2) = LVI.SubItems(2).Text
row(3) = LVI.SubItems(3).Text
row(4) = LVI.SubItems(4).Text
ds.Tables(0).Rows.Add(row)
Next
rReport.SetDataSource(ds.Tables(0))
ReportViewer.CrystalReportViewer1.ReportSource = rReport
End Sub

try like this..
For Each LVI As ListViewItem In LV.Items row = ds.Tables(0).NewRow
For i As Integer = 1 To ds.Table(0).Columns.Count()
If InlineAssignHelper(i, 0) Then
row(i) = LVI.Text
Else
row(i) =LVI.SubItems(i).Text
End If
Next
Next

Related

WPF Dynamic image generation and printing is not working

In an application I'm developing, the user can select a number of items (max. 6) in a datagrid. These items should then be printed in a matrix style on pre-printed forms (see it like CD labels, 6 on a page).
I'm generating these images dynamically containing the selected content from a database. I then put these in a grid so they can be printed on the pre-printed forms.
I have the following code that creates the grid, generates the images from a user control and adds them to the grid and then prints these images.
I'm not following the MVVM pattern for the printing action. I created a reference to my view model in my code-behind.
Private Sub PrintButton_Click(sender As Object, e As RoutedEventArgs) Handles ButtonPrint.Click
Dim dlg As New PrintDialog
dlg.PrintTicket.PageMediaSize = New PageMediaSize(PageMediaSizeName.ISOA4)
Dim pageWidth As Double = GetPageWidth(dlg)
'Since the label is a perfect square: labelWidth = labelHeight
Dim labelWidthInPx As Integer = Utilities.ConvertMmToPixels(My.Settings.LabelWidthInMm)
'Set spacing distances in pixels
Dim horizontalLabelSpacing As Integer = Utilities.ConvertMmToPixels(My.Settings.HorizontalLabelSpacinginMm)
Dim verticalLabelSpacing As Integer = Utilities.ConvertMmToPixels(My.Settings.VerticalLabelSpacingInMm)
Dim topMargin As Integer = Utilities.ConvertMmToPixels(My.Settings.TopMarginInMm)
Dim leftMargin As Integer = Utilities.ConvertMmToPixels(My.Settings.LeftMarginInMm)
Dim bottomMargin As Integer = Utilities.ConvertMmToPixels(My.Settings.BottomMarginInMm)
'Create the table/grid
Dim tbl As New Grid
If CheckBoxPrintGridLines.IsChecked Then
tbl.ShowGridLines = True
Else
tbl.ShowGridLines = False
End If
'Add 3 columns (2 for the labels, 1 for spacing)
Dim col1 As New ColumnDefinition With {
.Width = New GridLength(labelWidthInPx, GridUnitType.Pixel)
}
Dim col2 As New ColumnDefinition With {
.Width = New GridLength(horizontalLabelSpacing, GridUnitType.Pixel)
}
Dim col3 As New ColumnDefinition With {
.Width = New GridLength(labelWidthInPx, GridUnitType.Pixel)
}
tbl.ColumnDefinitions.Add(col1)
tbl.ColumnDefinitions.Add(col2)
tbl.ColumnDefinitions.Add(col3)
'Add 5 Rows (3 for labels, 2 for spacing)
Dim row1 As New RowDefinition With {
.Height = New GridLength(labelWidthInPx, GridUnitType.Pixel)
}
Dim row2 As New RowDefinition With {
.Height = New GridLength(verticalLabelSpacing, GridUnitType.Pixel)
}
Dim row3 As New RowDefinition With {
.Height = New GridLength(labelWidthInPx, GridUnitType.Pixel)
}
Dim row4 As New RowDefinition With {
.Height = New GridLength(verticalLabelSpacing, GridUnitType.Pixel)
}
Dim row5 As New RowDefinition With {
.Height = New GridLength(labelWidthInPx, GridUnitType.Pixel)
}
tbl.RowDefinitions.Add(row1)
tbl.RowDefinitions.Add(row2)
tbl.RowDefinitions.Add(row3)
tbl.RowDefinitions.Add(row4)
tbl.RowDefinitions.Add(row5)
'Add label images
Dim reelData = CType(DataGridReels.ItemsSource, List(Of ReelInfo))
Dim rowIndex As Integer = 0
Dim colIndex As Integer = 0
For Each reel In reelData.Where(Function(r) r.IsSelected = True)
Dim partNumberData = ViewModel.DataService.GetPartNumberDataAsync(reel.PartNumber)
Dim batchData = ViewModel.DataService.GetBatchDataAsync(reel.PartNumber, reel.HENBatchNumber)
LabelImageControl.IsPrinting = True
LabelImageControl.PartNumberData = partNumberData.Result
LabelImageControl.BatchData = batchData.Result
LabelImageControl.ReelData = reel
LabelImageControl.Refresh
UpdateUI()
Dim labelImage As New Image
labelImage = GetImageFromLabel(LabelImageControl)
labelImage.Width = labelWidthInPx
labelImage.Height = labelWidthInPx
Grid.SetRow(labelImage, rowIndex)
Grid.SetColumn(labelImage, colIndex)
tbl.Children.Add(labelImage)
tbl.Refresh
colIndex += 1
If colIndex > 1 Then
colIndex = 0
rowIndex += 1
End If
Next
Dim iuc As New InlineUIContainer(tbl)
Dim p As New Paragraph(iuc)
'Create print dialog
If dlg.ShowDialog.GetValueOrDefault Then
'Create a flow document
Dim doc As New FlowDocument With {
.Name = "LabelPage",
.ColumnWidth = pageWidth,
.PagePadding = New Thickness(leftMargin, topMargin, 0, bottomMargin)
}
doc.Blocks.Add(p)
'Create IDocumentPagniatorSource from FlowDocument
Dim idpSource As IDocumentPaginatorSource = doc
Try
Me.Cursor = Cursors.Wait
dlg.PrintDocument(idpSource.DocumentPaginator, "Label Page")
Catch ex As Exception
Me.Cursor = Cursors.Arrow
MessageBox.Show("An error occurred during printing: " & ex.Message, "Print error")
Finally
Me.Cursor = Cursors.Arrow
End Try
End If
End Sub
When I send the output to the PDF printer I only get one image in the top left corner of the page/grid.
Since the user control (LabelImageControl) is in the XAML, I can see it changing while debugging. So the data is coming into the user control correctly.
When I check the grid with the XML Visualiser I see it has the same number of children as the items I selected in the datagrid.
Can anyone point me in the right direction on how to get the grid printing correctly?

WPF ListBox values from another selected ListBox item then move up and down

We have a series of ListBoxes - when an item in the main ListBox is selected the relevant values are displayed in the sub ListBox. This works as intended...
We also have the ability to move items up or down, and this works as intended...
When the main ListBox has the SelectionChanged event wired up the ability to move items up and down in the sub list box stops working. Comment that out and up/down works again in the sub ListBox... I must have overlooked something glaringly obvious but after numerous changes still can't get it to work
Main ListBox SelectionChanged
Private Sub Reports_CashFlow_ListBox_IndexChanged(ByVal MainLB As String, ByVal NominalLB As String, ByVal NomDT As DataTable)
Try
Dim LB As LBx = ReportCashFlow_Grid.FindName(MainLB)
If LB.SelectedIndex = -1 Then
Exit Sub
End If
Dim NomLB As LBx = ReportCashFlow_Grid.FindName(NominalLB)
If NomLB Is Nothing Then
Exit Sub
End If
If LB.SelectedValue Is Nothing Then
Exit Sub
End If
If LB.SelectedValue.GetType.Name Is Nothing Then
Exit Sub
End If
If LB.SelectedValue.GetType.Name <> "DataRowView" Then
Dim CatID As Integer = LB.SelectedValue
Dim DV As New DataView(NomDT)
DV.RowFilter = "CatID = " & CatID & " AND FormID = " & Form_ID
DV.Sort = "Position"
With NomLB
.ItemsSource = DV
.Items.Refresh()
End With
LB.ScrollIntoView(LB.SelectedItem)
End If
Catch ex As Exception
EmailError(ex)
End Try
End Sub
Move items up
Private Sub Reports_BalanceSheet_ListBoxMoveUp(LB As ListBox, DT As DataTable, DisplayName As String, Optional MasterListBox As ListBox = Nothing)
Try
Dim StartIndex As Integer = LB.SelectedIndex
If StartIndex = -1 Then
AppBoxValidation("You have not selected an item to move up!")
Exit Sub
End If
If Not StartIndex = 0 Then
Dim CatID As Integer = 0
If DisplayName = "NomName" Then
CatID = MasterListBox.SelectedValue
End If
Dim vSelected As DataRow = DT.Rows(StartIndex)
Dim vNew As DataRow = DT.NewRow()
vNew.ItemArray = vSelected.ItemArray
DT.Rows.Remove(vSelected)
DT.Rows.InsertAt(vNew, StartIndex - 1)
DT.AcceptChanges()
LB.SelectedIndex = StartIndex - 1
Dim vPos As Integer = 0
For Each Row As DataRow In DT.Rows
If Not CatID = 0 Then
If Row("CatID") = CatID Then
Row("Position") = vPos
vPos += 1
End If
Else
Row("Position") = vPos
vPos += 1
End If
Next
LB.Items.Refresh()
End If
Catch ex As Exception
EmailError(ex)
End Try
End Sub
Turns out the issue related to subsets of data in the DataView - so needed to find the correct index for the selected item and the replacement index in the entire back-end table
Private Sub Reports_BalanceSheet_ListBoxMoveUp(LB As ListBox, DT As DataTable, DisplayName As String, Optional MasterListBox As ListBox = Nothing)
Try
Dim StartIndex As Integer = LB.SelectedIndex
If StartIndex = -1 Then
AppBoxValidation("You have not selected an item to move up!")
Exit Sub
End If
If Not StartIndex = 0 Then
Dim CatID As Integer = 0
If DisplayName = "NomName" Then
CatID = MasterListBox.SelectedValue
'As the view could be a subset of data we need to find the actual back end DB index
Dim SelectedID As Integer = LB.SelectedValue
Dim DR() As DataRow = DT.Select("ID = " & SelectedID, Nothing)
Dim vIndex As Integer = DT.Rows.IndexOf(DR(0))
Dim vCurrentPos As Integer = DR(0)("Position")
'Find the index of the one above in the grid
Dim DR2() As DataRow = DT.Select("CatID = " & CatID & " AND Position = " & vCurrentPos - 1, Nothing)
Dim vIndex2 As Integer = DT.Rows.IndexOf(DR2(0))
Dim vSelected As DataRow = DT.Rows(vIndex)
Dim vNew As DataRow = DT.NewRow()
vNew.ItemArray = vSelected.ItemArray
DT.Rows.Remove(vSelected)
DT.Rows.InsertAt(vNew, vIndex2)
DT.AcceptChanges()
Else
Dim vSelected As DataRow = DT.Rows(StartIndex)
Dim vNew As DataRow = DT.NewRow()
vNew.ItemArray = vSelected.ItemArray
DT.Rows.Remove(vSelected)
DT.Rows.InsertAt(vNew, StartIndex - 1)
DT.AcceptChanges()
End If
Dim vPos As Integer = 0
For Each Row As DataRow In DT.Rows
If Not CatID = 0 Then
If Row("CatID") = CatID Then
Row("Position") = vPos
vPos += 1
End If
Else
Row("Position") = vPos
vPos += 1
End If
Next
LB.SelectedIndex = StartIndex - 1
End If
Catch ex As Exception
EmailError(ex)
End Try
End Sub

Search for a column in database table and add the values to a datagridview

I want to search for the value where item = 'apple' and then add the entire column to a DataGridView in VB.net form application. I use following code lines to do my task, but the output i get is a blank data cell.
Dim table As DataTable = myTable.Tables("fruits")
Dim expression, item As String
expression = "item = 'apple'"
Dim foundRows() As DataRow
foundRows = table.Select(expression)
Dim dt As New DataTable
dt.Columns.Add("ID")
dt.Columns.Add("item")
dt.Columns.Add("price")
Dim row1 As DataRow = dt.NewRow
For Each row As DataRow In foundRows
row1.Item("ID") = row(0)
row1.Item("item") = row(1)
row1.Item("price") = row(2)
Next
dt.Rows.Add(row1)
DataGridView1.DataSource = dt
End Sub
Change your code as this... you should add columns in-order to add rows as u expect
Dim table As DataTable = myTable.Tables("fruits")
Dim expression As String
expression = "item = 'apple'"
Dim foundRows() As DataRow
foundRows = table.Select(expression)
Dim col, col1, col2 As New DataGridViewTextBoxColumn
col.HeaderText = "ID"
col1.HeaderText = "Item"
col2.HeaderText = "Price"
DataGridView1.Columns.Add(col)
DataGridView1.Columns.Add(col1)
DataGridView1.Columns.Add(col2)
For Each row As DataRow In foundRows
DataGridView1.Rows.Add(row(0), row(1), row(2))
Next
You're declaring the row to add once (row1) and looping through foundRows and assigning same var (row1) and then adding it only once to the DG, this will results in adding only the last found item.
Change your code starting from "Dim row1 As DataRow = dt.NewRow" to be:
For Each row As DataRow In foundRows
Dim row1 As DataRow = dt.NewRow
row1.Item("ID") = row(0)
row1.Item("item") = row(1)
row1.Item("price") = row(2)
dt.Rows.Add(row1)
Next
I'm not sure if this is the only reason, but give it a try :)

WPF ListBox - refresh

I have a ListBox populated by a DataTable - adding items, moving items all work but delete doesn't - it reflects in the DataTable but clears all items from the ListBox unless it is reloaded as part of a SelectionChanged event.
I have tried Listbox.Items.Refresh and setting the ItemsSource to Nothing and re-assigning back to the DataTable.
Any ideas?
Thanks
Private Sub Reports_BalanceSheet_NominalListBox_Delete(NomLB As String, DT As DataTable)
Try
Dim LB As ListBox = Reports_BalanceSheet_Grid.FindName(NomLB)
If LB.SelectedIndex = -1 Then
AppBoxValidation("No item has been selected for deletion!")
Exit Sub
End If
Dim FR() As DataRow = DT.Select("ID = " & LB.SelectedValue, Nothing)
Dim CatID As Integer = 0
For Each row As DataRow In FR
CatID = row("CatID")
row.Delete()
Next
DT.AcceptChanges()
Dim vDV As New DataView(DT)
vDV.RowFilter = "FormID = " & FormID & " AND CatID = " & CatID
vDV.Sort = "Position"
DT = vDV.ToTable
vDV = Nothing
Dim i As Integer = 0
For Each row As DataRow In DT.Rows
row("Position") = i
i += 1
Next
With LB
.ItemsSource = DT.DefaultView
.DisplayMemberPath = "Name"
.SelectedValuePath = "ID"
End With
Catch ex As Exception
EmailError(ex)
End Try
End Sub
Turns out the clue was 'unless it is reloaded as part of the SelectionChanged event'
added this to the end and it all works perfectly :-)
Have you ever noticed that you can spend hours going round in circles and the moment you post the problem you figure it out?
Dim MainLB As String = NomLB.Replace("Nominal", "")
Reports_BalanceSheet_ListBox_IndexChanged(MainLB, NomLB, DT)
and that runs
Private Sub Reports_BalanceSheet_ListBox_IndexChanged(ByVal MainLB As String, ByVal NominalLB As String, ByVal NomDT As DataTable)
Try
Dim LB As ListBox = Reports_BalanceSheet_Grid.FindName(MainLB)
If LB.SelectedIndex = -1 Then
Exit Sub
End If
Dim NomLB As ListBox = Reports_BalanceSheet_Grid.FindName(NominalLB)
If NomLB Is Nothing Then
Exit Sub
End If
If LB.SelectedValue Is Nothing Then
Exit Sub
End If
If LB.SelectedValue.GetType.Name Is Nothing Then
Exit Sub
End If
If LB.SelectedValue.GetType.Name <> "DataRowView" Then
Dim CatID As Integer = LB.SelectedValue
Dim DT As DataTable = NomDT.Copy()
Dim vDV As New DataView(DT)
vDV.RowFilter = "CatID = " & CatID & " AND FormID = " & FormID
vDV.Sort = "Position"
DT = vDV.ToTable
vDV = Nothing
With NomLB
.ItemsSource = DT.DefaultView
.SelectedValuePath = "ID"
.DisplayMemberPath = "NomName"
.Items.Refresh()
End With
End If
Catch ex As Exception
EmailError(ex)
End Try
End Sub

Import CSV into DataGrid

In winForms adding a CSV to a DataGrid was quite easy. I am now trying to add this to a Silverlight DataGrid. Here is my attempt - which yields 3 columns Capacity|Count|Items - mind you the values are correct 83|83|_ on each row. There are 83 rows, but the columns should be 23 with diff values in each. Thanks for looking and enjoy your bounty!
Code:
Try
Dim ofd As New OpenFileDialog
If ofd.ShowDialog Then
If IO.File.Exists(ofd.File.FullName) Then
Dim srsCol As New List(Of List(Of String))
Using fs As IO.FileStream = ofd.File.OpenRead
Using sr As New IO.StreamReader(fs)
While Not sr.Peek = -1
srsCol.Add(New List(Of String)(sr.ReadLine.Split(","c).ToList))
End While
End Using
End Using
dgStaff.ItemsSource = srsCol
End If
End If
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
I decided to use the BindableDataGrid from CodePlex Since the binding is being set dynamically I had to come up with a Random string generator and assign that for the binding and all is well.
csvDs.Tables.Clear()
Try
Dim ofd As New OpenFileDialog
If ofd.ShowDialog Then
If IO.File.Exists(ofd.File.FullName) Then
csvDs.Tables.Add(csvDt)
Using fs As IO.FileStream = ofd.File.OpenRead
Using sr As New IO.StreamReader(fs)
Dim i As Integer
While Not sr.EndOfStream
If i = 0 Then
Dim cols = sr.ReadLine.Split(","c)
For ii As Integer = 0 To cols.Count - 1
Dim rndValue As String = RndColName()
Dim col As New BindableDataGrid.Data.DataColumn(rndValue)
rndValues.Add(rndValue)
col.DataType = GetType(System.String)
col.Caption = ii.ToString
col.ReadOnly = True
col.AllowReorder = False
col.AllowResize = False
col.AllowSort = False
csvDt.Columns.Add(col)
AddItemsToCb(ii)
Next
Dim row As New BindableDataGrid.Data.DataRow
For _i As Integer = 0 To cols.Count - 1
Dim s As String = cols(_i).Replace("""", String.Empty)
row(rndValues(_i)) = s
csvValues.Add(s)
Next
csvDt.Rows.Add(row)
Else
Dim cols = sr.ReadLine.Split(","c)
Dim row As New BindableDataGrid.Data.DataRow
For _i As Integer = 0 To cols.Count - 1
row(rndValues(_i)) = cols(_i).Replace("""", String.Empty)
Next
csvDt.Rows.Add(row)
End If
i += 1
End While
End Using
End Using
dgStaff.DataSource = csvDs
dgStaff.DataMember = "csvTable"
dgStaff.DataBind()

Resources