Страницы: 1
RSS
Расширение виртуального массива с данными
 
Вопрос теоретический (без файла): о расширении массива, заполненного данными, по вертикали.
Нередко бывает, что размер массива задать сразу не представляется возможным - неизвестен объем информации.
По горизонтали понятно - ReDim Preserve... [добавить_"столбцы"]. По вертикали - не пройдет фокус.

Пример: извлечение данных из множества папок с множеством файлов.
Вариант1. Можно, конечно, пробежаться по всем файлам, посчитать выгрузку... Не оптимально.
Вариант2. Создать заведомо большущий массив. Плохой вариант:
а) можно промахнуться и до еще большего размера данных не дотянуть;
б) можно очень сильно "перетянуть" (а мы же за оптимизацию!).
Вариант3. Создать массив с жестким размером и периодически, при заполнении, выгружать данные.
Немного лучше, но нужно отслеживать и последнюю строку в уже заполненной таблице, и заполняемость массива, сбрасывая периодически счетчик "строк" массива.
Вариант4. Создаем "лежачий" массив: по горизонтали пишем "строки", по вертикали "столбцы". Работаем с ReDim Preserve. Перед выгрузкой циклом "ставим на ноги".
Такой способ неплохо работает при небольшом массиве (например, отслеживание и регистрация ошибок извлечения). На большом по скорости не проверял, но, в любом случае, присутствует дополнительная обработка массива.

Может, есть еще пути решения? Именно с массивами. Dictionary не предлагать. Не умею.
 
Цитата
vikttur пишет:
Вариант4. Создаем "лежачий" массив: по горизонтали пишем "строки", по вертикали "столбцы". Работаем с ReDim Preserve. Перед выгрузкой циклом "ставим на ноги".
Так работает GetRows() в ADODB.Recordset.GetRows() - именно лежачий массив.
В .NET Framework, например, Array.Resize именно так и работает, когда "размер" массива увеличился - создаётся новый массив с расширенными границами и в него копируются данные из старого массива.
vikttur, Всё-таки мне непонятно, что такое "извлечение данных из множества папок с множеством файлов". Что имеется ввиду? :) То есть что должно быть по строкам, а что по столбцам? :)
There is no knowledge that is not power
 
Цитата
Что имеется ввиду?
Какая разница? Любая задача похожего типа. Например, объединение данных из таблиц с известным количеством столбцов, но неизвестным количеством строк. Логично: создали массив под первую таблицу, расширили вниз для второй таблицы, ... для третьей-пятой-25... Нельзя!
 
Похожая тема
 
Спасибо, Юра.
Цитата
ZVI: Опасение использовать эти объектов [Collection и Dictionary ], чаще всего возникает из-за отсутствия опыта, а опыт нужно просто приобретать.
Нужно. Знаю. Но пока что-нибудь без них.

Цитата
слэн: а чем  tArr=application.transpose(Arr) не нравится?
Вот тут я, похоже, маху дал:
Цитата
Перед выгрузкой циклом "ставим на ноги".
Хотя... в случае с транспонированием нужно создать второй массив.
 
Цитата
vikttur пишет: Dictionary не предлагать. Не умею.
А вот это зря... Для подобных ситуаций самый подходящий вариант, работать с ним достаточно просто. Вот очень внятное описание http://www.osp.ru/win2000/2006/07/3643019/
Раньше тоже только массивами пользовался, иногда очень громоздко получается + разобраться в этих "художествах" через некоторое время бывает сложно... Я за Dictionary.
 
И я за. На практике убедился, что массивы  - не панацея. Расти надо, я же не отрицаю.
Буду вникать.
Как с регулярками:  дал мне Саша ссылки и пинок в этом направлении... Извини, Саша, до сих пор не взялся :)
 
