Arrays and variables clears itself after a end sub in VB.net - asp.net

I am writing a times tables program in ASP.net and I need some help. The problem I am experiencing is that when the button sub ends and the screen pops up again for user input, all the arrays and variables are now set to nothing or 0.
Is there are way to keep all the values for variables after a sub ends and to use them later on?
Any help will be appreciated.
Public Class PickTimesTables
Inherits System.Web.UI.Page
Dim count As Integer = 0
Dim NumberQ As Integer
Dim RandomN As Integer
Dim FirstNumber() As Integer
Dim FirstNumberTemp() As Integer
Dim SecondNumber() As Integer
Dim correctAnswers As Integer
Dim inc As Integer = 0
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
PanelQuestion.Visible = False
PanelAnalysis.Visible = False
End Sub
Protected Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click
PanelQuestion.Visible = True
lblOperator.Text = "X"
If chktimes1.Checked = False And chktimes2.Checked = False And chktimes3.Checked = False And chktimes4.Checked = False And chktimes5.Checked = False And chktimes6.Checked = False And chktimes7.Checked = False And chktimes8.Checked = False And chktimes9.Checked = False And chktimes10.Checked = False And chktimes11.Checked = False And chktimes12.Checked = False Then
MsgBox("Pick a Times Table to be Tested for..")
ElseIf txtNoQuestion.Text = "" Then
MsgBox("Pick the Number of Question for the test")
Else
NumberQ = txtNoQuestion.Text
count = 0
If chktimes1.Checked Then
count = count + 1
End If
If chktimes2.Checked Then
count = count + 1
End If
If chktimes3.Checked Then
count = count + 1
End If
If chktimes4.Checked Then
count = count + 1
End If
If chktimes5.Checked Then
count = count + 1
End If
If chktimes6.Checked Then
count = count + 1
End If
If chktimes7.Checked Then
count = count + 1
End If
If chktimes8.Checked Then
count = count + 1
End If
If chktimes9.Checked Then
count = count + 1
End If
If chktimes10.Checked Then
count = count + 1
End If
If chktimes11.Checked Then
count = count + 1
End If
If chktimes12.Checked Then
count = count + 1
End If
If txtNoQuestion.Text = 0 Then
MsgBox("You cannot have a test with 0 Questions")
Else
ReDim FirstNumberTemp(count - 1)
For i = 0 To count - 1
If chktimes1.Checked Then
FirstNumberTemp(i) = 1
chktimes1.Checked = False
ElseIf chktimes2.Checked Then
FirstNumberTemp(i) = 2
chktimes2.Checked = False
ElseIf chktimes3.Checked Then
FirstNumberTemp(i) = 3
chktimes3.Checked = False
ElseIf chktimes4.Checked Then
FirstNumberTemp(i) = 4
chktimes4.Checked = False
ElseIf chktimes5.Checked Then
FirstNumberTemp(i) = 5
chktimes5.Checked = False
ElseIf chktimes6.Checked Then
FirstNumberTemp(i) = 6
chktimes6.Checked = False
ElseIf chktimes7.Checked Then
FirstNumberTemp(i) = 7
chktimes7.Checked = False
ElseIf chktimes8.Checked Then
FirstNumberTemp(i) = 8
chktimes8.Checked = False
ElseIf chktimes9.Checked Then
FirstNumberTemp(i) = 9
chktimes9.Checked = False
ElseIf chktimes10.Checked Then
FirstNumberTemp(i) = 10
chktimes10.Checked = False
ElseIf chktimes11.Checked Then
FirstNumberTemp(i) = 11
chktimes11.Checked = False
ElseIf chktimes12.Checked Then
FirstNumberTemp(i) = 12
chktimes12.Checked = False
End If
Next
ReDim FirstNumber(NumberQ - 1)
For i = 0 To NumberQ - 1
Randomize()
RandomN = FirstNumberTemp(Int(Rnd() * count))
FirstNumber(i) = RandomN
Next
ReDim SecondNumber(NumberQ - 1)
For i = 0 To NumberQ - 1
Dim rn As New Random(Now.Millisecond)
RandomN = rn.Next(1, 13)
SecondNumber(i) = RandomN
Next
lblFirstN.Text = FirstNumber(0)
lblSecondN.Text = SecondNumber(0)
End If
End If
End Sub
Protected Sub txtInput_TextChanged(sender As Object, e As EventArgs) Handles txtInput.TextChanged
NumberQ = txtNoQuestion.Text
If txtInput.Text = FirstNumber(inc) * SecondNumber(inc) Then
lblFirstN.Text = FirstNumber(inc + 1)
lblSecondN.Text = SecondNumber(inc + 1)
correctAnswers = correctAnswers + 1
txtInput.BackColor = Drawing.Color.Green
Else
txtInput.BackColor = Drawing.Color.Red
lblFirstN.Text = FirstNumber(inc + 1)
lblSecondN.Text = SecondNumber(inc + 1)
End If
End Sub
End Class

