Retrieve a values from a different table in access vba - vba

I have a form in access and the final price is the result of certain combinations. I attach the code and the values that I multiply are put in the code directly.
Option Compare Database
Private Sub BOLETA_BeforeUpdate(Cancel As Integer)
End Sub
Private Sub CANTIDAD_BeforeUpdate(Cancel As Integer)
End Sub
Private Sub CLINICA_LostFocus()
If Me.CLINICA.Value = 400 Then
If Me.EXAMEN.Value = 10 Then
Me.PRECIO.Value = Me.CANTIDAD.Value * 45000
End If
If Me.EXAMEN.Value = 11 Then
Me.PRECIO.Value = Me.CANTIDAD.Value * 30000
End If
End If
End Sub
I would like to put the prices in a table so that I can modify it whenever I want without having to touch the code. Is this possible? Thanks!!!!

Related

VB.NET Random unique generator

I'l trying to generate a unique random number generator with the snippet of code from below, but it's not working. The IF section is suppose to test if it's the first random number generated, if it is, it's suppose to add the first random number to the ArrayList, if it's not the first random number, it's supposed to check if the random number is already in the ArrayList and if it's in the ArrayList it's suppose to MsgBox and generate a new unique random number that is not already in the ArrayList and add it to the ArrayList, but it's not doing any of those. Any help would be greatly appreciated.
Public Class Form1
Dim r As New Random
Dim dLowestVal As Integer = 1
Dim dHighestVal As Integer = 26
Dim dItemAmount As Integer = 1
Dim RollCheck As New HashSet(Of Integer)
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
End
End Sub
Private Sub btnRollDice_Click(sender As Object, e As EventArgs) Handles btnRollDice.Click
lblRandomNo.Text = r.Next(dLowestVal, dHighestVal)
lblItemAmount.Text = dItemAmount
If dItemAmount = 1 Then
RollCheck.Add(Val(lblRandomNo.Text))
ElseIf (RollCheck.Contains(Val(lblRandomNo.Text))) Then
MsgBox("Already Exists")
lblRandomNo.Text = r.Next(dLowestVal, dHighestVal)
RollCheck.Add(Val(lblRandomNo.Text))
End If
dItemAmount = dItemAmount + 1
Thanks in advance.
You could replace your whole method with this simple one
' This is globally declared at the top of your form
Dim values As New List(Of Integer)
' This is called when you construct your form
' It will store consecutive integers from 1 to 25 (25 elements)
values = Enumerable.Range(1, 25).ToList()
This is the method that extract an integer from your values that is not already used
Private Sub Roll()
' Get an index in the values list
Dim v = r.Next(0, values.Count)
' insert the value at that index to your RollCheck HashSet
RollCheck.Add(values(v))
' Remove the found value from the values list, so the next call
' cannot retrieve it again.
values.Remove(values(v))
End Sub
And you can call it from the previous event handler in this way
Private Sub btnRollDice_Click(sender As Object, e As EventArgs) Handles btnRollDice.Click
if values.Count = 0 Then
MessageBox("No more roll available")
else
Roll()
End Sub
End Sub
The point of the HashSet is that since it doesn't allow duplicates you can just check the return value of Add() to determine whether the number was successfully inserted or if it already exists in the list.
If you want to keep trying until it succeeds all you have to do is wrap it in a loop:
If dHighestVal - dLowestVal >= RollCheck.Count Then
'If the above check passes all unique values are MOST LIKELY already in the list. Exit to avoid infinite loop.
MessageBox.Show("List is full!")
Return 'Do not continue.
End If
Dim Num As Integer = r.Next(dLowestVal, dHighestVal)
'Iterate until a unique number was generated.
While Not RollCheck.Add(Num)
MessageBox.Show("Already exists!")
Num = r.Next(dLowestVal, dHighestVal)
End While
lblRandomNo.Text = Num
An alternative way of writing the loop is: While RollCheck.Add(Num) = False.

Need to know why code is repeating itself

