
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.123] |
![]() |
|
Сообщ.
#1
,
|
|
|
Здравствуйте. Помогите начинающему советом:)
Неделю назад открыл для себя что такое макрос, применительно к Екселю. Сегодня книжку купил, но все равное не разберусь никак... Смысл в том чтоб выгрузить двумерный массив чисел-integer к примеру 1000 на 100, а далее по определенным условиям перегрузить, соответственно уже кусок этого массива в другой массив. Понял как массив создать, как его отфильтровать, а вот выгрузить полученные значения в новый массив не получается. Посоветуйте пожалуйста что-нибудь, желательно куском кода:) Спасибо заранее з.ы. два цикла j=1 to 100 внутри i=1 to 1000; отбор значений идет после цикла j и сравнивать хотел там же, по просто думал будет работать чтото типа old(i,j)=new(i,j) а почемуто нет:( |
![]() |
Сообщ.
#2
,
|
|
Мож, стоит попробовать загрузить из старого массива в новый, а не наоборот: new(i,j)=old(i,j)
|
Сообщ.
#3
,
|
|
|
Я окончательно запутался
![]() Dim newM(1000,100) As Integer Dim oldM(1000, 100) As Integer Dim i As Integer: Dim j As Integer Sub Massiv() Randomize For i = 1 To 1000 For j = 1 To 100 oldM(i, j) = Fix(Rnd + 0.5) Next j If i > 500 Then newM(i, j) = oldM(i, j) Next i End Sub Выводит ошибку subscript out of range Почему не работает? ![]() |
![]() |
Сообщ.
#4
,
|
|
Цитата Kugeod @ Почему не работает? Потому что с логикой косяк. Выполняется цикл по j. От 1 до 100. Завершяется он, когда на очередном витке j становится больше 100, т.е. 101. Но следующей строкой ты делаешь newM(i, j) = oldM(i, j) - при j=101 иной реакции программы ожидать не следовало. |
Сообщ.
#5
,
|
|
|
![]() ![]() Dim newM(1000, 100) As Integer Dim oldM(1000, 100) As Integer Dim i As Integer: Dim j As Integer Sub Massiv() Randomize For i = 1 To 1000 For j = 1 To 100 oldM(i, j) = Fix(Rnd + 0.5) If i > 500 Then newM(i, j) = oldM(i, j) Next j 'If i > 500 Then newM(i, j) = oldM(i, j) Next i End Sub Это надо было? И вот ещё, обрати внимание. Объявляешь массив 0-1000, 0-100. Т.е. такой массив будет содержать 1001 "строку" и 101 "колонку". А цикл начинаешь с номера 1. Т.е. не будет никаких действий с 0-й строкой и нулевой колонкой. Добавлено И зря ты для экспериментов пользуешься такими большими массивами. Проще было бы (0-10, 0-4 ) например. Добавлено И лучше используй Long вместо Integer. Хоть памяти занимает больше, зато гимора в виде сообщений с ошибками намного меньше будет. |
![]() |
Сообщ.
#6
,
|
|
Цитата GDK @ И вот ещё, обрати внимание. Объявляешь массив 0-1000, 0-100. Т.е. такой массив будет содержать 1001 "строку" и 101 "колонку". А цикл начинаешь с номера 1. Т.е. не будет никаких действий с 0-й строкой и нулевой колонкой. Это при условии что выше нет незахваченного при копировании Option Base 1. ![]() |
Сообщ.
#7
,
|
|
|
Спасибо за ответы, почти разобрался с копированием. Вопрос возник.
![]() ![]() Sub Massiv() Dim g As Integer Randomize For i = 1 To 100 For j = 1 To 10 oldM(i, j) = Fix((Rnd + 0.6) * 2) If i > 50 Then newM(i, j) = oldM(i, j) 'это выражение присваивает новому массиву значения только с (50,1) до (100,10)?? Next j Next i Worksheets(1).Range(Cells(1, 1), Cells(100, 10)).Value = newM ' это я гдето подсмотрел что так можно:) End Sub Если первый комментарий в этом коде верный то почему итог выглядит как массив (1,1) (100,10) у которого значения до 50 заполнены нулями, а потом только выводится то что я хочу получить. Как сделать чтобы новый массив был только из 50 элементов по условию? и соответственно выводил 50 на 10. Заранее простите за тупость:( |
![]() |
Сообщ.
#8
,
|
|
Цитата Kugeod @ Если первый комментарий в этом коде верный то почему итог выглядит как массив (1,1) (100,10) у которого значения до 50 заполнены нулями, а потом только выводится то что я хочу получить. При определении переменной типа Integer (неважно, одиночка или массив) ей присваивается значение "ноль". Потом ты часть массива перезаписываешь - меняешь нули на значение, - а начало так и остаётся всё в нулях. Правильнее - так: ![]() ![]() Dim oldM(1 to 100, 1 to 10) As Integer Dim newM(1 to 50, 1 to 10) As Integer Sub Massiv() Dim i As Integer, j As Integer Randomize Timer For i = 1 To 100 For j = 1 To 10 oldM(i, j) = (Rnd + 0.6) * 2 If i > 50 Then newM(i-50, j) = oldM(i, j) Next j Next i Worksheets(1).Range(Cells(1, 1), Cells(50, 10)).Value = newM End Sub |
Сообщ.
#9
,
|
|
|
В принципе я с вашей помощью почти разобрался. Akina вы предлагаете
![]() ![]() if i>50 then newM(i-50,j)... А если у меня сложнее условие и я хочу на выходе получить массив только с теми значениями которые мне нужны, это вообще возможно? Без нулей? Как автоматически уменьшит размер выходного массива чтоб он был размером только под те значения, которые отфильтруются? Я вот тут накатал какоето безобразие, не знаю на правильном ли пути. Подскажите к примеру ![]() ![]() Sub Massiv() Dim g As Integer Randomize Timer g = 1 For i = 1 To 100 For j = 1 To 10 oldM(i, j) = (Rnd + 0.6) * 2 If (i > 50 And i < 60) Or (i > 80 And i < 90) Then newM(g, j) = oldM(i, j) Next j If (i > 50 And i < 60) Or (i > 80 And i < 90) Then g = g + 1 Next i Worksheets(1).Range(Cells(1, 1), Cells(g, 10)).Value = newM End Sub ввел переменную g чтобы вывести только те значения которые меня интересуют. Но все равно такое ощущение, что можно по другому, слишком нагромоздил.. Тем более что выходной массив при этом не уменьшается, а значит смысл теряется:( |
![]() |
Сообщ.
#10
,
|
|
ReDim Preserve
И вообще неплохо бы побольше читать. |
Сообщ.
#11
,
|
|
|
Осторожнее с ReDim Preserve! Используйте только для одномерных массивов! Для многомерных массивов данные, хранящиеся в "2-м, 3-м, ..." измерениях "обнуляются". Твоё безобразие - не безобразие.
Если не требуется высокое быстродействие могу посоветовать вместо массива использовать коллекции или ещё лучше объекты vbscript.Dictionary (вроде бы правильно написал). Но коллекциями можешь пользоваться сразу, а вот для чтобы был "доступ" к диктионари надо подключить библиотеку microsoft scripting runtime c помощью Tools-references.... Короче с ними работать намного удобнее. Особенно с dictionary. Но при его использовании по сравнению с коллекциями могут быть проблемы, т.к. на некоторых компах системные администраторы запрещают подключать некоторые библиотеки. |
![]() |
Сообщ.
#12
,
|
|
Цитата GDK @ Для многомерных массивов данные, хранящиеся в "2-м, 3-м, ..." измерениях "обнуляются". Что??? никогда не было такого! |
Сообщ.
#13
,
|
|
|
Да вот ReDim Preserve мне не помог никак:( Потому как Akina посоветовал мне почитать книгу и я прочел что можно изменять только последнее измерение многомерного массива. А меня то как раз интересует изменение первого измерения, так как мне оно не известно пока не закончится цикл, в этом же цикле вы предлагаете копировать массив в массив. За циклом его не скопировать а в цикле не переопределить первое измерение массива
![]() ![]() |
![]() |
Сообщ.
#14
,
|
|
Цитата Kugeod @ А меня то как раз интересует изменение первого измерения, так как мне оно не известно пока не закончится цикл Поменяйте местами индексы ![]() |
Сообщ.
#15
,
|
|
|
Поменяю индексы и что получится? Если имеете ввиду поменять местами циклы то это не возможно ввиду условий:( Написал бы ктонить что НИКАК я б и голову не ломал
|