Setting the value of a variable in Visual BASIC - vb.net

Hi i'm new in programming world and I've started my programming by Visual BASIC. I'm trying to set a value of a variable through the program closing event and load the same value in program load event. As example:
At first I tried:
Dim Age as Integer
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
Age = 50
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Textbox1.text = Age
End Sub
But when I close the program and restart it, it resets to zero.
Next I tried "Settings" from properties but if I move my program from one location to another then it also resets everything.
Finally I tried Stream readers and writers to catch the final value but for this I had to attach some text files to the programs which I don't want. Can anyone help me how to solve the following problem with custom class libraries or by something else?

All the variables that you have are run time variables. What that means is it will only have value till your program is running.
If you want to store the data taken from user, you store it in database. You can use any kind of database and connect it to your program, store everything in there. You can also retrieve the values from database to use in system when you restart your program.
If you are new to programming and trying to learn visual basic, start with basic concepts or pick up a book that start with basics. Once you know the basics of programming, you can read about connecting program to database.

The value of age is never going to remain static when the application is shut down unless you keep it in the application settings or some sort of flat file, database etc. The initial value could be set in the application when the form opens or from at static value in application settings, but unless you store the value somewhere other than memory, it will not persist.

What you can do is create a form called module1.vb . in this form declare and set your variables . . .
Example
Public Age As Integer = 50

Related

Needing Assistance with vb.NET Application

