Я пытаюсь создать пользовательскую форму, посредством которой люди могут размещать столько запросов, сколько захотят, с возможностью удаления запросов, которые они больше не хотят, а также других функций. У меня возникла проблема с удалением динамически создаваемых объектов после того, как функции add-remove-add были использованы в этой последовательности.Excel VBA - динамическая пользовательская форма с добавлением/удалением функциональности объекта
В приведенном ниже коде есть фрагмент объектов, добавленных в форму пользователя, а также изменения размеров в пользовательскую форму и объекты, уже встроенные в пользовательскую форму. Другие определенные части не включены ниже.
Dim RemoveButtonArray() As New Class_RemoveRequest
For i = Last To Last
Set AddRemoveButton = GenPurchaseRequest.Controls.Add("Forms.Image.1", "btnRemove" & ObjID)
With AddRemoveButton
'properties
End With
Set AddRemoveLabel = GenPurchaseRequest.Controls.Add("Forms.Label.1", "lblRemove" & ObjID)
With AddRemoveLabel
'properties
End With
Set AddRequest = GenPurchaseRequest.Controls.Add("Forms.Frame.1", "Frame" & ObjID)
With AddRequest
'properties
.Caption = "Purchase Request - " & ObjID
End With
With AddRequestButton
.Top = 168 + (126 * i)
.Left = 18
End With
With SubmitButton
.Top = 168 + (126 * i)
.Left = 200
End With
With CancelButton
.Top = 168 + (126 * i)
.Left = 381
End With
With GenPurchaseRequest
.ScrollHeight = 200 + (126 * i)
.ScrollTop = 200 + (126 * i)
End With
ReDim Preserve RemoveButtonArray(0 To i)
Set RemoveButtonArray(i).RemoveButton = AddRemoveButton
Next i
ObjID = ObjID + 1
Last = Last + 1
Это хорошо работает, и форма заполнена всем правильно. Когда пользователь удаляет запрос, приведенный ниже код работает отлично, а также:
Public WithEvents RemoveButton As MSForms.Image
Private Sub RemoveButton_click()
Dim ConfirmRemoval As Integer
Dim rbRefNo As String
Dim rbRefNoConvert As Integer
ConfirmRemoval = MsgBox("Are you sure you would like to remove this request?", vbYesNo)
If ConfirmRemoval = vbYes Then
rbRefNo = Mid(Me.RemoveButton.Name, 10)
rbRefNoConvert = CInt(rbRefNo)
With GenPurchaseRequest
If Last > 1 Then
.Controls.Remove ("Frame" & rbRefNo)
.Controls.Remove ("btnRemove" & rbRefNo)
.Controls.Remove ("lblRemove" & rbRefNo)
For i = rbRefNoConvert + 1 To Last - 1
.Controls("Frame" & i).Top = .Controls("Frame" & i).Top - 126
.Controls("btnRemove" & i).Top = .Controls("btnRemove" & i).Top - 126
.Controls("lblRemove" & i).Top = .Controls("lblRemove" & i).Top - 126
Next i
.AddRequestButton.Top = .AddRequestButton.Top - 126
.SubmitButton.Top = .SubmitButton.Top - 126
.CancelButton.Top = .CancelButton.Top - 126
.ScrollTop = .ScrollTop - 126
.ScrollHeight = .ScrollHeight - 126
Last = Last - 1
Else
MsgBox "There is only one active Purchase Request."
End If
End With
Else
'do nothing
End If
End Sub
Пользователь затем может вернуться добавить дополнительные запросы, а также удалить больше запросов, что они больше не хотят. Проблема возникает, когда они добавляют больше запросов, а затем пытаются удалить последний, добавленный непосредственно после удаления. Например: я добавил 4 запроса, а затем удалил второй. Затем я добавил другой запрос, но хотел удалить 4-й запрос, однако кнопка удаления больше не работает.
Я считаю, что проблема в том, что мне нужно переопределить массив, используемый для хранения кнопок удаления после вызова функции удаления, но я понятия не имею, как это сделать. Моя текущая попытка сделать это:
For j = 0 To Last
If j = rbRefNoConvert Then
j = j + 1
Else
ReDim RemoveButtonArray(0 To j)
Set RemoveButtonArray(j).RemoveButton = AddRemoveButton
End If
Next j
Но это ссылка на объект неправильно, и я не знаю, как ссылаться на него правильно. Я попытался обратиться к самому контролю, но это не сработало.
Я очень новичок в использовании модулей классов, массивов и динамических пользовательских форм, поэтому извините за длительный вопрос!
Любая помощь будет очень признательна!
Там много кода, поэтому сложно точно выяснить, что происходит. Более простой пример, используя только массив кнопок, вероятно, будет легче следовать. Вместо повторной организации массива всякий раз, когда заказ удаляется, вы можете просто установить этот элемент в массиве Nothing, а затем добавить любые новые порядки в конец массива (расширяя по мере необходимости). Чтобы перестроить компоновку формы, просто перейдем к массиву, игнорируя «пустые» элементы. –
[Этот ответ] (http://stackoverflow.com/a/7000798/1698517), который показывает, как удалить элемент из массива, может оказаться полезным. – Jaycal
@TimWilliams - Единственные элементы управления, которые я использую с массивами, будут элементами управления, которым нужен обработчик событий. Используя ваш пример, мне нужно будет поместить все мои элементы управления в отдельные массивы? –