powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Размерность динамического массива Variant (Array) типа? VBA в Excel.
11 сообщений из 11, страница 1 из 1
Размерность динамического массива Variant (Array) типа? VBA в Excel.
    #37654576
_Промешан_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.
Сейчас опишу ситуацию и вы увидете, к чему название топика.

Есть два листа в Excel. В одном примерно такая структура
ТитулИмяНомерАпрель 2009Май 2009Июнь 2009Июль 2009и тд до 2015 года21Строительство котлована345-прт-4437.АС103345.444454.010000.00.0и тд
Строк много.

Необходимо на втором листе транспонировать данные по периодам(датам) в таблицу.
ТитулИмяНомерДатаСумма21Строительство котлована345-прт-4437.АСАпрель 2009103345.421Строительство котлована345-прт-4437.АСМай 200944454.0
и тд.

Из соображений скорости делается все это таким кодом, используя массивы. Я привел примеры, однако исходной информации гораздо больше, поэтому в коде указываю только основное.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
Function GetFromSomeList(FromSheet As String, LastRow As Integer, StartY As Integer, EndY As Integer)
    Dim Smeta As Worksheet, From As Worksheet
    Dim BigArr() As Variant, CurArr() As Variant, ba As Variant, a As Variant
    
    Set Smeta = Worksheets("СМЕТЫ")
    Set From = Worksheets(FromSheet)
    
    ReDim BigArr(1)
    BigArr(1) = Empty
...    
    For i = 7 To 1000
      ReDim CurArr(1)
      If From.Cells(i, 1).Interior.Color = ColorConstants.vbWhite Then 'Выгружаем только те значения, у которых фон = белый
        For y = StartY To EndY Step 4                                         ' Объединенные ячейки с периодом и выполнением
          c11 = CDate(From.Cells(3, y).Value)                                 ' И ниже трансформируем в нужный формат даты
          c12 = 0
          c12 = CCur(From.Cells(i, y).Value)
          If с12 <> 0 Then
            If Not IsEmpty(CurArr(1)) Then ReDim Preserve CurArr(UBound(CurArr) + 1)
            CurArr(UBound(CurArr)) = Array(c11, c12)                      'Пишем дату и сумму для транспонирования в массив
          End If
        Next y
        If Not IsEmpty(CurArr(1)) Then
...          
          'Добавим данные в массив
          If Not IsEmpty(BigArr(1)) Then ReDim Preserve BigArr(UBound(BigArr) + 1)
          BigArr(UBound(BigArr)) = Array(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, CurArr, c14, c15, c16)
          'c1,c2 и тд, кроме CurArr - это ячейки, которые берутся из первого листа, т.е. для одной строки - несколько значений (дата,сумма)
        End If
      End If
    Next i
    Erase CurArr
    
    'Пишем на другой лист
    y = LastRow
    For Each ba In BigArr
      For Each a In ba(11)
        Smeta.Cells(y, 1).Value = ba(1)
        Smeta.Cells(y, 2).Value = ba(2)
        Smeta.Cells(y, 3).Value = ba(3)
        Smeta.Cells(y, 4).Value = ba(4)
        Smeta.Cells(y, 5).Value = ba(5)
        Smeta.Cells(y, 6).Value = ba(6)
        Smeta.Cells(y, 7).Value = ba(7)
        Smeta.Cells(y, 8).Value = ba(8)
        Smeta.Cells(y, 9).Value = ba(9)
        Smeta.Cells(y, 10).Value = "" 
        Smeta.Cells(y, 11).Value = a(1)  'Вот оно транспонирование
        Smeta.Cells(y, 12).Value = a(2)
        Smeta.Cells(y, 13).Value = a(3)
        Smeta.Cells(y, 14).Value = ba(12)
        Smeta.Cells(y, 15).Value = ba(13)
        Smeta.Cells(y, 16).Value = ba(14)
        y = y + 1
      Next a
    Next ba
    
    ba = Empty
    a = Empty
    Erase BigArr
    Set Smeta = Nothing
    Set From = Nothing
    GetFromSomeList = y - 1
End Function



Проблема: выгружаются не все данные. По дебагеру, показывает что BigArr имеет максимально 133 элемента. То есть фактически обработано только 133 строки из первого листа, а их там около 700.
При проверке - и правда не все данные выгружаются.

Вопрос - есть ограничение на массивы и как в данном случае поступить - что то сделать с массивами или забить на скорость и грузить сразу в лист?
...
Рейтинг: 0 / 0
Размерность динамического массива Variant (Array) типа? VBA в Excel.
    #37654642
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Затея с массивами не лишена смысла, но ее портит реализация.
Код: vbnet
1.
ReDim Preserve

Меееедленно. И делается эта операция (EndY-StartY)*1000/4 раз. А то и в два раза больше, в зависимости от условий. Лучше изначально делать простой Redim c запасом.
_Промешан_Проблема: выгружаются не все данные.Почему Step 4? Месяца же идут подряд.
...
Рейтинг: 0 / 0
Размерность динамического массива Variant (Array) типа? VBA в Excel.
    #37654969
