Dynamically add checkboxes to groupbox - vb.net

i am trying to dynamically add checkboxes to a groupd box based on the amount of rows in a datatable. when looping through i get my first result but i am not able to get the next results to show...here is my code
Dim q As String
Dim qt As DataTable
Dim gbHeight As Integer = 40
Dim checkHG As Integer = 5
Dim checkHN As Integer = 5
q = "Select * from loads where filenumber = " & Shipments2.txtFileNumber.Text
qt = GetSQL(q)
For i = 0 To qt.Rows.Count - 1
Dim items As New List(Of LoadDetails)
Dim ld As New LoadDetails
items = ld.GetListBySQL("select * from loadDetails where LoadNumber = " & qt.Rows(i).Item("id"))
For Each item As LoadDetails In items
Dim checkgross = New CheckBox
Dim checknet = New CheckBox
gbHeight += 20
'add checkbox control to form
checkgross.Location = New Point(40, checkHG + 20)
checkgross.Text = item.Description & " (Gross)"
checkgross.Size = New Size(250, 20)
checkgross.Name = item.ProductCode.ToString & "-gross"
gbGross.Size = New Size(329, gbHeight)
gbGross.Controls.Add(checkgross)
rbPrintingNet.Location = New Point(rbPrintingNet.Location.X, rbPrintingNet.Location.Y + 40)
checknet.Location = New Point(40, checkHN + 20)
checknet.Text = item.Description & " (Net)"
checknet.Size = New Size(250, 20)
checknet.Name = item.ProductCode.ToString & "-net"
gbNet.Location = New Point(44, rbPrintingNet.Location.Y + 25)
gbNet.Size = New Size(329, gbHeight)
gbNet.Controls.Add(checknet)
Me.Size = New Size(Me.Size.Width, Me.Size.Height + 50)
Next
Next

All your controls are on directly top of each other:
checkgross.Location = New Point(40, checkHG + 20)
Since checkHG never changes. Change the Location() for each dynamic control...

Related

Dynamic Labels | VB.Net

For every item it finds I want to add a few labels with details like prices and quantity.
I've made something and it only places them once and just rewrites everything. I assume the problem would be because I'm not returning, but if that is the case, I have no clue how to I could do that in this situation. Here's my code
Function addShoppingCartinfo() As System.Windows.Forms.Label
Dim lblQuantityCart As New System.Windows.Forms.Label
Dim lblPriceCart As New System.Windows.Forms.Label
Dim lblProductNameCart As New System.Windows.Forms.Label
Dim lblIndexInCart As New System.Windows.Forms.Label
Dim lblDescriptionCart As New System.Windows.Forms.Label
Dim lblSubtotalPriceInCart As New System.Windows.Forms.Label
Dim lblTotalPriceInCart As New System.Windows.Forms.Label
Dim var_Y As Integer = 47
Dim var_YTotal As Integer = 104
Dim var_YDescription As Integer = 72
For Each ItemInCart In list_Cart
For Each id In arr_ID
If id = ItemInCart Then
var_AmountInCart += 1
var_Y += var_AmountInCart
var_YTotal += var_AmountInCart
var_YDescription += var_AmountInCart
var_QuantityIndex = list_Cart.IndexOf(ItemInCart)
var_WinkelWagenIndex = Array.IndexOf(arr_ID, id)
var_SubTotalPrice = arr_Prices(var_WinkelWagenIndex) * list_Quantity(var_QuantityIndex)
list_Prices.Add(var_SubTotalPrice)
WinkelWagen.Controls.Add(lblQuantityCart)
WinkelWagen.Controls.Add(lblPriceCart)
WinkelWagen.Controls.Add(lblProductNameCart)
WinkelWagen.Controls.Add(lblIndexInCart)
WinkelWagen.Controls.Add(lblDescriptionCart)
WinkelWagen.Controls.Add(lblSubtotalPriceInCart)
WinkelWagen.Controls.Add(lblTotalPriceInCart)
For Each price In list_Prices
var_TotalPrice += price
Next
lblQuantityCart.Text = list_Quantity(var_QuantityIndex)
lblQuantityCart.Location = New Point(539, var_Y)
lblIndexInCart.Text = var_AmountInCart
lblIndexInCart.Location = New Point(494, var_Y)
lblIndexInCart.Visible = False
lblPriceCart.Text = "SRD " & arr_Prices(var_WinkelWagenIndex)
lblPriceCart.Location = New Point(494, var_Y)
lblDescriptionCart.Text = arr_Names(var_WinkelWagenIndex)
lblDescriptionCart.Location = New Point(240, var_Y)
lblSubtotalPriceInCart.Text = "SRD" & var_SubTotalPrice
lblSubtotalPriceInCart.Location = New Point(640, var_Y)
lblProductNameCart.Text = arr_Names(var_WinkelWagenIndex)
lblProductNameCart.Location = New Point(113, var_Y)
End If
Next
Next
lblTotalPriceInCart.Text = "SRD" & var_TotalPrice
lblTotalPriceInCart.Location = New Point(640, var_YTotal * var_AmountInCart)
Debug.WriteLine("this has " & var_AmountInCart & " Quantity")
End Function
When I've got 2 items it does this. (Image)

