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

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.

Related

Access - Strange Error with Date Function

This is a strange bug and I feel like I'm missing something easy.
When I use the standard access date function on one form it works without issue (see 'functions properly'). When I use it on another form (see 'code causing error') I get a debug error 'Database can't find the field 'Date' referred to in your expression.'
Hoping someone else sees a stupid/obvious mistake...
Functions properly:
With rs
.AddNew
If chkSubAssembly = True Then
.Fields("Document") = mySubassembly
.Fields("Type") = "S"
Else
.Fields("Document") = "M" & cmbCustomer & "-" & txtCustPN
.Fields("Type") = "D"
End If
.Fields("Description") = txtDMRDesc
.Fields("Author") = Forms("frmUser").lblUser.Caption
.Fields("CreationDate") = date
.Fields("Revision") = "Draft"
.Fields("PE") = cmbPE.Column(1)
.Fields("lasteditby") = Forms("frmUser").lblUser.Caption
.Update
End With
Code Causing Error:
With rs
.AddNew
.Fields("ValidNum") = myProtocol
.Fields("Description") = txtNewDescription
.Fields("Author") = Forms("frmUser").lblUser.Caption
.Fields("createdOn") = date
.Fields("lasteditby") = Forms("frmUser").lblUser.Caption
.Update
End With

Arrays and variables clears itself after a end sub in VB.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.

Trying to make a group of fields required on combobox selection in Access 2010

In Access 2010.
I have 3 separate groups of fields that can be active based on a combobox selection but I'm trying to get them to be required as well. I've looked everywhere but it doesn't appear to be any VB code to make a field required. Is there anyway I can accomplish this?
The code I have right now to make the selected group of fields active and make the one's not selected blank:
Private Sub Combo109_Click()
If Combo109 = "Germ" Then
cg_moisture.Enabled = True
cg_oil_nir.Enabled = True
extraneous_material.Enabled = True
fines.Enabled = True
cg_moisture.Enabled = True
cg_oil_nir.Enabled = True
extraneous_material.Enabled = True
fines.Enabled = True
Moist_cgm_nir.Enabled = False
prot_cgm_nir.Enabled = False
oil_cgm_nir.Enabled = False
meal_color.Enabled = False
load_out_temp.Enabled = False
moist_cgf_nir.Enabled = False
prot_cgf_nir.Enabled = False
oil_cgf_nir.Enabled = False
profat_nir.Enabled = False
starch_nir.Enabled = False
total_sug_nir.Enabled = False
loadout_temp.Enabled = False
screen_thrus.Enabled = False
screen_thrus.Value = ""
Moist_cgm_nir.Value = ""
prot_cgm_nir.Value = ""
oil_cgm_nir.Value = ""
meal_color.Value = ""
load_out_temp.Value = ""
moist_cgf_nir.Value = ""
prot_cgf_nir.Value = ""
oil_cgf_nir.Value = ""
profat_nir.Value = ""
starch_nir.Value = ""
total_sug_nir.Value = ""
loadout_temp.Value = ""
screen_thrus.Value = ""
screen_thrus.Value = ""
End If
IF all of the controls are in the 'Detail' section of your form, AND if a contrtol is Enabled, you require a value, then the code below should work. If you want more meaningful names to be displayed, either change your control names, or place a better name in the control 'Tag' field and reference that. The following code only checks Textboxes and CheckBoxes - modify to suit your needs.
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim ctl As Control
Dim blnMissing As Boolean
Dim strMissing As String
For Each ctl In Me.Section("Detail").Controls
If ctl.ControlType = acTextBox Or ctl.ControlType = acCheckBox Then
If ctl.Enabled = True Then
'Debug.Print ctl.Name & vbTab & ctl.Value
If ctl.Properties("Enabled") = True Then
If Me(ctl.Name) = "" Or IsNull(Me(ctl.Name)) Then
blnMissing = True
strMissing = strMissing & ctl.Name & "; "
End If
End If
End If
End If
Next ctl
If blnMissing = True Then
MsgBox "You are required to enter data in fields: " & strMissing, vbOKOnly + vbCritical, "Missing Required Data"
Cancel = True
End If
End Sub

Most efficient way to validate multiple textboxes against a tolerance value

