Домашняя страница Undo Do New Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/Как записать диапазон в массив - Мир MS Excel

Старая форма входа
  • Страница 1 из 1
  • 1
Модератор форума: китин, _Boroda_  
Мир MS Excel » Вопросы и решения » Вопросы по VBA » Как записать диапазон в массив (Макросы/Sub)
Как записать диапазон в массив
Serg5876 Дата: Суббота, 27.01.2024, 23:36 | Сообщение № 1
Группа: Пользователи
Ранг: Прохожий
Сообщений: 9
Репутация: 0 ±
Замечаний: 0% ±

2007
Доброго времени суток ! Почему-то не создается массив из диапазона((
Делаю данную операцию первый раз, поэтому скорее всего ошибка в синтаксисе. Но не могу найти !
Помогите, пожалуйста !
Текст макроса прикреплен, а также приведен ниже:

[vba]
Код
Option Explicit
Public OstFile As Workbook, gFirma$, gAdr As String, ID As Integer
Private Dinamyc As Workbook, DinamycFileName$, PatternRecFileName As String, Lr1&, Lr2&, Lr3 As Long, _
PatternRecom As Workbook, i&, j As Long
Dim NameOfEGAIS() As Variant, NameOfPattern() As Variant, ProdName As String

Sub AnalisOst()
Set OstFile = ThisWorkbook
'UserForm1.Show 'форма. Работает
ID = 30
OstFile.Worksheets(1).Activate
Lr1 = OstFile.Worksheets(1).Cells(Rows.Count, "B").End(xlUp).Row
DinamycFileName = OstFile.Path & "\dinamika_prodazh" & ID & ".xls"
Set Dinamyc = Workbooks.Open(DinamycFileName)
Lr2 = Dinamyc.Worksheets(1).Cells(Rows.Count, "C").End(xlUp).Row [color=blue]'в Debug Lr2=5, все верно[/color]

'перенос наименований товара и заполнение массива из ЕГАИС
NameOfEGAIS = Dinamyc.Worksheets(1).Range(Cells(2, 3), Cells(Lr2, 3)).Value[b] [color=red]' в массив ничего не записывается !!![/b][/color]
Debug.Print LBound(NameOfEGAIS), NameOfEGAIS(0) [b][color=red]' тут выдает ошибку Subscript out of range и LBound=1[/color][/b]

[b] [color=blue]'проверка: диапазон корректно копируется и вставляется[/color][/b]
Dinamyc.Worksheets(1).Range(Cells(2, 3), Cells(Lr2, 3)).Copy
OstFile.Worksheets(1).Activate
Range(Cells(3, 2), Cells(Lr2, 2)).PasteSpecial Paste:=xlPasteAllExceptBorders

Terminate_Sub:
Dinamyc.Close SaveChanges:=False
Application.CutCopyMode = False
Cells(3, 3).Select
End Sub
[/vba]
К сообщению приложен файл: 9698312.xlsm (28.5 Kb) · dinamika_prodazh30.xls (51.5 Kb)


Сергей

Сообщение отредактировал Serg5876 - Суббота, 27.01.2024, 23:38
 
Ответить
СообщениеДоброго времени суток ! Почему-то не создается массив из диапазона((
Делаю данную операцию первый раз, поэтому скорее всего ошибка в синтаксисе. Но не могу найти !
Помогите, пожалуйста !
Текст макроса прикреплен, а также приведен ниже:

[vba]
Код
Option Explicit
Public OstFile As Workbook, gFirma$, gAdr As String, ID As Integer
Private Dinamyc As Workbook, DinamycFileName$, PatternRecFileName As String, Lr1&, Lr2&, Lr3 As Long, _
PatternRecom As Workbook, i&, j As Long
Dim NameOfEGAIS() As Variant, NameOfPattern() As Variant, ProdName As String

Sub AnalisOst()
Set OstFile = ThisWorkbook
'UserForm1.Show 'форма. Работает
ID = 30
OstFile.Worksheets(1).Activate
Lr1 = OstFile.Worksheets(1).Cells(Rows.Count, "B").End(xlUp).Row
DinamycFileName = OstFile.Path & "\dinamika_prodazh" & ID & ".xls"
Set Dinamyc = Workbooks.Open(DinamycFileName)
Lr2 = Dinamyc.Worksheets(1).Cells(Rows.Count, "C").End(xlUp).Row [color=blue]'в Debug Lr2=5, все верно[/color]

'перенос наименований товара и заполнение массива из ЕГАИС
NameOfEGAIS = Dinamyc.Worksheets(1).Range(Cells(2, 3), Cells(Lr2, 3)).Value[b] [color=red]' в массив ничего не записывается !!![/b][/color]
Debug.Print LBound(NameOfEGAIS), NameOfEGAIS(0) [b][color=red]' тут выдает ошибку Subscript out of range и LBound=1[/color][/b]

[b] [color=blue]'проверка: диапазон корректно копируется и вставляется[/color][/b]
Dinamyc.Worksheets(1).Range(Cells(2, 3), Cells(Lr2, 3)).Copy
OstFile.Worksheets(1).Activate
Range(Cells(3, 2), Cells(Lr2, 2)).PasteSpecial Paste:=xlPasteAllExceptBorders

Terminate_Sub:
Dinamyc.Close SaveChanges:=False
Application.CutCopyMode = False
Cells(3, 3).Select
End Sub
[/vba]

Автор - Serg5876
Дата добавления - 27.01.2024 в 23:36
Gustav Дата: Воскресенье, 28.01.2024, 01:26 | Сообщение № 2
Группа: Друзья
Ранг: Участник клуба
Сообщений: 2652
Репутация: 1114 ±
Замечаний: 0% ±

начинал с Excel 4.0, видел 2.1
Полностью задачу пока не очень понимаю, поэтому начнём с малого - с красного текста.
в массив ничего не записывается !!!
Откуда такой вывод? Всё записывается - четыре элемента в столбик. Включите перед выполнением наблюдение за переменной NameOfEGAIS - по верхнему меню редактора VBA командой Debug \ Add Watch. Поставьте точку останова на следующую строку за чтением массива и всё увидите в Окне наблюдения (Watches).

выдает ошибку Subscript out of range и LBound=1
LBound=1 - всё правильно, это же нижняя граница. Чтобы верхнюю получить надо функцию UBound использовать. Вы случайно не на этом основании делаете вывод о пустоте массива? Ошибка же "за пределами массива" возникает из-за обращения к несуществующему элементу массива NameOfEGAIS(0). Дело в том, что массивы, считанные из диапазона рабочего листа, всегда двумерные и нумерация их строк и столбцов всегда начинается с 1 (даже если в программе явно установлено Option Base 0). И адресация к элементу такого массива тоже всегда двумерная: даже если массив состоит только из одной ячейки, то адрес ее в массиве будет NameOfEGAIS(1, 1).


МОИ: Ник, Tip box: 41001663842605

Сообщение отредактировал Gustav - Воскресенье, 28.01.2024, 01:29
 
Ответить
СообщениеПолностью задачу пока не очень понимаю, поэтому начнём с малого - с красного текста.
в массив ничего не записывается !!!
Откуда такой вывод? Всё записывается - четыре элемента в столбик. Включите перед выполнением наблюдение за переменной NameOfEGAIS - по верхнему меню редактора VBA командой Debug \ Add Watch. Поставьте точку останова на следующую строку за чтением массива и всё увидите в Окне наблюдения (Watches).

выдает ошибку Subscript out of range и LBound=1
LBound=1 - всё правильно, это же нижняя граница. Чтобы верхнюю получить надо функцию UBound использовать. Вы случайно не на этом основании делаете вывод о пустоте массива? Ошибка же "за пределами массива" возникает из-за обращения к несуществующему элементу массива NameOfEGAIS(0). Дело в том, что массивы, считанные из диапазона рабочего листа, всегда двумерные и нумерация их строк и столбцов всегда начинается с 1 (даже если в программе явно установлено Option Base 0). И адресация к элементу такого массива тоже всегда двумерная: даже если массив состоит только из одной ячейки, то адрес ее в массиве будет NameOfEGAIS(1, 1).

Автор - Gustav
Дата добавления - 28.01.2024 в 01:26
Serg5876 Дата: Воскресенье, 28.01.2024, 12:06 | Сообщение № 3
Группа: Пользователи
Ранг: Прохожий
Сообщений: 9
Репутация: 0 ±
Замечаний: 0% ±

2007
Gustav, вы мне просто пелену с глаз убрали !))) Я вчера поздно ночью уже впал в ступор))). Конечно, вы правы. Все заработало ! Насчет LBound - это конечно я ошибся, по аналогии с переменной Lr (Last Row) буква L у меня ассоциировалась с концом списка B) ). Окном Add Watch активно пользуюсь, но почему то решил, что массив оно вывести не в состоянии, и даже не попробовал)). Насчет двумерной нумерации не знал, так что тут для меня открылась новая информация, благодаря вам ! А полностью задачу не поняли, потому что я поудалял лишний код, чтоб не морочить вам голову, а оставил только тот фрагмент, который выдавал ошибку. Спасибо вам большое !