I don't normally post on forums because I try to find information for myself, and ask as an absolute last resort. I've tried scouring the net for answers, but I'm only receiving about half of the answer I'm looking for.
I'm currently building an application that deals with state law. There's one combo box and one text box. One for the offense title, and one for the numerical code for that particular code section. So say if I select "Kidnapping", it prepopulates the text box below it with "11-5-77", for example.
The method I've been using for, oh, about the last hour now, is:
If AWOffenseTitle.Text = "Kidnapping" Then
AWCN.Text = "11-5-77"
ElseIf AWOffenseTitle.Text = "False Imprisonment" Then
AWCN.Text = "11-5-78"
With AWOffenseTitle being the combo box name, and AWCN being the text box name. While this has proved to work perfectly well so far, I'm sure you can imagine with hundreds of offense titles, this is going to take a ridiculously long time. Well, I finally found a spreadsheet with offense titles and their respective title codes. What I'm looking to do is create two text files within a folder in the local directory "Offenses". One with a vertical list of offenses, and one with a vertical list of offense code numbers that populate the same lines in each. What I'm looking to do is populate the combo box with the contents of text file one (which I can do already), but then selecting an offense title will read the second text file and display it's proper title code. That's what has me at a loss. I'm relatively well-versed with vb.NET, but I'm not an expert by any means.
I'm hoping someone here will be able to provide a code example and explain it to me line-by-line so I can gain a better understanding. I want to get more proficient with VB although it's not so popular anymore. I've been using VB since 6.0, but not on a regular basis. More on a sporadic project kind of basis.
I really appreciate any assistance anyone might be able to provide, and if you need more information, I'd be glad to answer any questions. I tried to be as thorough as I could.
Thank you in advance!
First, you need to retrieve your data. I demonstrated using an Sql Server database containing a table named Offenses with columns named OffenseTitle and OffenseCode. You will have to change this code to match your situation.
Private Function GetOffenseData() As DataTable
Dim dt As New DataTable
Using cn As New SqlConnection("Your connection string"),
cmd As New SqlCommand("Select OffenseTitle, OffenseCode From Offenses;")
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
Return dt
End Function
As the Form loads, set the properties of the ComboBox. DisplayMember matches the name of the title column and ValueMember is the name of the code column.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dt = GetOffenseData()
ComboBox1.DisplayMember = "OffenseTitle"
ComboBox1.ValueMember = "OffenseCode"
ComboBox1.DataSource = dt
End Sub
Then when the selected item in the combo changes, just set the .Text property of TextBox to the SelectedValue in the combo and your code appears.
Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
TextBox1.Text = ComboBox1.SelectedValue.ToString
End Sub
There are other ways to do this if your data source is other than a database. Please advise if you need additional help.
In addition to HardCode's comment and Mary's detailed answer, I can only add an answer that's somewhere in between them.
It might be the case, that the information is not taken from a database, but from another source, like a text/data file or a web service. So it might be useful to create an abstraction for the data source you actually use.
First, I create a class or struct that will hold the data for each combo box item.
Class Offense
Public ReadOnly Property Title As String
Public ReadOnly Property Code As String
Public Sub New(title As String, code As String)
Me.Title = title
Me.Code = code
End Sub
End Class
Next, you need a method that retrieves a list of offenses that you can bind to your combo box. It's entirely up to you how you fill/fetch the offenses list. I have simply hard coded your two values here.
Private Function GetOffenseData() As List(Of Offense)
Dim offenses As New List(Of Offense)
offenses.Add(New Offense("Kidnapping", "11-5-77"))
offenses.Add(New Offense("False Imprisonment", "11-5-78"))
Return offenses
End Function
At a certain moment (probably in your form's Load event handler), you need to initialize your combo box. Just like Mary did, I use data binding.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AWOffenseTitle.DropDownStyle = ComboBoxStyle.DropDownList
AWCN.ReadOnly = True
AWOffenseTitle.DisplayMember = NameOf(Offense.Title)
AWOffenseTitle.ValueMember = NameOf(Offense.Code)
AWOffenseTitle.DataSource = GetOffenseData()
End Sub
Note that I use the NameOf operator to get the desired property names of the Offense class. If you ever decide to rename the properties of your Offense class, you will be able to easily detect where they are used, since the compiler will complain if your code still uses the wrong property names somewhere.
Finally, the app needs to react to combo box value changes, so that the text box will show the corresponding offense code. Mary used an event handler for the SelectionChangeCommitted event, but I use a handler for the SelectedIndexChanged event instead:
Private Sub AWOffenseTitle_SelectedIndexChanged(sender As Object, e As EventArgs) Handles AWOffenseTitle.SelectedIndexChanged
AWCN.Text = AWOffenseTitle.SelectedValue
End Sub
(Up to now, I was not aware of the SelectionChangeCommitted event of the ComboBox control. I will need to look into this event to see if it is actually a better choice for this scenario, but I found that the SelectedIndexChanged event does the job just fine, so for now I sticked with that event, since I am more familiar with it.)

Vending Machine Project VB: Money Not Displaying As I Would Like

I'm making a vending machine project in VB and am fairly new to VB. I'm using Visual Studio 2017. Every time I click a button, I want the money to add up in the textbox.
For example, if I click the button 10p once, and then click it again I would want the textbox to display 20p.
I have tried using += in Visual basic but it doesn't work. I've tried googling solutions but I can't seem to find any, so as always, this is my last resort.
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click​
Dim total_money As Integer​
Dim clicks As Integer​
Const pence_sign As String = "p"​
​
clicks += 1​
​
txtMoneyDisplay.Text = (10 * clicks) & pence_sign​
I have no error messages which I can't fix.
But if I click 10p twice it won't show as 20p it will keep on showing as 10p, no matter how many times I click, how can I fix this?
The fix you should apply is moving this line Dim clicks As Integer to be outside of the function Sub Button1_Click making it a member variable instead of a local variable.
Example:
Public Class Form1
Dim clicks As Integer
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click​
Dim total_money As Integer​​
Const pence_sign As String = "p"​
clicks += 1​
txtMoneyDisplay.Text = (10 * clicks) & pence_sign
Simple Further explanation
Local variables will be re-created each time the function is fun. They will be assigned either the default value (in the vase of Integers, this will be 0 (Zero)) or whatever value you initialise them to.
Moving the declaration to be outside of the function turns them in to Member Variables. Member variables hold their value as long as the class containing them (and the Object referencing the class) remains in existence. In this case, the Form class will remain in existence while the form is displayed. The member variable will be reset when the class is re-created (or the Form is re-displayed)
Additional
You may want to include a button to return the customer money to them, in code for your app, this would translate to a function that will set the clicks member variable to 0. This is the same as re-initialising the member variables, resetting your applications state to the same as when it first loaded.
This is an MSDN article that may help you: Variable Declaration in Visual Basic

Saving Database issue

So basically, I believe I am using the correct code yet the database will still not update. It will work for the current session, however, when I stop and restart the program, it appears that the data has not been updated in the database.
The really interesting part is that I am using the same method to update the database elsewhere, which when used and session restarted, the database has been updated.
p.s. I also have the same adapters and binding sources set up etc on both forms
I am so confused, help pls
Code that I believe is correct but is not working: (updating on another form so I have one place where all forms update hence FRMMain. etc)
Private Sub btnConfirm_Click(sender As Object, e As EventArgs) Handles btnConfirm.Click
Dim CurrentPoints As Integer
Dim UpdatedPoints As Integer
CurrentPoints = FRMMain.MyDBDataSet.Tables("TBLPupil").Rows(looopcount)(15)
UpdatedPoints = CurrentPoints + stfPoints
FRMMain.MyDBDataSet.Tables("TBLPupil").Rows(looopcount)(15) = UpdatedPoints
FRMMain.TBLPupilTableAdapter.Update(MyDBDataSet.TBLPupil)
FRMMain.TBLPupilTableAdapter.Fill(MyDBDataSet.TBLPupil)
End Sub
Code that I am using in another form that that DOES work:
Private Sub BtnYes_Click(sender As Object, e As EventArgs) Handles BtnYes.Click
Dim Points As Integer = FRMPupil.Pointss
Dim Cost As Integer = FRMPupil.RewardCost
Points = Points - Cost
FRMPupil.LePoints = Points
MyDBDataSet.Tables("TBLPupil").Rows(FRMLogin.DBLocation)(15) = Points
FRMMain.TBLPupilTableAdapter.Update(MyDBDataSet.TBLPupil)
FRMMain.TBLPupilTableAdapter.Fill(MyDBDataSet.TBLPupil)
Me.Hide()
End Sub
My code is correct but is not working.
No, if it is not working, then it is not correct!
There are different things you can do: DRY, Dont Repeat Yourself. You are repeating the code for updating points at several places in your code. This is error prone. Write it once and re-use it, e.g. by applying the the Repository Pattern. It makes it easier to detect errors and correct them. It allows you to re-use code that has already been tested in other scenarios (on another form).
Debug, debug, debug. Place breakpoints in the not working methods and see what happens. Do all the variables have the expected values? E.g., does looopcount have the same value as FRMLogin.DBLocation? There must be a difference somewhere. See: Navigating through Code with the Debugger or the more recent article Debug your Hello World application with Visual Studio 2017.

How do you launch an .exe in a VB.net application who's directory varies amongst users?

I am creating an application for an Arma 3 server that directly launches the game and connects the user to a specific server. The problem that I am encountering, being the relatively new VB coder that I am, is that the Arma3battleye.exe directory (the .exe used to launch the game) may be installed in different directories depending on where the user originally installed it. I've developed the code to connect the user to the server if they've installed Arma in the normal location:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Process.Start("C:\Program Files (x86)\Steam\steamapps\common\Arma 3\arma3battleye.exe", "2 1 -noSplash -skipIntro -useBE -noPause -world=empty -connect=192.99.36.80 -port=2505 -mod=#Exile;#AlRayak;#AllInArmaTerrainPack;#CUP Units;#CUP Vehicles;#CUP Weapons;#CBA_A3;#TRYK's Multi-Play Unifrom's pack")
End Sub
However, after researching for many hours, I cannot determine how to have the program automatically determine the install directory of the arma3batteye.exe and then execute it with all of the correct start parameters included. Any solutions or pointers to help solve this problem would be greatly appreciate.
TLDR: What is the easiest way to program an application to automatically find the install directory of a given .exe and then execute it with the given parameters as I've done above?
Edit: Another thread similar to mine asks a similar question (how to view/get to the steam folder without hard coding it. They arrive at the conclusion that if you do (for winx32):
Dim strSteamInstallPath as String = My.Computer.Registry.GetValue(
"HKEY_LOCAL_MACHINE\SOFTWARE\Valve\Steam", "InstallPath", Nothing)
Or using this registry location for winx64:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Valve\Steam
and then were to create a button using Process.Start that it would allow you to ultimately view the directory. At this point I haven't discovered a way for that to translate into being able to execute the battleyearma3.exe from within that steam directory with the proper parameters. While it seems this code may be useful in arriving at the solution I'm looking for, I can only get the program to view the general steam directory at this time.
edit: Solution posted at bottom. Thanks to #VisualVincent who was really the one that allowed me to complete this. It really should be you having posted the correct answer, not me.
I would use the registry...
You add a key like HKEY_LOCAL_MACHINE\Software\Arma3\ServerPath = "..." when you install the server.
And whenever you need to start the client, you check up the path from that registry key.
So with the comments and tips you gave me (especially #VisualVincent) I managed to piece enough stuff together to solve my issue. Thanks to everyone for the help:
First I declared 2 variables. The first one (BattleyePath) goes into the registry as far as I can get it to dig. Executing this variable on its own will open the users steam directory. I then declared a second variable (BattleyePath2) which uses IO.Path.Combine get to the directory the users Arma3.exe is installed in:
Dim BattleyePath As String = My.Computer.Registry.GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Valve\Steam", "InstallPath", Nothing)
Dim BattleyePath2 As String = IO.Path.Combine(BattleyePath, "SteamApps", "common", "Arma 3", "arma3battleye.exe")
I added a couple buttons to close the program and mute the sound:
`Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Me.Close()
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
My.Computer.Audio.Stop()
End Sub`
Finally I created the button that actually launches the game:
`Private Sub Button4_Click_1(sender As Object, e As EventArgs) Handles Button4.Click
Process.Start(BattleyePath2, "2 1 -noSplash -skipIntro -useBE -noPause -world=empty -connect=192.99.36.80 -port=2505 -mod=#Exile;#AlRayak;#AllInArmaTerrainPack;#CUP Units;#CUP Vehicles;#CUP Weapons;#CBA_A3;#TRYK's Multi-Play Unifrom's pack")
End Sub`

How to handle unexpected shut down of vb.net application

I'm developing VB.Net application and i wanted to block users from open another session of the program while they already has one
so i made a value in my DB that changes from Offline to Online and reverse according to the status of the log in
Program Started = Online (In Form Load Event)
Program Closed = Offline (In Form Closing Event)
The problem is : some times the program hang or windows ..... etc so the program don't change the DB value for that user from Online to Offline and this prevent him from opening the application
so how i can handle the unexpected shut down of my program to deal with this case?
you could simply use the built in functionality Single instance application by clicking on your project and on application check Make Single instance application as the screen shot shows
I think you're talking about user session management here. If I understand you correctly, you want to stop any one user from logging in to two instances at the same time rather than there being two copies of your application open at one time (obviously with different users logged into each). If this is the case then it isn't actually that difficult to implement something very basic.
When your user logs on, perform a check to see if they already have a record in your session table. If not, then create one and issue that user with the session id. This id must then be supplied during all operations so that you can check it is valid. So far, so good.
If there is already a record in that session table then invalidate it (delete it, change the status - whatever) so that the old session id can't be used and issue a new one. That way, if your user already has a logged in copy of the app open then start another, the first one will no longer actually do anything useful (don't forget to inform users that an invalid session id is the reason why they can't do anything).
Obviously you will need to persist that session id for the life of the application, but for the love of all that is good, don't put it in a global variable: Pass it as part of the constructor to any object you instantiate which will perform any DB actions. Maybe even wrap it in a class of it's own if you need functionality and that variable or object can be private to your main class.
For example, lets say your main class is a form called frmMain which spawns a login dialog when it starts to capture username and password:
Public Class SessionManagerClass
_dal As New DAL
Private _sessionId As Int
Private _userName As String
Public Sub New(ByVal UserName As String, ByVal Password As string)
_sessionId = _dal.Login(UserName, Password)
End Sub
End Class
Partial Class frmMain
Private _session As SessionManagerClass
Public Sub frmMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim loginForm As New dlgLogin
loginForm.ShowDialog()
_session = New SessionManagerClass(loginForm.UserName, loginForm.Password)
loginForm.Dispose()
End Sub
Public Sub btnLaunchChildForm_Click(ByVal sednder As Object, ByVal e As EventArgs) Handles btnLaunchChildForm.Click
Dim frm As New frmChildForm(_session)
frm.ShowDialog()
End Sub
End Class
Partial Class frmChildForm
_session As SessionManagerClass
_dal As New DAL
Public Sub New(ByVal Session As SessionManagerClass)
_session = Session
End Sub
Private Sub DoSomething()
If _dal.SaveValues(_session.SessionId, Value1, Value2, Value3) Then
'All Good
Else
'Something went wrong. Maybe invalid session ID or perhaps you didn't validate your data. Whatever. Handle the problem if you can.
End If
End Sub
End Class
This is in no way working code, just an example of how you might go about it to get you started.
You should attempt to remove the lock from the database when your application exits, but you can't stop someone going into task manager and ending the process. In this case your application does not get any notification of a shutdown and so can't write to the database.
We handle this occurrence by getting users to request an unlock code a secret code which allows them to clear the logged in flag. The unlock code changes each day so if they want one tomorrow they have to ask for another one.
Review your entire approach: you can use the Process class instead.
Dim list() As Process = Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName)
If list.Length > 1 Then
Application.Exit()
End If
Well,
I've created a new solution
another field should be created with name currentsession
when the user open the program it takes a number
and when UN-expected shutdown occur i made a patch to change the current status to offline and the session id to the next number
then I've created a check sub in each save button to check for the current session and if it matches the one in the database it will continue
and if not it will shutdown the program