This is a common mistake for newcomers to ASP.Net Webforms. There is this idea that your page class instance lives for an entire session, for all of a user's interactions with the page in the browser. This does not happen. Any interaction with your page that causes an event to fire creates a new postback from the client to the server, and every postback uses a brand new instance of the Page class. By the time the user sees your page in their browser, whatever Page object you used to render the html for that view has already been destroyed and garbage collected.
There are some things you can do to get around this, like putting variables in the Session, URL, or ViewState, but often you need to completely re-think your approach to something that is more natural for a web site.
Additionally, you'll want to re-think handling a TextChanged event in your VB.Net code. Generally speaking, TextChanged events need to return to the user in 25-40 milliseconds, or the view will feel extremely sluggish. It's not usually a problem when the program is running right there on the user's computer, and has all the memory and CPU power of that workstation available. It's a whole other story for web sites, where you might have an 80ms delay before the request even reaches the server and another 80ms for the response, all before doing any processing, and the server is sharing it's CPU and memory resources to support as many users as you can fit.
Instead, look into using a javascript event for that processing, and only validate the text in your VB.Net code when the user finally tries to submit or save the end result.
Finally, those calls to the MsgBox() function need to go, too. It only seems to work on your system because your web server is on the same machine as the web browser. When you go to actually put this on a real server and test from a different place, those message will display on the server, not in the user's web browser.

They'll all be reset because that's the stateless nature of the web. They don't keep their values because each subsequent time you view that page (or step through it using the debugger), it's a new request.
You should google storing asp.net variables in ViewState or Session, i.e. ViewState-backed properties.

Related

Renumber all records when one is updated

I am using Access 2010. I have a datasheet form called Projects with two fields, [Project Name] and [Priority]. I would like to be able to update the priority number for one of the records and have all other priority numbers update automatically. For example, Project Red is priority 1. Project Orange is Priority 2 and Project Blue is Priority 3. If I update Blue to number 1, I would like Red to update to 2 and Orange to update to 3. Is this possible?
Projects Form
That is possible.
Use the AfterUpdate event of the textbox with Priority:
Private Sub Priority_AfterUpdate()
Dim rst As DAO.Recordset
Dim lngId As Long
Dim lngPriorityNew As Long
Dim lngPriorityFix As Long
' Save record.
Me.Dirty = False
' Prepare form.
DoCmd.Hourglass True
Me.Repaint
Me.Painting = False
' Current Id and priority.
lngId = Me!Id.Value
lngPriorityFix = Nz(Me!Priority.Value, 0)
If lngPriorityFix <= 0 Then
lngPriorityFix = 1
Me!Priority.Value = lngPriorityFix
Me.Dirty = False
End If
' Rebuild priority list.
Set rst = Me.RecordsetClone
rst.MoveFirst
While rst.EOF = False
If rst!Id.Value <> lngId Then
lngPriorityNew = lngPriorityNew + 1
If lngPriorityNew = lngPriorityFix Then
' Move this record to next lower priority.
lngPriorityNew = lngPriorityNew + 1
End If
If Nz(rst!Priority.Value, 0) = lngPriorityNew Then
' Priority hasn't changed for this record.
Else
' Assign new priority.
rst.Edit
rst!Priority.Value = lngPriorityNew
rst.Update
End If
End If
rst.MoveNext
Wend
' Reorder form and relocate record.
Me.Requery
Set rst = Me.RecordsetClone
rst.FindFirst "Id = " & lngId & ""
Me.Bookmark = rst.Bookmark
' Present form.
Me.Painting = True
DoCmd.Hourglass False
Set rst = Nothing
End Sub

