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 ?
Related
How can I make my textbox.text when I enter something to fetch results in flowlayoutpanel and if i remove text form textbox to show all again.
Simply search option inside the flowpanel to show found records.
The code that create the flowlayoutpanel when form loads:
Private Sub GenerateDynamicUserControl()
FlowLayoutPanel1.Controls.Clear()
Dim dt As DataTable = New ClassBLL().GetItems()
If dt IsNot Nothing Then
If dt.Rows.Count > 0 Then
Dim listItems As ListItem() = New ListItem(dt.Rows.Count - 1) {}
For i As Integer = 0 To 1 - 1
For Each row As DataRow In dt.Rows
Dim listItem As New ListItem()
listItems(i) = listItem
'Dim ms As New MemoryStream(CType(row("userPic"), Byte()))
Dim ms As New MemoryStream(CType(row("UserPictureFrom"), Byte()))
Dim ms2 As New MemoryStream(CType(row("UserPictureTo"), Byte()))
listItems(i).Width = FlowLayoutPanel1.Width - 30
listItems(i).Icon = New Bitmap(ms)
listItems(i).Icon2 = New Bitmap(ms2)
listItems(i).OrderFrom = row("orderfrom").ToString()
listItems(i).OrderTitle = row("UserPositionFrom").ToString()
listItems(i).OrderReceiver = row("orderreceiver").ToString()
listItems(i).OrderTitle2 = row("UserPositionTo").ToString()
'listItems(i).ButtonBackground = orderButtonBackString
listItems(i).ButtonText = row("orderstatus").ToString()
listItems(i).OrderDate = row("orderdate")
listItems(i).IDOrder = row("orderid").ToString()
listItems(i).Subject = row("ordersubject").ToString()
listItems(i).SubjectText = row("ordersubjecttext").ToString()
If listItems(i).ButtonText = "Accepted" Then
listItems(i).ButtonBackground = Color.FromArgb(26, 168, 92)
ElseIf listItems(i).ButtonText = "Declined" Then
listItems(i).ButtonBackground = Color.FromArgb(246, 50, 90)
ElseIf listItems(i).ButtonText = "Proceed" Then
listItems(i).ButtonBackground = Color.FromArgb(255, 174, 33)
ElseIf listItems(i).ButtonText = "Waiting" Then
listItems(i).ButtonBackground = Color.FromArgb(53, 121, 255)
Else
listItems(i).ButtonBackground = Color.FromArgb(91, 146, 255)
End If
FlowLayoutPanel1.Controls.Add(listItems(i))
Next
Next
End If
End If
End Sub
The class:
Public Function ReadItemsTable() As DataTable
Using cons As New SQLiteConnection(ServerStatus)
Using cmd As New SQLiteCommand()
cmd.Connection = cons
'cmd.CommandText = "SELECT * FROM OrdersAssigned ORDER BY ID ASC"
cmd.CommandText = "SELECT OrdersAssigned.*,
ProfilesFrom.userPosition AS UserPositionFrom,
ProfilesFrom.userPicture AS UserPictureFrom,
ProfilesTo.userPosition AS UserPositionTo,
ProfilesTo.userPicture AS UserPictureTo
FROM
(OrdersAssigned
LEFT OUTER JOIN Profiles AS ProfilesFrom ON OrdersAssigned.orderacc = ProfilesFrom.userAccount)
LEFT OUTER JOIN Profiles AS ProfilesTo ON OrdersAssigned.orderreceiveracc = ProfilesTo.userAccount
ORDER BY
OrdersAssigned.ID ASC;"
cons.Open()
Using sda As New SQLiteDataAdapter(cmd)
Dim dt As New DataTable()
sda.Fill(dt)
Return dt
End Using
End Using
End Using
End Function
and on my button "btnSearchOrders_TextChanged" I need to input the search method any ideas how to do that without calling new query?
On the textbox TextChanged event try something like:
For Each myControl As Control In myflowlayoutcontrol.Controls
If myControl.text=mytextboxname.text then
'found it!
End if
'more code goes here
Next
the code inside the .TextChanged function will run every time the text of the textbox change and will search for the text on it in the flow control objects .text strings.
Let me know if you need more help.
So I use this code to display my data in a DataGridView:
Sub display_Infodata()
DGUSERS.Rows.Clear()
Dim sql As New MySqlDataAdapter("select * from tbl_info", con)
Dim ds As New DataSet
DGUSERS.AllowUserToAddRows = False
DGUSERS.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
DGUSERS.RowTemplate.Height = 40
sql.Fill(ds, 0)
For i As Integer = 0 To ds.Tables(0).Rows.Count - 1
Dim xx As Integer = DGUSERS.Rows.Add
Dim uid As String = ds.Tables(0).Rows(i).Item(0).ToString
Dim sqls As New MySqlDataAdapter("select * from tbl_other where userid='" & uid & "'", con)
Dim dss As New DataSet
sqls.Fill(dss, 0)
With DGUSERS.Rows(xx)
If dss.Tables(0).Rows.Count > 0 Then
.Cells(0).Value = uid
.Cells(1).Value = ds.Tables(0).Rows(i).Item(2).ToString
.Cells(2).Value = ds.Tables(0).Rows(i).Item(3).ToString
.Cells(3).Value = ds.Tables(0).Rows(i).Item(4).ToString
.Cells(4).Value = ds.Tables(0).Rows(i).Item(5).ToString
.Cells(5).Value = ds.Tables(0).Rows(i).Item(6).ToString
.Cells(6).Value = dss.Tables(0).Rows(0).Item(1).ToString
.Cells(7).Value = ds.Tables(0).Rows(0).Item(2).ToString
.Cells(8).Value = ds.Tables(0).Rows(0).Item(8).ToString
.Cells(9).Value = ds.Tables(0).Rows(0).Item("Image")
.Cells(10).Value = dss.Tables(0).Rows(0).Item(2).ToString
.Cells(11).Value = dss.Tables(0).Rows(0).Item(3).ToString
Else
End If
End With
Next
End Sub
It displays and works, but my problem is that when I try to display the data in the DataGridView of another form it shows the following error:
This is what I use:
Try
With View_Info
Dim index As Integer
Dim selectedRow As DataGridViewRow
selectedRow = DGUSERS.Rows(index)
.UserID.Text = DGUSERS.SelectedRows(0).Cells("UserID").Value
.UserType.Text = DGUSERS.SelectedRows(0).Cells("UserType").Value
.Fname.Text = DGUSERS.SelectedRows(0).Cells("Firstname").Value
.Mname.Text = DGUSERS.SelectedRows(0).Cells("Middlename").Value
.Lname.Text = DGUSERS.SelectedRows(0).Cells("Lastname").Value
.Contact.Text = DGUSERS.SelectedRows(0).Cells("Contact").Value
.Standing.Text = DGUSERS.SelectedRows(0).Cells("Standing").Value
.Guardian.Text = DGUSERS.SelectedRows(0).Cells("Guardian").Value
.ContactG.Text = DGUSERS.SelectedRows(0).Cells("GuardianContact").Value
.DPCreated.Text = DGUSERS.SelectedRows(0).Cells("DateCreated").Value
.DPValidity.Text = DGUSERS.SelectedRows(0).Cells("Validity").Value
Dim img As Byte()
img = DGUSERS.SelectedRows(0).Cells("Image").Value
Dim ms As New MemoryStream(img)
.UploadImage.Image = Image.FromStream(ms)
.Show()
.Focus()
End With
Catch ex As Exception
MsgBox(ex.Message & " Please select a corresponding records.", MsgBoxStyle.Exclamation)
End Try
Any help please?
It's hard to see the full picture, but the problem is most likely that you have created a DataGridViewImageColumn which you've chosen to call Image.
The compiler will always choose local variables, properties or classes over library/pre-imported namespace objects with the same name. Thus, your column by the name Image will be used rather than System.Drawing.Image because the former is "more local".
Try specifying the namespace as well and it should work:
.UploadImage.Image = System.Drawing.Image.FromStream(ms)
So what I did to solve this is by:
Dim pCell As New DataGridViewImageCell
pCell = Me.DGUSERS.Item("Picture", e.RowIndex)
.UploadImage.Image = byteArrayToImage(pCell.Value)
and using this function:
Private Function byteArrayToImage(ByVal byt As Byte()) As Image
Dim ms As New System.IO.MemoryStream()
Dim drwimg As Image = Nothing
Try
ms.Write(byt, 0, byt.Length)
drwimg = New Bitmap(ms)
Finally
ms.Close()
End Try
Return drwimg
End Function
I have been using ITextSharp to replicate the information on a webpage so that the information on the page can be printed in PDF format.
I generate my table by using the following code.
Protected Sub GenerateTable(noOfRows As Integer, reader As SqlClient.SqlDataReader)
Dim table As Table
Dim row As TableRow
Dim cell As TableCell
Dim lbl As Label
Dim lblVolume As Label
Dim lblUnitPrice As Label
Dim lblTotalPrice As Label
table = VolumeTable
table.ID = "VolumeTable"
'Page.Form.Controls.Add(table)
For i As Integer = 1 To noOfRows Step 1
row = New TableRow()
For j As Integer = 0 To 5 Step 1
cell = New TableCell()
If j = 1 Then
lblVolume = New Label()
lblVolume.ID = "LabelRow_" & i & "Col_" & j
cell.Controls.Add(lblVolume)
lblVolume.Text = reader.GetValue(2)
ElseIf j = 2 Then
lblUnitPrice = New Label()
lblUnitPrice.ID = "UnitLabel" & i
lblUnitPrice.Text = "Unit Price: "
cell.Controls.Add(lblUnitPrice)
ElseIf j = 3 Then
lblUnitPrice = New Label()
lblUnitPrice.ID = "LabelRow_" & i & "Col_" & j
cell.Controls.Add(lblUnitPrice)
lblUnitPrice.Text = reader.GetValue(5)
ElseIf j = 4 Then
lblUnitPrice = New Label()
lblUnitPrice.ID = "TotalPrice" & i
lblUnitPrice.Text = "Total Price: "
cell.Controls.Add(lblUnitPrice)
ElseIf j = 5 Then
lblTotalPrice = New Label()
lblTotalPrice.ID = "LabelRow_" & i & "Col_" & j
cell.Controls.Add(lblTotalPrice)
lblTotalPrice.Text = reader.GetValue(6)
ElseIf j = 0 Then
lbl = New Label()
lbl.ID = "Label" & i
lbl.Text = "Volume " & i
cell.Controls.Add(lbl)
End If
row.Cells.Add(cell)
Next
table.Rows.Add(row)
reader.Read()
Next
'SetPreviousTableData(noOfRows)
ViewState("RowsCount") = noOfRows
Session("RowsCount") = noOfRows
End Sub
How would I go about replicating this table in ITextSharp using Visual Basic. All of the solutions I have looked at so far have been in C# but I cant figure out to do this in VB
any advice would be appreciated.
Below is the most basic usage of iTextSharp in VB.Net. I'm not binding it to any data model, just two loops for rows and columns since it seems like you've got that part down. See the code comments for more details.
''//Filename that we're going to write to
Dim FileName = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.pdf")
''//Create a Stream to write to. This could also be a MemoryStream or anything else that inherits from System.IO.Stream
Using FS As New FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.None)
''//Create an abstract PDF document
Using Doc As New Document()
''//Create a PdfWriter that binds the abstraction to the stream
Using Writer = PdfWriter.GetInstance(Doc, FS)
''//Open the document to allow writing
Doc.Open()
''//Create a Pdf table with 4 columns
Dim table As New PdfPTable(4)
''//Loop through 10 rows
For RowNumber = 1 To 10
''//Loop through 4 columns
For ColumnNumber = 1 To 4
''//Write some text to the table
table.AddCell(New Paragraph(String.Format("Hello from {0}x{1}", RowNumber, ColumnNumber)))
Next
Next
''//Add the table to the document
Doc.Add(table)
''//Close the document to disable writing and flush buffers
Doc.Close()
End Using
End Using
End Using
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...
I have created a dynamic table using for loop condition.In which it has a button while i click a specific button it should open a file.But in my coding it is opening a file button in the last row.
If Not IsPostBack Then
txtlogsdate.Text = FormatDate(Now)
End If
Try
trViewlogs.Visible = True
lbllogs.Visible = False
lbllogname.Visible = True
RT1.Visible = False
pb.Visible = False
Dim d1 As DateTime = txtlogsdate.Text
Dim dd As String = d1.ToString("dd")
Dim mm As String = d1.ToString("MM")
Dim yy As String = d1.ToString("yy")
Dim d2 As String = yy & "" & mm & "" & dd
Dim di As DirectoryInfo = New DirectoryInfo(Server.MapPath("~\logs"))
Dim files As FileInfo() = di.GetFiles("*.log")
Dim tab As New Table()
tab.CellPadding = 0
tab.CellSpacing = 0
tab.BorderStyle = BorderStyle.Double
tab.Attributes.Add("style", "margin-left: 0.5px; width: 800px;")
Dim row As New TableRow()
Dim headerCell1 As New TableHeaderCell()
headerCell1.Text = "Logs"
headerCell1.Attributes.Add("style", "margin-left: 0.5px; height: 20px;")
headerCell1.BackColor = System.Drawing.Color.CornflowerBlue
headerCell1.ForeColor = System.Drawing.Color.White
row.Controls.Add(headerCell1)
tab.Controls.Add(row)
Dim headerCell2 = New TableHeaderCell()
headerCell2.Attributes.Add("style", "margin-left: 0.5px; height: 20px;")
headerCell2.BackColor = System.Drawing.Color.CornflowerBlue
headerCell2.ForeColor = System.Drawing.Color.White
headerCell2.Text = "Download"
row.Controls.Add(headerCell2)
tab.Controls.Add(row)
For i As Integer = 0 To files.Length - 1
Dim a As String = files(i).ToString.Replace("Event-", "")
Dim c As String = a.Substring(0, 6)
Dim sw As String
If d2 = c Then
sw = My.Computer.FileSystem.ReadAllText(_
GetWebSitePhysicalRoot & "\logs\" & files(i).ToString)
lbllogname.Text = files(i).ToString
lbllogname.Visible = False
row = New TableRow()
If i Mod 2 = 0 Then
row.BackColor = System.Drawing.Color.White
Else
row.BackColor = System.Drawing.Color.AliceBlue
End If
Dim cell As New TableCell()
cell.Text = lbllogname.Text
'cell.Width = New Unit("1000px")
cell.HorizontalAlign = HorizontalAlign.Center
row.Controls.Add(cell)
Dim cell2 As New TableCell()
Dim bt As New Button
bt.BorderStyle = BorderStyle.Solid
bt.Text = files(i).ToString
AddHandler bt.Click, AddressOf bt_Click
cell2.HorizontalAlign = HorizontalAlign.Center
cell2.Controls.Add(bt)
row.Controls.Add(cell2)
tab.Controls.Add(row)
Panel1.Controls.Add(tab)
End If
Next i
If lbllogname.Text = "" Then
lbllogname.Text = "No Logs to Display !"
End If
Session("pageurl") = ""
Session("pagecount") = ""
ib.SetInfo("Reports > View Logs", Infobar.InfoTypes.Caption)
Dim mi As Integer = GetQueryStringToInt("menuindex", 1)
If Not IsPostBack Then
leftmenu1.AddItem("View Logs", _
GetWebSiteUrlRoot & "/staff_rpt.aspx?rpt=logs&page=1&menuindex=" & mi)
End If
Catch ex As Exception
WriteLog(LogWriter.EventType.eError, ex.StackTrace.ToString)
End Try
Protected Sub bt_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs
Dim a As String
a = lbllogname.Text
Response.ContentType = "text/plain"
Response.AppendHeader("Content-Disposition", "attachment; filename=" & a)
Response.TransmitFile(Server.MapPath("~/logs/" & a))
Response.End()
End Sub
To use the dynamic table structure you have built in your code, then you need to uniquely name each button in each row; otherwise the button click handler (bt_Click) cannot figure out the correct row to open the file in, because they are all called the same and will use the last one.
Since you want a table structure, then I suggest you use the GridView server control, as it will provide similar output, but provide the ability to use templating to name the controls of each row the same, but allow for you to differentiate individual rows when a click event happens.