Two Listboxes with almost the same info.

My form has two listboxes. Both display filenames after a search of the drive (*.avi). However, i put in a function that strips the path from one listbox(the one the user will see).

Here is the Form_Load.

Private Sub Form_Load()

Dim strFind() As String
Dim lngFound As Long
Dim lngCount As Long

Set objFind = New clsFileFinder

DoEvents
 
 lngFound = objFind.LocateFileLocally("*.avi", strFind)
   If objFind.blnFindAbort Then
    Exit Sub
   End If
 
 For lngCount = 0 To lngFound - 1
 
  List1.AddItem sGetFileName(strFind(lngCount)) 'no path
  List2.AddItem (strFind(lngCount))  'path included
  List1.ItemData(List1.NewIndex) = List2.NewIndex 'line from mcrider
 Next

Set objFind = Nothing

End Sub


Function sGetFileName(sFullPath As String) As String
Dim i As Integer
   For i = Len(sFullPath) To 1 Step -1
    If (Mid$(sFullPath, i, 1) = "\") Then Exit For
   Next
   sGetFileName = Mid$(sFullPath, i + 1)
End Function



This works awesome!!! Until,
I set the .Sorted Property to True on one or two listboxes. Then they don't stay in synch.

mcrider gave me the .NewIndex line but it still doesn't work.

What am i doing wrong?

see Q.10227083 for the history of this question if you want to.

Experts: Please don't answer this question until i can verify that it works properly through your comments.(feel kinda funny rejecting an answer after you spent some time on it.:))
kkoserAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jgvCommented:
If nothing better comes along you can try this. It only works if the number of items in each listbox doesn't change once they're filled.
As items are entered into each listbox, match their ItemData values:

For lngCount = 0 To lngFound - 1
   
  List1.AddItem sGetFileName(strFind(lngCount)) 'no path
  List2.AddItem (strFind(lngCount))  'path included
  List1.ItemData(List1.NewIndex) = lngCount
  List2.ItemData(List2.NewIndex) = lngCount
Next

Once everything is in, find the matching ItemData values to get the proper listindex:

Dim a, b
For a = 0 To List1.ListCount - 1
    For b = 0 To List2.ListCount - 1
        If List1.ItemData(a) = List2.ItemData(b) Then
            List1.ItemData(a) = b
            List2.ItemData(b) = a
            Exit For
        End If
    Next
Next

0
kkoserAuthor Commented:
not yet...

Looked like it Should've worked.

I didn't realize what kind of headache this was going to be...
0
jgvCommented:
Strange, I tested it and it worked fine with either listbox sorted. Oh well, good luck :)
0
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

wyllikerCommented:
If you really need both listboxes to be sorted, then jgv's code in his comment above will work correctly if implemented EXACTLY as he has it. Of course, substituting any names of functions or variables that may be different in your code - though it looks as if he has used yours.

I don't know what you could have done to make it not work!  From an algorithmic standpoint there is no way that it could not work.

It works from both list boxes - ie. it is transitive.  After jgv's two For loops have finished you can get the fullpath corresponding to a filename by ...

FullPathIndex = List1.ItemData(List1.ListIndex)

Conversely you can get the filename that corresponds to a full path by ...

FullNameIndex = List2.ItemData(List2.ListIndex)



That said, I can think of no reason whatsoever for the fullpath list box to be sorted - since (I am infering from your question) that the user will never see it.

To repeat and hopefully help to explain mcrider's answer - which was absolutely correct and I thought was clear - to your previous question ...

The first thing you need to do is to make the listbox that the user will see SORTED (.Sorted = True) and the hidden listbox that you are using to hold the full path as UNSORTED (.Sorted = False).

If the user never sees the fullpath listbox, there is absolutely no reason for it to be sorted.  It won't make synchronization any easier - in fact it will make it worse!


The following will only work if the filename listbox is SORTED and the fullpath listbox is UNSORTED.

