I have attached my program which adds student names and their marks to 2 seperate list boxes once inputted using text boxes
Problem is every student name and student mark is added twice - please help me figure out why?
Second problem: I have added a find command button, so when user enters a student mark it will highlight their name and mark, but I keep getting a compile error "argument not optional" because I think one of the properties is incorrectly assigned to a listbox in a sub procedure I call...
Why would you have the AddItem in a For Next Loop?!
Code:
For Index = 1 To frmStudentMarks.Number
lstNames.AddItem Students(Index).StudentName
lstMarks.AddItem Students(Index).StudentMark
Next Index
And what do you use the Number variable for? I see you increment it every time you add an item, but you can just use List1.ListCount to get the item count.
Also, it would be wise to use a two columned ListView instead of two separate List boxes.
You also have no error handling. (Try running the project and clicking the cmdAddRecord button without entering any data)
EDIT: And, why are you at the same time adding student/mark records to an array and to lists?
Last edited by baja_yu; Apr 1st, 2010 at 02:25 PM.
i have put additem in a loop so that a record is added to each list box
i have two seperate list boxes as one it to show the name inputted and the other shows the mark
all in all i have to do the task this way thats why i did do so...
i appreciate your solution but i was hoping you could find the error in my program and resolve why:
- everytime a name and mark is added it adds twice to each list box instead of once?
- when the user enters the student mark the student name and mark in the list box is not highlighted..
i know in VB there are loads of ways to do things, however I really need to do it this way...
i have put additem in a loop so that a record is added to each list box
...
- when the user enters the student mark the student name and mark in the list box is not highlighted..
That's not what Loops are for. A For loop will execute a command the number of times it iterates. So if you the For goes 5 rounds, an item will be added five times. To add to both lists simply use two lines of code, one to add to the first list and the other to add to the second list.
To highlight an item in the listbox use the ListIndex property. For example, to highlight the last item do
could you amend my code without the loop please but keep the module? i believe this will resolve the first problem i.e. not add 1 student name and mark twice...
also could you change it to show me where the code for highlighting the name and mark code should be placed?
thanks...
p.s. im just learning arrays so have to do it this way...i know your code is much cleaner..
Simply remove the For Next loop and leave just the .AddItem lines. And I already gave you the highlighting code: List1.ListIndex = List1.ListCount - 1
Just apply it to the Listboxes you have.
I removed the loop, and left the two additem lines so now it only adds 1 student name and 1 student mark as required..
I also used your code to find a student mark and highlight their name - BUT - the program automatically highlights the last student name and mark added which is wrong as it should highlight the student name and mark the user wants to find....please can you show me the error in my ways?
Please also take a look at my module, it only allows 20 students to be added which is wrong, what do I need to change to add as many students are required?
Finally, in the search box, there is a label below the textbox, which should display:
- student mark has been found (if it exists in the listboxes) and highlight student name and student mark in lstboxes
- student mark does not exist (if it is not in the listboxes)
Please can you show me how this is done??
Finally thank you for your guidance, help and support..
That code does select the last item in the list. It is just an example of how to do it. You have to adapt it to your needs. To select the right item you first need to find it in the list. You have to have a For Loop go through all the items in the list comparing them to what you are looking for. When you find it, use the index of the find item with the ListIndex property to have it highlighted/selected.
I have two list boxes though, doesnt the above code only take care of one listbox?
Please also take a look at my module, it only allows 20 students to be added which is wrong, what do I need to change to add as many students are required?
Finally, in the search box, there is a label below the textbox, which should display:
- student mark has been found (if it exists in the listboxes) and highlight student name and student mark in lstboxes
- student mark does not exist (if it is not in the listboxes)
Please can you show me how this is done??
Finally thank you for your guidance, help and support..
sorry its just that as I dont know sometimes you learn from seeing, i really dont intend for you to do any work for me, seeing it though helps you understand
Private Sub cmdFind_Click()
Dim lngIndex As Long
For lngIndex = 0 To lstMarks.ListCount - 1
If lstMarks.List(lngIndex) = Val(txtFind.Text) Then
lstNames.Selected(lngIndex) = True
lstMarks.Selected(lngIndex) = True
Exit For
End If
Next
End Sub
You also have at least one other problem. When an invalid grade is entered you display a message but the value is still added.
Private Sub cmdAddRecord_Click()
Element = Element + 1
Number = Number + 1
Students(Element).StudentName = txtStudentName.Text
Students(Element).StudentMark = txtStudentMark.Text
If txtStudentMark.Text <= 0 Then
MsgBox "student mark cannot be less than zero"
Exit Sub
ElseIf txtStudentMark.Text > 100 Then
MsgBox "student mark cannot be greater than 100"
Exit Sub
End If
lstNames.AddItem txtStudentName.Text
lstMarks.AddItem txtStudentMark.Text
End Sub
Public Sub DisplayStudent(Index As Integer)
With Students(Index)
lstNames.Selected = True
lstMarks.Selected = True
End With
End Sub
You can probably see from the code that I've already posted that your use of Selected is not correct, but why are you using the With structure? With is meant to be used as a shortcut to coding and as a speed improvement when the program runs and it is used like this
Code:
Public Sub DisplayStudent(Index As Integer)
With Students(Index)
' lstNames.Selected = True
' lstMarks.Selected = True
MsgBox .StudentMark
End With
End Sub
Where (if the Index were, say, 2) the MsgBox .StudentMark would be the same as MsgBox Students(2).StudentMark but faster.
any chance you can show me how to resolve these issues please:
Please also take a look at my module, it only allows 20 students to be added which is wrong, what do I need to change to add as many students are required?
Finally, in the search box, there is a label below the textbox, which should display:
- student mark has been found (if it exists in the listboxes) and highlight student name and student mark in lstboxes
- student mark does not exist (if it is not in the listboxes)
Please also take a look at my module, it only allows 20 students to be added which is wrong, what do I need to change to add as many students are required?
You can't make an unlimited array. You can put a larger number for start, then check (every time you add a new item) if that number has been reached and if has use ReDim Preserve to increase it further.
thanks baja i see, so i will just make 1 to 20 a very large number like 1 to 1000 instead...
Re: this question, will my amended version of Martin's below code work? Please advise
Finally, in the search box, there is a label below the textbox, which should display:
- student mark has been found (if it exists in the listboxes) and highlight student name and student mark in lstboxes
- student mark does not exist (if it is not in the listboxes)
Private Sub cmdFind_Click()
Dim lngIndex As Long
For lngIndex = 0 To lstMarks.ListCount - 1
If lstMarks.List(lngIndex) = Val(txtFind.Text) Then
lstNames.Selected(lngIndex) = True
lstMarks.Selected(lngIndex) = True
lblresult = "your query has been found"
ElseIf lstNames.Selected(lngIndex) = false AND lstMarks.Selected (lngIndex) = false Then
lblresult = "your query does not exist please try again"
Exit For
End If
Next
Option Explicit
Dim Element As Integer
Private Sub cmdAddRecord_Click()
'~~~ Checking. This should be done first !
If Val(txtStudentMark.Text) <= 0 Then
MsgBox "student mark cannot be less than zero. Please re-enter it"
Exit Sub
ElseIf Val(txtStudentMark.Text) > 100 Then
MsgBox "student mark cannot be greater than 100. Please re-enter it"
Exit Sub
End If
Element = Element + 1
ReDim Preserve Students(1 To Element) '~~~> We are dynamically allocating size for the array
Students(Element).StudentName = txtStudentName.Text
Students(Element).StudentMark = txtStudentMark.Text
lstNames.AddItem txtStudentName.Text
lstMarks.AddItem txtStudentMark.Text
End Sub
Private Sub cmdClearRecord_Click()
txtStudentName.Text = ""
txtStudentMark.Text = ""
txtStudentName.SetFocus
End Sub
Private Sub cmdFind_Click()
'~~~~ MartinLiss's code in your thread.
Dim lngIndex As Long
For lngIndex = 0 To lstMarks.ListCount - 1
If Val(lstMarks.List(lngIndex)) = Val(txtFind.Text) Then
lstNames.Selected(lngIndex) = True
lstMarks.Selected(lngIndex) = True
Exit For
End If
Next
End Sub
Private Sub Form_Load()
Element = 0
End Sub
Public Sub DisplayStudent(Index As Integer)
With Students(Index)
.Selected = True
.Selected = True
End With
End Sub
In module:
Code:
Public Type StudentType
StudentName As String
StudentMark As Integer
End Type
Public Students() As StudentType
....
If my post was helpful to you, then express your gratitude using Rate this Post.
And if your problem is SOLVED, then please Mark the Thread as RESOLVED (see it in action - video) My system: AMD FX 6100, Gigabyte Motherboard, 8 GB Crossair Vengance, Cooler Master 450W Thunder PSU, 1.4 TB HDD, 18.5" TFT(Wide), Antec V1 Cabinet Social Group:VBForums - Developers from India
but can you please show me where i can implement the below into the code?
Finally, in the search box, there is a label called "message" below the textbox, which should display:
- student mark has been found (if it exists in the listboxes) and highlight student name and student mark in lstboxes
- student mark does not exist (if it is not in the listboxes)
I believe it should go inside the cmdFindRecord code? But where?
Private Sub cmdFind_Click()
'~~~~ MartinLiss's code in your thread.
Dim lngIndex As Long
For lngIndex = 0 To lstMarks.ListCount - 1
If Val(lstMarks.List(lngIndex)) = Val(txtFind.Text) Then
lstNames.Selected(lngIndex) = True
lstMarks.Selected(lngIndex) = True
Label1.Caption = "Record Found !"
Exit Sub
End If
Next
Label1.Caption = "Record Not found !"
End Sub
(I didn't tested it)
..
If my post was helpful to you, then express your gratitude using Rate this Post.
And if your problem is SOLVED, then please Mark the Thread as RESOLVED (see it in action - video) My system: AMD FX 6100, Gigabyte Motherboard, 8 GB Crossair Vengance, Cooler Master 450W Thunder PSU, 1.4 TB HDD, 18.5" TFT(Wide), Antec V1 Cabinet Social Group:VBForums - Developers from India
Private Sub cmdFind_Click()
Dim lngIndex As Long
For lngIndex = 0 To lstMarks.ListCount - 1
If Val(lstMarks.List(lngIndex)) = Val(txtFind.Text) Then
lstNames.Selected(lngIndex) = True
lstMarks.Selected(lngIndex) = True
lblMessage.Caption = "record not found"
ElseIf lstNames.Selected(lngIndex) = False And lstMarks.Selected(lngIndex) = False Then
lblMessage.Caption = "record found"
Exit Sub
End If
Next
End Sub
that doesnt quite work as intended, when it finds the first record it says found, when it finds the second record message displays "record not found"
if the record doesnt exist it still says "record found"
Private Sub cmdFind_Click()
'~~~ Deselecting any previously selected item
If lstMarks.ListIndex <> -1 Then
lstMarks.Selected(lstMarks.ListIndex) = False
End If
If lstNames.ListIndex <> -1 Then
lstNames.Selected(lstNames.ListIndex) = False
End If
'~~~~ MartinLiss's code in your thread.
Dim lngIndex As Long
For lngIndex = 0 To lstMarks.ListCount - 1
If Val(lstMarks.List(lngIndex)) = Val(txtFind.Text) Then
lstNames.Selected(lngIndex) = True
lstMarks.Selected(lngIndex) = True
LblMessage.Caption = "Record Found !"
Exit Sub
End If
Next
LblMessage.Caption = "Record Not Found !"
End Sub
I had tested it..
If my post was helpful to you, then express your gratitude using Rate this Post.
And if your problem is SOLVED, then please Mark the Thread as RESOLVED (see it in action - video) My system: AMD FX 6100, Gigabyte Motherboard, 8 GB Crossair Vengance, Cooler Master 450W Thunder PSU, 1.4 TB HDD, 18.5" TFT(Wide), Antec V1 Cabinet Social Group:VBForums - Developers from India
how can i amend the cmdfind text box to search using the marks or by the name?
i know i can use the ISNUMERIC function (I THINK) but how?
please let me know
cheers
So, you want to make it available to use marks or name in the same textbox for searching?
I think ISNUMERIC will fail in certain cases. If you search this forum, you will find some posts of anhn, which he had described it in a very neat manner ..
If my post was helpful to you, then express your gratitude using Rate this Post.
And if your problem is SOLVED, then please Mark the Thread as RESOLVED (see it in action - video) My system: AMD FX 6100, Gigabyte Motherboard, 8 GB Crossair Vengance, Cooler Master 450W Thunder PSU, 1.4 TB HDD, 18.5" TFT(Wide), Antec V1 Cabinet Social Group:VBForums - Developers from India
should i search for any syntax in particular by ANHN?? i.e. ISNUMERIC or a particular keyterm that will enable me to acheive this task? to avoid me reading through numerous posts...
should i search for any syntax in particular by ANHN?? i.e. ISNUMERIC or a particular keyterm that will enable me to acheive this task? to avoid me reading through numerous posts...
In the Advance Search page of this forum, write isnumeric in Keywords box. And for the User Name box, write anhn
Advanced Search option is available in the dropdown list of Search at the top of this page
If my post was helpful to you, then express your gratitude using Rate this Post.
And if your problem is SOLVED, then please Mark the Thread as RESOLVED (see it in action - video) My system: AMD FX 6100, Gigabyte Motherboard, 8 GB Crossair Vengance, Cooler Master 450W Thunder PSU, 1.4 TB HDD, 18.5" TFT(Wide), Antec V1 Cabinet Social Group:VBForums - Developers from India
what code am I looking for? i can find how to validate numbers but not text and numbers using your ISNUMERIC..
please help me understand the function I need...
thank you
So what's the question?
If my post was helpful to you, then express your gratitude using Rate this Post.
And if your problem is SOLVED, then please Mark the Thread as RESOLVED (see it in action - video) My system: AMD FX 6100, Gigabyte Motherboard, 8 GB Crossair Vengance, Cooler Master 450W Thunder PSU, 1.4 TB HDD, 18.5" TFT(Wide), Antec V1 Cabinet Social Group:VBForums - Developers from India
ok well, i studied the 6 links that appeared under anhn username with regards to ISNUMERIC function...
I could not see figure out how the ISNUMERIC function can validate both text and numbers, so needed someone to guide me to the section where it shows this? or alternatively explain how a textbox can search my listbox using numbers and text?
Private Sub cmdFind_Click()
'~~~ Deselecting any previously selected item
If lstMarks.ListIndex <> -1 Then
lstMarks.Selected(lstMarks.ListIndex) = False
End If
If lstNames.ListIndex <> -1 Then
lstNames.Selected(lstNames.ListIndex) = False
End If
'~~~~ MartinLiss's code in your thread.
Dim lngIndex As Long
If IsNumeric(txtfind.Text) Then
For lngIndex = 0 To lstMarks.ListCount - 1
If Val(lstMarks.List(lngIndex)) = Val(txtfind.Text) Then
lstNames.Selected(lngIndex) = True
lstMarks.Selected(lngIndex) = True
LblMessage.Caption = "Record Found !"
Exit Sub
End If
Next
Else
For lngIndex = 0 To lstNames.ListCount - 1
If lstNames.List(lngIndex) = txtfind.Text Then
lstNames.Selected(lngIndex) = True
lstMarks.Selected(lngIndex) = True
LblMessage.Caption = "Record Found !"
Exit Sub
End If
Next
End If
LblMessage.Caption = "Record Not Found !"
End Sub
all names and marks entered can be sorted in descending order into two seperate listboxes...
I am trying to use "bubblesorting methods" to acheive this but just do not understand how it can be done, can someone take a look at the program and tell me how the entered names and marks can be sorted in descending order by number in the below listboxes if the user presses the sort command button?? and possibly "comment" the code so i can understand whats happening...
If you take a look at my program you will see what I mean...i have attached a copy
all names and marks entered can be sorted in descending order into two seperate listboxes...
I am trying to use "bubblesorting methods" to acheive this but just do not understand how it can be done, can someone take a look at the program and tell me how the entered names and marks can be sorted in descending order by number in the below listboxes if the user presses the sort command button?? and possibly "comment" the code so i can understand whats happening...
If you take a look at my program you will see what I mean...i have attached a copy
please help
thanks for your time and support
Where's the code for sorting ? I didn't see any code for sorting other than 2 other listboxes and a button for SORT !
You have to do some effort !
If my post was helpful to you, then express your gratitude using Rate this Post.
And if your problem is SOLVED, then please Mark the Thread as RESOLVED (see it in action - video) My system: AMD FX 6100, Gigabyte Motherboard, 8 GB Crossair Vengance, Cooler Master 450W Thunder PSU, 1.4 TB HDD, 18.5" TFT(Wide), Antec V1 Cabinet Social Group:VBForums - Developers from India
I assume you want to keep the data together but do you want to sort on the names or do you want to sort on the marks? Also why do you have the Enabled property of lstNames and lstMarks set to False?
akhileshbc is right about showing your work but here is a sort based on the name.
Code:
Private Sub cmdSort_Click()
Dim lngIndex As Long
Dim bSwapped As Boolean
Dim strName As String
Dim intMark As Integer
' Since we are going to loop until bSwapped = False we need to set it to
' True at the start
bSwapped = True
Do Until Not bSwapped
' Set it to false so if there are no values to be swapped, the
' process will end
bSwapped = False
' Loop through the data. we start at 1 rather than zero because we
' have to look at the previous value
For lngIndex = 1 To lstNames.ListCount - 1
' If the current value is greater than the previous one then we
' need to swap the values
If lstNames.List(lngIndex) > lstNames.List(lngIndex - 1) Then
' Store the high values
strName = lstNames.List(lngIndex)
intMark = lstMarks.List(lngIndex)
' Replace the high values with the low values
lstNames.List(lngIndex) = lstNames.List(lngIndex - 1)
lstMarks.List(lngIndex) = lstMarks.List(lngIndex - 1)
' Replace the low values with the stored high values
lstNames.List(lngIndex - 1) = strName
lstMarks.List(lngIndex - 1) = intMark
' Indicate that we have swapped some data
bSwapped = True
' Get out of the For/Next loop
Exit For
End If
Next
Loop
End Sub
the numbers are not sorted in descending order in the screenshot, the number 5 should be last...please help me understand why?? im learning this and dont understand explanations found so your explanation would be most appreciated
The sort I provided keeps the mark with the name of the person it is associated with. So since Paul is second in the sorted list the mark of 5 he got is also second. It wouldn't make sense IMO for the two lists to be sorted separately, but you can I'm sure make that modification if you want to by duplicating the sort code and making one refer only to the lstNames and the other only to lstMarks. (Don't forget to reset bSwapped to True between the two sorts)