Public Class Form1
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim EvenNum, EvenNumCount, EvenNumAverage, Number, Result As Integer
Calculations(EvenNum, EvenNumCount)
GetInput(Number)
Output(Result)
End Sub
Sub GetInput(ByRef Number)
Number = txtInput.Text
End Sub
Sub Calculations(ByRef EvenNum, ByRef EvenNumCount)
Dim ListedNumbers, lstOutputSize As Integer
GetInput(lstOutputSize)
For i As Integer = 0 To lstOutputSize - 1
ListedNumbers = InputBox("Enter Numbers", "Input")
lstOutput.Items.Add(ListedNumbers)
Next
For i As Integer = 0 To lstOutput.Items.Count - 1
If (CInt(lstOutput.Items(i)) Mod 2 = 0) Then
EvenNum += lstOutput.Items(i)
EvenNumCount += 1
End If
Next
End Sub
Function Average(ByRef EvenNumAverage As Integer) As Integer
Dim EvenNum, EvenNumCount As Integer
Calculations(EvenNum, EvenNumCount)
EvenNumAverage = EvenNum / EvenNumCount
Return EvenNumAverage
End Function
Sub Output(ByRef EvenNumAverage)
lstOutput.Items.Add(Average(EvenNumAverage))
End Sub
The program is supposed to get input from a textbox for a desired number of numbers to be entered into a listbox from inputboxes.
It is then supposed to get the average of only the even numbers and then display that average into the listbox.
In it's current state the program will do what it is intended to do, it just repeats the calculation code. This only happens when I add the Output call statement under the button procedure.
You're calling Calculations twice
From btnCalculate_Click
From Average which is called by Output

Using a Sub Procedure to call a random number and display a string to a label

Im trying to get a random number to generate and take said random number to display a certain line of text assigned to that number to a label through a Sub Procedure.
If this is any easier:
Generate Random Number 1 Through 5
Call Random Number using Sub Procedure
Display a string to a label that is connected to that random number.
I'll show my code just so you guys know what my direction is and if it's correct.
Public Class Form1
Private Sub btnInsult_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInsult.Click
Dim strInsult As String
Dim intNumber As Integer
Randomize()
intNumber = Int((5 - 1 + 1) * Rnd() + 1)
End Sub
Sub showInsult()
End Sub
End Class
It really isn't much and I think I'm moving in the right direction. Please ask me if you need more clarification on things.
I had a similar piece of code for generating random messages.
Unlike your code above, this was written inside a form module, not a class one and prints to a text box, not a label. I am not sure whether by
Display a string to a label
you actually mean changing an actual label caption. If so, then use the showInsultEx sub instead. Here it is, adapted to your needs. I hope this helps.
Private arrInsults() As Variant
Private nInsultCount As Integer
Private Sub Insult_InitRepertoire()
'init the insult array
arrInsults = Array( _
"Insult 1", _
"Insult 2", _
"Insult 3", _
"Insult 4", _
"Insult 5")
nInsultCount = UBound(arrInsults) - LBound(arrInsults) + 1
End Sub
Private Sub showInsult()
'init the insult array if empty
If nInsultCount = 0 Then Insult_InitRepertoire
'get a random entry from the insult table
'and print it in the text field
Randomize
Me.TextBox1.Text = arrInsults(LBound(arrInsults) + Int(Rnd() * nInsultCount))
End Sub
Private Sub btnInsult_Click()
'invoke the pseudo-random inslut generator
showInsult
End Sub
Private Sub UserForm_Initialize()
'prevent user input
Me.TextBox1.Locked = True
End Sub
Private Sub showInsultEx()
Dim nId As Integer
'init the insult array if empty
If nInsultCount = 0 Then Insult_InitRepertoire
'get a random entry from the insult table
'and print it in the text field
Randomize
nId = LBound(arrInsults) + Int(Rnd() * nInsultCount)
'get a control associated with the insult number
'change its caption to the generated text
'you'll have to make sure to number the controls
'according to the array indices
Me.Controls("Label" & nId).Caption = arrInsults(nId)
End Sub

Array as structure members Assignment Student Test Scores

