is there a way to combine strings into a working save / delete funtion - vb.net

I am using two separate functions: one to save and one to delete. I would like to roll them into one function if possible even though VB gives me the wrong information. This is what I have so far:
Public Sub popup(sender As Object, e As EventArgs)
Dim ans As String
ans = MsgBox(Operation & name, vbYesNo + Type, tital)
If ans = vbYes Then
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Save.Click
'save
Dim name As New String = "NAME_HERE"
Dim Operation As New String = "Would you like to Save your Changes to "
Dim tital As New String = "save this record "
Dim Type As New String = vbQuestion
Call popup(e, e)
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Delete.Click
'delete
Dim name As New String = "NAME_HERE"
Dim Operation As String = "Would you like to Delete your Record "
Dim tital As New String = "Delete this record "
Dim Type As New String = vbExclamation
Call popup(e, e)
End Sub
Is the only way to roll it into one function to extend the ans = with strings like name2, Operation2, tital2, Type2 or is there a tidy solution?

Your popup is a subroutine but I think it should be a function. You want to act on the result of the MsgBox. Here's a function that returns what the user selected:
Public Function Popup(name As String, operation As String, title As String, style As MsgBoxStyle) As MsgBoxResult
Return MsgBox(operation & name, vbYesNo + style, title)
End Function
I've adjusted a few things in your code:
You cannot use New with String the way you are trying to (Dim name As New String = "NAME_HERE")
I made type into a MsgBoxStyle variable
Here's the updated code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Save.Click
'save
Dim name As String = "NAME_HERE"
Dim Operation As String = "Would you like to Save your Changes to "
Dim tital As String = "save this record "
Dim style As MsgBoxStyle = MsgBoxStyle.Question
Dim result As MsgBoxResult = Popup(name, Operation, tital, style)
Select Case result
Case MsgBoxResult.Yes
' Save changes
Case Else
End Select
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Delete.Click
'delete
Dim name As String = "NAME_HERE"
Dim Operation As String = "Would you like to Delete your Record "
Dim tital As String = "Delete this record "
Dim style As MsgBoxStyle = MsgBoxStyle.Exclamation
Dim result As MsgBoxResult = Popup(name, Operation, tital, style)
Select Case result
Case MsgBoxResult.Yes
' Delete record
Case Else
End Select
End Sub