Я вот не понял: а чем массив массивов не угодил, раз словари лень учить? Плюс неплохо бы знать что ты туда помещаешь: обработанный результат или тупо данные файлов? Если первое - то массив массивов не всегда выход(зависит от того, какие манипуляции надо со всеми данными произвести). Если второе - то скорее даже именно массив массивов больше подойдет, чем словарь. Опять же - зависит от того, что надо получить в итоге.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Данные перед загрузкой в массив предварительно обрабатываются.
Цитата
чем массив массивов не угодил
Я не писал, что "да ну его".  Показал пути, которые я знаю. Но вдруг есть неведомые стежки-дорожки?
Тема о "а как еще можно?"
Сейчас работаю с выгрузкой массива и следующим заполнением. Второй, небольшой массив - транспонирую.
 
И всё-таки, как правильно объявить динамические строки в Redim, если x будет известен только по окончании макроса, который пробежится по всем листам? С этим
Код
If x > 0 Then        
ReDim c(1 To x, 1 To 9)
    Else
        ReDim Preserve c(1 To 1, 1 To 9)
    End If
у меня проблемы.


Скрытый текст
Изменено: Владимир - 12.12.2016 17:01:43
"..Сладку ягоду рвали вместе, горьку ягоду я одна."
 
Код
Sub Union2Columns()
  Dim aru(), ar, uc&, i&, sh As Worksheet
  ReDim aru(1 To 2, 1 To 1)
  For Each sh In Worksheets
    ar = sh.UsedRange.Value
    ReDim Preserve aru(1 To 2, 1 To uc + UBound(ar))
    For i = 1 To UBound(ar)
      aru(1, uc + i) = ar(i, 1): aru(2, uc + i) = ar(i, 2)
    Next
    uc = uc + UBound(ar)
  Next
  Worksheets.Add after:=Worksheets(Worksheets.Count)
  Cells(1, 1).Resize(UBound(aru, 2), 2).Value = WorksheetFunction.Transpose(aru)
  MsgBox "array (" & UBound(aru, 2) & "x2)  done"
End Sub
при каждом очередном выполнении этого макроса в файле будет добавлен лист с данными со всех листов)  
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Владимир, в многомерном массиве (Ваш двумерный как частный случай) директивой ReDim Preserve можно изменять только ПОСЛЕДНЮЮ размерность.
Попробуйте этот код. Или приложите файл-пример с желаемым результатом
Код
Sub search()
Dim rng As Range, i&, y&, x&, j&
Dim arrC()
Application.ScreenUpdating = False
For i = 2 To Sheets.Count
    Set rng = Sheets(i).UsedRange
    For y = 1 To rng.Rows.Count
        If rng(y, 9).Interior.Color = 65535 Then
            ReDim Preserve arrC(1 To 9, 1 To x)
            For j = 1 To UBound(arrC)
                Select Case j
                    Case 1, 2, 7, 8, 9
                        arrC(j, x) = rng(y, j)
                End Select
            Next
            x = x + 1
        End If
    Next
Next
Sheets(1).[A5].Resize(UBound(arrC, 2) + 1, 9) = Application.Transpose(arrC)
Application.ScreenUpdating = True
End Sub
Изменено: Sanja - 12.12.2016 17:53:15
Согласие есть продукт при полном непротивлении сторон
 
Sanja, Вы эту задачку сегодня здесь решали.
Завтра буду разбираться, вечером нет у меня компьютера.
"..Сладку ягоду рвали вместе, горьку ягоду я одна."
 
Если будете использовать ADO, попробуйте - ИСПОЛЬЗОВАНИЕ ПРЕДЛОЖЕНИЯ UNION
 
1 to x спотыкается и это логично  - 1 to 0 не может быть.
"..Сладку ягоду рвали вместе, горьку ягоду я одна."
 
Логично
Скрытый текст

Изменено: Sanja - 13.12.2016 11:36:04
Согласие есть продукт при полном непротивлении сторон
 
Теперь я понял, о чём писалось выше - положить таблицу на 90 градусов, а потом вернуть обратно.
Кстати, никогда не видел потребности зачем и когда использовать Select Case, а вот теперь увидел.
Спасибо, Sanja, за науку.
----
Спасибо ребята.
"..Сладку ягоду рвали вместе, горьку ягоду я одна."
Страницы: 1
Наверх