I am making for fun, a small program in VB.net Console, that allows users to enter films, the director and the genre, and then can sort/order them however the user wants. Essentially the problem I am hitting is that I can't pass a variable between sub routines. I thought this was achieved by using aa an example: (ByRef CurrentIndex As Integer), which would be referencing the variable that was declared in another sub-routine. This isn't working though, and I think I am not understanding some of the theory behind this.
This is the block where the variable is declared:
Sub AddDvdToDatabase()
Dim choice As String = ""
Dim i As Integer
Dim CurrentIndex As Integer = 1
i = CurrentIndex
Do Until choice = "exit"
choice = ""
Console.WriteLine("Add the title of the film")
dvd(i).Title = Console.ReadLine()
Console.WriteLine("Add the director of the film")
dvd(i).Director = Console.ReadLine()
Console.WriteLine("Add the genre of the film")
dvd(i).Genre = Console.ReadLine()
Do Until choice = "yes" Or choice = "exit"
Console.WriteLine("Would you like to add another fim to the database? <yes/exit>")
choice = Console.ReadLine()
Loop
i += 1 'Save the value of i to a separate text file to read from when opening again. This stops previuos elements from the array being overwritten.
Loop
CurrentIndex = i
Menu(CurrentIndex)
End Sub
And then here is where I am trying to pass the value of CurrentIndex to:
Sub ViewDatabase(ByRef CurrentIndex As Integer)
Console.Clear()
Dim i As Integer
For i = 1 To CurrentIndex
Console.WriteLine(i & ". " & dvd(i).Title & " " & dvd(i).Director & " " & dvd(i).Genre)
Next
Console.ReadLine()
End Sub
edit
I am calling it in the Sub Menu(), when the user selects to view the database after entering films.
I am getting the error "Argument not specified for parameter 'CurrentIndex' of 'Public Sub ViewDatabase(ByRef CurrentIndex As Integer)'"
Sorry, I am very new to Stack Overflow and I'm still learning the conventions etc.
I see that this post is old however it appears that you are tying to get the value of CurrentIndex at the end of your sub routine AddDvdToDatabase and use the output in ViewDatabase. To do this you could simply make the variable global outside of both sub routines.
Dim CurrentIndex as Integer
Your code would look like this:
Dim CurrentIndex As Integer
Sub AddDvdToDatabase()
Dim choice As String = ""
Dim i As Integer
CurrentIndex = 1
i = CurrentIndex
Do Until choice = "exit"
choice = ""
Console.WriteLine("Add the title of the film")
dvd(i).Title = Console.ReadLine()
Console.WriteLine("Add the director of the film")
dvd(i).Director = Console.ReadLine()
Console.WriteLine("Add the genre of the film")
dvd(i).Genre = Console.ReadLine()
Do Until choice = "yes" Or choice = "exit"
Console.WriteLine("Would you like to add another fim to the database? <yes/exit>")
choice = Console.ReadLine()
Loop
i += 1 'Save the value of i to a separate text file to read from when opening again. This stops previuos elements from the array being overwritten.
Loop
CurrentIndex = i
Menu(CurrentIndex)
End Sub
Sub ViewDatabase()
Console.Clear()
Dim i As Integer
For i = 1 To CurrentIndex
Console.WriteLine(i & ". " & dvd(i).Title & " " & dvd(i).Director & " " & dvd(i).Genre)
Next
Console.ReadLine()
End Sub
Related
I have this case where I need that the user enters some data. All I need is to allow the user to enter numbers from 0 to 100, if the user is entering an amount bigger than 100, than display a message like: please enter number from 0 to 100 and then show them again where they need to enter that number.
For example, Console.Write("Español: ") in the terminal is:
Español: ' the user should enter the number here
if the user enters more than 100, then display this:
Please enter number from 0 to 100. Español: ' here enter the number again
I was thinking on doing this as in the code below, with an If ... Else, but, is there a better way?
Here is the actual code:
Sub Main()
Dim Español1 As Integer
Dim Matematicas1 As Integer
Dim Ciencias1 As Integer
Dim EstudiosSociales1 As Integer
Dim Ingles1 As Integer
Dim ArtesPlasticas1 As Integer
Dim ArtesIndustriales1 As Integer
Select Case Menu
Case 2
Console.Write("Ingrese las notas: ")
Console.ReadLine()
Console.Write("Español: ")
' I was thinking on doing this
If Console.ReadLine() >= 100 Then
Console.Write("La nota debe ser 100 o menos: ")
Español1 = Console.ReadLine()
Else
Español1 = Console.ReadLine()
End If
If Español1 = True Then
Console.Write("Matematicas: ")
Matematicas1 = Console.ReadLine()
End If
Console.Write("Ciencias: ")
Ciencias1 = Console.ReadLine()
Console.Write("Estudios Sociales: ")
EstudiosSociales1 = Console.ReadLine()
Console.Write("Ingles: ")
Ingles1 = Console.ReadLine()
Console.Write("Artes plasticas: ")
ArtesPlasticas1 = Console.ReadLine()
Console.Write("Artes Industriales: ")
ArtesIndustriales1 = Console.ReadLine()
Console.Clear()
End Select
End Sub
So, any suggestions?
I'm not really experienced with VB, but try this:
Dim n as Integer
n = Console.WriteLine()
Do While n >= 100
Console.WiteLine("Enter new Value:") 'Sorry, no pienso la lengua español :(
n = Console.ReadLine()
Loop
Edit 3.0
Add your subject names into the array subjects.
Sub Main()
Dim subjects As Array = {"Math", "English", "German"} 'Three example names
Dim subjectsInt As New Dictionary(Of String, Integer)
Dim i, input As Integer
Dim check, FirstTry As Boolean
For i = 0 To (subjects.Length - 1)
check = False
FirstTry = True
Do
If FirstTry = True Then
Console.WriteLine(subjects(i) & ": ")
FirstTry = False
Else
Console.WriteLine("Please enter a value between 1 and 100" & " (" & subjects(i) & "):")
End If
input = Console.ReadLine()
If input <= 100 And input > 0 Then
subjectsInt.Add(subjects(i), input)
check = True
End If
Loop While check = False
Next
For i = 0 To (subjects.Length - 1)
Console.WriteLine(subjects(i) & ": " & subjectsInt(subjects(i)))
Next
Console.ReadLine()
End Sub
Well I dont know VBA unfortunately . But I believe in every language is the same. You do a do {}while cycle and in the while you check if you conditions are met. And until they are met you continue reading from the console. Good look with your VBA :)
Basically I wrote a code, which is to be used in userform. The thing is that userform is created by other macro (amount of checkboxes differs, depends how many words string strNamn contains, that is why userform must be created by macro).
I would like to, somehow, include loop counter in the line:
If UserForm1.CheckBox0.Value = True Then
to make it like this:
If UserForm1.CheckBox(i).Value = True Then
But it obviously doesn't work like this :(
Any suggestion how to declare checkbox to include the counter in the line?
Code in UserForm1 to execute macro looks like:
Private Sub cmd_1_Click()
Call clicker
End Sub
Macro code:
Sub clicker()
Dim strNamnOK As String
Dim strNamn As String
Dim strNamnA() As String
strNamn = "one, two, three, four"
strNamnA = Split(strNamn, ", ")
Dim intAmount As Integer
intAmount = UBound(strNamnA)
strNamnOK = ""
For i = 0 To intAmount
If UserForm1.CheckBox0.Value = True Then
strNamnOK = strNamnOK & " " & strNamnA(i)
End If
Next
strNamnOK = Left(strNamnOK, 12)
MsgBox strNamnOK
End Sub
I'm trying to set the focus in a form after update. When I do this within the forms class module I have no problem. However, I need to do this in a few forms so I'm trying to write it in the module. My problem is I can't get the .SetFocus to work unless I hardcode the form name within the class module. WHno is the name of the control I'm trying to set focus.
I have attempted a number of options and none seem to work.
Here is the sub. Everything works wonderfully except the .SetFocus procedure.
Sub ValidateWHNO()
Dim EnteredWHNO As Integer
Dim actForm As String
Dim deWHNO As Variant
msg As Integer
Dim ctrlWHNO As Control
EnteredWHNO = Screen.ActiveControl.Value
actForm = Screen.ActiveForm.Name
Set ctrlWHNO = [Forms]![frmEnterBookData]![WHno]
deWHNO = DLookup("[WHno]", "tblDataEntry", "[WHno] = " & EnteredWHNO)
If EnteredWHNO = deWHNO Then
msg = MsgBox("You have already entered " & EnteredWHNO & " as a WHNO. The next number is " & DMax("[WHno]", "tblDataEntry") + 1 & ", use this?", 4 + 64, "Already Used WHno!")
If msg = 6 Then
Screen.ActiveControl.Value = DMax("[WHno]", "tblDataEntry") + 1
Else
Screen.ActiveControl.Value = Null
ctrlWHNO.SetFocus 'CODE THAT WONT RUN
End If
End If
End Sub
I've tried a number of other methods to set focus, such as:
Forms(actForm).WHno.SetFocus,
Forms(actForm).Controls(WHno).SetFocus, Screen.ActiveControl.SetFocus
The current result is that if No is selected in the MsgBox, the value is cleared, but the focus moves to the next control.
Thanks in advanced for any help that may be offered.
Does the following make a difference?
Sub ValidateWHNO(frm as Access.Form)
Dim EnteredWHNO As Integer
Dim actForm As String
Dim deWHNO As Variant
msg As Integer
EnteredWHNO = frm.ActiveControl.Value
actForm = frm.Name
deWHNO = DLookup("[WHno]", "tblDataEntry", "[WHno] = " & EnteredWHNO)
If EnteredWHNO = deWHNO Then
msg = MsgBox("You have already entered " & EnteredWHNO & " as a WHNO. The next number is " & DMax("[WHno]", "tblDataEntry") + 1 & ", use this?", 4 + 64, "Already Used WHno!")
If msg = 6 Then
frm.ActiveControl.Value = DMax("[WHno]", "tblDataEntry") + 1
Else
frm.ActiveControl.Value = Null
frm![WHno].SetFocus
End If
End If
End Sub
And your call from each form would be:
VaidateWHNO Me
Instead of using a relative reference to the form (Screen.ActiveForm), the code passes the form reference through directly and uses that reference as the parent of the .setFocus method.
I'm trying to make some labels on my Form to be visible, but i don't want to use a lot of if statements, but for some reason whenever i put Me.Controls(lbl).Visbel = True in a for or do loop it skips the whole loop. The code worked perfectly the way I wanted it until i got an error for calling Dim lbl = Controls("Label" & counter_3) for the whole class instead of in the From_load private sub. Sometimes i can get it to work, but only one label is visible
Dim chararray() As Char = word_list(random_word).ToCharArray
Dim lbl = "Label" & counter_3
For Each item In chararray
If item = Nothing Then
Else
word_list(counter_2) = item.ToString()
counter_2 += 1
End If
Next
For Each item In chararray
If item = Nothing Then
Else
counter_3 += 1
Me.Controls(lbl).Visible = True
MsgBox(item & " " & counter_3)
End If
Next
I've also tried. In both the loops are completely skipped over. I know this because the MsgBox's don't appear.
Dim chararray() As Char = word_list(random_word).ToCharArray
Dim lbl = Controls("Label" & counter_3)
For Each item In chararray
If item = Nothing Then
Else
word_list(counter_2) = item.ToString()
counter_2 += 1
End If
Next
For Each item In chararray
If item = Nothing Then
Else
counter_3 += 1
lbl.Visble = True
MsgBox(item & " " & counter_3)
End If
Next
The thing that I am noticing is that you are creating a Char array based on a random word returned from your word_list, you then iterate through the Char array using the count of the character in the array as an index into your word_list, if the amount of characters in your word exceeds the amount of words in your list you will get an error and since this error is in the Forms Load event it will be swallowed and all the code after it will be aborted. There are also other issues that I would change like making sure all declarations have a type and I would probably use the Controls.Find Method instead and check that it has an actual object. But what I would probably do first is move your code to a separate Subroutine and call it after your IntializeComponent call in the Forms Constructor(New) Method.
Something like this.
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
YourMethod
End Sub
Public Sub YourMethod()
Dim chararray() As Char = word_list(random_word).ToCharArray
Dim lbl As Control() = Controls.Find("Label" & counter_3, True)
For Each item In chararray
If item = Nothing Then
Else
word_list(counter_2) = item.ToString()
counter_2 += 1
End If
Next
For Each item In chararray
If item = Nothing Then
Else
counter_3 += 1
If lbl.Length > 0 Then
lbl(0).Visible = True
Else
MsgBox("Control not Found")
End If
MsgBox(item & " " & counter_3)
End If
Next
End Sub
MVC 3. Vb.net. Part of my app generates PDF files using Itextsharp. Some strings are too long to go onto the background image correctly. So I basically need to split this string when its over 26 characters long and when it splits it cant split in the middle of a word. from there I will use newline to add the string to the right to the next line... Any ideas that might point me in the right direction.. I did start bulding the function that I will pass the string into test for length and then pass back the string after it finishes but I am stummped after that..
Private Function stringLength(ByVal _string As String) As String
If _string.Length < 26 Then
_string.Split(
End If
End Function
I'm sure there's a million different ways to do this.
You basically need to get all of your words split by the space into a list. After that, you just need to keep checking if the current word plus a space plus the next word reach your threshold or not, and if it does, you move to the next line. Once you have all of your lines, then you rejoin the list into a single string again.
Private Function LimitWidth(ByVal text As String, ByVal maxCharacters As Integer) As String
Dim words As List(Of String) = text.Split(" "c).ToList()
If text.Length < maxCharacters OrElse words.Count = 1 Then
Return text
Else
Dim lines As New List(Of String)
Dim currentLine As String = words(0)
For i As Integer = 1 To words.Count - 1
If (currentLine & " " & words(i)).Length > maxCharacters Then
lines.Add(currentLine)
currentLine = words(i)
If i = words.Count - 1 Then
lines.Add(currentLine)
End If
Else
If i = words.Count - 1 Then
lines.Add(currentLine & " " & words(i))
End If
currentLine &= " " & words(i)
End If
Next
Return String.Join(Environment.NewLine, lines.ToArray())
End If
End Function
To Test:
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
MessageBox.Show(LimitWidth("This is a really long sentence " & _
"meant to demonstrate how to split " & _
"the words into a confined character length.", 26))
End Sub
It sounds like you are asking for a word wrap function.
Since I feel that it's better to answer in a way that promotes learning than to just give answers, I have for you a link that walks you through the process of using Test Driven Development (TDD) to solve this problem. It just so happens that the word wrap problem is a popular coding kata, and Robert C. Martin wrote a somewhat silly fictional story about a developer being taught how to use TDD to solve the word wrap kata.
The code examples are in Java, but it should be trivial to read and translate.
http://thecleancoder.blogspot.com/2010/10/craftsman-62-dark-path.html
The goofy bits are skip-able. Just jump down to the sentences right before the first code snippet.
I would add to it handling of multiline input text with following:
Private Function LimitWidth(ByVal text As String, ByVal maxCharacters As Integer, SplitSign As String) As String
Dim Output As String = ""
Dim OrgLines As List(Of String) = text.Split(Environment.NewLine).ToList()
For x As Integer = 1 To OrgLines.Count - 1
Dim words As List(Of String) = OrgLines(x).Split(" "c).ToList()
If text.Length < maxCharacters OrElse words.Count = 1 Then
Output += OrgLines(x)
Else
Dim lines As New List(Of String)
Dim currentLine As String = words(0)
For i As Integer = 1 To words.Count - 1
If (currentLine & " " & words(i)).Length > maxCharacters Then
lines.Add(currentLine)
currentLine = words(i)
If i = words.Count - 1 Then
lines.Add(currentLine)
End If
Else
If i = words.Count - 1 Then
lines.Add(currentLine & " " & words(i))
End If
currentLine &= " " & words(i)
End If
Next
Output += String.Join(SplitSign, lines.ToArray())
End If
Next
Return Output
End Function
use:
LimitWidth("your text", 80, Environment.NewLine)