Combine Row Cell for Repeater Record

I'm trying to combine the row cells when the campaign code and vehicle no are repeated as shown in below image. The result listed below is with gridview 20 page size
Problem
When the grid view page size is set with 2 for example, the row cell no longer combined. The result show each separated record.
If campaign code is sorted ascending/descending, the last record row cells will always not combine even though the campaign code and vehicle no are matched. Below image shown campaign code sorted in ascending. So when the campaign code is sorted descending, all the CMP002 are combined, while the last record of CMP001 will not be combined as shown in below image anymore.
Code Behind
Private Sub GV_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GV.RowDataBound
For rowIndex As Integer = GV.Rows.Count - 2 To 0 Step -1
Dim gvRow As GridViewRow = GV.Rows(rowIndex)
Dim gvPreviousRow As GridViewRow = GV.Rows(rowIndex + 1)
Dim sCurrCampaignCode As String = GV.DataKeys(rowIndex).Values("CAMPAIGN_CODE")
Dim sCurrVehicleNo As String = GV.DataKeys(rowIndex).Values("VEHICLE_NO")
Dim sPreviousCampaignCode As String = GV.DataKeys(rowIndex + 1).Values("CAMPAIG_CODE")
Dim sPreviousVehicleNo As String = GV.DataKeys(rowIndex + 1).Values("VEHICLE_NO")
If sCurrCampaignCode = sPreviousCampaignCode AndAlso sCurrVehicleNo = sPreviousVehicleNo Then
If sCurrCampaignCode = sPreviousCampaignCode Then
If gvPreviousRow.Cells(1).RowSpan < 2 Then
gvRow.Cells(1).RowSpan = 2
gvRow.Cells(2).RowSpan = 2
gvRow.Cells(3).RowSpan = 2
Else
gvRow.Cells(1).RowSpan = gvPreviousRow.Cells(1).RowSpan + 1
gvRow.Cells(2).RowSpan = gvPreviousRow.Cells(2).RowSpan + 1
gvRow.Cells(3).RowSpan = gvPreviousRow.Cells(3).RowSpan + 1
End If
gvPreviousRow.Cells(1).Visible = False
gvPreviousRow.Cells(2).Visible = False
gvPreviousRow.Cells(3).Visible = False
End If
End If
Next
End Sub
I just found a solution. Code have to be moved from RowDataBound to OnDataBound instead

Multiple record increase by one

I have this code to access:
Option Compare Database
Public Sub batchAdd(records As Integer)
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim i As Integer
Set db = CurrentDb
Set rs = db.OpenRecordset("tblMeters")
i = 1
Do While i <= records
rs.AddNew
rs!value1 = Me.value1
rs!Ticket = Me.Ticket
rs!value2 = Me.value2
rs!value3 = Me.value3
rs!value4 = Me.value4
rs!value5 = Me.value5
rs!value6 = Me.value6
rs!value7 = Me.value7
rs.Update
i = i + 1
Loop
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
Private Sub cmdAddRecords_Click()
batchAdd Me.txtRecords
Me.tblMeters_sub.Requery
End Sub
My question was how to increase the ticket value of +1 for each record inserted.
Example: If I insert the ticket with a value of 1 to 10 times, the first time will be 1 and the second 2, then 3 .... how do I change this code for the ticket value?
Adjust this line to:
rs!Ticket = i

