Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.05.2013, 10:19   #1
VictorM
Старожил
 
Аватар для VictorM
 
Регистрация: 15.05.2008
Сообщений: 2,058
По умолчанию Добавть новые строки в массив

Здравствуйте, Уважаемые!
Ну не могу я въехать в массивы, хоть убей (
Есть рабочий код прихода товара на склад, работатет на циклах.
Пока объемы были небольшие, все устраивало, но с увеличением количества товара макрос стал заметно тормозить.
Решил сделать все на циклах, просмотрел темы на форуме, взял примеры кода, вроде даже стало получаться).
Но получается только треть задачи, а вот если принимается товар с другой ценой или такого товара вообще нет на складе - нужно добавить новые строки в массив и вот тут я потух!
Пробовал разные варианты кодов с форума, но видимо я не могу понять логику массивов или синтаксис.
Понимаю, что нужен где-то тут ReDim, а вот дальше...
Подскажите, пожалуйста, как все это сделать, мне просто понять нужно.
Спасибо.
Вложения
Тип файла: zip СкладГП_массивы.zip (31.9 Кб, 13 просмотров)
"Дайте людям рыбы, и вы накормите их на весь день; научите их ловить рыбу - и вы накормите их на всю жизнь"
"Большое спасибо" - Z261597841314, R208907249777, U447361470499
VictorM вне форума Ответить с цитированием
Старый 15.05.2013, 10:45   #2
IgorGO
Новичок
СтарожилДжуниор
 
Аватар для IgorGO
 
Регистрация: 05.02.2008
Сообщений: 9,487
По умолчанию

ReDim Preserve ...
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете
IgorGO вне форума Ответить с цитированием
Старый 15.05.2013, 11:03   #3
VictorM
Старожил
 
Аватар для VictorM
 
Регистрация: 15.05.2008
Сообщений: 2,058
По умолчанию

Цитата:
ReDim Preserve ...
Да, это я понимаю, только куда все это прикрутить...
"Дайте людям рыбы, и вы накормите их на весь день; научите их ловить рыбу - и вы накормите их на всю жизнь"
"Большое спасибо" - Z261597841314, R208907249777, U447361470499
VictorM вне форума Ответить с цитированием
Старый 15.05.2013, 11:27   #4
Скрипт
Форумчанин
 
Регистрация: 24.12.2012
Сообщений: 776
По умолчанию

VictorM, если предполагается работать с большим количеством строк в VBA-массиве (количество не могу сказать - надо тестирование провести), то макрос будет долго работать, т.к. при добавлении новой строки в VBA-массив на самом деле создаётся новый массив, а прежний удаляется. Нигде об этом на написано (я так понял) - это кто-то где-то как-то узнал.

Если предполагается сделать VBA-массив, а его размер заранее не известен, то если есть возможность, нужно сразу создать массив с тем количеством строк, которое может быть максимально. После заполнения массива, можно перенести данные в другой массив для удобства написания кода, удалив таким образом пустые строки.
Скрипт вне форума Ответить с цитированием
Старый 15.05.2013, 12:25   #5
Казанский
Старожил
 
Аватар для Казанский
 
Регистрация: 31.12.2010
Сообщений: 2,133
По умолчанию

VictorM, в двумерный массив нельзя добавить "строку", а можно только "столбец". Т.е. в Redim Preserve можно менять только верхнюю границу последней размерности многомерного массива.
В принципе, можно транспонировать массив при считывании с диапазона. Тогда строки станут вторым индексом и добавить их можно. Но Application.Transpose (функцию ТРАНСП) в серьезном проекте использовать нежелательно, у этой функции есть существенные ограничения. А перекладывать один массив в другой в цикле некрасиво
Если нужно добавлять строки (записи), можно использовать Collection, Dictionary или Recordset.
Для данной задачи можно добиться ускорения, если поиск Наименования на листе СкладГотПр производить методом Range.Find или функцией Application.Match (ПОИСКПОЗ). Это будет быстрее, чем перебор циклом в массиве.
exceleved@yandex.ru Яндекс.Деньги: 410011500007619
Казанский вне форума Ответить с цитированием
Старый 15.05.2013, 12:59   #6
VictorM
Старожил
 
Аватар для VictorM
 
Регистрация: 15.05.2008
Сообщений: 2,058
По умолчанию