По дальнейшей цели создания этих массивов: есть два списка наименований (примерно по 1т в каждом, но не одинаковое кол-во), нужно сравнить все элементы 1го списка со вторым и несовпадающие добавить в конец 2го списка (поэтому 2й список при запуске программы явно может быть больше). Я после выгрузки этих списков в массивы дальше перебираю их циклом For Next, сравнивая каждый элемент 1го списка с каждым элементом 2го. Не очень оптимально, но зато все ясно и прозрачно. Но долго. Есть ли какой-то более продвинутый функционал для решения этой задачи ? Может, надо не в массивы загрузить списки, а в словари и потом использовать функцию Filter (ни разу еще это не делал) ? Читал, что в словарях какой-то алгоритм бинарного поиска очень шустрый.. Или использовать функцию WorksheetFunction.Match ? В каком направлении двигаться ?


Сергей

Сообщение отредактировал Serg5876 - Воскресенье, 28.01.2024, 12:08
 
Ответить
СообщениеGustav, вы мне просто пелену с глаз убрали !))) Я вчера поздно ночью уже впал в ступор))). Конечно, вы правы. Все заработало ! Насчет LBound - это конечно я ошибся, по аналогии с переменной Lr (Last Row) буква L у меня ассоциировалась с концом списка B) ). Окном Add Watch активно пользуюсь, но почему то решил, что массив оно вывести не в состоянии, и даже не попробовал)). Насчет двумерной нумерации не знал, так что тут для меня открылась новая информация, благодаря вам ! А полностью задачу не поняли, потому что я поудалял лишний код, чтоб не морочить вам голову, а оставил только тот фрагмент, который выдавал ошибку. Спасибо вам большое !