VB.NET copy data from treevew to datagridview

I want to copy some/all data from treeview to the datagridview
For example: if I select one node of a department or a company node, when I click a button I want all employees of that node to be copied to the datagridview with checking for repeatation.
Someone Please explain to me the mechanism of this.
This is the code I tried to write but I had difficulties to make it
For i = 0 To TreeView1.Nodes.Count - 1
'MsgBox(i & " " & TreeView1.Nodes(i).Text)
Dim node As TreeNode = TreeView1.Nodes(i)
For j = 0 To node.Nodes.Count - 1
'MsgBox(j & " " & node.Nodes(j).Text)
Dim subnode As TreeNode = node.Nodes(j)
For z = 0 To subnode.Nodes.Count - 1
'MsgBox(z & " " & subnode.Nodes(z).Text)
Dim Usubnode As TreeNode = subnode.Nodes(j)
DGV.Rows(z).Cells(0).Value = subnode.Nodes(z).Name.ToString
DGV.Rows(z).Cells(1).Value = subnode.Nodes(z).Text.ToString
Next '' z
Next ''j
Next '' i
'''''''''''''''''''''''''''''''''''''''''''
the treeview was populated this way:
For Each dr As DataRow In dt.Rows
Dim coName = dr("CompName").ToString()
Dim coNodeId = "co" & dr("ID").ToString()
''''find or create the company node
Dim nodes = TreeView2.Nodes.Find(coNodeId, True)
Dim coNode As TreeNode
If nodes.Length = False Then ''''didn't find: create and add
coNode = New TreeNode() {.Name = coNodeId, .Text = coName}
TreeView2.Nodes.Add(coNode)
Else ''''did find
coNode = nodes(0)
End If
Dim depName = dr("depName").ToString()
Dim depNodeId = "dep" & dr("depNum").ToString()
''''find or create the dep node under the co node
nodes = coNode.Nodes.Find(depNodeId, True)
Dim depNode As TreeNode
If nodes.Length = 0 Then
depNode = New TreeNode() {.Name = depNodeId, .Text = depName}
coNode.Nodes.Add(depNode)
Else
depNode = nodes(0)
End If
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''create the emp node
Dim EmpName = dr("EmpName").ToString()
Dim empNodeId = "emp" & dr("EmpNum").ToString()
''''find or create the emp node under the dep node
nodes = depNode.Nodes.Find(empNodeId, True)
Dim empNode As TreeNode
If nodes.Length = 0 Then
empNode = New TreeNode() {.Name = empNodeId, .Text = EmpName}
depNode.Nodes.Add(empNode)
Else
empNode = nodes(0)
End If
Next
You populated the tree from a datatable. Bind the grid to the same table, through a BindingSource. While you are adding nodes, store a string in the Tag of the node to dictate a BindingSource filter:
depNode = New TreeNode() {.Name = depNodeId, .Text = depName, .Tag = $"[depNum] = '{dr("depNum")}'"}
Put a different filter for each kind of node(co/dep/emp)
Add a handler to the treeview's AfterSelect event (https://learn.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-determine-which-treeview-node-was-clicked-windows-forms) and set the Filter property of the BindingSource to e.Node.Tag.ToString()

VB Net What is the fastest way to generate object created programmatically

I have create an application that need to generate about 100 to 1000 object programmatically. This object will be generated with the same amount in the database. In order to accomplish objective above, of course i need to call the data from database, then i looping through each data to generate each object. But it takes such a very long time before it done. I hoping that you have an alternative way beside how i do this.
Below is my code to call the data from database
Dim tbls As New DataTable
Using cons As New SqlConnection(stringconnection)
Dim sqls = "select * from tbsectiondetail where IDSection = '" & txtIDSection.Text &
"' AND KodeLocation like '%" & txtCari.Text &
"%' AND Status like '%" & cbStatus.Text &
"%' ORDER BY Status DESC"
Dim adps As New SqlDataAdapter(sqls, cons)
adps.Fill(tbls)
adps.Dispose()
cons.Dispose()
End Using
If i just generate the data only, its just take only 1 to 2 second. So i don't think there is problem about how i call the data from database
And below is how i generate the object through looping the data
Dim resultsx As DataRow() = tbls.Select("")
If resultsx.Count > 0 Then
For iX = 0 To resultsx.Count - 1
'CREATE A VARIABLE
Dim IDSectionDetail = resultsx(iX)("IDSectionDetail").ToString
Dim NamaLocation = resultsx(iX)("NamaLocation").ToString
Dim SectionKode = resultsx(iX)("KodeLocation").ToString
Dim StatusSection = resultsx(iX)("Status").ToString
Dim StatusSectionAt = resultsx(iX)("StatusAt").ToString
Dim StatusC1 = resultsx(iX)("StatusC1").ToString
Dim StatusC2 = resultsx(iX)("StatusC2").ToString
'GENERATE A PANEL
Dim pnlContainer As New Panel
pnlContainer.Size = New Size(290, 200)
Tablex.Controls.Add(pnlContainer, curColumn, rowNo)
pnlContainer.Dock = DockStyle.Fill
Dim pnlHeader As New Panel
pnlContainer.Controls.Add(pnlHeader)
pnlHeader.Dock = DockStyle.Top
pnlHeader.Size = New Size(pnlContainer.Width, 35)
If StatusSection = "Open" Then
pnlHeader.BackColor = Color.DarkSlateGray
Else
pnlHeader.BackColor = Color.FromArgb(185, 58, 50)
End If
pnlContainer.Controls.SetChildIndex(pnlHeader, 2)
'GENERATE LABEL HEADER
Dim lblHeader As New Label
lblHeader.Text = NamaLocation & " - " & SectionKode
pnlHeader.Controls.Add(lblHeader)
lblHeader.Font = New Font("Century Gothic", 9, FontStyle.Bold Or FontStyle.Italic)
lblHeader.ForeColor = Color.White
lblHeader.Location = New Point(8, 7)
lblHeader.AutoSize = True
'GENERATE LABEL STATUS
Dim lblStatus As New Label
lblStatus.Text = "Status : " & StatusSection
pnlHeader.Controls.Add(lblStatus)
lblStatus.Font = New Font("Century Gothic", 8, FontStyle.Bold Or FontStyle.Italic)
lblStatus.ForeColor = Color.White
lblStatus.TextAlign = ContentAlignment.MiddleRight
lblStatus.Height = pnlHeader.Height
lblStatus.Dock = DockStyle.Right
lblStatus.AutoSize = True
'GENERATE PANEL FOOTER
Dim pnlFooter As New Panel
pnlContainer.Controls.Add(pnlFooter)
pnlFooter.Dock = DockStyle.Fill
pnlFooter.Size = New Size(pnlFooter.Width, 35)
pnlFooter.BackColor = Color.White
pnlContainer.Controls.SetChildIndex(pnlFooter, 0)
'GENERATE BUTTON DETAIL
Dim btnDetail As New Button
pnlFooter.Controls.Add(btnDetail)
btnDetail.Name = "btn" & SectionKode
btnDetail.FlatStyle = FlatStyle.Flat
btnDetail.FlatAppearance.BorderColor = Color.FromArgb(46, 74, 98)
btnDetail.FlatAppearance.BorderSize = 1
btnDetail.FlatAppearance.MouseDownBackColor = Color.Gold
btnDetail.FlatAppearance.MouseOverBackColor = Color.Gold
btnDetail.BackColor = Color.DarkSlateGray
btnDetail.Text = "Detail"
btnDetail.Image = My.Resources.search2_icon
btnDetail.Font = New Font("Century Gothic", 8, FontStyle.Bold)
btnDetail.TextImageRelation = TextImageRelation.TextBeforeImage
btnDetail.Location = New Point(181, 84)
btnDetail.Anchor = AnchorStyles.Right And AnchorStyles.Top
btnDetail.Size = New Size(75, 28)
btnDetail.ForeColor = Color.White
AddHandler btnDetail.Click, Sub() DetailSection(IDSectionDetail, SectionKode)
curColumn += 1
If curColumn >= 5 Then
curColumn = 0
RowCount += 1
Tablex.RowCount = RowCount
rowNo += 1
End If
Next
End If
pnlFill.Controls.Add(Tablex)
Actually there is still more object to generate through that looping. But from my analysis, the looping already take such a long time already just from code above.
The result of the generated object
I just wonder if there is another and faster alternative to generate such object. Or do i need to give up to design and just make it simple black and white ?

Split output result by n and loop

I'm solving an issue where I need to create one PDF form.
That PDF form has 8 sections where I need to put info about and looks like shown on picture (only 4 shown).
The point is that my query will return 0 - n different results. So I need to split by 8 and post on different pages.
I tried like shown below but that seems not to work since I always load a new document. Does anyone have some advice how to make it?
Try
Dim sCommand As OleDb.OleDbCommand
sCommand = New OleDb.OleDbCommand("SELECT a,b,c Query to fetch n results ", _dbCon)
sCommand.CommandTimeout = 0
Dim _dbREADER As OleDb.OleDbDataReader
_dbREADER = sCommand.ExecuteReader
Dim dt As DataTable = New DataTable()
dt.Load(_dbREADER)
Dim totalPages As Integer = dt.Rows.Count / 8
Dim currentPage As Integer = 1
Dim rowCounter As Long = 0
If dt.Rows.Count > 0 Then
For Each row In dt.Rows
rowCounter += 1
If rowCounter = 8 Then
currentPage += 1
rowCounter = 0
End If
_pdfDocumentOutput = System.IO.Path.GetTempPath() & "MailingForm_" & currentPage & ".pdf"
SaveFromResources(_pdfDocument, My.Resources.template)
Using reader As New PdfReader(_pdfDocument)
Using stamper As New PdfStamper(reader, New IO.FileStream(_pdfDocumentOutput, IO.FileMode.Create))
Dim fontName As String = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "SCRIPTIN.ttf")
Dim bf As BaseFont = BaseFont.CreateFont(fontName, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED)
Dim pdfForm As AcroFields = stamper.AcroFields
pdfForm.AddSubstitutionFont(bf)
pdfForm.SetField(rowCounter - 1 & "0", row("Customer")) 'Checks the top radiobutton of the VrPr4 field
pdfForm.SetField(rowCounter - 1 & "1", row("Address"))
pdfForm.SetField(rowCounter - 1 & "2", row("Location"))
stamper.FormFlattening = True
End Using
End Using
Next
End If
Status.Text = "Store info loaded ! "
Catch ex As Exception
Status.Text = ex.Message
End Try
I found the solution by splitting tables
Private Shared Function SplitTable(ByVal originalTable As DataTable, ByVal batchSize As Integer) As List(Of DataTable)
Dim tables As List(Of DataTable) = New List(Of DataTable)()
Dim i As Integer = 0
Dim j As Integer = 1
Dim newDt As DataTable = originalTable.Clone()
newDt.TableName = "Table_" & j
newDt.Clear()
For Each row As DataRow In originalTable.Rows
Dim newRow As DataRow = newDt.NewRow()
newRow.ItemArray = row.ItemArray
newDt.Rows.Add(newRow)
i += 1
If i = batchSize Then
tables.Add(newDt)
j += 1
newDt = originalTable.Clone()
newDt.TableName = "Table_" & j
newDt.Clear()
i = 0
End If
If row.Equals(originalTable.Rows(originalTable.Rows.Count - 1)) Then
tables.Add(newDt)
j += 1
newDt = originalTable.Clone()
newDt.TableName = "Table_" & j
newDt.Clear()
i = 0
End If
Next
Return tables
End Function
And after that loop through each one of table . And put all results to one file
Dim tables = SplitTable(dt, 8)

VB For loop karstieji(x).Location = New Point(0, a) nullreferenceException was unhandled

Vb application freezes I get nullreferenceException was unhandled on new point(0 ,a) here is the code.
For x = 1 To 5
Dim karstieji(x) As Label
Dim karstieji1(x) As Button
Dim a As Integer
Dim b As Integer
a = 0
b = 0
Panel2.Controls.Add(karstieji(x))
karstieji(x).Location = New Point(0, a)
karstieji(x).Size = New Size(140, 20)
karstieji(x).Text = "Bulvyniai blynai"
karstieji(x).Font = New Font(1, 12)
Panel2.Controls.Add(karstieji1(x))
karstieji1(x).Location = New Point(140, b)
karstieji1(x).Size = New Size(12, 12)
a += 20
b += 12
Next
You cannot use control arrays in VB.NET so the code you are trying to use will not work.
I would suggest using a generic list if you need to keep a reference to the controls:
'In your class
Private _labels As New List(Of Label)
Private _buttons As New List(Of Button)
'create the controls
Dim a As Integer = 0
Dim b As Integer = 0
For x = 1 To 5
Dim karstieji As New Label
Dim karstieji1 As New Button
Panel2.Controls.Add(karstieji)
karstieji.Location = New Point(0, a)
karstieji.Size = New Size(140, 20)
karstieji.Text = "Bulvyniai blynai"
karstieji.Font = New Font(1, 12)
Panel2.Controls.Add(karstieji1)
karstieji1.Location = New Point(140, b)
karstieji1.Size = New Size(12, 12)
a += 20
b += 12
'add a reference to the controls so you can refer to them later
_labels.Add(karstieji)
_buttons.Add(karstieji1)
Next
Note I have also moved the a and b variables to outside the loop as these will always be zero otherwise