How do i get access to checkboxes dynamically generated in loop - asp.net

I am new to asp.net and vb.net programming and i can't find a answer to my problem. I have dynamically generated checkboxes in a loop at runtime within a sub.
This is a grid scheduler program that displays selected day's and selected hours from a location which is selected from a different page. I want to acces the checkboxes by id but i cant get acces to them because the checkboxes are not declared at class level.
Can anyone help me please, i have searched all day long for a solution. I Prefer VB but C# is fine also.
Below is my codebehind
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
BindLocationDayTime()
End If
End Sub
Public Sub BindLocationDayTime()
Dim ID As Integer
Dim Name As String
Dim Day As Integer
Dim Time As Integer
Dim StartDate As DateTime
Dim EndDate As DateTime
Dim Locations As SqlDataReader = GetLocations()
For Each Item In Locations
Dim LRow As New TableRow()
Dim LCell As New TableCell()
LCell.Text = Locations.Item("Name")
LCell.Attributes.Add("class", "LocationHeader")
LCell.Attributes.Add("colspan", "5")
LRow.Cells.Add(LCell)
LocationData.Rows.Add(LRow)
Dim Location As SqlDataReader = GetLocation(Convert.ToInt32(Locations.Item("Id")))
While Location.Read()
Name = Location("Name").ToString()
StartDate = Location("StartDate")
EndDate = Location("EndDate")
End While
Dim dtfi As Globalization.DateTimeFormatInfo = Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat
Dim tRowCount As Integer = 0
Do While StartDate <= EndDate
Dim LocationDayTime As SqlDataReader = GetPlayDayTime(Convert.ToInt32(Locations.Item("Id")))
For Each row In LocationDayTime
Day = LocationDayTime.Item("DayID")
Time = LocationDayTime.Item("TimeID")
ID = Locations.Item("Id")
If Day = 1 Then
If StartDate.DayOfWeek = DayOfWeek.Monday Then
BindDays(StartDate, ID, tRowCount, Time)
tRowCount = tRowCount + 1
End If
ElseIf Day = 2 Then
If StartDate.DayOfWeek = DayOfWeek.Tuesday Then
BindDays(StartDate, ID, tRowCount, Time)
tRowCount = tRowCount + 1
End If
ElseIf Day = 3 Then
If StartDate.DayOfWeek = DayOfWeek.Wednesday Then
BindDays(StartDate, ID, tRowCount, Time)
tRowCount = tRowCount + 1
End If
ElseIf Day = 4 Then
If StartDate.DayOfWeek = DayOfWeek.Thursday Then
BindDays(StartDate, ID, tRowCount, Time)
tRowCount = tRowCount + 1
End If
ElseIf Day = 5 Then
If StartDate.DayOfWeek = DayOfWeek.Friday Then
BindDays(StartDate, ID, tRowCount, Time)
tRowCount = tRowCount + 1
End If
End If
Next
StartDate = StartDate.AddDays(1)
Loop
Next
End Sub
Public Sub BindDays(ByVal StartDate As DateTime, ByVal ID As Integer, ByVal tRowCount As Integer, ByVal Time As Integer)
Dim dtfi As Globalization.DateTimeFormatInfo = Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat
Dim tRow As New TableRow()
Dim Cell1 As New TableCell()
Dim strDayOfWeek As String = dtfi.GetDayName(StartDate.DayOfWeek)
Cell1.Text = UppercaseFirstLetter(strDayOfWeek & " ") & (StartDate.Date.ToShortDateString & " om ") & (Time & "uur ")
Cell1.Attributes.Add("class", "MemberCell")
tRow.Cells.Add(Cell1)
Dim Cell2 As New TableCell()
Dim cbAvailible As New CheckBox()
cbAvailible.ID = (StartDate.Date) & "," & (Time)
cbAvailible.Checked = False
Cell2.Controls.Add(cbAvailible)
tRow.Cells.Add(Cell2)
Dim Cell3 As New TableCell()
Dim Label As New Label()
Label.Text = ("(Op deze datum ben ik verhinderd)")
Cell3.Controls.Add(Label)
tRow.Cells.Add(Cell3)
If tRowCount Mod 2 Then
tRow.Attributes.Add("class", "alternatingItemStyle")
Else
tRow.Attributes.Add("class", "itemStyle")
End If
LocationData.Rows.Add(tRow)
End Sub
#End Region
#Region " Events "
Private Sub Insert_Click(sender As Object, e As EventArgs) Handles Insert.Click
' I want to get here al the checkbox id and insert the values to a databse
End Sub
End Region

