View Full Version : Dragging Listbox Items within same listbox up/down
LOSS1574
01-15-2009, 10:27 AM
the below code works for a single column listbox. However I need to adjust the code to allow dragging within a four column listbox...
Private Sub lstMulti_BeforeDropOrPaste(ByVal Cancel As MSForms.ReturnBoolean, _
ByVal Action As MSForms.fmAction, _
ByVal Data As MSForms.DataObject, _
ByVal X As Single, _
ByVal Y As Single, _
ByVal Effect As MSForms.ReturnEffect, _
ByVal Shift As Integer)
Dim lTo As Long
With Me.lstMulti
lTo = .TopIndex + Int(Y * 0.85 / .Font.Size)
If lTo >= .ListCount Then lTo = .ListCount
Cancel = True
Effect = fmDropEffectMove
.AddItem Data.GetText, lTo
If mobjFromList = Me.lstMulti And lTo < mlFrom Then
mobjFromList.RemoveItem (mlFrom + 1)
Else
mobjFromList.RemoveItem mlFrom
End If
Set mobjFromList = Nothing
End With
End Sub
Thank you,
Kenneth Hobs
01-15-2009, 11:34 AM
You will need to iterate the Column property most likely. An attached xls would help us help you more easily.
LOSS1574
01-15-2009, 12:17 PM
Please see the attached xls
LOSS1574
01-16-2009, 09:01 AM
Any help with this issue would be appreciated...
Move and drag item with Mouse for a four column listbox
Kenneth Hobs
01-16-2009, 04:37 PM
I will have to rework what I was working on for this. I was able to create a string using the BoundColumn property in a loop. However, the tab delimiter that I added to not match what the range set so I will have to think on this more.
The lTo is a bit confusing.
Private Sub lstMulti_BeforeDropOrPaste(ByVal Cancel As MSForms.ReturnBoolean, _
ByVal Action As MSForms.fmAction, _
ByVal Data As MSForms.DataObject, _
ByVal X As Single, _
ByVal Y As Single, _
ByVal Effect As MSForms.ReturnEffect, _
ByVal Shift As Integer)
Dim lTo As Long
With Me.lstMulti
lTo = .TopIndex + Int(Y * 0.85 / .Font.Size)
If lTo >= .ListCount Then lTo = .ListCount
Cancel = True
Effect = fmDropEffectMove
.AddItem Data.GetText, lTo
If mobjFromList = Me.lstMulti And lTo < mlFrom Then
mobjFromList.RemoveItem (mlFrom + 1)
Else
mobjFromList.RemoveItem mlFrom
End If
Set mobjFromList = Nothing
End With
End Sub
Kenneth Hobs
01-16-2009, 06:14 PM
Private mobjFromList As MSForms.ListBox
Private mlFrom As Long
Private aItem() As String
Private Sub lstMulti_MouseMove(ByVal Button As Integer, _
ByVal Shift As Integer, _
ByVal X As Single, _
ByVal Y As Single)
Dim objData As DataObject
Dim lEffect As Long
Dim i As Integer
Const lLEFTMOUSEBUTTON As Long = 1
With lstMulti
If Button = lLEFTMOUSEBUTTON Then
Set objData = New DataObject
Set mobjFromList = Me.lstMulti
ReDim aItem(0 To .ColumnCount - 1) As String
For i = 1 To .ColumnCount - 1
aItem(i) = .Column(i, .ListIndex)
Next i
'objData.SetText Me.lstMulti.Text
mlFrom = Me.lstMulti.ListIndex
lEffect = objData.StartDrag
End If
End With
' If Int(Y / 10) < lstMulti.ListCount Then
' lstMulti.ListIndex = Int(Y / 10)
' End If
End Sub
Private Sub lstMulti_BeforeDragOver(ByVal Cancel As MSForms.ReturnBoolean, _
ByVal Data As MSForms.DataObject, _
ByVal X As Single, _
ByVal Y As Single, _
ByVal DragState As MSForms.fmDragState, _
ByVal Effect As MSForms.ReturnEffect, _
ByVal Shift As Integer)
Cancel = True
Effect = fmDropEffectMove
End Sub
Private Sub lstMulti_BeforeDropOrPaste(ByVal Cancel As MSForms.ReturnBoolean, _
ByVal Action As MSForms.fmAction, _
ByVal Data As MSForms.DataObject, _
ByVal X As Single, _
ByVal Y As Single, _
ByVal Effect As MSForms.ReturnEffect, _
ByVal Shift As Integer)
Dim r As Range, s As String
Dim i As Integer
Dim lTo As Long
With Me.lstMulti
lTo = .TopIndex + Int(Y * 0.85 / .Font.Size)
If lTo >= .ListCount Then lTo = .ListCount
Cancel = True
Effect = fmDropEffectMove
Set r = Range(Cells(Rows.Count, 1), Cells(Rows.Count, .ColumnCount))
For i = 1 To .ColumnCount - 1
.Column(i, lTo) = aItem(i)
Next i
If mobjFromList = Me.lstMulti And lTo < mlFrom Then
mobjFromList.RemoveItem (mlFrom + 1)
Else
mobjFromList.RemoveItem mlFrom
End If
Set mobjFromList = Nothing
End With
End Sub
Private Sub cmdWeiter_Click()
Unload Me
End Sub
Private Sub UserForm_Initialize()
Dim r As Range
Set r = Sheet1.Range("List1")
With lstMulti
.List = r.Value
.ColumnWidths = "0.5 in;1.5 in;0.5 in; 0.5 in"
End With
End Sub
LOSS1574
01-17-2009, 01:31 PM
Keith:
Thanks for the code. I'm getting an error message when i attempt to move the last item in the listbox up..
If mobjFromList = Me.lstMulti And lTo < mlFrom Then
mobjFromList.RemoveItem (mlFrom + 1) -------------This line
Else
mobjFromList.RemoveItem mlFrom
End If
Set mobjFromList = Nothing
End With
Kenneth Hobs
01-17-2009, 02:46 PM
I will have to think about your logic some more. As you can see from multiple moves in the Immediate window with debug, your code is removing items. Try moving the 3rd to the 2nd, twice. The ListCount should not be changing.
Private Sub lstMulti_BeforeDropOrPaste(ByVal Cancel As MSForms.ReturnBoolean, _
ByVal Action As MSForms.fmAction, _
ByVal Data As MSForms.DataObject, _
ByVal X As Single, _
ByVal Y As Single, _
ByVal Effect As MSForms.ReturnEffect, _
ByVal Shift As Integer)
Dim r As Range, s As String
Dim i As Integer
Dim lTo As Long
With Me.lstMulti
lTo = .TopIndex + Int(Y * 0.85 / .Font.Size)
If lTo >= .ListCount Then lTo = .ListCount
Cancel = True
Effect = fmDropEffectMove
Set r = Range(Cells(Rows.Count, 1), Cells(Rows.Count, .ColumnCount))
For i = 1 To .ColumnCount - 1
.Column(i, lTo) = aItem(i)
Next i
If mobjFromList = Me.lstMulti And (lTo < mlFrom) Then
Debug.Print 1, mlFrom, lTo, .ListCount
mobjFromList.RemoveItem (mlFrom + 1)
Else
Debug.Print 1, mlFrom, lTo, .ListCount
mobjFromList.RemoveItem mlFrom
End If
Set mobjFromList = Nothing
End With
End Sub
I will probably look at what Andy Pope did in: http://www.ozgrid.com/forum/showthread.php?t=58952
The code there is shown below. You can get Andy's xls or use his code below for a UserForm with ListBox1.
Option Explicit
Private m_sngLBRowHeight As Single
Private Sub ListBox1_BeforeDragOver(ByVal Cancel As MSForms.ReturnBoolean, _
ByVal Data As MSForms.DataObject, _
ByVal X As Single, ByVal Y As Single, _
ByVal DragState As MSForms.fmDragState, ByVal Effect As MSForms.ReturnEffect, _
ByVal Shift As Integer)
Cancel = True
Effect = 1
End Sub
Private Sub ListBox1_BeforeDropOrPaste(ByVal Cancel As MSForms.ReturnBoolean, _
ByVal Action As MSForms.fmAction, _
ByVal Data As MSForms.DataObject, _
ByVal X As Single, ByVal Y As Single, _
ByVal Effect As MSForms.ReturnEffect, ByVal Shift As Integer)
Cancel = True
Effect = 1
Dim s As String
Dim i As Integer
Dim lngListRow As Long
' hit test
lngListRow = (Y / m_sngLBRowHeight) + ListBox1.TopIndex - 1
If lngListRow > (ListBox1.ListCount - 1) Then lngListRow = ListBox1.ListCount - 1
If lngListRow < 0 Then lngListRow = 0
s = Data.GetText
i = Mid(s, InStr(1, s, "@@") + 2, Len(s))
ListBox1.RemoveItem i
ListBox1.AddItem Left(s, InStr(1, s, "@@") - 1), lngListRow
End Sub
Private Sub UserForm_Activate()
Dim sngOldHeight
If m_sngLBRowHeight = 0 Then
With ListBox1
.TopIndex = .ListCount - 1
sngOldHeight = .Height
Do While .TopIndex = 0
.Height = .Height - 10
.TopIndex = .ListCount - 1
Loop
m_sngLBRowHeight = .Height / (.ListCount - .TopIndex + 1)
.Height = sngOldHeight
.TopIndex = 0
End With
End If
End Sub
Private Sub ListBox1_MouseMove(ByVal Button As Integer, _
ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
Dim myDataObject As DataObject
If Button = 1 Then
Set myDataObject = New DataObject
Dim Effect As Integer
myDataObject.SetText ListBox1.Value & "@@" & ListBox1.ListIndex
Effect = myDataObject.StartDrag
End If
End Sub
Private Sub UserForm_Initialize()
Dim i As Long
For i = 1 To 5
ListBox1.AddItem "Choice " & (ListBox1.ListCount + 1)
Next i
End Sub
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.