#arrays #excel #vba #for-loop #userform
#массивы #excel #vba #для цикла #пользовательская форма
Вопрос:
Я столкнулся с проблемой с блоком кода, который я пытаюсь разработать на своей работе. По сути, я создаю пользовательскую форму в Excel, где пользователи будут вводить данные для вагонов по мере их загрузки в определенном месте (мы будем называть их «точка 1, точка 2, точка 3 и т. Д.»).
Иногда им приходится перемещать этот вагон в другое место, и в этом случае я хочу, чтобы они могли сохранить всю информацию о вагоне из первой / исходной записи, а затем стереть данные из исходного места, как только это будет сделано.
Чтобы выполнить это более упрощенным способом, я установил массивы для каждого из 5 мест, которые ссылаются на все ячейки, в которые они вводят данные в пользовательской форме:
Dim spot1information(14)
spot1information(0) = UserForm.ProductType1.Value
spot1information(1) = UserForm.ProductID1.Value
spot1information(2) = UserForm.BatchID1.Value
etc....
Dim spot2information(14)
spot2information(0) = UserForm.ProductType2.Value
spot2information(1) = UserForm.ProductID2.Value
spot2information(2) = UserForm.BatchID2.Value
etc....
И так далее для всех пяти мест. Я не знаю, усложняет ли это задачу, но обратите внимание, что не все эти значения массива имеют один и тот же тип. Например, index (0) будет строкой, но index (10) — это ДАТА-ВРЕМЯ, а index (12) определяется как Long .
Итак, скажем, что они перемещают автомобиль из точки 1 в точку 2. Короче говоря, я хочу, чтобы код выполнял следующее:
- Замените значения индексов 0 — 6 в spot2information (который в настоящее время пуст) на значения индексов 0 — 6 в spot1information (которые пользователь заполнил в пользовательской форме).
- Меня интересует перенос индексов 0-6 только потому, что они содержат соответствующую информацию о вагоне
- Очистите каждое значение spot1information до «»
Для достижения этой цели я попробовал следующий код и несколько его вариантов:
If OriginalSpot.Value = 1 Then
If DestinationSpot.Value = 2 Then
For i = 0 to 6
spot2information(i) = spot1information(i)
Next
For Each i in spot1information
spot1information(i) = ""
Next
End If
End If
Однако это продолжает приводить к несоответствию типов. Я полагаю, потому что данные в массиве spot2information пусты, а данные в массиве spot1information — нет, но я не совсем уверен, как это обойти.
Обновление: я сделал то, что было предложено ниже, и заменил: spot1information(i) = ""
на Erase spot1information
Теперь код по существу работает! Значения массива «spot2information» теперь являются прежними значениями «spot1information», а «spot1information» теперь пуст.
Предложенный ниже 2D-массив также работает как шарм. Новая проблема, с которой я столкнулся, заключается в том, что значения массива обновляются, а пользовательская форма — нет. (примечание: в будущем я буду публиковать подобные вещи как отдельный вопрос, мои извинения!)
Комментарии:
1. Ваш второй цикл должен иметь
i = ""
asi
, представляющий элемент, а не индекс.2. Вы имеете в виду vbscript или VBA? Если последнее, пожалуйста, исправьте свой тег.
3. Предполагается, что если на вопрос был дан ответ, то для завершения этого вопроса принимается соответствующий ответ. Если после реализации решения возникают «новые проблемы» , то откройте новый вопрос. Пожалуйста, не продолжайте добавлять требования к первоначальному вопросу, это вредно и неуместно.
4. Абсолютно, работаю над этим прямо сейчас! Спасибо за указатель!
Ответ №1:
Проще управлять этим как 2D-массивом:
Sub Tester()
Dim spots(1 To 5, 0 To 14), n As Long, i As Long
'fill your spot arrays from the form....
For n = 1 To 5
spots(n, 0) = UserForm.Controls("ProductType" amp; n).Value
spots(n, 1) = UserForm.Controls("ProductID" amp; n).Value
spots(n, 2) = UserForm.Controls("BatchID" amp; n).Value
'etc etc
Next n
'swap a spot with another
Debug.Print spots(2, 1), spots(3, 1)
SwapSpots spots:=spots, fromSpot:=2, toSpot:=3
Debug.Print spots(2, 1), spots(3, 1)
End Sub
Sub SwapSpots(spots, fromSpot As Long, toSpot As Long)
Dim n As Long
For n = 0 To 6
spots(toSpot, n) = spots(fromSpot, n)
spots(fromSpot, n) = Empty 'empty the source slot value
Next n
End Sub
Комментарии:
1. Я только что попробовал это сегодня, и я должен сказать, что вы, сэр, гений, я определенно собираюсь начать включать многомерные массивы в мои другие проекты.
Ответ №2:
Предполагая DataType
, что массивы одинаковы Index
, т.Е. index(0)
string
Для всех пятен, Index(2)
long
Для всех пятен и так далее.
Если это так, то эта часть не должна выдавать никаких ошибок:
For i = 0 to 6
spot2information(i) = spot1information(i)
Next
Ошибка должна возникать в этой части, точнее, в строке, отмеченной #
For Each i in spot1information
spot1information(i) = "" '#
Next
и причина ошибки, по-видимому, заключается в том, что попытка присвоить строковое значение ""
числовому типу, учитывая ошибку «несоответствие».
Использование For Each i in spot1information
указывает, что вы хотите «инициировать» или стереть весь массив, поэтому я предлагаю использовать эту строку вместо For…Next
метода.
Erase spot1information
В связи с этим:
Но теперь я столкнулся с новой проблемой, когда значения в пользовательской форме не были обновлены, чтобы отразить новые значения, хранящиеся в массиве. Нужно ли мне как-то «обновить» пользовательскую форму?
Вы только что обновили массивы, затем вам нужно запустить процедуры, используемые для обновления значений объектов, на которые влияют оба массива в UserForm
.
Комментарии:
1. О, хорошо, это имеет большой смысл! и вы правы, я изменил оператор «Для каждого» на оператор «Стереть» и больше не получал ошибку несоответствия типов.
2. Спасибо за ваш ответ на последующие действия, теперь я знаю, что это своего рода нетрадиционная вещь, которую нужно сделать здесь, в будущем я опубликую отдельный вопрос, чтобы избежать путаницы. Вы знаете, нужно ли мне использовать указатели для обновления значений тех объектов, на которые влияют массивы?
3. Я предполагаю, что массивы получены из пользовательских вводов в
UserForm
объекты (или в результате этих вводов). Теперь вам нужно установить процедуру для обновления этих объектов данными из массива.4. Звучит хорошо! Я попробую и, если не смогу разобраться, опубликую отдельный вопрос