Solution 1 - Using recursive control search
I have done something similar with a dynamically generated form with a variable number of controls (textboxes, dropdowns, and checkboxes) and control state being data driven. I would not be looking to tie into the events of the generated controls (would require a jerky postback) but have a "Save" button and from that event do a recursive GetChildControls function that starts from the container holding your dynamic controls. Have a convention when assigning an id for each dynamic control so when you later loop back through them you can know which control is related to which record.
The recursive function:
Public Class ControlUtils
Shared Function GetChildControls(ByVal ctrl As Control, Optional ByVal ctrlType As Type = Nothing) As Control()
Dim controls As New ArrayList()
For Each c As Control In ctrl.Controls
' add this control and all its nested controls
If ctrlType Is Nothing OrElse ctrlType.IsAssignableFrom(c.GetType()) Then
controls.Add(c)
controls.AddRange(GetChildControls(c))
End If
Next
' return the result as an array of Controls
Return DirectCast(controls.ToArray(GetType(Control)), Control())
End Function
End Class
Basic idea with a contrived dynamic form...
A class to represent the database info:
Public Class Location
Public Property ID As Integer
Public Property Name As String
Public Property StartDate As Date
Public Property EndDate As Date
Shared Function GetSampleLocations() As List(Of Location)
Dim sample As New List(Of Location)
Dim loc As Location
For j = 1 To 5
loc = New Location
loc.ID = j
loc.Name = "Location " & j
loc.StartDate = Date.Today
loc.EndDate = Date.Today.AddDays(6 - j)
sample.Add(loc)
Next
Return sample
End Function
End Class
The class that has the methods to build the "form" and save its data:
Public Class LocationsDynamicForm
Dim _Locations As IEnumerable(Of Location)
Sub New(locations As IEnumerable(Of Location))
_Locations = locations
End Sub
Sub InsertEditForm(plc As PlaceHolder, setUserInput As Boolean)
'build and add controls to placeholder
Dim tbl As New Table
Dim r As TableRow
Dim c As TableCell
For Each loc As Location In _Locations
r = New TableRow
'add cell for location name
c = New TableCell
c.Controls.Add(New LiteralControl(loc.Name)) 'add plain text through literal control
r.Cells.Add(c)
'add cell for each day in the date range for current location
Dim currentDate As Date = loc.StartDate
Do Until currentDate > loc.EndDate
c = New TableCell
Dim chk As New CheckBox
chk.ID = "chkLocationDate_" & loc.ID & "_" & currentDate.Ticks
chk.Text = currentDate.ToShortDateString
If setUserInput Then
'set the check state based on current database value
Dim pretendValueCameFromDB As Boolean = True
chk.Checked = pretendValueCameFromDB
End If
c.Controls.Add(chk)
r.Cells.Add(c)
currentDate = currentDate.AddDays(1)
Loop
tbl.Rows.Add(r)
Next
plc.Controls.Add(tbl)
End Sub
Sub SaveForm(ByVal plc As PlaceHolder)
Dim ctl As Control
Dim controlIDParts() As String
Dim drp As DropDownList
Dim txt As TextBox
Dim chk As CheckBox
For Each ctl In ControlUtils.GetChildControls(plc, GetType(Control))
If ctl.GetType Is GetType(DropDownList) Then
drp = CType(ctl, DropDownList)
If drp.ID Like "drpIT_*" Then
controlIDParts = drp.ID.Split("_")
'update record...
End If
ElseIf ctl.GetType Is GetType(TextBox) Then
txt = CType(ctl, TextBox)
If txt.ID Like "txtIT_*" Then
controlIDParts = txt.ID.Split("_")
'update record...
End If
ElseIf ctl.GetType Is GetType(CheckBox) Then
chk = CType(ctl, CheckBox)
If chk.ID Like "chkLocationDate_*" Then
controlIDParts = chk.ID.Split("_")
Dim locationID = controlIDParts(1)
Dim ticks As Long = Val(controlIDParts(2))
Dim d As New Date(ticks)
'update record...
End If
End If
Next
'commit record changes...
End Sub
End Class
And its use inside the webform (assuming you have a save button and placeholder control):
Dim _Locations As List(Of Location)
Dim _LocationsForm As LocationsDynamicForm
Protected Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init
_Locations = Location.GetSampleLocations()
_LocationsForm = New LocationsDynamicForm(_Locations)
_LocationsForm.InsertEditForm(plcLocations, Not Me.IsPostBack)
End Sub
Protected Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
_LocationsForm.SaveForm(plcLocations)
End Sub
Solution 2 - Use AddHandler with Dynamically added controls
This is closer to what you want, but requires a postback on each checkbox change. In your BindDays routine add these lines when you are adding the checkbox.
cbAvailible.AutoPostBack = True
AddHandler cbAvailible.CheckedChanged, AddressOf Insert_Click
You should trim the Handles keyword at the end of your sub Insert_Click signature. The Handles is nice when you have foreknowledge of the control(s) you will be handling but the controls don't exist at design time.
Private Sub Insert_Click(sender As Object, e As EventArgs)
' I want to get here al the checkbox id and insert the values to a databse
Dim chk As CheckBox = CType(sender, CheckBox)
Label1.Text = "ID = " & chk.ID & ", Checked = " & chk.Checked
End Sub
I'm not sure how you are persisting your 'LocationData' across postbacks or adding it to the web page but I was able to get a modified version of your code working.

