Страницы: 1
RSS
Залить разные диапазоны в разные массивы (VBA).
 
Всем привет!

Нет опыта работы с массивами в VBA. Нужно залить выборочные диапазоны по условию в массив 1 и массив 2 в зависимости от условия (прописано в процедуре).
Предполагается, что набор диапазонов будет разным поэтому объявлен динамический массив, но каждый новый диапазон затирает значения предыдущего в массиве при последующей итерации в цикле. Как этого избежать и наполнить массив без потери данных? Теория гласит что нужно изменять размер массивов через ReDim - реализовать практически не получилось, help plz!  
 
Заливайте ВСЁ в один массив, а при работе с ним выбирайте нужное в данный момент значение
Согласие есть продукт при полном непротивлении сторон
 
Нет, так не подходит. Данные из первого массива будут обрабатываться в последующем на одном листе, а со второго на другом листе.
 
Vitaliy Ptashnik, а на листе всегда данные как бы через строку?
 
Нет, бывают случаи последовательного расположения строки 1,3,5,7 и т.д. - потому записал условие в цикле. Вообще, это будет фрагментарная обработка по выделению диапазона, но я не стал это примешивать, да бы не вносить дополнительного смысла в код. Предполагается, также, на будущее с помощью условия в цикле формировать выборку и по другим признакам, но, опять же, это не так важно как то как понять способ наполнения массива выборочными диапазонами по условию.    
 
Код
Sub Мяу()
    Dim ar0, ar1(), ar2()
    Dim i&, k&, n&, j&
    ar0 = [a1].CurrentRegion.Value
    ReDim ar1(1 To UBound(ar0) / 2, 1 To UBound(ar0, 2))
    ReDim ar2(1 To UBound(ar0) / 2, 1 To 3)
    For i = 1 To UBound(ar0)
        If i Mod 2 Then
            k = k + 1
            For j = 1 To UBound(ar1, 2)
                ar1(k, j) = ar0(i, j)
            Next
        Else
            n = n + 1
            For j = 1 To UBound(ar2, 2)
                ar2(n, j) = ar0(i, j + 2)
            Next
        End If
    Next
End Sub
 
Но можно же обрабатывать для разных листов разные записи массива. Или Вы хотите заполнять массив по условию - или одним диапазоном. или другим?
Все в один массив и:
Код
For i = 1 To UBound(ar0)
   If i Mod 2 Then
         ' работа с листом 1
   Else
         ' работа с листом 2
   End If
Next i

Работа с масивами зависит от задачи.
 
Цитата
vikttur написал:
Но можно же обрабатывать для разных листов разные записи массива.
Можно если постараться.

Но, мне кажется, правильнее будет сначала сформировать нужную выборку данных (массив) и затем подвергать ее обработке.
Сформированный массив ArrOrdsMM (диапазоны: A1:I1;A3:I3;A5:I5;A7:I7;A9:I9;A11:I11) нужно будет вставить и обработать на определенном листе.
Сформированный массив ArrPB (диапазоны: C2:E2;C4:E4;C6:E6;C8:E8;C10:E10;C12:E12) также нужно будет вставить и обработать на другом листе.

Цитата
vikttur написал: Или Вы хотите заполнять массив по условию - или одним диапазоном. или другим?
Нет, выборка по первому условию строго для первого массива(ArrOrdsMM), по второму условию - для второго массива (ArrPB)
 
Еще вариант с одним массивом для случая, когда обработку нельзя провести по варианту из сообщения #7
Код
For i = 1 To UBound(ar0) Step 2
         ' работа с листом 1
Next i

For i = 2 To UBound(ar0) Step 2
         ' работа с листом 2
Next i

А правильнее, как писал выше: для коротких и длинных  ног разные штанишки
 
RAN,  то что нужно. Спасибо огромное! Если будут еще варианты буду рад рассмотреть!
 
Посмотрите вариант. Правда, оба массива получаются с запасом и их потом нужно будет перебросить в итоговые, оставив только заполненную "верхушку".
Верхнюю границу массива делением на 2 не определял, как у RAN, учитывая ответ в #5.
 
Цитата
Vitaliy Ptashnik написал: Нет, так не подходит.
Ваша уверенность в этом опровергает Ваше же
Цитата
Vitaliy Ptashnik написал: Нет опыта работы с массивами в VBA.
То, что показал Вам RAN, это частный случай моего
Цитата
Sanja написал: Заливайте ВСЁ в один массив, а при работе с ним выбирайте нужное в данный момент значение
Все зависит от задачи, которую Вы решаете
Цитата
Vitaliy Ptashnik написал: Данные из первого массива будут обрабатываться в последующем на одном листе, а со второго на другом листе.
Это вообще ерунда. Массив обрабатывается не зависимо от листов. Или под массивом Вы имеете ввиду что-то другое
Согласие есть продукт при полном непротивлении сторон
 
