Hi I'm creating a "Toilet paper tracker" on visual basic and I'm struggling with saving and reading files, I know I am missing stuff. The user should be able to login and input a threshold and when reached a warning will pop up saying "buy more toilet paper" (i haven't coded this yet) and the user can add to create a total and subtract from it too. The user should also be able to save the total to a file and I want the program to be able to read the file and change the total if the user wants to add or subtract again. It would be greatly appreciated if you pointed me in the right direction, I'm only young so it's relatively simple. Here is my program :)
Imports System.IO
Public Class frmTPT
Private Sub TPT_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Call loadchangetotal()
End Sub
Sub loadchangetotal()
cboChange.Items.Add("Add to Total")
cboChange.Items.Add("Subtract from Total")
End Sub
Private Sub cboVenue_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboChange.SelectedIndexChanged
If cboChange.Text = "Add to Total" Then
Dim frmChangeACopy As New frmChangeA
frmChangeACopy.Show()
Me.Hide()
ElseIf cboChange.Text = "Subtract from Total" Then
Dim frmChangeSCopy As New frmChangeS
frmChangeSCopy.Show()
Me.Hide()
End If
End Sub
Private Sub btnReturn_Click(sender As Object, e As EventArgs)
Dim frmLoginCopy As New frmLogin
frmLoginCopy.Show()
Me.Hide()
End Sub
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
txtThreshold.Text = ""
cboChange.Text = ""
txtTotal.Text = ""
End Sub
Private Sub ExitToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExitToolStripMenuItem.Click
End
End Sub
Private Sub LogoutToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles LogoutToolStripMenuItem.Click
Dim frmLoginCopy As New frmLogin
frmLoginCopy.Show()
Me.Hide()
End Sub
Private Sub btnReadTotal_Click(sender As Object, e As EventArgs) Handles btnReadTotal.Click
Dim FileReader As StreamReader
Dim result As DialogResult
result = OpenFileDialog1.ShowDialog
If result = DialogResult.OK Then
FileReader = New StreamReader(OpenFileDialog1.Filename)
txtFileContent.Text = FileReader.ReadToEnd() 'i want to be able to read a
'previously saved total so that
FileReader.Close() 'it can be used to find the new total
'after it has been added to
End If 'or subtratced
End Sub
Private Sub SaveToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SaveToolStripMenuItem.Click
Call SaveFile()
End Sub
Private Sub btnDisplay_Click(sender As Object, e As EventArgs) Handles btnDisplay.Click
Dim A, S, NewTotal As Integer
A = Val(frmChangeA.txtAdd.Text)
S = Val(frmChangeS.txtSubtract.Text)
NewTotal = A - S 'I want to be able to load a previously saved total if one exists and add and
'subtract from it
End Sub
End Class
Sub SaveFile()
Dim FileWriter As StreamWriter
Dim results As DialogResult
results = SaveFileDialog1.ShowDialog
If results = DialogResult.OK Then
FileWriter = New StreamWriter(SaveFileDialog1.FileName, False)
FileWriter.Write(txtFileContent.Text) ' is txtFileContent supposed to be
' the name of my textbox?
FileWriter.Close()
End If
End Sub
Design
You didn't mention if you were using .Net Core or 4.x. If the later, you can sometimes use the Insert Snippet functionality to learn how to do common tasks. For example in this case you could right click in the code editor and select Insert Snippet then Fundamentals then File System and finally Write text to a file. This will result in the following VB code:
My.Computer.FileSystem.WriteAllText("C:\Test.txt", "Text", True)
Unfortunately, this option doesn't work with .Net core since the My namespace wasn't ported to core.
The key point of this problem lies in reading and writing data from text. It is a clear idea to write two methods to achieve read and write.
You can refer to the following code. The two methods in the following example are WriteTotal(), ReadTotal().
Design:
Public Class Form1
Dim Oldtotal As Integer
Dim Newtotal As Integer
Private Sub btnLoadTotal_Click(sender As Object, e As EventArgs) Handles btnLoadTotal.Click
WriteTotal()
ReadTotal()
End Sub
Private Sub btnUpdateTotal_Click(sender As Object, e As EventArgs) Handles btnUpdateTotal.Click
cboChange.Text = Nothing
WriteTotal()
ReadTotal()
MsgBox("Inventory updated")
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
cboChange.SelectedIndex = 0
ReadTotal()
End Sub
Sub WriteTotal()
Using swriter As IO.StreamWriter = New IO.StreamWriter("D:/paperstore.txt", False, System.Text.Encoding.UTF8)
If cboChange.Text = "Add to Total" Then
Newtotal = Oldtotal + CType(txtThreshold.Text, Integer)
swriter.WriteLine(Newtotal)
ElseIf cboChange.Text = "Subtract from Total" Then
If CType(txtThreshold.Text, Integer) > Oldtotal Then
swriter.WriteLine(Oldtotal)
MsgBox("buy more toilet paper")
Else
Newtotal = Oldtotal - CType(txtThreshold.Text, Integer)
swriter.WriteLine(Newtotal)
End If
Else
swriter.WriteLine(txtTotal.Text)
End If
End Using
End Sub
Sub ReadTotal()
Using sreader As IO.StreamReader = New IO.StreamReader("D:/paperstore.txt", System.Text.Encoding.UTF8)
Try
Oldtotal = sreader.ReadLine()
txtTotal.Text = Oldtotal
Catch ex As Exception
MsgBox(ex.Message)
End
End Try
End Using
End Sub
End Class
Related
I want to modify my program in VB 2015 that captures a photo using a webcam and saves it to my folder. The problem is that it replaces every picture taken, I want to save every picture with this format name picture01, picture02 etc.
Info: I am using Emgu.
picture
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Try
PictureBox1.Image = capture.QueryFrame.ToBitmap()
Catch ex As Exception
capture = New Emgu.CV.Capture
End Try
End Sub
Private Sub startWebcam_Click(sender As Object, e As EventArgs) Handles startWebcam.Click
Timer1.Start()
End Sub
Private Sub captWebcam_Click(sender As Object, e As EventArgs) Handles captWebcam.Click
Dim picnumber As Integer = 0
Timer1.Stop()
'Save the picture
PictureBox1.Image.Save("D:\WEBCAM\Img01.JPEG", Imaging.ImageFormat.Jpeg)
capture.Dispose()
End Sub
You could make your file name a date stamp, that way it will always be unique:
Dim a As String = Now.ToShortDateString & Now.ToLongTimeString
a = a.Replace(":", "").Replace("/", "").Replace("\", "")
PictureBox1.Image.Save("D:\WEBCAM\" & a & ".JPEG", Imaging.ImageFormat.Jpeg)
You could also use a simple integer increment:
Private FileID as Integer = 0
Private Sub captWebcam_Click(sender As Object, e As EventArgs) Handles captWebcam.Click
Timer1.Stop()
'Save the picture
FileID += 1
PictureBox1.Image.Save("D:\WEBCAM\Img" & FileID.ToString("00") & ".JPEG", Imaging.ImageFormat.Jpeg)
capture.Dispose()
End Sub
I have orders in text files in the debug folder and when i type the name of the order in a text box it displays the order is a list box and there is a combo box underneath where i can change the status of the meal preparation (Being prepared, ready to deliver etc,). If i go back to that form and type in the same order name into the textbox i need to previous prepartion status to be already in the textbox. Thanks for any help!
Public Class frmOrderStatus
Private Sub btnStatus_Click(sender As Object, e As EventArgs) Handles btnStatus.Click
Dim sr As IO.StreamReader = IO.File.OpenText(strTxtOrderNum & ".txt")
Do Until sr.EndOfStream
lstOrder.Items.Add(sr.ReadLine)
Loop
End Sub
Private Sub OrderStatus_Load(sender As Object, e As EventArgs) Handles MyBase.Load
lstOrder.Items.Clear()
btnStatus.Enabled = False
ChangeStatus.Enabled = False
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnValidate.Click
strTxtOrderNum = txtOrderNum2.Text
btnStatus.Enabled = True
ChangeStatus.Enabled = True
End Sub
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
strSaveStatus = ChangeStatus.SelectedIndex
End Sub
Private Sub ChangeStatus_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ChangeStatus.SelectedIndexChanged
End Sub
End Class
It recognizes the file; it just tells you it is in use. A Stream must be closed and disposed. I don't see the StreamReader even being closed let alone disposed. A `Using...End Using block will close and dispose of objects even if there is an error.
I just used a text file I happened to have to test.
Private strTxtOrderNum As String = "host"
Private Sub ReadFile()
Using sr As IO.StreamReader = IO.File.OpenText(strTxtOrderNum & ".txt")
Do Until sr.EndOfStream
ListBox1.Items.Add(sr.ReadLine)
Loop
End Using
End Sub
Private Sub WriteFile()
Dim strSelectedItem = ComboBox1.Text
Using swVar As IO.StreamWriter = IO.File.AppendText(strTxtOrderNum & ".txt")
swVar.WriteLine(strSelectedItem)
End Using
End Sub
i'm trying to make a music player using AxWindowsMediaPlayer but i have a small problem on this import code. (the imported items go to a listbox #listbox1)
Public Class Form1
Dim song As String()
Dim directory As String()
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
If (OpenFileDialog1.ShowDialog = DialogResult.OK) Then
song = OpenFileDialog1.SafeFileNames
directory = OpenFileDialog1.FileNames
For items As Integer = 0 To song.Count - 1
ListBox1.Items.Add(song(items))
Next
End If
Catch ex As Exception
End Try
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
Try
AxWindowsMediaPlayer1.URL = directory(ListBox1.SelectedIndex)
AxWindowsMediaPlayer1.Ctlcontrols.play()
End Sub
End Class
Catch ex As Exception
End Try
But when trying to re-import new songs (after the first import) and trying to play it, the newly reimported songs overwrites the previous ones (e.g. oldimportedsong1 gets overwritten by newimportedsong1, oldimportedsong2 gets overwritten by newimportedsong2)
Please help me out!
It will simplify your code if you use List(Of T). Otherwise you will have to ReDim Preserve your arrays.
What is happening in your code is you are overwritting your arrays every time you click the button.
Private song As New List(Of String)
Private directory As New List(Of String)
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Try
If OpenFileDialog1.ShowDialog = DialogResult.OK Then
song.AddRange(OpenFileDialog1.SafeFileNames)
directory.AddRange(OpenFileDialog1.FileNames)
ListBox1.DataSource = Nothing
ListBox1.DataSource = song
End If
Catch ex As Exception
'empty catch boxes are the devil's workshop
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
Dim i As Integer = ListBox1.SelectedIndex
Dim path As String = directory(i)
End Sub
This is a homework assignment that I am working on. I have an .mdb file that is supposed to connect to my application and then I should be able to navigate among the records. The database is connected as a data source. But, when I run the application no data is populated and I get a IndexOutOfRangeException was unhandled error when I press a button on my toolstrip. I have tried to ask for assistance from the professor but she has been non-existent all semester. What am I doing wrong here? I'm only looking for help for where to focus my attention so that I can figure this out on my own.
Public Class Form1
Dim strMemoryConnection As String = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " &
Application.StartupPath & "\memory.mdb"
Dim strSQLMem As String
Dim dtMem As New DataTable()
Dim intTotalRows As Integer
Dim intCurrentRow As Integer
Private Sub displayRecord()
Me.txtTitle.Text = CStr(dtMem.Rows(intCurrentRow)("title"))
Me.txtAuthor.Text = CStr(dtMem.Rows(intCurrentRow)("author"))
Me.txtPublisher.Text = CStr(dtMem.Rows(intCurrentRow)("publisher"))
Me.txtStuff.Text = CStr(dtMem.Rows(intCurrentRow)("stuff"))
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventHandler)
dtMem.Clear()
strSQLMem = "SELECT * FROM Memory"
Dim dataAdapter As New OleDb.OleDbDataAdapter(strSQLMem, strMemoryConnection)
dataAdapter.Fill(dtMem)
dataAdapter.Dispose()
intTotalRows = dtMem.Rows.Count
intCurrentRow = 0
displayRecord()
End Sub
#Region "Tool Strip Button Clicks"
Private Sub btnTop_Click(sender As Object, e As EventArgs) Handles btnTop.Click
intCurrentRow = 1
displayRecord()
End Sub
Private Sub btnPrev_Click(sender As Object, e As EventArgs) Handles btnPrev.Click
intCurrentRow = intCurrentRow - 1
If intCurrentRow < 0 Then
intCurrentRow = 1
End If
displayRecord()
End Sub
Private Sub btnNext_Click(sender As Object, e As EventArgs) Handles btnNext.Click
intCurrentRow = intTotalRows + 1
If intCurrentRow = intTotalRows Then
intCurrentRow = intTotalRows - 1
End If
displayRecord()
End Sub
Private Sub btnBot_Click(sender As Object, e As EventArgs) Handles btnBot.Click
intCurrentRow = intTotalRows - 1
displayRecord()
End Sub
#End Region
End Class
In the end, it was as I expected. The data was not loading properly. I finally realized that the Form1_Load argument was not correct.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventHandler)
Needed to be:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
I will be letting my professor and fellow classmates know that this is incorrect.
Thanks to Bugs for the troubleshooting. At the least, I now know how to create a SQL connection very easily. I also appreciate whomever downvoted my question and their help in figuring this out.
I have a listview loop that is adding 150,000 items to my listview. For testing purposes I moved this code to a background worker with delegates, but it still freezes up the UI. I am trying to find a solution so that it can add these items in the background while I do other stuff in the app. What solutions do you guys recommend?
this is what I am using
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListView1.Clear()
ListView1.BeginUpdate()
bw.WorkerReportsProgress = True
bw.RunWorkerAsync()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If bw.IsBusy Then bw.CancelAsync()
End Sub
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork
For x = 1 To 125000
Dim lvi As New ListViewItem("Item " & x)
If bw.CancellationPending Then
e.Cancel = True
Exit For
Else
bw.ReportProgress(0, lvi)
End If
Next
End Sub
Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bw.ProgressChanged
Try
Dim lvi As ListViewItem = DirectCast(e.UserState, ListViewItem)
Me.ListView1.Items.Add(lvi)
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Sub
Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
ListView1.EndUpdate()
If Not e.Cancelled Then
Debug.Print("Done")
Else
Debug.Print("Cancelled")
End If
End Sub
End Class
Give this a try, it's a great example for what you would need... I also had a progress bar that shows the progress and such, see example image that is attached. Also I wasn't seeing any delegate that you need to perform such operation, mine has one that will be required. The reason is you are adding items to a control on the UI thread, in order to add items we need to know if an Invoke is required, if so we invoke otherwise we add the item to the control... Also I made the thread sleep, so it can take a break; this also prevents the UI from wanting to lock up here and there, now it's responsive with NO FREEZING.
Option Strict On
Option Explicit On
Public Class Form1
Delegate Sub SetListItem(ByVal lstItem As ListViewItem) 'Your delegate..
'Start the process...
Private Sub btnStartProcess_Click(sender As Object, e As EventArgs) Handles btnStartProcess.Click
lvItems.Clear()
bwList.RunWorkerAsync()
End Sub
Private Sub AddListItem(ByVal lstItem As ListViewItem)
If Me.lvItems.InvokeRequired Then 'Invoke if required...
Dim d As New SetListItem(AddressOf AddListItem) 'Your delegate...
Me.Invoke(d, New Object() {lstItem})
Else 'Otherwise, no invoke required...
Me.lvItems.Items.Add(lstItem)
End If
End Sub
Private Sub bwList_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bwList.DoWork
Dim intCount As Integer = CInt(txtCount.Text)
Dim dblPercent As Integer = 100
Dim intComplete As Integer = 0
Dim li As ListViewItem = Nothing
For i As Integer = 1 To CInt(txtCount.Text)
If Not (bwList.CancellationPending) Then
li = New ListViewItem
li.Text = "Item " & i.ToString
AddListItem(li)
Threading.Thread.Sleep(1) 'Give the thread a very..very short break...
ElseIf (bwList.CancellationPending) Then
e.Cancel = True
Exit For
End If
intComplete = CInt(CSng(i) / CSng(intCount) * 100)
If intComplete < dblPercent Then
bwList.ReportProgress(intComplete)
End If
If li IsNot Nothing Then
li = Nothing
End If
Next
End Sub
Private Sub bwList_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bwList.ProgressChanged
pbList.Value = e.ProgressPercentage
End Sub
Private Sub bwList_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwList.RunWorkerCompleted
If pbList.Value < 100 Then pbList.Value = 100
MessageBox.Show(lvItems.Items.Count.ToString & " items were added!")
End Sub
Private Sub btnStopWork_Click(sender As Object, e As EventArgs) Handles btnStopWork.Click
bwList.CancelAsync()
End Sub
Private Sub btnRestart_Click(sender As Object, e As EventArgs) Handles btnRestart.Click
pbList.Value = 0
lvItems.Items.Clear()
txtCount.Text = String.Empty
End Sub
End Class
Screenshot in action...