' Global declaration inside the "Form" class.
Public Checkboxes as New List(of Checkbox)
Each time you create a "new checkbox" add it to the collection.
...
Dim cbAvailible As New CheckBox()
Checkboxes.Add(cbAvailable)
...
Later you can simply refer to the checkbox by Index.
Dim chk as boolean = Checkboxes(2).checked ' example
The other Alternative is to use a Generic.Dictionary to store the checkboxes, in that case each box can have a "Key" like a string that relates to the row or something specific.
Looping through Checkboxes.
For iQ AS integer = 0 to Checkboxes.Count -1
Dim cb as checkbox = Checkboxes(iq) ' just a way to not use long name during operations.
Dim checked as boolean = cb.checked ' ... ' do your work here
' ...
Next iQ
Odds are you will need to do the same with all your objects (per row).
The Last Index should be the same for all of them. Which should be the same as the number of rows in your table object as well.

Related

Allow only some check boxes to be checked. Loaded on page_load

I am dynamically adding asp check boxes to my page based off of number of rows in my db table, by ID. Also the checkbox is being assigned an ID from the db table. I also two columns in my db table "numberOffered" and "numberAllowed". My idea is on page load only allow the user to check say 3 of the 10 check boxes shown. I have removed a lot of the code I thought would be unnecessary. Thank you very much in advance.
For Each Arow As Object In ATable.Rows
For Each Brow As Object In BTable.Rows
If Brow(1) = a_ID Then
If Brow(2) = b_ID Then
Dim cbShown As Integer = Arow(5)
Dim cbAllowed As Integer = Arow(6)
Dim checkBox As New CheckBox()
End If
End If
Next
Next
checkBox.ID = Crow(0)
divcontrol.Controls.Add(checkBox)
EDIT:
Full Page_load sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not (Session("studentLoggedIn") Or Session("adminLoggedIn")) Then
Routines.LogOut()
End If
If Session("adminLoggedIn") = True Then
castVote.Enabled = False
castVote.CssClass = "btnDisabled"
Dim p As New HtmlGenericControl()
p.TagName = "p"
p.InnerText = "Vote button disabled. Only students may vote."
adminMsg.Controls.Add(p)
End If
Dim ballot_ID As Integer = CType(Session.Item("ballot_ID"), Integer)
Dim ballotName As String = CType(Session.Item("ballotName"), String)
Dim ballotsAdapter As New eVoteTableAdapters.ballotsTableAdapter()
Dim ballotsTable As New eVote.ballotsDataTable
ballotsTable = ballotsAdapter.GetDataBy3getBallotsByID(ballot_ID)
Dim sectionsAdapter As New eVoteTableAdapters.sectionsTableAdapter()
Dim sectionsTable As New eVote.sectionsDataTable
sectionsTable = sectionsAdapter.GetDataBygetsectionsByBallotID(ballot_ID)
Dim candidatesAdapter As New eVoteTableAdapters.candidatesTableAdapter()
Dim candidatesTable As New eVote.candidatesDataTable
candidatesTable = candidatesAdapter.GetDataBygetCandidatesByballotID(ballot_ID)
openBallotName.InnerText = ballotName
Dim section_ID
For Each row As Object In sectionsTable.Rows
If row(1) = ballot_ID Then
section_ID = row(0)
Dim sectionName As New HtmlGenericControl()
Dim sectionDescription As New HtmlGenericControl()
Dim divcontrol As New HtmlGenericControl()
Dim br As New HtmlGenericControl()
divcontrol.Attributes("ID") = section_ID
divcontrol.Attributes("runat") = "server"
divcontrol.Attributes("style") = "border: solid;"
divcontrol.TagName = "div"
br.TagName = "br"
sectionName.TagName = "h4"
sectionDescription.TagName = "p"
mainBallotDiv.Controls.Add(divcontrol)
mainBallotDiv.Controls.Add(br)
sectionName.InnerText = row(2)
sectionDescription.InnerText = row(3)
divcontrol.Controls.Add(sectionName)
divcontrol.Controls.Add(sectionDescription)
For Each Crow As Object In candidatesTable.Rows
If Crow(1) = ballot_ID Then
If Crow(2) = section_ID Then
Dim checkBox As New CheckBox()
Dim canImg As New Image()
Dim canName As New HtmlGenericControl()
Dim canBio As New HtmlGenericControl()
Dim rmImg As New Image()
Dim rmName As New HtmlGenericControl()
Dim rmBio As New HtmlGenericControl()
Dim canBytes As Byte() = Crow(6)
Dim canBase64String As String = Convert.ToBase64String(canBytes, 0, canBytes.Length)
Dim rmBytes As Byte() = Crow(11)
Dim rmBase64String As String = Convert.ToBase64String(rmBytes, 0, rmBytes.Length)
checkBox.ID = Crow(0)
canName.TagName = "h3"
canBio.TagName = "p"
rmName.TagName = "h3"
rmBio.TagName = "p"
canName.InnerText = Crow(4) & " " & Crow(5)
canBio.InnerText = Crow(7)
canImg.ImageUrl = Convert.ToString("data:image/png;base64,") & canBase64String
canImg.Height = 120
rmName.InnerText = Crow(9) & " " & Crow(10)
rmBio.InnerText = Crow(12)
rmImg.ImageUrl = Convert.ToString("data:image/png;base64,") & rmBase64String
rmImg.Height = 120
divcontrol.Controls.Add(checkBox)
divcontrol.Controls.Add(canImg)
divcontrol.Controls.Add(canName)
divcontrol.Controls.Add(canBio)
If row(4) = True Then
divcontrol.Controls.Add(rmImg)
divcontrol.Controls.Add(rmName)
divcontrol.Controls.Add(rmBio)
End If
End If
End If
Next
End If
Next
End Sub
You will want a variable (integer) for the amount of checkboxes allowed, then another variable for the amount of checkboxes currently checked, finally a List containing the name of each checkbox, (have all these variables as class fields)
then in your event handler something like
Sub Check_Clicked(sender As Object, e As EventArgs)
checked += 1
If checked >= NumberAllowedChecked Then
For Each a As CheckBox In MyCheckBoxList
If Not CheckBox.Checked Then CheckBox.Enabled = False
Next
End If
End Sub
I am not overly familiar with VB but I think this should set you on the right track on how to implement it for yourself
Edit: you will want to add in logic for if a user unchecks a check box that it will subtract one from 'checked;