There is no overload of constructors for a String that does not have parameters. .Net allows you declare a String directly.
vbExclamation and vbQuestion are not a strings.
I have no idea what you expect to get with Call popup(e, e) Why would you want to send the EventArgs for the button to your popup Sub? You declared a message and a title in the button event but these values are never passed to the popup Sub. Those variables are local to the the button event and not visible in the popup method. Even if they were available, why would you want to concatenate the
When you declare your own methods (like popup) you can determine what needs to be sent to the method so it can do its work. These are the parameters of the method. When you call the method you pass arguments that match the expected parameters. The values in these arguments can be used inside your method.
BTW, the Call keyword is not needed except in special circumstanse.
I would like to show you the .Net way to use MessageBox instead of the old VB6 way. If you start to code in C# you will be comfortable with MessageBox.
I used a Select Case so it would be easy to add other message boxes, for example an Update message box.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim RetVal = CustomMB("Delete")
If RetVal = DialogResult.Yes Then
'Code to delete
End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim RetVal = CustomMB("Save")
If RetVal = DialogResult.Yes Then
'Code to save
End If
End Sub
Private Function CustomMB(MBType As String) As DialogResult
Dim dr As New DialogResult()
Select Case MBType
Case "Delete"
dr = MessageBox.Show("Would you like to Delete your Record", "Delete this record ", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation)
Case "Save"
dr = MessageBox.Show("Would you like to Save your Changes to ", "save this record ", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
Case Else
dr = MessageBox.Show("Sorry, no matching message box was found")
End Select
Return dr
End Function

Related

Display variable content dynamically

I'm trying to do this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim my_variable as String = "hello"
Dim blabla as string = "my_variable"
msgbox(blabla) ' I want this to display: "hello"
End Sub
Any way you guys can help me in VB.NET (not C# please).
What you want cannot be done for a LOCAL variable like my_variable.
If that variable is at CLASS level, though, it can be done with REFLECTION.
If the variable is at class level and is PUBLIC, you can cheat and use CallByName:
Public Class Form1
Public counter As Integer = 911
Public my_variable As String = "Hello World!"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim variable As String = TextBox1.Text
Try
Dim value As String = CallByName(Me, variable, CallType.Get)
MessageBox.Show(variable & " = " & value)
Catch ex As Exception
MessageBox.Show("Variable not found: " & variable)
End Try
End Sub
End Class
Type the name of the variable in TextBox1 and its value will be displayed in the message box....easy peasy.
If you don't want the variables to be public, then it can be accomplished via Reflection, but it doesn't look quite as simple and pretty. Look it up if you want to go that route.
--- EDIT ---
Here's a version that can find public members of a module:
Code:
Imports System.Reflection
Public Class Form2
Public counter As Integer = 911
Public my_variable As String = "Hello World!"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
lblResults.Text = ""
Dim variable As String = TextBox1.Text
Try
Dim value As String = CallByName(Me, variable, CallType.Get)
lblResults.Text = variable & " = " & value
Catch ex As Exception
End Try
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
lblResults.Text = ""
Dim moduleName As String = txtModule.Text
Dim moduleField As String = txtModuleMember.Text
Dim myType As Type = Nothing
Dim myModule As [Module] = Nothing
For Each x In Assembly.GetExecutingAssembly().GetModules
For Each y In x.GetTypes
If y.Name.ToUpper = moduleName.ToUpper Then
myType = y
Exit For
End If
Next
If Not IsNothing(myType) Then
Exit For
End If
Next
If Not IsNothing(myType) Then
Dim flags As BindingFlags = BindingFlags.IgnoreCase Or BindingFlags.NonPublic Or BindingFlags.Public Or BindingFlags.Static Or BindingFlags.Instance
Dim fi As FieldInfo = myType.GetField(moduleField, flags)
If Not IsNothing(fi) Then
Dim value As String = fi.GetValue(Nothing)
lblResults.Text = moduleField & " = " & value
End If
End If
End Sub
End Class
Public Module PutThings
Public SomeValue As String = "...success!..."
End Module
My suggestion (just 1 idea, thinking out loud) would be to create a separate, global list of all of your variables, and every single time one of the variables you want to know the contents of changes, update the global list.
For example:
' Global declaration
Dim dictionary As New Dictionary(Of String, String)
Sub Form_Load()
' Add keys to all vars you want to lookup later
With dictionary
.Add("varCarrot", String.Empty)
.Add("varPerl", String.Empty)
End With
End Sub
Sub SomeSub()
strCarrot = "hello"
intPerl = 12
' Any time the vars change that you want to track, update the respective dictionary key
dictionary(varCarrot) = strCarrot
dictionary(varPerl) = intPerl.ToString
Do Until intPerl = 100
intPerl += 1
strCarrot = "hello " & intPerl
dictionary(varCarrot) = strCarrot
dictionary(varPerl) = intPerl.ToString
Loop
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
dim strLookup as String = text1.text ' the variable you want to lookup entered in the text1 textbox; i.e. "varCarrot"
' See if the requested key exists
If dictionary.ContainsKey(strLookup) Then messagebox.show(dictionary.Item(strLookup))
End Sub
When you're ready to no longer have that functionality in your app, such as when all done debugging it, and ready to finally release it, comment out all the dictionary stuff.

Search through text file and return a line of text

I am trying to create a program that will search a text file for a line of text and then return the full line of information.
Example line: Joe Blogs JBL 1234
Search: Joe Blogs
Search returns: Joe Blogs JBL 1234
To make it as simple as possible, I have 2 text boxes & 1 button.
Textbox1 = search
Textbox2 = Search results
Button = Search button
Can anyone tell me how to do this because I'm finding it really difficult. I'm new to VB coding so the simplest of code would be helpful!
This is what I have so far:
Imports System.IO
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Input Text Error
If TextBox1.TextLength = 0 Then
MsgBox("Please enter a Staff Name or Staff Code", MsgBoxStyle.Information, "Error")
End If
'Perform Search
Dim strText As String = SearchFile("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt", TextBox1.Text)
If strText <> String.Empty Then
TextBox2.Text = strText
End If
End Sub
'Search Function
Public Shared Function SearchFile(ByVal strFilePath As String, ByVal strSearchTerm As String) As String
Dim sr As StreamReader = New StreamReader(strFilePath)
Dim strLine As String = String.Empty
Try
Do While sr.Peek() >= 0
strLine = String.Empty
strLine = sr.ReadLine
If strLine.Contains(strSearchTerm) Then
sr.Close()
Exit Do
End If
Loop
Return strLine
Catch ex As Exception
Return String.Empty
End Try
End Function
'Clear Button
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
TextBox2.Text = ""
TextBox1.Text = ""
End Sub
' Open The text file
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Process.Start("C:\Users\kylesnelling\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt")
End Sub
End Class
Whenever I perform a search, all I get back is the last line of the text file... does anyone know why?
As Alex B has stated in comments, line If strLine.Contains("textbox1.text") should be If strLine.Contains(strSearchTerm)
Also you are not passing in the search item to the function. The below line you have passed in the string textbox1.text as a string rather than the text inside the textbox. Hence why you never find the line you are searching for and always returns the last record of your file.
Dim strText As String = SearchFile("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt", "textbox1,text")
This line should be:
Dim strText As String = SearchFile("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt", textbox1.text)
Also with this line Dim sr As StreamReader = New StreamReader("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt") why have you used the same path destination when you have already passed in this file location in the variable strFilePath.
line should be Dim sr As StreamReader = New StreamReader(strFilePath)
Its best to use the variables being passed into the function otherwise this function won't be very useful to other parts of code that may be referencing it or if search terms or filepaths change.
Updated from comments:
strLine.ToUpper.Contains(strSearchTerm.ToUpper) this line will make both text uppercase and the word you are searching for to uppercase, which will allow them to ignore case sensitivity, so for example, "text" can match with "Text" by both being converted to "TEXT" when used to compare.
Give this a try friend.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim searchResult As String = SearchFile("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt", _
"text to search for")
Me.TextBox2.Text = searchResult
End Sub
Public Shared Function SearchFile(ByVal strFilePath As String, ByVal strSearchTerm As String) As String
Dim fs As New System.IO.StreamReader(strFilePath)
Dim currentLine As String = String.Empty
Try
Dim searchResult As String = String.Empty
Do While fs.EndOfStream = False
currentLine = fs.ReadLine
If currentLine.IndexOf(strSearchTerm) > -1 Then
searchResult = currentLine
Exit Do
End If
Loop
Return searchResult
Catch ex As Exception
Return String.Empty
End Try
End Function

How to jump to a row of a DataView based on partial match search criteria?

Currently, my application uses the RowFilter property on an expression to search for a user-defined string within a DataView. Currently my code looks something like this:
Public Class MyClass
Private custView As DataView
Private Sub form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
dsDataSet = <"DataAccessLayer call to SQL Stored Procedure">
custView = New DataView(dsDataSet.Tables(0))
custView.Sort = "Column Name"
Me.C1FlexGrid1.DataSource = custView
End Sub
Private Sub txtSearch_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtSearch.TextChanged
Dim searchText As String = txtSearch.Text
Dim expression As String = "Column Name LIKE '" + searchText + "%'"
custView.RowFilter = expression
Me.C1FlexGrid1.DataSource = custView
End Sub
End Class
My goal is to modify the behavior of this such that instead of filtering out rows that do not meet the search results, it will keep all rows present but jump to the first instance of a partial match as the user types in the search box. If DataView.Find() supported wildcards I would be set, but unfortunately it doesn't.
The solution I've come up with is to use some iteration logic. However this is done on the object the DataView has been bound to and not the DataView itself. Although this code can be modified to do exactly that.
Private Sub txtSearch_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtSearch.TextChanged
'Unselect all
Me.C1FlexGrid1.Select(-1, -1, True)
If txtSearch.Text <> "" And [column index] <> -1 Then
'Typed text
Dim s As String = txtSearch.Text.Trim.ToLower
Dim column As Int32 = [column index] + 1
'Recurse until match in first column is found
For i As Integer = 0 To Me.C1FlexGrid1.Rows.Count - 1
If C1FlexGrid1.GetData(i, column) <> Nothing Then
If C1FlexGrid1.GetData(i, column).ToString.ToLower.StartsWith(s) Then
Me.C1FlexGrid1.Select(i, column, True)
Exit Sub
End If
Else
MsgBox("Error message", vbOKOnly, "NO MATCHES")
'Reset search criteria
Call ResetSearch()
End If
Next
MsgBox("Error message", vbOKOnly, "NO MATCHES")
End If
End Sub

Variable 'details' is used before it has been assigned a value.

Variable details is used before it has been assigned a value. What is the problem with details?
Option Explicit On
Imports System.Text
Imports System.IO
Public Class Main
Private SelectedItem As ListViewItem
Dim data As String
Dim strpriority As String
Dim task As String
Dim createdate As String
Dim duedate As String
Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
AddTask.Show()
Me.Hide()
End Sub
Private Sub HistoryToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles HistoryToolStripMenuItem.Click
History.Show()
Me.Hide()
End Sub
Private Sub Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim fpath As String
Dim splitdata
fpath = AppDomain.CurrentDomain.BaseDirectory
Dim filepath As String
filepath = fpath & "task.txt"
Dim details As String
details = My.Computer.FileSystem.ReadAllText(filepath)
splitdata = Split(details, vbCrLf)
Dim i As Integer
For i = 0 To UBound(splitdata)
lblTaskName.Items.Add(splitdata(i))
Next
lblTime.Enabled = True
Timer1.Interval = 10
Timer1.Enabled = True
lblDate.Text = DateTime.Now.ToString("dd MMMM yyyy")
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
lblTime.Text = TimeOfDay
End Sub
Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click
End
End Sub
Private Sub btnRemove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRemove.Click
If lblTaskName.SelectedItem = "" Then
MsgBox("Please select a record")
Else
If lblTaskName.Items.Count > 0 Then
If MessageBox.Show("Do you really want to delete this record?", "Delete", MessageBoxButtons.YesNo) = MsgBoxResult.Yes Then
lblTaskName.Items.Remove(lblTaskName.SelectedItem.ToString())
Else
MessageBox.Show("Operation Cancelled")
End If
End If
End If
Try
Dim fpath As String
fpath = AppDomain.CurrentDomain.BaseDirectory
Dim filepath As String
filepath = fpath & "task.txt"
Dim details As String
If lblTaskName.Items.Count > 0 Then
details = lblTaskName.Items(0)
Dim i As Integer
For i = 1 To lblTaskName.Items.Count - 1
details = details & vbCrLf & lblTaskName.Items(i)
Next
End If
My.Computer.FileSystem.WriteAllText(filepath, details, False)
Catch ex As Exception
MsgBox("Values Can't be inserted this time")
End Try
End Sub
Private Function filepaths() As String
Throw New NotImplementedException
End Function
End Class
The problem is in the btnRemove_Click method in this part:
Dim details As String
If lblTaskName.Items.Count > 0 Then
details = lblTaskName.Items(0)
If the condition evaluates to false, the details variable is used before it is initialized, because it is only set in the if block up to now.
I suppose you want to move the following line into the if block to solve the problem:
My.Computer.FileSystem.WriteAllText(filepath, details, False)
Alternatively, you can come up with a default value for details so that it is set in any case. For performance reasons, you can set the default value (e.g. a text or String.Empty) in an else branch:
Dim details As String
If lblTaskName.Items.Count > 0 Then
' ...
Else
details = "Default Value"
End If
You need to think through the flow of your program. Consider this code:
Dim details As String
If lblTaskName.Items.Count > 0 Then
details = lblTaskName.Items(0)
Dim i As Integer
For i = 1 To lblTaskName.Items.Count - 1
details = details & vbCrLf & lblTaskName.Items(i)
Next
End If
My.Computer.FileSystem.WriteAllText(filepath, details, False)
You declare the details variable at the top. Then you check that there is at least 1 item in the lblTaskName control. If that test passes, then you assign the first item to details. But what if that test doesn't pass? What if there are 0 items in the lblTaskName control? In that case, the interior of the If block never runs, and nothing ever gets stored in details. Then in the final line, you try to use the value of the details variable *outside of the If block. This is illegal because it may not have been assigned a value.
Perhaps you meant for that WriteAllText line to be inside of If block? Otherwise, you'll need to add an Else clause to your If statement to handle the case where there are 0 items in lblTaskName.
Aside from that, stylistically speaking, you should prefer to initialize variables at the time of declaration whenever possible. So for example, instead of writing:
Dim fpath As String
Dim splitdata
fpath = AppDomain.CurrentDomain.BaseDirectory
Dim filepath As String
filepath = fpath & "task.txt"
Dim details As String
details = My.Computer.FileSystem.ReadAllText(filepath)
splitdata = Split(details, vbCrLf)
write it as:
Dim fpath As String = AppDomain.CurrentDomain.BaseDirectory
Dim filepath As String = fpath & "task.txt"
Dim details As String = My.Computer.FileSystem.ReadAllText(filepath)
Dim splitdata() As String = Split(details, vbCrLf)
(I'm OCD, so I line up my equals signs. That part is totally optional.)
It doesn't make the code run any faster, but it does make it easier to read! More importantly, it decreases the potential for bugs.

read single word from listbox vb

I have an order form I created in VB.NET and I have a ListBox that is populated by order. You can double click on the order and it populates the order number in the order form. The problem I'm having is that it populates the TextBox with both the order number and the persons name. How can I use a delimiter to only pull out the order number and not the name also.
Imports Business_Objects
Public Class frmSummary
Private ctrl As Controller
Dim listID As ArrayList
Private Sub frmSummary_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ctrl = CType(MdiParent, frmMain).ctrl
Dim list As ArrayList
list = ctrl.GetOrders
Dim order As Business_Objects.Order
For Each order In list
lstOrders.Items.Add(order.ID & "," & " " & order.Server)
Next
End Sub
Private Sub lstOrders_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lstOrders.DoubleClick
Dim result As Boolean = False
If lstOrders.Text <> "" Then
result = True
Dim frm As New OrderForm
frm.MdiParent = Me.MdiParent
frm.Show()
frm.txtOrderNo.Text = lstOrders.Text
frm.btnFetch.PerformClick()
Else
MessageBox.Show("there are no orders here to click")
End If
End Sub
Private Sub btnRefresh_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRefresh.Click
lstOrders.Items.Clear()
ctrl = CType(MdiParent, frmMain).ctrl
Dim list As ArrayList
list = ctrl.GetOrders
Dim order As Business_Objects.Order
For Each order In list
lstOrders.Items.Add(order.ID & " " & order.Server)
Next
End Sub
End Class
If all of your data is being stored as a single field, or something like:
4322305 John Smith Carrots $3.00
845825 Sam White Oranges $1.25
Then you can read each record as a string, and then use split that into an array based on " " as your delimiter.
The code would look something like:
dim myArray as string() = myLongTextRecord.Split(" ")
And in that format,
textBoxName.Text = myArray[1]
You're almost there. You could use the split function, but another approach would be to add the Order object directly to the listbox and not text.
Private Sub frmSummary_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ctrl = CType(MdiParent, frmMain).ctrl
Dim list As ArrayList
list = ctrl.GetOrders
Dim order As Business_Objects.Order
For Each order In list
lstOrders.Items.Add(order)
Next
End Sub
Private Sub lstOrders_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lstOrders.DoubleClick
Dim result As Boolean = False
If lstOrders.Text <> "" Then
result = True
Dim frm As New OrderForm
frm.MdiParent = Me.MdiParent
frm.Show()
frm.txtOrderNo.Text = DirectCast(lstOrders.SelectedItem, Order).ID.ToString
frm.btnFetch.PerformClick()
Else
MessageBox.Show("there are no orders here to click")
End If
End Sub
You'll need to go into the Order object and override the .ToString function so that the text in the Listbox displays whatever value you want (ie. Return ID & "," & " " & Server)