Без создания вспомогательного массива (паразитируем на коде Андрея):
Код
Sub Exp_OnlineMM_Orders2()
    Dim ArrOrdsMM(), ArrPB()
    Dim i&, k&, n&, j&
    
    With Worksheets("Лист1")
        i = .UsedRange.Rows.Count + .UsedRange.Row - 1
        ArrOrdsMM = .Range("A1:I" & i).Value
    End With
    
    ReDim ArrPB(1 To i / 2, 1 To 3)
    
    For i = 1 To UBound(ArrOrdsMM)
        If i Mod 2 Then
            k = k + 1
            For j = 1 To UBound(ArrOrdsMM, 2)
                ArrOrdsMM(k, j) = ArrOrdsMM(i, j)
            Next j
        Else
            n = n + 1
            ArrPB(n, 1) = ArrOrdsMM(i, 3)
            ArrPB(n, 2) = ArrOrdsMM(i, 4)
            ArrPB(n, 3) = ArrOrdsMM(i, 5)
        End If
    Next i

    MsgBox "Выполнено!", 64, ""
End Sub

ArrOrdsMM использовать от 1 до k  (For i = 1 To k). Второй массив тоже можно от 1 до n

Совет. Создайте тему. Там и увидите, что лучше для Вашей задачи.
 
Цитата
Vitaliy Ptashnik написал:
способ наполнения массива выборочными диапазонами по условию.
напрямую зависит от этих условий, и искать универсальное решение - только время терять.
 
Завтра утром сопоставлю все варианты решения и напишу заключение или замечания по вышеперечисленным комментариям.
На сегодня всем спасибо, должен покинуть чат.
 
Добрый день!
Цитата
Sanja написал:
Ваша уверенность в этом опровергает Ваше же Цитата Vitaliy Ptashnik  написал: Нет опыта работы с массивами в VBA.
Уточню, нет "достаточного" опыта работы чтоб прийти к соответствующему заключению.
Цитата
Sanja написал:
Массив обрабатывается не зависимо от листов
Пришел к этому выводу в процессе обсуждения, так как сначала был слишком увлечен идеей с наполнением нескольких массивов. Попробую выполнить обработку единого массива по условиям на разных листах.

Как показал опыт всех участников обсуждения этой темы - наполнение нескольких массивов по условиям с одного диапазона таки возможно. Варианты  #6, #11, #13  отрабатывают хоть и с оговорками. В любом случае, идеи предоставлены с Вашей стороны дают повод к дальнейшей самостоятельной работе в данном направлении. Всем участникам форума выражаю глубокую признательность и благодарность за уделенное время и затраченные усилия.  
Изменено: Vitaliy Ptashnik - 06.07.2019 12:56:13
 
Цитата
Vitaliy Ptashnik написал: Варианты  #6, #11, #13  отрабатывают
Код
ar0 = [a1].CurrentRegion.Value   '#6
Код
ArrOrdsMM = .Range("A1:I" & i).Value   '#13
не что иное, как
Цитата
Sanja написал: Заливайте ВСЁ в один массив
а далее в этих кодах
Цитата
Sanja написал: при работе с ним выбирайте нужное в данный момент значение
Вариант от Юрий М, (#11) тоже имеет место быть, но он самый медленный из всех. На больших объемах разница будет ощутима
Согласие есть продукт при полном непротивлении сторон
 
Цитата
Sanja написал:
Вариант от  Юрий М , (#11) тоже имеет место быть, но он самый медленный из всех.
Согласен )) Но никто ведь не мешает СНАЧАЛА забрать всё в "главный" массив, как и предлагалось, а уже из него формировать два других массива. Тогда будет быстро.
Только что-то мне подсказывает, что именно два массива и не потребуются. Но всё же нужно чётко понимать конечную цель.
 
Цитата
Юрий М написал: Но никто ведь не мешает СНАЧАЛА забрать всё в "главный" массив
Да, но тогда Ваш вариант Юрий М, потеряет индивидуальность и будет похож на два предыдущих, в которых именно СНАЧАЛА... :D  ;)  
Согласие есть продукт при полном непротивлении сторон
 
Так ему (варианту) и надо! )
 
Цитата
Юрий М написал:
Но всё же нужно чётко понимать конечную цель
Добрый день!

Конечная цель - это обработка частей диапазона на других листах в зависимости от критериев выборки в исходном диапазоне обработки. Если работать сугубо с объектом Range - выполнение выходит достаточно длительным. Другое дело - обрабатывать данные через объявление массива. Процедура значительно быстрее отрабатывает. Собственно говоря, я по этому пути и пошел придя к этому варианту в процессе обсуждения на форуме. Учитывая тот факт, что обрабатываемый массив будет до 300позиций - то такое исполнение удовлетворяет текущую потребность по скорости выполнения.
Изменено: Vitaliy Ptashnik - 08.07.2019 11:28:55
Страницы: 1
Наверх