По дальнейшей цели создания этих массивов: есть два списка наименований (примерно по 1т в каждом, но не одинаковое кол-во), нужно сравнить все элементы 1го списка со вторым и несовпадающие добавить в конец 2го списка (поэтому 2й список при запуске программы явно может быть больше). Я после выгрузки этих списков в массивы дальше перебираю их циклом For Next, сравнивая каждый элемент 1го списка с каждым элементом 2го. Не очень оптимально, но зато все ясно и прозрачно. Но долго. Есть ли какой-то более продвинутый функционал для решения этой задачи ? Может, надо не в массивы загрузить списки, а в словари и потом использовать функцию Filter (ни разу еще это не делал) ? Читал, что в словарях какой-то алгоритм бинарного поиска очень шустрый.. Или использовать функцию WorksheetFunction.Match ? В каком направлении двигаться ?

Автор - Serg5876
Дата добавления - 28.01.2024 в 12:06
Gustav Дата: Воскресенье, 28.01.2024, 16:18 | Сообщение № 4
Группа: Друзья
Ранг: Участник клуба
Сообщений: 2652
Репутация: 1114 ±
Замечаний: 0% ±

начинал с Excel 4.0, видел 2.1
Читал, что в словарях какой-то алгоритм бинарного поиска очень шустрый.. Или использовать функцию WorksheetFunction.Match ? В каком направлении двигаться ?