Accessing multiple dynamic controls values

I am adding multiple controls dynamically based on a dropdownlist that the user selects. i.e. if the user selects 3 then 3 sets of the controls are added. My problem is not in adding the controls, I can add them fine, I haven't added all my code but the main parts to understand what I am doing.
Once the controls have been created, the relevant info is captured. On the Update click I need to access the values of these dynamic controls by looping through in the correct order and retrieve the values and write to the database. I can't seem to access them correctly.
Hopefully I am making sense. Any help would be appreciated. Thanks
''Loop through first set of controls and get values and then the next set etc..
Dim Description as string = ''Get Textbox value
Dim Type as string = ''Get RadComboBox value
Dim XFieldName as string = ''Get RadComboBox value
Dim Colour as string = ''Get RadColorPicker value
Below is my Code:
VB
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
RecreateControlsTxt("txt", "TextBox")
RecreateControlsChart("comboChart", "RadComboBox")
RecreateControls("combo", "RadComboBox")
RecreateControlsCP("cp", "RadColorPicker")
End Sub
Protected Sub AddControls_Click(sender As Object, e As EventArgs) Handles AddControls.Click
For i As Integer = 0 To ddlFieldNames.SelectedIndex
CreateTextbox("txt-" & Convert.ToString(i + 1))
Next
For i As Integer = 0 To ddlFieldNames.SelectedIndex
CreateComboChart("comboChart-" & Convert.ToString(i + 1))
Next
For i As Integer = 0 To ddlFieldNames.SelectedIndex
CreateComboField("combo-" & Convert.ToString(i + 1))
Next
For i As Integer = 0 To ddlFieldNames.SelectedIndex
CreateColourPicker("cp-" & Convert.ToString(i + 1))
Next
End Sub
Private Sub CreateTextbox(ByVal ID As String)
Dim txt As New TextBox()
txt.ID = ID
txt.Height = 20
Me.divDesc.Controls.Add(txt)
End Sub
Private Sub CreateComboField(ByVal ID As String)
Dim combo As New RadComboBox()
combo.ID = ID
combo.DataSource = Me.odsChartsSeriesField
combo.DataTextField = "FieldNames"
combo.DataValueField = "FieldNames"
combo.DataBind()
Me.divField.Controls.Add(combo)
End Sub
Private Sub CreateComboChart(ByVal ID As String)
Dim comboChart As New RadComboBox()
comboChart.ID = ID
Dim item1 As New RadComboBoxItem()
item1.Text = "Line"
item1.Value = "smoothedLine"
item1.ImageUrl = ("Images/linechart.png")
comboChart.Items.Add(item1)
Dim item2 As New RadComboBoxItem()
item2.Text = "Column"
item2.Value = "column"
item2.ImageUrl = ("Images/bar chart.png")
comboChart.Items.Add(item2)
Dim item3 As New RadComboBoxItem()
item3.Text = "Pie"
item3.Value = "pie"
item3.ImageUrl = ("Images/pie chart.jpg")
comboChart.Items.Add(item3)
Me.divChart.Controls.Add(comboChart)
End Sub
Private Sub CreateColourPicker(ByVal ID As String)
Dim cp As New RadColorPicker()
cp.ID = ID
cp.ShowIcon = True
cp.Style("padding-top") = "1px"
cp.CssClass = "CustomHeight"
Me.divCol.Controls.Add(cp)
End Sub
Protected Sub Update_Click(sender As Object, e As EventArgs) Handles Update.Click
Try
Dim alltxt = divDesc.Controls.OfType(Of TextBox)()
Dim allcomboChart = divChart.Controls.OfType(Of RadComboBox)()
Dim allcomboField = divField.Controls.OfType(Of RadComboBox)()
Dim allcp = divCol.Controls.OfType(Of RadColorPicker)()
''Loop through first set of controls and get values and then the next etc..
Dim Description as string = ''Get Textbox value
Dim Type as string = ''Get RadComboBox value
Dim XFieldName as string = ''Get RadComboBox value
Dim Colour as string = ''Get RadColorPicker value
If Page.IsValid Then
Dim da As New dsSVTableAdapters.Chart
Dim Result As String = da.Series(60, Description, Type, Colour, "YFieldName", XFieldName)
End If
Catch ex As Exception
lblResult.Text = ex.Message
End Try
End Sub
You have a repeated set of controls. Therefore you need a corresponding repeated set of variables that store these values.
I suggest creating a class where you can store a variable (or property) set.
Public Class ControlSet
Public Property Description As String
Public Property Type As String
Public Property XFieldName As String
Public Property Colour As String
End Class
Create an array that holds these values
Dim Values = New ControlSet(ddlFieldNames.SelectedIndex) {}
And retrieve the values in a loop
For i As Integer = 0 To Values.Length - 1
Values(i).Description = CType(divDesc.FindControl("txt-" & Convert.ToString(i + 1)), TextBox).Text
Values(i).Type = CType(divChart.FindControl("comboChart-" & Convert.ToString(i + 1)), RadComboBox).SelectedValue
Values(i).XFieldName = ...
...
Next
Also use the ID of the control; this helps to avoid confusion in case you have several controls of the same type.
you can use .FindControl(string id) method, and you should keep the controls count in your view state or session:
Protected Sub Update_Click(sender As Object, e As EventArgs) Handles Update.Click
Try
''Loop through first set of controls and get values and then the next etc..
For i As Integer = 0 To controlsCount - 1
Dim Description as string = ((TextBox)divDesc.FindControl("txt-" & Convert.ToString(i + 1))).Text ''Get Textbox value
Dim Type as string = ((RadComboBox)divChart.FindControl("comboChart-" & Convert.ToString(i + 1))).SelectedValue ''Get RadComboBox value
Dim XFieldName as string = ((RadComboBox)divField.FindControl("combo-" & Convert.ToString(i + 1))).SelectedValue ''Get RadComboBox value
Dim Colour as string = ((RadColorPicker)divField.FindControl("cp-" & Convert.ToString(i + 1))).SelectedValue ''Get RadColorPicker value
If Page.IsValid Then
Dim da As New dsSVTableAdapters.Chart
Dim Result As String = da.Series(60, Description, Type, Colour, "YFieldName", XFieldName)
Next
End If
Catch ex As Exception
lblResult.Text = ex.Message
End Try
End Sub