When loading the listboxes, the code should look something like this ...
(Substitute your variable, function and control names)

    For ii = 0 to UBound(ArrayToLoad)
        List1.AddItem (ArrayToLoad(ii))
        List2.AddItem (StripPath(ArrayToLoad(ii)))
        List1.ItemData(List1.NewIndex) = List2.NewIndex
    Next

Now, each item in the visible listbox (List1) has the corresponding index of where you will find the full path in the hidden listbox.

To retrieve the hidden full path you would use ...

    FullPathIndex = List1.ItemData(List1.ListIndex)
    FullPathString = List2.List(FullPathIndex)

If you want to test this approach out to verify that it works ...

1- Make both of your lists visible so you can see what happens.

2- Set the List1_Click Event to do the following ...

    List2.ListIndex = List1.ItemData(List1.Index)

When you run the program you will see that every time you click on a filename the correct fullpath will be selected in List2.  Note that List2 will scroll automaticallly as necessary so that the selection is visible.

0
ventondCommented:
Why not make one listbox? Put the filename in the .List and put the path in the .ItemData field. That way no syncronization problem remains.
0
kkoserAuthor Commented:
sorry ventond, Need the two for making room on the form. The user only needs to see the filename.



0
kkoserAuthor Commented:
Private Sub Form_Load()
     
Dim strFind() As String
Dim lngFound As Long
Dim lngCount As Long


Set objFind = New clsFileFinder

DoEvents
 
 lngFound = objFind.LocateFileLocally("*.avi", strFind)
   If objFind.blnFindAbort Then
    Exit Sub
   End If
 
 For lngCount = 0 To lngFound - 1
 
  List1.AddItem sGetFileName(strFind(lngCount)) 'no path
  List2.AddItem (strFind(lngCount))  'path included
  List1.ItemData(List1.NewIndex) = List2.NewIndex 'line from mcrider
fullPathIndex = List1.ItemData(List1.NewIndex)
fullPathstring = List2.List(fullPathIndex)
Next

End Sub