Да, наверное, эффективнее всего для решения поставленной задачи здесь использовать объект "Словарь" (Scripting.Dictionary). Без всяких утомительных попарных сравнений элементов двух массивов. Сначала записываете в словарь элементы массива 2 (циклом по этому массиву). А затем, тоже циклом, добавляете в словарь элементы массива 1. При этом, если очередного элемента массива 1 еще нет в словаре, он добавляется в конец словаря, иначе - просто игнорируется. По окончании процесса имеете словарь, содержащий все уникальные элементы обоих массивов.

Теоретически хорошо бы еще и сортировку по алфавиту к элементам словаря применить, чтобы получился классический отсортированный "справочник" уникальных элементов. Но если сортировка нужна только для ускорения доступа к элементам (как это было бы уместно для списка на рабочем листе), то для этого в словаре существует механизм доступа по ключам, а также быстрая проверка наличия того или иного значения. Поэтому фактическая последовательность элементов внутри словаря не столь уж и важна, и, соответственно, необходимость сортировки - не столь уж актуальна.


МОИ: Ник, Tip box: 41001663842605
 
Ответить
Сообщение
Читал, что в словарях какой-то алгоритм бинарного поиска очень шустрый.. Или использовать функцию WorksheetFunction.Match ? В каком направлении двигаться ?

Да, наверное, эффективнее всего для решения поставленной задачи здесь использовать объект "Словарь" (Scripting.Dictionary). Без всяких утомительных попарных сравнений элементов двух массивов. Сначала записываете в словарь элементы массива 2 (циклом по этому массиву). А затем, тоже циклом, добавляете в словарь элементы массива 1. При этом, если очередного элемента массива 1 еще нет в словаре, он добавляется в конец словаря, иначе - просто игнорируется. По окончании процесса имеете словарь, содержащий все уникальные элементы обоих массивов.

Теоретически хорошо бы еще и сортировку по алфавиту к элементам словаря применить, чтобы получился классический отсортированный "справочник" уникальных элементов. Но если сортировка нужна только для ускорения доступа к элементам (как это было бы уместно для списка на рабочем листе), то для этого в словаре существует механизм доступа по ключам, а также быстрая проверка наличия того или иного значения. Поэтому фактическая последовательность элементов внутри словаря не столь уж и важна, и, соответственно, необходимость сортировки - не столь уж актуальна.

Автор - Gustav
Дата добавления - 28.01.2024 в 16:18
Serg5876 Дата: Воскресенье, 28.01.2024, 16:24 | Сообщение № 5
Группа: Пользователи
Ранг: Прохожий
Сообщений: 9
Репутация: 0 ±
Замечаний: 0% ±

2007
Да, наверное, эффективнее всего для решения поставленной задачи здесь использовать объект "Словарь" (Scripting.Dictionary).

Спасибо, Gustav, за совет !
Буду пробовать в этом направлении ...


Сергей
 
Ответить
Сообщение
Да, наверное, эффективнее всего для решения поставленной задачи здесь использовать объект "Словарь" (Scripting.Dictionary).

Спасибо, Gustav, за совет !
Буду пробовать в этом направлении ...

Автор - Serg5876
Дата добавления - 28.01.2024 в 16:24
Мир MS Excel » Вопросы и решения » Вопросы по VBA » Как записать диапазон в массив (Макросы/Sub)
  • Страница 1 из 1
  • 1
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!