Есть ли что-то похожее на оператор With, который можно использовать с массивами?

#excel #vba

Вопрос:

В if инструкции рассматриваются критерии, позволяющие определить, какой лист следует использовать для следующего раздела. Затем он соответствующим образом задает имя листа.

Я не уверен, что лучший способ-поместить массив в любой оператор вместо того, как это происходит в настоящее время с диапазонами рабочих листов, так как я не верю, что могу использовать WITH оператор для хранения имени массива, на которое ссылается.

Любая помощь будет признательна. Спасибо

 'sets which date range sheet to use
If spbe30array(i, 22) >= orders Then
    Set spbe = spbe30
Else
    Set spbe = spbe60
End If
            
'the section below is using a sheet name that is determined from the if statement above
i = i   1
With spbe
    Do While LCase(.Range("b" amp; i).Value) = "placement"
        If LCase(.Range("aa" amp; i).Value) = "product" Then
            PPclicks = .Range("t" amp; i).Value
        ElseIf LCase(.Range("aa" amp; i).Value) = "rest" Then
            ROSclicks = .Range("t" amp; i).Value
        End If
        i = i   1
    Loop
End With
 

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

1. Что вы имеете в виду под «преобразовать все в массив»? Что именно вы хотите перекодировать с использованием массивов? В приведенном выше коде уже используются массивы spbe30array , так что же именно вы пытаетесь сделать?

2. В настоящее время я запускаю весь сценарий, ссылающийся на диапазоны рабочих листов. Я хочу ускорить его, преобразовав все, начиная с диапазонов рабочих листов, вместо этого используя массивы…

3. Значит, вместо .Range("t" amp; i).Value тебя войдешь t_array(i,1) вместо меня? В этом случае больше нет необходимости в With заявлениях. На самом деле, в заявлениях никогда нет необходимости With , это просто удобство, поэтому вам не нужно каждый раз полностью уточнять рабочую книгу/лист/диапазон.

4. это моя проблема — первое утверждение IF рассматривает критерии, чтобы определить, с каким массивом работать. Затем он задает переменную имени массива, на которую ссылается остальная часть сценария. Я просто не знаю, как сказать: ArrayToUse=Array1 ArraytoUse(1,2)

5. Вы можете извлекать значения в массивы после оператора if. Таким образом, существует только один набор массивов для работы, увядания spbe30 или spbe60

Ответ №1:

Мне кажется, я понимаю, чего ты хочешь.

Вы можете извлечь значения из рабочего листа после того, как выбор будет сделан с помощью If инструкции.

     'sets which date range sheet to use
    If spbe30array(i, 22) >= orders Then
        Set spbe = spbe30
    Else
        Set spbe = spbe60
    End If
       
    Dim b_array() As Variant, aa_array() As Variant, t_array() As Variant
    Dim n_rows As Long
    
    n_rows = 100 'Figure Out how many rows to process
    
    ' Start from row#2 skipping headers
    b_array = spbe.Range("b2").Resize(n_rows, 1).Value
    aa_array = spbe.Range("aa2").Resize(n_rows, 1).Value
    t_array = spbe.Range("t2").Resize(n_rows, 1).Value

             
    'the section below is using a sheet name that is determined from the if statement above
    i = i   1
    Do While LCase(b_array(i, 1)) = "placement"
        If LCase(aa_array(i, 1)) = "product" Then
            PPclicks = t_array(i, 1)
        ElseIf LCase(aa_array(i, 1)) = "rest" Then
            ROSclicks = t_array(i, 1)
        End If
        i = i   1
    Loop
 

Основываясь на дальнейших комментариях, я рекомендую использовать массив массивов

 Dim b_array() as Variant, aa_array() as Variant, t_array() as Variant

b_array = Array( _
    spbe30.Range("b2").Resize(n_rows, 1).Value, 
    spbe60.Range("b2").Resize(n_rows, 1).Value )

aa_array = Array( _
    spbe30.Range("aa2").Resize(n_rows, 1).Value, 
    spbe60.Range("aa2").Resize(n_rows, 1).Value )

t_array = Array( _
    spbe30.Range("t2").Resize(n_rows, 1).Value, 
    spbe60.Range("t2").Resize(n_rows, 1).Value )
 

а затем выберите тот, который будет использоваться

     Dim index as Long
    If spbe30array(i,22) >= orders Then
        index = 0
    Else
        index = 1
    End If

    Do While LCase(b_array(index)(i, 1)) = "placement"
        If LCase(aa_array(index)(i, 1)) = "product" Then
            PPclicks = t_array(index)(i, 1)
        ElseIf LCase(aa_array(index)(i, 1)) = "rest" Then
            ROSclicks = t_array(index)(i, 1)
        End If
        i = i   1
    Loop
 

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

1. в конечном счете, я хочу сказать: если критерии 1, то X=массив1, если критерии 2, то X=массив2. Как только это будет определено, затем сошлитесь на массив как X(1,1)

2. Я думаю, что в Excel есть ошибка, которая Array( Range().Value ) не будет работать. сначала вам нужно поместить значения в рабочие массивы, а затем объединить их с Array() функцией. Я просто хотел изложить суть этого здесь.

Ответ №2:

Зубчатый массив, ByRef/БыВал

  • Вы можете записать значения диапазонов в массивы и скопировать массивы в другой массив (неровный массив или массив массивов). Затем, используя индекс зубчатого массива в IIf функции, вы можете легко решить, какой массив использовать.
  • Чтобы не загромождать свой код, вы можете дополнительно создать другую процедуру для выполнения этой работы из своего With заявления.
  • Для меня это все Do Loop еще не имеет смысла. Может быть, ты пропустил одну Exit Do или две.
 Option Explicit

Sub Snippet()
    
'    ' Your initial variables (to be able to compile my code)
'    Dim spbe30array As Variant, PPClicks As Variant, ROSclicks As Variant
'    Dim orders As Double
'    Dim i As Long
    
    Dim spbeData As Variant: ReDim spbeData(1 To 2)
    spbeData(1) = spbe30.Value
    spbeData(2) = spbe60.Value
 
    Dim Index As Long: Index = IIf(spbe30array(i, 22) >= orders, 1, 2)
    
    i = i   1
    UpdateClicks spbeData, Index, i, PPClicks, ROSclicks
    ' 'i', 'PPClicks', 'ROSclicks' have been passed 'By Ref',
    ' so they are possibly modified.
    ' If 'i' is not relevant for the continuation, pass it 'ByVal'.
    ' 'spbeData' and 'Index' remain unchanged.
    
End Sub

Sub UpdateClicks( _
        ByVal spbeData As Variant, _
        ByVal Index As Long, _
        ByRef i As Long, _
        ByRef PPClicks As Variant, _
        ByRef ROSclicks As Variant)
        
    Do While LCase(spbeData(Index)(i, 2)) = "placement"
        If LCase(spbeData(Index)(i, 27)) = "product" Then
            PPClicks = spbeData(Index)(i, 20)
        ElseIf LCase(spbeData(Index)(i, 27)) = "rest" Then
            ROSclicks = spbeData(Index)(i, 20)
        End If
        i = i   1
    Loop

End Sub