Time value out of datetime column gets converted to 12 hour format after DataReader.Read

My app allows users to make meeting appointments. Before the appointment is saved to the database, the user selects a date from a Calendar control. Once a date is selected, the page should get a list of appointments for that day out of the database, and examine the time of day for each recorded appointment. Any timeslots that have already been booked are to be removed from a DropDownList that the user will select a convenient time from.
The problem comes in with my time comparisons. Most of the code below is meant to strip the apart the date/time values to get something I can compare with.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
PopulateTime()
End If
End Sub
Protected Sub PopulateTime()
Dim db As New Database
Dim sql As String = "select apptinterval from centres where centreid = #id"
Dim args As New List(Of SqlParameter)
args.Add(New SqlParameter("#id", Session("CentreID")))
Dim dr As SqlDataReader = db.GetReader(sql, args.ToArray)
Dim interval As Integer = 0
If dr.Read Then
interval = dr("apptinterval")
End If
Dim time = TimeSpan.FromHours(8)
While time < TimeSpan.FromHours(17)
time += TimeSpan.FromMinutes(interval)
ddlAppointmentTime.Items.Add(New ListItem(time.ToString, time.ToString))
End While
End Sub
Protected Sub calAppointmentDate_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles calAppointmentDate.SelectionChanged
Dim seldate As String = Left(calAppointmentDate.SelectedDate, 10)
Dim dateargs() As String = seldate.ToString.Split("/")
Dim newdate As String = dateargs(0) & "-" & dateargs(1) & "-" & dateargs(2)
GetTimes(newdate)
End Sub
Protected Sub GetTimes(ByVal TargetDate As String)
Dim db As New Database
Dim args As New List(Of SqlParameter)
Dim sql As String = "select apptdate from appointments where apptdate between #date1 and #date2 order by apptdate"
args.Add(New SqlParameter("#date1", TargetDate & " 12:00:00"))
args.Add(New SqlParameter("#date2", TargetDate & " 23:59:59"))
Dim dr As SqlDataReader = db.GetReader(sql, args.ToArray)
If dr.HasRows Then
dr.Read()
For i As Integer = 0 To ddlAppointmentTime.Items.Count - 1
If Left(ddlAppointmentTime.Items(i).Value, 5) = Mid(dr("apptdate"), 12, 5) Then
ddlAppointmentTime.Items.RemoveAt(i)
End If
Next
End If
dr.Close()
End Sub
If the loop here, the value for Mid(dr("apptdate"), 12, 5) is being returned as 01:00. The actual value in the database says 13:00.
Can anyone suggest why this conversion is happening? It's causing the comparison to fail, and so, that timeslot is not being removed from the DropDownList.
Thanks in advance!
It seems it was the Mid that did it. The conversion to string involved here changed the value.
I worked around this by removing the Mid and changing the sql statement as follows:
Dim sql As String = "select left(CONVERT(time, apptdate, 14), 5) as apptdate from appointments"
Dim dr As SqlDataReader = db.GetReader(sql, args.ToArray)
If dr.HasRows Then
While dr.Read
For i As Integer = 0 To ddlAppointmentTime.Items.Count - 1
If Left(ddlAppointmentTime.Items(i).Value, 5) = dr("apptdate") Then
ddlAppointmentTime.Items.RemoveAt(i)
End If
Next
End While
End If
dr.Close()

