我有一个包含10次的列表框。我有向上和向下按钮来上下移动项目。仅当我将listbox multiselect属性设置为“无”时,我的VBA才有效。对于multiselect = simple选项,它会抛出错误,就像在这行代码中有效使用null一样
sText = lbfNames.Column(0, iIndex)
我的VBA
Private Sub cmdUP_Click()
Dim sText As String
Dim iIndex As Integer
iIndex = lbfNames.ListIndex
'check: only proceed if there is a selected item
If lbfNames.ListCount > 1 Then
'index 0 is top item which can't be moved up!
If iIndex <= 0 Then
MsgBox ("Can not move the item up any higher.")
Exit Sub
End If
' If iIndex = -1 Or lbfNames.ListCount > 1 Then
'save items text and items indexvalue
sText = lbfNames.Column(0, iIndex)
lbfNames.RemoveItem iIndex
'place item back on new position
lbfNames.AddItem sText, iIndex - 1
'if you keep that item selected
'you can keep moving it by pressing cmdUp
lbfNames.Selected(iIndex - 1) = True
iIndex = iIndex - 1
End If
End sub
我试图将下面的C#代码(在stackoverflow中找到)转换为Access VBA抛出错误。找不到某些数据成员。
public void MoveUp()
{
MoveItem(-1);
}
public void MoveDown()
{
MoveItem(1);
}
public void MoveItem(int direction)
{
// Checking selected item
if (listBox1.SelectedItem == null || listBox1.SelectedIndex < 0)
return; // No selected item - nothing to do
// Calculate new index using move direction
int newIndex = listBox1.SelectedIndex + direction;
// Checking bounds of the range
if (newIndex < 0 || newIndex >= listBox1.Items.Count)
return; // Index out of range - nothing to do
object selected = listBox1.SelectedItem;
// Removing removable element
listBox1.Items.Remove(selected);
// Insert it in new position
listBox1.Items.Insert(newIndex, selected);
// Restore selection
listBox1.SetSelected(newIndex, true);
}
无论如何都要在访问vba中执行此操作。
答案 0 :(得分:0)
我实际上重建了这个设置,但永远不会得到你提到的错误。我确实玩过代码来调整它以适应你想要做的事情。试试这个:
Private Sub cmdup_Click()
Dim sText As String
Dim iIndex As Variant
Dim selection() As Integer
Dim n, topSelection As Integer
' save the indexes of the selected items,
' they will be deselected after the first removal
For Each iIndex In lbfnames.ItemsSelected
ReDim Preserve selection(0 To n)
selection(n) = iIndex
n = n + 1
Next
'loop through all the selected indexes
'this will also ensure you will only proceed if there is a selected item
For n = LBound(selection) To UBound(selection)
'save items text and items indexvalue
sText = lbfnames.Column(0, selection(n))
If selection(n) <= topSelection Then 'index topSelection is top item which can't be moved up!
MsgBox ("Can not move item '" & sText & "' up any higher.")
topSelection = topSelection + 1
Else
'first remove item from old position
lbfnames.RemoveItem selection(n)
'place item back on new position
lbfnames.AddItem sText, selection(n) - 1
'change the index of the selected value to the new index (for reselection)
selection(n) = selection(n) - 1
End If
Next
'loop through the selection again to reselect
For n = LBound(selection) To UBound(selection)
lbfnames.Selected(selection(n)) = True
Next
End Sub
我认为代码和注释不言自明,但这是一个快速的贯穿:
注意:示例C#代码显示了两个移动方向的更通用的功能。我没有调整它,我认为这是一个好主意,但留给你实现(总是一个很好的练习来理解代码)。
答案 1 :(得分:0)
以下代码是安全的,可以使用枚举指示方向。 该解决方案允许在列表中上下移动。 解决方案将移动内容包裹起来(例如,如果位于列表顶部,然后尝试向上移动,则将项目包裹到底部。
Private Enum directions
down = -1
up = 1
End Enum
Private Sub cmdDown_Click()
moveListItem (down)
End Sub
Private Sub cmdMvUp_Click()
moveListItem (up)
End Sub
Private Sub moveListItem(direction As directions)
With Me.ListBox1
Select Case .ListIndex
' at bottom and moving down then wrap around to top
Case Is >= .ListCount + direction
.AddItem .Column(0, .ListCount - 1), 0
.RemoveItem (.ListCount - 1)
.Selected(0) = True
' at top and moving up then wrap around to bottom
Case Is < direction
.AddItem .Column(0, 0), .ListCount
.RemoveItem (0)
.Selected(.ListCount - 1) = True
Case Else
.AddItem .Column(0, .ListIndex - direction), .ListIndex + ((direction + 1) / 2)
.RemoveItem (.ListIndex - direction)
End Select
End With
End Sub
答案 2 :(得分:0)
如果您不希望使用环绕式功能,请修改上述解决方案。
Option Explicit
Private Enum directions
down = -1
up = 1
End Enum
Private Sub cmdDown_Click()
moveListItem (down)
End Sub
Private Sub cmdMvUp_Click()
moveListItem (up)
End Sub
Private Sub moveListItem(direction As directions)
With Me.ListBox1
Select Case .ListIndex
' at bottom and moving down then wrap around to top
Case Is >= .ListCount + direction
' at top and moving up then wrap around to bottom
Case Is < direction
Case Else
.AddItem .Column(0, .ListIndex - direction), .ListIndex + ((direction + 1) / 2)
.RemoveItem (.ListIndex - direction)
End Select
End With
End Sub