Страницы: 1
RSS
Перебор переменных и запись их в массив
 
Уважаемые форумчане!! Прошу помощи кто понимает в массивах)))

Суть проблемы такова: сначала задумывался файлик для загрузки отчетности в контур - написал макрос, который преобразовывал таблицу в необходимую структуру и всё работало, пока наше законодательство в очередной раз не поменялось и файлик из 1000 строк превратился в 99000. Макрос также прекрасно работает, но ооооочень долго... примерно уходит 20 минут на создание необходимой структуры в 400 000 строк.... В связи с этим было принято решение перевести макрос с листа в массив и преобразовать там -  и уже на лист выводить результат. - читал что это должно существенно сократить время обработки.
До этого никогда с массивами не работал - так как это для меня темный лес... В файле я набросал макрос, но так и не получилось создать одномерный массив - не получается у меня перебирать данные и записывать их новый массив. что я не так делаю?!!!
 
посмотрел мельком. начало вроде нормальное,создаете массив из ячеек, перебираете его..где затык?
Живи и дай жить..
 
Вот затык  в поле
Код
 ReDim Preserve sumArr(counter To counter + 14)
For b = 1 To 14
sumArr(counter) = arrtemp1
sumArr(counter + 1) = arrtemp2
sumArr(counter + 2) = arrtemp3
...
sumArr(counter + 13) = arrtemp14
Next

Мне нужно получить цикл, чтобы одномерный массив был заполнен последовательно в столбце , а вот что у меня в файле не работает.... пишет ошибку 9  и ругается на строчку redim
 
Цитата
real-593 написал:
ReDim Preserve sumArr(counter To counter + 14)
хрень. Увеличить размерность с сохранением(Preserve) можно только на один элемент. Т.е. по-любому надо идти циклом от 1 до 14 и последовательно заполнять согласно счетчика.
Что-то вроде:
Код
For b = 1 To 14
ReDim Preserve sumArr(counter To counter + b) 
sumArr(counter) = arrtemp1
counter =counter +1
Next 
Изменено: The_Prist - 30.05.2016 15:44:16
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
В идеале я хотел получить цикл вот такого вида
Код
 ReDim Preserve sumArr(counter To counter + 14)
             
 For b = 1 To 14
sumArr(counter + b) = arrtemp & b
Next b