Can I use the ID of a control as parameter to subroutine in ASP using VB?

I have a page that has many (100+) fields that are all similar in their function. When the page is displayed, a value read from a database for each field will be checked to determine the display properties of the field and a couple of related fields. see code example.
If fieldvalue = 2 Then
Myfield.visible = False
Myfieldx.Checked = False
Myfieldz.visible = True
ElseIf fieldvalue = 1 Then
Myfield.visible = True
Myfieldx.Checked = True
Myfieldz.visible = False
Else
Myfield.visible = True
Myfieldx.Checked = False
Myfieldz.visible = False
End If
Each field has identical testing done. Each group of fields also has a fixed naming convention so that I can potentially use a subroutine to do this.
Fieldname, fieldname+x, fieldname+z
The code above works great but it is a lot of code to replicate for that many fields (each with a different ID). I would like to simplify the above code use a routine to do this testing. Something like
Protected Sub CheckStatusLoad(ByVal fieldID As String, ByVal fieldvalue As Integer)
Dim fieldIDx As String, fieldIDz As String
fieldIDx = String.Concat(fieldID, "x")
fieldIDz = String.Concat(fieldID, "z")
Dim Mainfield As New WebControls.Button
Dim MainfieldChkBox As New WebControls.CheckBox
Dim MainfieldStrike As New WebControls.Button
Mainfield = DirectCast(Page.FindControl(fieldID), WebControls.Button)
MainfieldChkBox = DirectCast(Page.FindControl(fieldIDx), WebControls.CheckBox)
MainfieldStrike = DirectCast(Page.FindControl(fieldIDz), WebControls.Button)
If fieldvalue = 2 Then
Mainfield.Visible = False
MainfieldChkBox.Checked = False
MainfieldStrike.Visible = True
ElseIf fieldvalue = 1 Then
Mainfield.Visible = True
MainfieldChkBox.Checked = True
MainfieldStrike.Visible = False
Else
Mainfield.Visible = True
MainfieldChkBox.Checked = False
MainfieldStrike.Visible = False
End If
End Sub
Then call this for each field being loaded
CheckStatusLoad("fieldname", testval)
This code now works using FindControl. I just needed to play around with the syntax to get the quotes adjusted properly.
The code above has been edited so that it now works. It took me a while to understand Page.FindControl, but once I got the proper syntax it worked just fine.

VB.net For Loop to capture data from multiple controls (CheckBoxList Items)

I have two CheckBoxList controls (chkListVideoMedia and chkListAudioMedia) on my page that I want to capture information from and insert the records into the database. I have it working for one of the controls, I just need help modifying my code below to include the second CBL
Dim values As New ArrayList()
For counter As Integer = 0 To chkListVideoMedia.Items.Count - 1
If chkListVideoMedia.Items(counter).Selected Then
MyTextBox.Text = chkListVideoMedia.Items(counter).Value
values.Add(newId)
End If
Next
If values.Count > 0 Then
For item As Integer = 0 To values.Count - 1
If item = 0 Then
MyMedia1.Text = values(item).ToString
End If
If item = 1 Then
MyMedia2.Text = values(item).ToString
End If
If item = 2 Then
MyMedia3.Text = values(item).ToString
End If
If item = 3 Then
MyMedia4.Text = values(item).ToString
End If
Next
End If
Thanks,
James
You can find out which Collection has the most Items, then check to make sure that count is not greater than the maximum Items in each collection. Something like this.
Dim values As New ArrayList()
Dim counter As Integer
If chkListVideoMedia.Items.Count > chkListAudioMedia.Items.Count Then
counter = chkListVideoMedia.Items.Count - 1
Else
counter = chkListAudioMedia.Items.Count - 1
End If
For x = 0 To counter
If Not (counter > chkListVideoMedia.Items.Count - 1) Then
'Do your work here
End If
If Not (counter > chkListAudioMedia.Items.Count - 1) Then
'Do your work here
End If
Next

Resources