compare the content of 2 gridviews in one aspx page

we need to compare the content of 2 identical gridviews and extract rows that differ in a third gridview, is this doable?
i tried a lot but faced no luck, please help me.
at our office we take daily backup of ASP.net application ms access backend
for the next few days we need to evaluate the changes made to records in the database tables
at the end of each day i want to compare 2 access databases first database is the backup of yesterday and second database is the backup of today
i thought of the following algorithm, please read carefully and tell me how to proceed to compare the datatables / gridviews
i need to display th rows / cells containing the differences / updates / deleted data
comparing two ms access backend databases of an asp.net web application
my team and myseld figured it out
Imports System.Data
Imports System.Data.OleDb
Partial Class MoKoTrack
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim myDB = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|databaseName.mdb;Persist Security Info=True")
Session("CurrentDB") = myDB
myDB.open()
Dim mytables = myDB.GetOleDbSchemaTable(OleDbSchemaGuid.Primary_Keys, New Object() {})
Dim CurrentTable As String
For i = 1 To mytables.Rows.Count
CurrentTable = mytables.Rows(i - 1).Item(2).ToString
If CurrentTable.Contains("Backup") Then CompareTable(CurrentTable, mytables.Rows(i - 1).Item(3).ToString)
Next i
' Dim myGrid As New GridView
'myGrid.DataSource = mytables
'myGrid.DataBind()
'Me.Form.Controls.Add(myGrid)
'myDB.Close()
End Sub
Sub CompareTable(ByVal BackupTableName As String, ByVal myPrimKey As String)
Dim OriginalTable As New DataTable
Dim BackupTable As New DataTable
Dim ModificationsTable As New DataTable
Dim AddedTable As New DataTable
Dim DeletedTable As New DataTable
Dim myDB = Session("CurrentDB")
Dim FinalSQLString = "SELECT * FROM [" + BackupTableName + "]"
Dim myDBCommand = New OleDbCommand(FinalSQLString, myDB)
Dim myReader As IDataReader = myDBCommand.ExecuteReader()
BackupTable.Load(myReader)
Dim OriginalTableName = Left(BackupTableName, Len(BackupTableName) - 6)
Dim FinalSQLString2 = "SELECT * FROM [" + OriginalTableName + "]"
Dim myDBCommand2 = New OleDbCommand(FinalSQLString2, myDB)
'Generate a temporary reader to get the number of cases
Dim myReader2 As IDataReader = myDBCommand2.ExecuteReader()
OriginalTable.Load(myReader2)
Dim myPrimColumn(0) As DataColumn
myPrimColumn(0) = OriginalTable.Columns(myPrimKey)
OriginalTable.PrimaryKey = myPrimColumn
Dim myPrimColumn2(0) As DataColumn
myPrimColumn2(0) = BackupTable.Columns(myPrimKey)
BackupTable.PrimaryKey = myPrimColumn2
AddedTable = OriginalTable.Clone
DeletedTable = OriginalTable.Clone
ModificationsTable = OriginalTable.Clone
ModificationsTable.PrimaryKey = Nothing
Dim CurrentVal As String
For i = 0 To OriginalTable.Rows.Count - 1
CurrentVal = OriginalTable.Rows(i).Item(myPrimKey).ToString
Dim foundRow As DataRow = BackupTable.Rows.Find(CurrentVal)
If foundRow IsNot Nothing Then
For t = 0 To OriginalTable.Columns.Count - 1
If Not foundRow.Item(t).ToString = OriginalTable.Rows(i).Item(t).ToString Then
ModificationsTable.ImportRow(OriginalTable.Rows(i))
'ModificationsTable.Rows(ModificationsTable.Rows.Count - 1).Item(t) = ModificationsTable.Rows(ModificationsTable.Rows.Count - 1).Item(t) & "Modified"
ModificationsTable.ImportRow(foundRow)
End If
Next
Else
AddedTable.ImportRow(OriginalTable.Rows(i))
End If
Next
For i = 0 To BackupTable.Rows.Count - 1
CurrentVal = BackupTable.Rows(i).Item(myPrimKey).ToString
Dim foundRow As DataRow = OriginalTable.Rows.Find(CurrentVal)
If foundRow Is Nothing Then
DeletedTable.ImportRow(OriginalTable.Rows(i))
End If
Next
If AddedTable.Rows.Count > 0 Then
Dim myLabel As New Label
myLabel.Text = "<br/> The following records were added to table " & OriginalTableName & "<br/> <br/>"
Me.form1.Controls.Add(myLabel)
Dim myGrid As New GridView
myGrid.DataSource = AddedTable
myGrid.DataBind()
Me.form1.Controls.Add(myGrid)
End If
If ModificationsTable.Rows.Count > 0 Then
Dim myLabel As New Label
myLabel.Text = "<br/> The following records were modified in table " & OriginalTableName & "<br/> <br/>"
Me.form1.Controls.Add(myLabel)
Dim myGrid As New GridView
myGrid.DataSource = ModificationsTable
myGrid.DataBind()
Me.form1.Controls.Add(myGrid)
End If
If DeletedTable.Rows.Count > 0 Then
Dim myLabel As New Label
myLabel.Text = "<br/> The following records were deleted from table " & OriginalTableName & "<br/> <br/>"
Me.form1.Controls.Add(myLabel)
Dim myGrid As New GridView
myGrid.DataSource = DeletedTable
myGrid.DataBind()
Me.form1.Controls.Add(myGrid)
End If
End Sub
End Class
I usually compare it using LINQ
This will give you a head start
var SearchResults1 = from u in YourDB.YourUserTable1
orderby u.YourColumn
select u;
GridView1.DataSource = SearchResults1;
GridView1.DataBind();
var SearchResults2 = from u in YourDB.YourUserTable2
orderby u.YourColumn
select u;
GridView2.DataSource = SearchResults2;
GridView2.DataBind();
var SearchResults3 = from u1 in SearchResults2
where !(from u2 in SearchResults1
select u2.YourTablePrimaryKey).Contains(u1.YourTablePrimaryKey)
orderby u1.YourColumn
select u1;
GridView3.DataSource = SearchResults3;
GridView3.DataBind();
You can further elaborate SearchResults 3 if you want like comparing whats in SearchResults1 but not in SearchResults2 and vice versa