Казанский, большое спасибо за толковое разьяснение.
Особенно вот это
Цитата:
в двумерный массив нельзя добавить "строку", а можно только "столбец". Т.е. в Redim Preserve можно менять только верхнюю границу последней размерности многомерного массива.
Почему-то я этого нигде не нашел.
Методом Range.Find я пользуюсь в текущем варианте кода, но что-то мне казалось, что с массивами будет быстрее.
Еще раз спасибо, думаю, вопрос снят.
"Дайте людям рыбы, и вы накормите их на весь день; научите их ловить рыбу - и вы накормите их на всю жизнь"
"Большое спасибо" - Z261597841314, R208907249777, U447361470499
VictorM вне форума Ответить с цитированием
Старый 15.05.2013, 13:34   #7
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

Я Redim Preserve практически не использую - всегда можно сделать иначе.
Например так - берём исходные данные в массив, создаём аналогичный такого же размера, перекладываем нужные данные (пустой "хвост" отбросим при выгрузке).
Или при анализе собираем коллекцию номеров нужных строк, затем по полученной коллекции создаём массив, перекладываем (это если например нужно один огромный массив разложить по сотне маленьких массивов).
С другой стороны, можно номера строк собирать в словарь, и затем просто из исходного массива выбирать данные из этих строк, не создавая другие массивы.

А эту задачу я бы делал так (с учётом что данных много, копируемых мало, и чтоб не сложный код):
1. Старые в массив, его перебираем, заполняем словарь наименование & "|" & цена
2. Новые в массив, его перебираем, ищем в словаре наименование & "|" & цена
3. Если нет в словаре - добавляем новое в словарь, копируем строку (номер известен, куда можно сразу определить, затем двигать индекс, ну или каждый раз копировать вниз)

Если же копируемых строк тысячи - тогда как выше: коллекция номеров, затем массив и переложить, затем выгрузить вниз. Формулы протянуть после выгрузки - адреса от/до ведь будут известны.
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 15.05.2013, 14:42   #8
Казанский
Старожил
 
Аватар для Казанский
 
Регистрация: 31.12.2010
Сообщений: 2,133
По умолчанию

Цитата:
Сообщение от VictorM Посмотреть сообщение
Особенно вот это... Почему-то я этого нигде не нашел.
F1 - ReDim Statement
Цитата:
If you use the Preserve keyword, you can resize only the last array dimension and you can't change the number of dimensions at all...
Similarly, when you use Preserve, you can change the size of the array only by changing the upper bound; changing the lower bound causes an error.
exceleved@yandex.ru Яндекс.Деньги: 410011500007619
Казанский вне форума Ответить с цитированием
Старый 15.05.2013, 14:46   #9
Казанский
Старожил
 
Аватар для Казанский
 
Регистрация: 31.12.2010
Сообщений: 2,133
По умолчанию

Однако, неточность в Справке есть:
Цитата:
If you pass an array to a procedure by reference, you can't redimension the array within the procedure.
Очень даже могу
Код:
Sub test()
Dim a() As Long, i As Long
ReDim a(1 To 3)
a(1) = 10: a(2) = 20: a(3) = 30
MySub a
For i = LBound(a) To UBound(a): Debug.Print a(i): Next
End Sub

Sub MySub(ByRef arr() As Long)
ReDim Preserve arr(LBound(arr) To UBound(arr) + 1)
arr(UBound(arr)) = 99
End Sub
exceleved@yandex.ru Яндекс.Деньги: 410011500007619
Казанский вне форума Ответить с цитированием
Старый 15.05.2013, 18:06   #10
VictorM
Старожил
 
Аватар для VictorM
 
Регистрация: 15.05.2008
Сообщений: 2,058
По умолчанию

Цитата:
А эту задачу я бы делал так
Да, строк НЕ тысячи и можно было бы сделать так, как Вы предлагаете, но словари для меня "темный лес"))
Остановлюсь, наверное, на том что есть, т.е. Range.Find
"Дайте людям рыбы, и вы накормите их на весь день; научите их ловить рыбу - и вы накормите их на всю жизнь"
"Большое спасибо" - Z261597841314, R208907249777, U447361470499
VictorM вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Дан двумерный массив. начиная с 1 строки сдвинуть все строки на 2 вниз, а последние 2 переместить на место первых двух строк. Proskurina Помощь студентам 5 03.03.2013 21:38
Как добавлять новые элементы (ключ=>значение) в ассоциативный массив программно. SkAndrew PHP 38 09.04.2012 20:18
Из строки в массив San4o Помощь студентам 13 11.09.2009 14:30
строки массив Артэс Общие вопросы C/C++ 1 06.09.2009 20:31
Как сделать чтобы новые строки всегда были в области видимости? neugadal Microsoft Office Excel 9 06.09.2008 12:23