Function sGetFileName(sFullPath As String) As String
Dim i As Integer
   For i = Len(sFullPath) To 1 Step -1
    If (Mid$(sFullPath, i, 1) = "\") Then Exit For
   Next
   sGetFileName = Mid$(sFullPath, i + 1)
End Function

Private Sub List1_Click()
List2.ListIndex = List1.ItemData(List1.Index)
End Sub




list1_Click event gave me an "object not an array" error message.

But

 List2.ListIndex = List1.ItemData(fullPathIndex)

returned me to the first record.(no matter which one i clicked on.)

I think it's working but i just don't have it setup right. (I think).
0
jgvCommented:
Private Sub List1_Click()
List2.ListIndex = List1.ItemData(List1.Index)
End Sub

Should be:

Private Sub List1_Click()
List2.ListIndex = List1.ItemData(List1.ListIndex)
End Sub
0
ventondCommented:
The .ItemData field is not visible to the user. If you put the path in that "list" of the list box then the user won't see it and you won't have to worry about syncronizing the two listboxes. The List box sorts on the .List "List".
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jgvCommented:
ventond, only a long integer can be assigned to a list entry's .ItemData property.
0
wyllikerCommented:
Last attempt at this one ...

The code you have presented above will not work as long as List2.Sorted = True!

This is because a full path may get inserted into List2 that causes all entries in the list to move down one position and therefore all of your List1.ItemData values from that point on will be wrong!


To illustrate:
(In olden days we called this a paper trace)

First Insertion

C:\thispath\file1.AVI

List1 has

file1.AVI

List2 has

C:\thispath\file1.AVI

List1.ItemData(List1.NewIndex) = List2.NewIndex  is effectively

List1.ItemData(1) = 1


Second Insertion

C:\thatpath\file2.AVI

List1 has

file1.AVI
file2.AVI

List2 has

C:\thatpath\file2.AVI
C:\thispath\file1.AVI


List1.ItemData(List1.NewIndex) = List2.NewIndex  is effectively

List1.ItemData(2) = 1


Third Insertion

C:\anotherpath\file3.AVI

List1 has

file1.AVI
file2.AVI
file3.AVI

List2 has

C:\anotherpath\file3.AVI
C:\thatpath\file2.AVI
C:\thispath\file1.AVI


List1.ItemData(List1.NewIndex) = List2.NewIndex  is effectively

List1.ItemData(3) = 1


Now, the ItemData associated with List1 will look like this:

List1.ItemData(1) = 1
List1.ItemData(2) = 1
List1.ItemData(3) = 1

This is almost exactly the behavior you are reporting.



If you make List2.Sorted = False

First Insertion

C:\thispath\file1.AVI

List1 has

file1.AVI

List2 has

C:\thispath\file1.AVI

List1.ItemData(List1.NewIndex) = List2.NewIndex  is effectively

List1.ItemData(1) = 1


Second Insertion

C:\thatpath\file2.AVI

List1 has

file1.AVI
file2.AVI

List2 has

C:\thispath\file1.AVI
C:\thatpath\file2.AVI


List1.ItemData(List1.NewIndex) = List2.NewIndex  is effectively

List1.ItemData(2) = 2


Third Insertion

C:\anotherpath\file3.AVI

List1 has

file1.AVI
file2.AVI
file3.AVI

List2 has

C:\thispath\file1.AVI
C:\thatpath\file2.AVI
C:\anotherpath\file3.AVI


List1.ItemData(List1.NewIndex) = List2.NewIndex  is effectively

List1.ItemData(3) = 3

Now, the ItemData associated with List1 will look like this:

List1.ItemData(1) = 1
List1.ItemData(2) = 2
List1.ItemData(3) = 3


Can you at least explain why it is required that List2 (FullPath) be sorted?

Also, if you cut and paste jgv's code from his first response to you and you use the List1_Click event handler correction to your code that he presented to you in his next to last message everything should work.

I have a running version of exactly what you want your code to do - and it is the code jgv gave you.  Fix your List1_Click event and use his code!



0
kkoserAuthor Commented:
you went above and beyond the call of duty. Thanx a bunch. Sorry for not returning the thread for a couple days, Had to move my sister.

I had it all along and just didn't see what was staring at me in front of my face.

I had pasted jgv's code in the Form_load() but i didn't paste the
List1_Click line. It looked like the same so I didn't bother.


I was using:

 List2.ListIndex = List1.ItemData(List1.Index)

When i should have been using:

 List2.ListIndex = List1.ItemData(List1.ListIndex)

Thanx a lot jgv!

I was doing it the right way but i wasn't calling it the right way.


I don't need List2 sorted.
0
jgvCommented:
I'm glad I could help but out of curiosity, why did you accept a completely wrong answer? Both wylliker and myself spent a bit of time helping and I think one of us should have been offered the points....

"Experts: Please don't answer this question until i can verify that it works properly through your comments.(feel kinda funny rejecting an answer after you spent some time on it)"

0
wyllikerCommented:
jgv,

I think he picked the wrong expert by mistake (At least I hope he did!).  You should get the points here.

You were dead on with the nested loop re-sync and if you had seen where mcrider had gone in this question (asked previously) he had an equally viable solution - though he got points.

I really wanted to re-emphasize and illustrate the correct answer you had given so that it wouldn't get bypassed because of what turned out to be that List_click event problem.

Hope you get invited to a question to at least get some points.

0
jgvCommented:
wylliker,
  I'm not too concerned about the points and I also think this must have been an oversite on kkoser's part. I simply wanted to point it out, mainly becaue you and I provided the only viable feedback to this Q in the form of comments (as per kkosers request). IMHO, if someone takes the time to help solve a question then the Q'er should take the time to evaluate the comments/answers.
Helping someone to find a solution to their problem is the main reason I give any input but the points are part of the system and should be respected.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.