comparing two ms access backend databases of an asp.net web application

at our office we take daily backup of ASP.net application ms access backend
for the next few days we need to evaluate the changes made to records in the database tables
at the end of each day i want to compare 2 access databases first database is the backup of yesterday and second database is the backup of today
i thought of the following algorithm, please read carefully and tell me how to proceed to compare the datatables / gridviews
i need to display th rows / cells containing the differences / updates / deleted data
Imports System.Data
Imports System.Data.OleDb
Partial Class MoKoTrack
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim myDB = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|database.mdb;Persist Security Info=True")
Session("CurrentDB") = myDB
myDB.open()
Dim mytables = myDB.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, New Object() {})
Dim CurrentTable As String
Dim ee As Integer = mytables.Rows.Count
Dim OriginalTables(ee) As String
Dim BackupTables(ee) As String
Dim X As Integer = 0
For i = 1 To mytables.Rows.Count
CurrentTable = mytables.Rows(i - 1).Item(2).ToString
If mytables.Rows(i - 1).Item(3).ToString = "TABLE" Or mytables.Rows(i - 1).Item(3).ToString = "VIEW" Then
If CurrentTable.Contains("Backup") Then
BackupTables(X) = CurrentTable
Else
OriginalTables(X) = CurrentTable
End If
X = X + 1
End If
Next i
For i = 0 To BackupTables.Count - 1
If Not BackupTables(i) = "" Then
CompareTable(BackupTables(i))
End If
Next
myDB.Close()
End Sub
Sub CompareTable(ByVal BackupTableName As String)
Dim OriginalTable As New DataTable
Dim BackupTable As New DataTable
Dim ModificationsTable As New DataTable
Dim myDB = Session("CurrentDB")
Dim FinalSQLString = "SELECT * FROM [" + BackupTableName + "]"
Dim myDBCommand = New OleDbCommand(FinalSQLString, myDB)
'Generate a temporary reader to get the number of cases
Dim myReader As IDataReader = myDBCommand.ExecuteReader()
'Dim myColumns = myReader.GetSchemaTable
'For I = 1 To myColumns.Rows.Count
' OriginalTable.Columns.Add(myColumns.Rows(I - 1).Item(0).ToString())
'Next I
BackupTable.Load(myReader)
Dim OriginalTableName = Left(BackupTableName, Len(BackupTableName) - 6)
Dim FinalSQLString2 = "SELECT * FROM [" + BackupTableName + "]"
Dim myDBCommand2 = New OleDbCommand(FinalSQLString, myDB)
'Generate a temporary reader to get the number of cases
Dim myReader2 As IDataReader = myDBCommand.ExecuteReader()
OriginalTable.Load(myReader2)
'Dim myGrid As New GridView
'myGrid.DataSource = OriginalTable
'myGrid.DataBind()
'Me.form1.Controls.Add(myGrid)
'Dim myGrid2 As New GridView
'myGrid2.DataSource = BackupTable
'myGrid2.DataBind()
'Me.form1.Controls.Add(myGrid2)
For i = 0 To OriginalTable.Rows.Count - 1
For t = 0 To OriginalTable.Columns.Count - 1
Next
Next
End Sub
End Class
i am using the following VBA code to rename backup database tables into "tablebackup"
Private Sub Command0_Click()
Dim tdf As TableDef
For Each tdf In CurrentDb.TableDefs
If Left(tdf.Name, 4) <> "MSys" Then
tdf.Name = tdf.Name & "backup"
End If
Next
End Sub
Can you add a ModifiedOn field for each table and extract the rows that have been modified since the last day. You can compare the modified ones (the ones that exist in the backup) and write out all new ones (the ones that don't).

Resources