Есть ли способ инициализировать общедоступный массив на основе условия?

#excel #vba #multidimensional-array

#excel #vba #многомерный массив

Вопрос:

У меня есть массив с 3 измерениями. Я хотел бы получить доступ к этому массиву из нескольких модулей в Excel VBA. По этой причине я использую Public для его объявления. В настоящее время я использую этот код:

 Public MyData(1 To 400, 1 To 10, 1 To 3000) As Double 
  

Я хотел бы инициализировать первую и третью переменные один раз при запуске моего кода с определенным значением в зависимости от размеров моих данных.

Поскольку ReDim может использоваться только для последней переменной в массиве, я пытаюсь сделать что-то подобное, хотя это невозможно:

 If x < 400 and z < 3000 Then    
    Public MyData(1 To 400, 1 To 10, 1 To 3000) As Double 
End If

If x < 200 and z < 1000 Then    
    Public MyData(1 To 200, 1 To 10, 1 To 1000) As Double 
End If
  

Есть ли способ инициализировать массив на основе условия (значения x и z ниже определенного уровня)?

Спасибо!

Ответ №1:

  1. ReDim может быть выполнено для любого измерения. ReDim Preserve ограничивается изменением только последнего измерения с сохранением существующего значения загруженных элементов. Но также для ReDim Preserve существует обходной путь: вы делаете последнее измерение тем, которое хотите изменить, сохраняете и, наконец, транспонируете массив;

  2. ReDim может быть выполнено только для объявленного массива, но без настройки размеров при его объявлении. Итак, объявляем его следующим образом:

 Public MyData() As Double
  

будет работать так, как вам нужно…

  1. Public Переменная может быть размещена только поверх вашего модуля, в области объявлений. Итак, там не разрешен какой-либо подобный код. Вы можете только ReDim сделать это так, как вы пытались, в модуле Sub/Function , только если вы объявите его так, как я рекомендовал выше

Комментарии:

1. Спасибо, что заметили эту ошибку. Значит, я могу выполнить повторную настройку только один раз? (Этого будет достаточно.)

2. @ FaneDuru Мне кажется, что массив можно переделать дважды. Я добавил пример выше. Или ты имеешь в виду что-то другое? Я вижу, я потерял данные в myArray (2,9)!

3. @пользователь2165379: Да. Если вы объявите это без каких-либо измерений, это возможно… Я был недостаточно внимателен, когда отвечал в приведенном выше комментарии. Хорошо бы не злоупотреблять ReDim для хорошего управления памятью.

4. @ FaneDuru Значит, не стоит использовать Redim Preserve для каждого увеличения z из-за управления памятью? Было бы лучше увеличить z с шагом 1000?

5. @user2165379: Если вы не можете оценить максимальное количество загружаемых элементов и, наконец, используете Redim Preserve только один раз, решение с использованием больших шагов лучше, чем использовать его для каждого необходимого загружаемого элемента, да.

Ответ №2:

Вот типичный ReDim пример:

 Public multiArray()

Sub initL()
    Dim larry As Long, moe As Long, curley As Long
    
    larry = 7
    moe = 11
    curley = 13
    
    ReDim multiArray(1 To larry, 1 To moe, 1 To curley)
End Sub