Фотография AndreTM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И еще много повторных вычислений внутри циклов...
И вообще - вы уверены, что использование массивов в этом случае оправдано? Понимаете, если бы вы использовали не циклы при загрузке/выгрузке из массива - то еще ничего бы. А так - вы сначала переписываете данные в массив, потом - обратно...

А дали бы вы файлик с реальными данными (можно и без скриптов), но с большИм размером исходной таблицы и кусочком получаемой таблицы... Ибо мнится мне, что ваша задача решается даже функциями листа, не говоря уж о более простых методах переноса.
...
Рейтинг: 0 / 0
Размерность динамического массива Variant (Array) типа? VBA в Excel.
    #37655015
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А почему не обратиться к данным листа как таблице БД? Один запрос - и de-pivot готов, пустые строки прибиты, можно вываливать на лист... осталось только позаботиться о правильной сортировке, что не так уж и сложно.
...
Рейтинг: 0 / 0
Размерность динамического массива Variant (Array) типа? VBA в Excel.
    #37655029
Фотография AndreTM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina , это я и имел в виду...
Просто, иногда и прямое копирование может выйти быстрее, особенно если выборка/запись делается сильно нелинейно (например, надо отслеживать "отмеченные" ячейки).
...
Рейтинг: 0 / 0
Размерность динамического массива Variant (Array) типа? VBA в Excel.
    #37655251
_Промешан_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AndreTM,

Файлик выложить не могу, т.к. коммерческая тайна - там цифры и тп. С этим строго.

Почему Step 4 .
На самом деле в реальном файле расблюдовка по периодам сложная (см. картинку).
Из картинки видно, что период идет в 4 столбца. А получить нужно два (не как в примере один) столбца с ценами. При чем получить надо из этих четырех. Алгоритм получения на примере Августа 2010
1. Если столбец 89 не пустой, а 90 пустой, то берем значение из 89. Если же столбец 89 пустой, а 90 не пустой - то берем значение из 90. Если оба пусты - то ничего не берем.
2. То жесамое для второй пары столбцов 91 и 92.
И так по всем периодам.

Плюс в таблице видно, что есть закрашенные строки - это промежуточные итоги/суммирование. Их не должно быть в итоговом листе, как и пустых строк и тд. Поэтому проверка на белый фон.

Идеи?

И еще много повторных вычислений внутри циклов...
Каких?

В любом случае, не эта проблема главная, а та, почему не выгружаются все данные в массив?
...
Рейтинг: 0 / 0
Размерность динамического массива Variant (Array) типа? VBA в Excel.
    #37655293
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В представленном отрывке ничего лишнего кроме c12 = 0 и Erase CurArr я не вижу. Первая идея все та же — выкинуть Preserve, это главный тормоз. Еще есть идея вместо "Пишем на другой лист" создать двумерный массив, у экселя вроде есть метод, позволяющий одним махом вставить весь массив в лист без унылого перебора ячеек.
...
Рейтинг: 0 / 0
Размерность динамического массива Variant (Array) типа? VBA в Excel.
    #37655315
_Промешан_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AntonariyВ представленном отрывке ничего лишнего кроме c12 = 0 и Erase CurArr я не вижу. Первая идея все та же — выкинуть Preserve, это главный тормоз. Еще есть идея вместо "Пишем на другой лист" создать двумерный массив, у экселя вроде есть метод, позволяющий одним махом вставить весь массив в лист без унылого перебора ячеек.

если не делать с12=0 (а в реальном примере есть еще и с13), то каким-то образом в один из столбцов попадают произвольные суммы (из предыдущих вычислений), если в паре столбцов с первого листа нет значений, а в другой паре столбцов есть.
Если в обоих парах столбцов нет значений - такая запись не попадает в отбор.

Благодарю насчет метода единовременной вставки, только как вы вставите и всю служебную информацию и данные по периоду и двум суммам? Зачем двумерный массив?

пс: все же речь основная про количество элементов. Почему из максимально 133 и не больше?

ппс: не особо тут важно заморочиться с оптимизацией, т.к. выгрузка один или два раза. Но я понимаю, что напрямую это будет дольше.
...
Рейтинг: 0 / 0
Размерность динамического массива Variant (Array) типа? VBA в Excel.
    #37655606
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насчет проблемы ничем помочь не могу, это нужно конкретно доходить до 133го элемента и дальше пошагово смотреть, что происходит. Нужно элементы сравнивать, вдруг 133й в массиве это 700й на листе?
...
Рейтинг: 0 / 0
Размерность динамического массива Variant (Array) типа? VBA в Excel.
    #37655655
_Промешан_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AntonariyНасчет проблемы ничем помочь не могу, это нужно конкретно доходить до 133го элемента и дальше пошагово смотреть, что происходит. Нужно элементы сравнивать, вдруг 133й в массиве это 700й на листе?Ложная тревога. Протупил - просто по условию туда данные и не должны отбираться.

Всех сорри и спасибо :)
...
Рейтинг: 0 / 0
Размерность динамического массива Variant (Array) типа? VBA в Excel.
    #37656711
Фотография AndreTM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyВ представленном отрывке ничего лишнего кроме c12 = 0 и Erase CurArr я не вижу. c11 вычисляется для каждого y - 994 раза вместо одного...
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Размерность динамического массива Variant (Array) типа? VBA в Excel.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]