Есть ли способ перенести все значения из одного массива в другой, а затем стереть исходный массив?

#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 = "" as i , представляющий элемент, а не индекс.

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. Звучит хорошо! Я попробую и, если не смогу разобраться, опубликую отдельный вопрос