ASSIGNMENT
A teacher has six students and wants you to create an application that stores their grade data in a file and prints a grade report. The application should have a structure that stores the following student data: Name (a string), Test Scores (an array of five Doubles), and Average (a Double). Because the teacher has six students, the application should use an array of six structure variables.
The application should allow the user to enter data for each student, and calculate the average test score.
The user should be abled to save the data to a file, read the data from the file, and print a report showing each student's test scores and average score. The form shows a meny system. You may you buttons instead if you prefer.
Input validation: Do not accept test scores less that zero or greater than 100.
]
my understanding of how it should be structured
For the Moment I don't understand that in the FOR EACH loop I can not accumulate total it saying that I am not allowed to use + . I am trying to get scores from txtScore1Std1 (For example) assign it to dblTestScoreArray and using for each loop to find sum of those 5 score and when find average and output it to lbl average for student number 1.
Code Module:
Module StudentTestScoresModule
Const intMAX_SUBSCRIPT_STUDENT As Integer = 6
Const intMAX_SUBSCRIPT_STUDENT_SCORES As Integer = 5
'create structure
Public Structure StudentData
Dim strName As String
Dim dblTestScoresArray() As Double
Dim dblAverage As Double
End Structure
Dim dblTotalStd1 As Double
Dim dblScore As Double
Dim StudentsArray(intMAX_SUBSCRIPT_STUDENT) As StudentData
Sub StudentNameDataInput()
StudentsArray(0).strName = MainForm.txtStdName1.Text
StudentsArray(1).strName = MainForm.txtStdName2.Text
StudentsArray(2).strName = MainForm.txtStdName3.Text
StudentsArray(3).strName = MainForm.txtStdName4.Text
StudentsArray(4).strName = MainForm.txtStdName5.Text
StudentsArray(5).strName = MainForm.txtStdName6.Text
End Sub
Sub StudentScoreDataInput()
For intIndex = 0 To intMAX_SUBSCRIPT_STUDENT
ReDim StudentsArray(intIndex).dblTestScoresArray(4)
Next
'test scores for first student
StudentsArray(0).dblTestScoresArray(0) = CDbl(MainForm.txtScore1Std1.Text)
StudentsArray(1).dblTestScoresArray(1) = CDbl(MainForm.txtScore2Std1.Text)
StudentsArray(2).dblTestScoresArray(2) = CDbl(MainForm.txtScore3Std1.Text)
StudentsArray(3).dblTestScoresArray(3) = CDbl(MainForm.txtScore4Std1.Text)
StudentsArray(4).dblTestScoresArray(4) = CDbl(MainForm.txtScore5Std1.Text)
For Each i As StudentData In StudentsArray
dblTotalStd1 += i
Next
dblAverage = dblTotalStd1 / intMAX_SUBSCRIPT_STUDENT_SCORES
MainForm.lblAvgStd1.Text = (dblAverage.ToString)
End Sub
Sub CalculateAverage()
End Sub
End Module
Code Main Form:
Public Class MainForm
Private Sub mnuHelpAbout_Click(sender As Object, e As EventArgs) Handles mnuHelpAbout.Click
'about program
MessageBox.Show("Student test score calculator version 0.1")
End Sub
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
' Close(program)
Me.Close()
End Sub
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
StudentScoreDataInput()
End Sub
End Class
just by looking, without testing, what you need to do is;
'untested code
For Each i As StudentData In StudentsArray
For Each S as Double in i.dblTestScoresArray
dblTotalStd1 += s
Next
Next
you cannot do += on a structure, you need to do it on the member and since its an array, you need to loop through it

cannot read from combo box to use as a variable in a sub-routine

