#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