На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Организуем VBA-FAQ! Если у Вас есть предложения, выскажитесь здесь: Пишем FAQ, интересно Ваше мнение
Популярные разделы FAQ:    user posted image Общие вопросы    user posted image Особенности VBA-кода    user posted image Оптимизация VBA-кода    user posted image Полезные ссылки

1. Старайтесь при создании темы указывать в заголовке или теле сообщения название офисного приложения и (желательно при работе с Office 95/97/2000) его версию. Это значительно сократит количество промежуточных вопросов.
2. Формулируйте вопросы как можно конкретнее, вспоминая (хотя бы иногда) о правилах ВЕЛИКОГО И МОГУЧЕГО РУССКОГО ЯЗЫКА, и не забывая, что краткость - сестра таланта.
3. Не забывайте использовать теги [сode=vba] ...текст программы... [/code] для выделения текста программы подсветкой!
4. Темы с просьбой выполнить какую-либо работу полностью за автора здесь не обсуждаются и переносятся в раздел ПОМОЩЬ СТУДЕНТАМ.
Модераторы: Old Bat, MIF
  
> копирование массива в массив , массив в екселе
    Здравствуйте. Помогите начинающему советом:)
    Неделю назад открыл для себя что такое макрос, применительно к Екселю. Сегодня книжку купил, но все равное не разберусь никак...
    Смысл в том чтоб выгрузить двумерный массив чисел-integer к примеру 1000 на 100, а далее по определенным условиям перегрузить, соответственно уже кусок этого массива в другой массив. Понял как массив создать, как его отфильтровать, а вот выгрузить полученные значения в новый массив не получается. Посоветуйте пожалуйста что-нибудь, желательно куском кода:) Спасибо заранее
    з.ы. два цикла j=1 to 100 внутри i=1 to 1000; отбор значений идет после цикла j и сравнивать хотел там же, по просто думал будет работать чтото типа old(i,j)=new(i,j) а почемуто нет:(
    Сообщение отредактировано: Kugeod -
      Мож, стоит попробовать загрузить из старого массива в новый, а не наоборот: new(i,j)=old(i,j)
        Я окончательно запутался :(

        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 Почему не работает? :(
          Цитата Kugeod @
          Почему не работает?

          Потому что с логикой косяк.
          Выполняется цикл по j. От 1 до 100. Завершяется он, когда на очередном витке j становится больше 100, т.е. 101. Но следующей строкой ты делаешь newM(i, j) = oldM(i, j) - при j=101 иной реакции программы ожидать не следовало.
          Сообщение отредактировано: Akina -
            ExpandedWrap disabled
              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. Хоть памяти занимает больше, зато гимора в виде сообщений с ошибками намного меньше будет.
              Цитата GDK @
              И вот ещё, обрати внимание. Объявляешь массив 0-1000, 0-100. Т.е. такой массив будет содержать 1001 "строку" и 101 "колонку". А цикл начинаешь с номера 1. Т.е. не будет никаких действий с 0-й строкой и нулевой колонкой.

              Это при условии что выше нет незахваченного при копировании Option Base 1. :D
                Спасибо за ответы, почти разобрался с копированием. Вопрос возник.
                ExpandedWrap disabled
                  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.
                Заранее простите за тупость:(
                  Цитата Kugeod @
                  Если первый комментарий в этом коде верный то почему итог выглядит как массив (1,1) (100,10) у которого значения до 50 заполнены нулями, а потом только выводится то что я хочу получить.

                  При определении переменной типа Integer (неважно, одиночка или массив) ей присваивается значение "ноль". Потом ты часть массива перезаписываешь - меняешь нули на значение, - а начало так и остаётся всё в нулях.

                  Правильнее - так:

                  ExpandedWrap disabled
                    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
                    В принципе я с вашей помощью почти разобрался. Akina вы предлагаете
                    ExpandedWrap disabled
                      if i>50 then newM(i-50,j)...

                    А если у меня сложнее условие и я хочу на выходе получить массив только с теми значениями которые мне нужны, это вообще возможно? Без нулей? Как автоматически уменьшит размер выходного массива чтоб он был размером только под те значения, которые отфильтруются?
                    Я вот тут накатал какоето безобразие, не знаю на правильном ли пути. Подскажите
                    к примеру
                    ExpandedWrap disabled
                      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 чтобы вывести только те значения которые меня интересуют. Но все равно такое ощущение, что можно по другому, слишком нагромоздил.. Тем более что выходной массив при этом не уменьшается, а значит смысл теряется:(
                      ReDim Preserve

                      И вообще неплохо бы побольше читать.
                        Осторожнее с ReDim Preserve! Используйте только для одномерных массивов! Для многомерных массивов данные, хранящиеся в "2-м, 3-м, ..." измерениях "обнуляются". Твоё безобразие - не безобразие.
                        Если не требуется высокое быстродействие могу посоветовать вместо массива использовать коллекции или ещё лучше объекты vbscript.Dictionary (вроде бы правильно написал). Но коллекциями можешь пользоваться сразу, а вот для чтобы был "доступ" к диктионари надо подключить библиотеку microsoft scripting runtime c помощью Tools-references.... Короче с ними работать намного удобнее. Особенно с dictionary. Но при его использовании по сравнению с коллекциями могут быть проблемы, т.к. на некоторых компах системные администраторы запрещают подключать некоторые библиотеки.
                        Сообщение отредактировано: GDK -
                          Цитата GDK @
                          Для многомерных массивов данные, хранящиеся в "2-м, 3-м, ..." измерениях "обнуляются".

                          Что??? никогда не было такого!
                            Да вот ReDim Preserve мне не помог никак:( Потому как Akina посоветовал мне почитать книгу и я прочел что можно изменять только последнее измерение многомерного массива. А меня то как раз интересует изменение первого измерения, так как мне оно не известно пока не закончится цикл, в этом же цикле вы предлагаете копировать массив в массив. За циклом его не скопировать а в цикле не переопределить первое измерение массива :(:(
                              Цитата Kugeod @
                              А меня то как раз интересует изменение первого измерения, так как мне оно не известно пока не закончится цикл

                              Поменяйте местами индексы :D
                                Поменяю индексы и что получится? Если имеете ввиду поменять местами циклы то это не возможно ввиду условий:( Написал бы ктонить что НИКАК я б и голову не ломал
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0692 ]   [ 16 queries used ]   [ Generated: 19.08.25, 19:36 GMT ]