I have a series of text boxes in a table to gather input as below:
The user will input a target and actual value for each measurement point they require. I would then like to validate the actual values against the target values based upon the tolerance inputted in the tolerance textbox. The tolerance will be the same for all measurement points inputted, however the user will not always input all 10 measurement points.
I have also created a very basic class containing a function that accepts the target, actual and tolerance values then returns a Boolean depending on whether the actual value is within tolerance. I realise I could use this with a ruck load of if statements to check each textbox for input then use the class to perform the validation, however this seems like a lot of code repetition and a bit crude. My question being is there a better way I can perform this validation?
EDIT Class content
Public Class TolerenceHelper
Public Function IsInTolerence(ByVal target As Integer, ByVal actual As Integer, ByVal tolerence As Integer) As Boolean
Dim upper As Integer = target + tolerence
Dim lower As Integer = target - tolerence
If actual < lower OrElse actual > upper Then
Return False
Else
Return True
End If
End Function
Calling the function as below:
Dim m1 As TolerenceHelper
Dim flag As Boolean = True
m1 = New TolerenceHelper
If m1.IsInTolerence(Integer.Parse(txtT1.Text), Integer.Parse(txtA1.Text), Integer.Parse(txtTolerance.Text)) = False Then
flag = False
End If
If flag = False Then
lblTest.Text = "Out of tolerance"
Else
lblTest.Text = "In tolerance"
End If
Your helper method seems to be ok, but you haven't shown the important part that you want to improve. The part where you load all textboxes and check whether they are valid or not.
Here is an approach that uses a custom class Measurement. You can use
Math.Abs(target.Value - actual.Value) <= tolerance
to determine if the value is valid according to the target and the tolerance.
Public Class Measurement
Public Property Tolerance As Int32
Public Property Target As Int32
Public Property Value As Int32
Public ReadOnly Property IsValid As Boolean
Get
Return Math.Abs(Target - Value) <= Tolerance
End Get
End Property
End Class
I would add all textboxes into the same container control like a Panel. Then you could use Enumerable.OfType to find the relevant textboxes. I use Enumerable.Zip to bring the values and the targets together. Use Int32.TryParse to validate the text.
Dim tolerance As Int32
If Not Int32.TryParse(txtTolerance.Text, tolerance) Then
lblTest.Text = "Enter a valid tolerance! Tolerance must be a positive integer(incl. zero)."
Return
End If
Dim value As Int32
Dim allTxtTarget = From txt In Me.PnlMeasurement.Controls.OfType(Of TextBox)()
Where txt.ID Like "txtT#*" AndAlso Int32.TryParse(txt.Text, value)
Let x = New With {.TextBox = txt, .Value = value, .Type = "Target", .Number = txt.ID.Substring(4)}
Order By x.Number
Select x
Dim allTxtActual = From txt In Me.PnlMeasurement.Controls.OfType(Of TextBox)()
Where txt.ID Like "txtA#*" AndAlso Int32.TryParse(txt.Text, value)
Let x = New With {.TextBox = txt, .Value = value, .Type = "Value", .Number = txt.ID.Substring(4)}
Order By x.Number
Select x
Dim allMeasurements = allTxtTarget.Zip(allTxtActual,
Function(target, actual) New Measurement With {
.Tolerance = tolerance,
.Target = target.Value,
.Value = actual.Value
}).ToList()
Output the results:
For i As Int32 = 0 To allMeasurements.Count - 1
Dim m = allMeasurements(i)
Console.WriteLine("Measurement {0}: Tolerance:{1} Target:{2} Value:{3} Valid:{4}",
i+1, tolerance, m.Target, m.Value, m.IsValid)
Next
If you actually need to check if all or at least one measurement is valid you can use:
Dim allValid = allMeasurements.All(Function(m) m.IsValid)
Dim anyValid = allMeasurements.Any(Function(m) m.IsValid)
or to find the highest valid measurement:
Dim validMeasurements = From m In allMeasurements
Where m.IsValid
Order By m.Value Descending
Dim highestMeasurement = validMeasurements.FirstOrDefault()

Search for multiple keywords using LINQ vb

I have some existing code that I need to modify to search more than one keyword. (I am new to all this by the way)
Dim topics As IQueryable(Of Global.Platform.Core.Data.Topic) = _
From t In _db.Topics
Where t.IsActive = True And t.TopicTitle.Contains(criteria) And t.ForumID = 0 And Not t.TopicTitle.Contains("default") And t.Member.IsActive = True And t.IsActive = True
Order By t.DateCreated Descending
Select t
Take (take_x)
Return topics
How would i go about changing this so if I entered criteria "cat hair" it would do an OR search. so ...t.TopicTitle.Contains("cat") OR t.TopicTitle.Contains("hair") ....
Of course it would need to be dynamic.
I tried this but could not get it to work.
Dim criteriaArr As Array = criteria.Split(" ")
Dim new_criteria As String = " t.TopicTitle.Contains(" + criteriaArr(0) + ")"
If criteriaArr.Length > 1 Then
For Each item As String In criteriaArr
new_criteria += " Or t.TopicTitle.Contains(" + item + ")"
Next
End If
The idea was to split the spaces and keep appending to the where clause. I know in SQL this might have worked, but how would I go about in this scenario?
You can use a combination of .Any and .Contains:
var strings = new List<string> { "cat", "dog", "bill" };
using (var context = new MyEntities())
{
var matches = context.MyObject.Where(x => strings.Any(s => x.TopicTitle.Contains(s)));
}
VB:
Dim strings = {"cat", "dog", "bill"}
Using context = New MyEntities()
Dim matches = context.MyObject.Where(Function(x) strings.Any(Function(s) x.TopicTitle.Contains(s)))
End Using
This is taking the strings list of query words, and checking to see if there are any of them that the TopicTitle contains.
Sorry, that's in C#, but you can see how to do the lamda expression in the .Where. Just send in a List to your method that does the query, and you're good to go.
Assuming TopicTitle and the criteria are space delimited strings I would intersect the two collections and check if there were any matches.
Dim topics As IQueryable(Of Global.Platform.Core.Data.Topic) = _
From t In _db.Topics
Where t.IsActive = True And t.TopicTitle.Intersect(criteria).Any()
And t.ForumID = 0 And Not t.TopicTitle.Contains("default")
And t.Member.IsActive = True And t.IsActive = True
Order By t.DateCreated Descending
Select t
Take (take_x)
Return topics

Resources