где arrtemp & b = динамическая переменная, что в реалии к сожалению невозможно((
 
Цитата
real-593 написал: В идеале я хотел получить...
о-о-о...нет, это из разряда фантастики(для VBA в Excel, по крайней мере).
А зачем это вообще надо? Зачем хранить переменные в массиве? Может имеет смысл просто в массив в заранее заданные места задавать значения и все?
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
А меня вот эта строка насторожила (да и с ошибкой на ней вываливается)
Код
For b = arrtemp1 To arrtemp14
где arrtemp1 = "          <ПерПредСд НаимПредСд=" &......, ну то есть явно строка
Согласие есть продукт при полном непротивлении сторон
 
я так понял, что тут:
Код
           For b = arrtemp1 To arrtemp14
            ReDim Preserve sumArr(counter)
            sumArr(counter) = b
            counter = counter + 1
            'MsgBox (b)
            Next
для конструкции For b= ... to ... нужны числовые b, а у вас они текстовые. For Each тоже тут не годится.
Вам нужно вместо отдельных переменных arrtemp1 ... arrtemp14 создать массив
Код
arrtemp(1 To 14)
, и переменным присваивать значения так:
Код
arrtemp(1) = ...
тогда приведенная выше конструкция вообще не нужна,
Код
For i = 1 To UBound(arrtemp)
    Project.Range("a" & i + 11).Value = arrtemp(i)
Next
F1 творит чудеса
 
А я файл вообще не смотрел - мне сама затея не очень нравится :)
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Переменные создаются из-за того, что есть шаблон для загрузки и переменные данные, которые заполняет бухгалтер. нажимая кнопку он формирует структурный документ.

Про цикл с шагом один я думал....  
В первоначальном варианте, когда работаешь с листом там можно путешествовать по ячейкам с помощью .offset, а почитав про массивы как я понял здесь такое не прокатит.
 
Цитата
real-593 написал: есть шаблон для загрузки и переменные данные
поменяйте в шаблоне отдельные переменные на массив...
F1 творит чудеса
 
Цитата
Максим Зеленский написал:
23For i = 1 To UBound(arrtemp)    Project.Range("a" & i + 11).Value = arrtemp(i)Next
Максим спасибо!

Я тоже думал о таком варианте, просто рассматривал создание структуры в массиве а потом перенос на лист. Как вы считатаете это ускорит процесс переписав цикл как вы предложили: первоначально макрос работал также  как вы написали, но только данные не из массива получал а обращался к листу?
 
Цитата
есть шаблон для загрузки и переменные данныепоменяйте в шаблоне отдельные переменные на массив...
Максим, так я в коде поменял переменные на данные из первоначального массива.
например
Код
 arrtemp1 = " ....... & """" & myArr(n, 12) & .......
 
Цитата
real-593 написал: создание структуры в массиве а потом перенос на лист
похоже, тут небольшое недопонимание.
Смотрите, вы неким образом обрабатываете входные данные (массив myArr()), в итоге получаете 14 переменных, которые собираете из myArr() и разметки.
В правила обработки я не вдавался, неважно. Суть в том, что вы хотите получить 14 строк на лист под "шапку"

Вы пытались сделать так:
  1. создать некие строки из начальных данных
  2. загрузить их в массив SummArr (тут была ошибка, так цикл сделать нельзя)
  3. потом этот массив выгрузить на лист.
Мой совет такой:
  1. Определить массив по количеству нужных строк вывода (их ведь 14?)
  2. Присвоить каждому элементу массива значения по вашим правилам обработки
  3. выгрузить массив на лист.
в моем варианте вы не создаете лишний массив SumArr для выгрузки, а просто сразу пишете данные в элементы массива/переменные.
По идее, количество переменных у вас фиксированное, вы можете сразу писать эти значения на лист начиная с 12 строки, но это некрасиво и неэффективно, получите 12 обращений к листу вместо 1.
F1 творит чудеса
 
Максим,
Огромное спасибо что помогаете!

строк вывода может колебаться в зависимости от того что указано в исходном файле. например для первой строки arrtemp будет 13 или 14 а вот для второй будет уже всего 3 или 4 в зависимости от заполнения исходника.

То есть в коде  ReDim arrtemp (1 To 14) мне нужно 14 постоянно увлечивать через цикл:
Например:
первая строчка в исходники
ReDim arrtemp (1 To 14)
и далее заполнили все arrtemp
вторая строчка исходника
ReDim arrtemp (15 To 17)
и далее заполнили три arrtemp
третья строчка исходника
ReDim arrtemp (18 To 21)
и так далее.....

Можно ли как то это сделать создав цикл.... например Redim arrtemp ( a to b)
Смысл SumArr в том, что я думал, что создав временный массив  arrtemp в зависимости от наполнения исходника и далее полученный массив запихиваем в конечный массив и стираем результат временного.... но вот как то не получилось((
 
Я правильно понимаю, что количество строк вывода для одной строки исходника должно быть разным?
Просто по коду я понял так, что заполняются всегда все 14 переменных. Может, ошибся - на эту часть смотрел невнимательно
F1 творит чудеса
 
Хотел поблагодарить всех участников, особенно Максима!

На основе идеи Максима, отказаться от массива в массиве получилось у меня написать код, увеличивая массив на определенное кол-во строк в зависимости от данных в первичном массиве!

Так как это был мой первый опыт написания массива провозился долго, но результат превзошел все ожидания: 100 тыс строк которые я ранее преоброзовывал в форму уже из 400 тыс строк макросом с записью в ячейку - на это уходило от 15 до 20 минут, то с помощью массива на это уходит 40-50 секунд!  
 
Не вникал в задачу  - но если можно постоянно увеличивающийся массив заменить на коллекцию, то думаю можно время сократить ещё где-то вдвое.
 
Ну это совсем круто для меня будет научиться создавать коллекции...
Но пока столкнулся с одной моей "хотелкой"
Получившийся код из 400 тыс строк нужно запихнуть в другой файл. Нашел на форуме от Hugo пост пытался сделать, но что так и не заработало.... Видимо это особенности файла в который надо всё запихнуть. Макрокордер тоже никак не помогает.
Код
Sub Open_save_file()
Open "C:\Users\sscsyp\Desktop\example.xlm" For Output As #1
MsgBox (ok)
Print #1, Join(Application.Transpose(Project.Range("A1:A390832").Value), vbLf)
Close #1
End Sub

Задача макроса такова:
1)Написать путь к файлу - это изначально пустой шаблон, который будет храниться где то очень глубоко в недрах общих сетевых дисков. Макрос должен скопировать от туда  файл к себе в папку и открыть его.
2)Запихнуть туда код, сохранить и закрыть.

шаблон в формате xml и открывается только в блокноте.

Реально ли такое вообще делать?
Не могу приложить файл-шаблон - ругается на формат.
Страницы: 1
Читают тему
Наверх