I am trying to have a variable input come from a combobox. i had thought it would be a simpler task but i am stuck on this and would be grateful for some help.
i am working with pre-packaged code that connects to an API, connects to a server and does stuff. I am customizing it to do a few additional calculations, all of which now work fine, but the variables i use to perform those calcs, inside of one of the sub-routines, are hard coded, and i want to be able to read them in instead using a combobox. i had done this many times using VB6 and VBA, but i am new to vb.net (2010) and even though i have the combobox on my form, every reference to the selected number in the combobox ends up with an empty result
in a simpler application, like the one below, i am able to get the data from the combo box:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim divisor As Integer
Dim res1 As Integer
If Int32.TryParse(ComboBox1.Text, divisor) Then
MsgBox(ComboBox1.Text)
Else
MsgBox("error" & ComboBox1.Text)
End If
res1 = divisor - 9
MsgBox(res1)
End Sub
End Class
Unfortunately the code i am working with is not cooperating with the code above. without posting all the code, here is the basic structure, maybe this will help you help me figure out where to write the code above so it will grab the value in the combobox where the 'divisor' in the sub13 (see below) will be the number from the combobox instead of it being hard coded
and every reference you see below to the combobox was 'auto-generated'. that is, once i placed the combobox on the form all of that code appeared.
Imports X.API
Public Class frmMain
Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
InitializeComponent()
End Sub
Protected Sub Dispose(ByVal disposing As Boolean)
End Sub
Private components As System.ComponentModel.IContainer
Friend WithEvents Panel1 As System.Windows.Forms.Panel
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.ComboBox1 = New System.Windows.Forms.ComboBox()
Me.ComboBox1.FormattingEnabled = True
Me.ComboBox1.Location = New System.Drawing.Point(710, 117)
Me.ComboBox1.Name = "ComboBox1"
Me.ComboBox1.Size = New System.Drawing.Size(121, 21)
Me.ComboBox1.TabIndex = 3
End Sub
#End Region
#Region " Member Variables "
Private mTable As DataTable
#End Region
#Region " Form and Control Events "
Private Sub frmMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub frmMain_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
End Sub
Private Sub s1()
End Sub
Private Sub s2()
End Sub
Private Sub s3()
End Sub
Private Sub s4()
End Sub
#End Region
#Region " Operations "
Private Sub s5()
End Sub
Private Sub s6()
End Sub
Private Sub s7()
End Sub
Private Sub s8()
End Sub
#End Region
#Region " API Events "
Private Sub s8()
End Sub
Private Sub s9()
End Sub
Private Sub s10()
End Sub
Private Sub s11()
End Sub
Private Sub s12()
End Sub
#End Region
Private Sub s13()
Dim divisor As Integer = 1
'[this is where i want the divisor to draw from the combobox]
'so instead of "Dim divisor As Integer = 1"
i want "Dim divisor As Integer = contents of combobox
End Sub
' i have no idea why this code appears here
Friend WithEvents ComboBox1 As System.Windows.Forms.ComboBox
Private Class Item1
Public Sub s14()
End Sub
End Class
Private Class Item2
Public Sub s15()
End Sub
End Class
Private Class Item3
Public Sub s16()
End Sub
End Class
End Class
the sub i am working on is "s13()", but when i try to read from the combobox i get a blank.
exactly where to place the code that works as shown in my first example in the structure i show immediately above is unknown to me. i would have thought it would be much easier to read from a combobox, but i am stumped.
Given the names of your functions, it's difficult to tell exactly what you're trying to do. But you have a couple of options here. The function itself can access the value from the combo box if it's called while the combo box has a value in it, or the function can require the value as a function argument and whatever calls the function can pass the combo box's value.
For the first, it would look something like this:
Private Sub s13()
Dim divisor as Int32 = 1
If Int32.TryParse(Me.ComboBox1.Text, divisor) Then
' Perform your logic
Else
' The input wasn't a valid integer, maybe show an error?
End If
End Sub
Whereas the second approach might look like this:
Private Sub s13(ByVal divisor as Integer)
' Perform your logic
End Sub
And the code which calls that would need to get the value:
Dim divisor as Int32 = 1
If Int32.TryParse(Me.ComboBox1.Text, divisor) Then
s13(divisor)
Else
' The input wasn't a valid integer, maybe show an error?
End If
The main thing to note in all of this is that you should use Int32.TryParse() to determine if the inputted value in the combo box is actually an integer, and handle the error condition when it isn't.
You have to use the selected item :
If Int32.TryParse(ComboBox1.selectedItem, divisor) Then
MsgBox(ComboBox1.selectedItem)
Else
MsgBox("error" & ComboBox1.selectedItem)
End If
for anybody stuck with the same problem, here is the solution.
the code i had to work with is mammoth, so it would not let me pull in a combobox variable into any of the subs, esp as this is a multi-threaded prog. i knew, however, the solution had to be simple. and that is always something to keep in mind -- the solution is never that complicated, and you never need as much code as you think.
in this case i went down the path of a public variable,
Public Shared divisor As Integer
i placed this line underneath the very first line
Public Class frmMain
since there were other drop-down lists on the form that were clearly being drawn from, i went to the code associated with the button that initiated the steps to get the data from the server, just another button_click sub
if that sub pulled in the other combo boxes, then it had to grab the data in the one i wanted. all i did then was add this line of code to that button_click sub
divisor = ComboBox1.Text
since divisor is now a public variable, what was recorded in the button_click sub easily passes to another private sub that runs other routines. so anywhere in the code i want to use the variable 'divisor' all i have to do is mention it :)
if divisor > 0 then
'do something
end if