Страницы: 1 2 След.
RSS
Массив массивов из переменных, Как правильно обновить значения переменных после их изменения внутри массива
 
Доброго времени суток, Планетяне!

1. Формирую массив из переменных (тоже массивов): temp=Array(arr1,arr2,arr3)
2. Передаю этот массив массивов в функцию, которая оставляет в переменных только подходящие по индексу элементы
Значения переменных при этом не меняются, если смотреть как ?Join(arr1) (самостоятельная переменная), но меняются, если смотреть как ?Join(arrArr(1)) (переменная в составе массива).
Если, после функции фильтрации переприсваивать каждую переменную руками (arr1=arrArr(1)), то это, конечно, работает, но чёт долго  :)

Как можно выполнить переприсваивание в цикле (или ещё как-то восстановить связь с переменными, поскольку в реале более 20 переменных бывает) и вообще почему так получается?
(Так получается, потому что при формировании массива массивов теряется связь с источником — одномерными массивами)
КОД
Изменено: Jack Famous - 12.11.2018 11:00:31
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, Ех.... и вы туда же. так что нужно? совет в чем?  :D  
Изменено: ivanok_v2 - 08.11.2018 17:42:20
 
ivanok_v2, обновил)
Цитата
ivanok_v2: и вы туда же
а кто ещё и почему это плохо?… В реале это глобальные переменные, в которых находятся данные из других файлов
Изменено: Jack Famous - 08.11.2018 17:46:46
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
почему это плохо
я ето не говорил, а акцентировал ваше  внимание, что не понятен вопрос и суть проблемы. ;)
Цитата
Jack Famous написал:
а кто ещё
в идеале каждый товый ТС. Но бывают исключения
Изменено: ivanok_v2 - 08.11.2018 18:56:34
 
Добрый день, коллеги! Я не вижу никаких проблем в #1. В макросе t массив arrarr содержит 4 элемента, каждый из которых является массивом. Эти элементы не являются ссылкой на arr0, arr1,..., как это было бы в случае с объектами, a живут собственной жизнью. Естественно, их изменение никак не может затронуть arr0,...
Владимир
 
sokol92, спасибо! А как в таком случае сделать правильно? Чтобы передавать переменные и менялись именно они…
Может UDF написать надо (какого рода) или класс создать (пока не делал)?
Изменено: Jack Famous - 08.11.2018 19:15:45
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, используйте вместо ByVal, ByRef
 
ivanok_v2, насколько я понимаю, это как раз вообще ничего не изменит во входящих данных. В таком случае придётся переделать функцию, чтобы возвращала массив массивов, а не изменяла входящий. Вы пробовали?

UPD: я попробовал — был прав  :D

UPD2:
Цитата
ivanok_v2: используйте вместо ByVal, ByRef
я невнимательно прочитал, переставив местами — прошу прощения…
В таком случае, непонятно - где (в какой функции) менять и как это может помочь? В основной функции для фильтрации как раз стоит ByRef (хотя можно было и не писать, т.к. он по-умолчанию подразумевается программой)
Изменено: Jack Famous - 08.11.2018 19:51:21
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous,  Алексей,
1. переходите от MSGBOX на debug.print .
2. при передаче значения в дочерней функции создается новый элемент. При ссылке работа ведется с тем что передали.  Соответственно, если хотите менять то передавайте ссылку. Если правильно помню, то по умолчанию, если ничего не прописывать то ссылка будет и b будет 2

Скрытый текст

пока писал ТС написал  сам о том же
Изменено: БМВ - 08.11.2018 20:40:31
По вопросам из тем форума, личку не читаю.
 
Цитата
Jack Famous написал:
А как в таком случае сделать правильно
Пример для двумерного массива (в отладчике можно посмотреть на массив "a" в конце макроса test) :
Код
' Обрабатывает двумерный массив и к текстовым значениям, начинающимся на апостроф и знак равенства, добавляет слева апостроф
Sub RngChg(ByRef arr())
    Dim i As Long, j As Long
    For i = LBound(arr, 1) To UBound(arr, 1)
        For j = LBound(arr, 2) To UBound(arr, 2)
            If Left(arr(i, j), 1) = "=" Or Left(arr(i, j), 1) = "'" Then
                arr(i, j) = "'" & arr(i, j)
            End If
        Next j
    Next i
End Sub

Sub test()
  Dim a(1 To 2, 1 To 5)
  a(2, 3) = "'Литерал SQL'"
  a(2, 5) = "=формула"
  a(1, 1) = 5454 ' число
  a(1, 2) = "Обычный текст"
  RngChg a
End Sub
Владимир
 
Всем доброго утра!
Цитата
БМВ: переходите от MSGBOX на debug.print
спасибо — уже давно использую (особенно с длинными строками), а тут MsgBox остался для пошаговой отладки  :)

БМВ, sokol92, по примерам в целом понятно, но неясно главное — как это применить для моего примера  :D

Дело в том, что переменные одномерных массивов с нуля из примера (arr1, arr2 и т.д.) в реальности представляют собой целые столбцы данных из разных файлов. То есть, я открываю файл-программу (например для списания) и, при запуске, из разных справочников забираются вот такие массивы (бывает более 20ти). Public-переменные для них хранятся в надстройке. Вот наполнил я эти переменные и потом начинаю фильтровать под разные задачи - для этого и написал функцию фильтрации по массиву индексов. А передаю массив массивов, потому что не ясно - сколько массивов будет фильтроваться, а массив массивов всегда один. Можно передать один одномерный массив (частный случай). Как-то так:
Парочка реальных UDF
Если можно, то покажите на моём примере передачи массива массивов — как потом эти исходные массивы (arr1, arr2 и т.д.) можно быстро "актуализировать" (если это вообще реализуемо)…
Изменено: Jack Famous - 09.11.2018 10:41:14
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, вернусь к вашему сообщению #1
у вас есть код
Код
MsgBox Join(arr1, "-") & vbLf & Join(arr2, "-") & vbLf & Join(arr3, "-")
MsgBox Join(arrArr(1), "-") & vbLf & Join(arrArr(2), "-") & vbLf & Join(arrArr(3), "-")
вам нужно что бы омонвился arr1 значением arrArr(1) или  arrArr(1) значением arr1?
 
ivanok_v2, нужно, чтобы arr1 обновился значением arrArr(1), т.к. после выполнения функции именно arrArr(1) изменяется, а arr1 остаётся таким же
Изменено: Jack Famous - 09.11.2018 11:46:28
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous,сделайте так
Код
MsgBox Join(arr1, "-") & vbLf & Join(arr2, "-") & vbLf & Join(arr3, "-")
arr1 = arrArr(1)
MsgBox Join(arr1, "-") & vbLf & Join(arr2, "-") & vbLf & Join(arr3, "-")
MsgBox Join(arrArr(1), "-") & vbLf & Join(arrArr(2), "-") & vbLf & Join(arrArr(3), "-")
или по аналогии цыклом
Изменено: ivanok_v2 - 09.11.2018 11:49:06
 
Цитата
ivanok_v2: arr1 = arrArr(1)
Цитата
Jack Famous: Если переприсваивать каждую руками (arr1=arrArr(1)), то это, конечно, работает, но чёт долго
Цитата
ivanok_v2: или по аналогии циклом
а вот цикл по аналогии не получается…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
а вот цикл по аналогии не получается…
делайте два массива массивов и забудте об arr0, arr1, arr2, arr3
Код
arrArrMain = Array(arr0, arr1, arr2, arr3)
arrArr = arrArrMain 
.....
Erase arrArrMain
redim arrArrMain(ubound(arrArr))
for i%=lbound(arrArrMain) to lbound(arrArrMain)
  arrArrMain(i%)=arrArr(i%)
next
 
Здравствуйте, Алексей! Трудно давать советы, не зная в деталях сущность задачи. Если Вы изначально рассчитываете, что будете работать с массивом массивов, то зачем "одиночные" массивы? Работайте в #1 сразу с ArrArr (изменен только стартовый макрос):
Код
Sub t()
    Dim arrArr, arrInd, x, crit
    ReDim arrArr(0 To 3)
    arrArr(0) = RngToArray1x([_0])
    arrArr(1) = RngToArray1x([_1])
    arrArr(2) = RngToArray1x([_2])
    arrArr(3) = RngToArray1x([_3])
    crit = 2: arrInd = IndexFromArrayByValue(crit, arrArr(0))
    If Not ArrFilt(arrArr, arrInd) Then Exit Sub
    ' ...
 End Sub
Чтобы часто не менять размерность arrArr можно изначально распределить его с запасом (например, на 1000 элементов, это потребует по нынешним временам немного дополнительной памяти) и в отдельной переменной типа long хранить последний занятый элемент. Естественно, эту переменную нужно предусмотреть и в обрабатывающих процедурах.
Владимир
 
Цитата
ivanok_v2: делайте два массива массивов и забудьте об arr0, arr1, arr2, arr3
да как я могу о них забыть, если это публичные переменные с данными, которые должны измениться после функции???
Цитата
sokol92: зачем "одиночные" массивы?
Здравствуйте, Владимир  :) По описанной выше (и подробнее в #11) причине.

Смотрите: заменим arr'ки из примера на более реальные arrName, arrVal, arrMeas, arrPrice и arrCost. Каждый из этих массивов представляет собой столбец одной и той же таблицы в другом файле (Наименование, КОЛ-ВО, Ед. изм., Цена и Стоимость — соответственно). И вот мне нужно как бы "отфильтровать" все эти массивы-столбцы, оставив только нужные (одинаковые для каждого) индексы (массив индексов получен отдельно).
Для этого была написана функция. Главный вопрос - можно ли каким-то образом ТАК передать эти массивы в неё через массив массивов, чтобы после работы функции сами эти одиночные массивы изменились?

Я так понимаю, что как раз из-за формирования массива массивов это невозможно.
Изменено: Jack Famous - 09.11.2018 12:58:41
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, если я верно уловил суть...
Скрытый текст

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
JayBhagavan, как раз подумал посмотреть в сторону ParamArray(), чтобы уйти от массива массивов  :)
Цитата
JayBhagavan: arr1 = dict(1)
вы всё равно вручную переприсваиваете переменные, а это, по сути, то же самое, что
Цитата
Jack Famous: Если, после функции фильтрации переприсваивать каждую переменную руками (arr1=arrArr(1)), то это, конечно, работает, но чёт долго
поэкспериментирую с ParamArray()  ;)
Изменено: Jack Famous - 09.11.2018 13:49:06
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, Ваша задумка с ParamArray не увенчается успехом, т.к. он принимает ТОЛЬКО значения, но не ссылки на объекты. (судя из справки и по экспериментам, которые я первым делом провёл)
+++
Тогда, возможно, так...
Скрытый текст
+++
Мои выводы были преждевременны и неверны. Разоблачение тут.
Изменено: JayBhagavan - 12.11.2018 12:08:19

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Jack Famous, А если циклом пробежать по массиву массивов и функцией их все переделать, или я что то не так понимаю?
"Все гениальное просто, а все простое гениально!!!"
 
Цитата
JayBhagavan: возможно, так
спасибо вам за науку и тесты! Попробую…

Nordheim, а вот не получается циклом)) Пробовал циклы типа i=-1: For each x in arrArr: i=i+1: arrArr(i)=x: Next x
Изменено: Jack Famous - 09.11.2018 16:53:23
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал: а вот не получается циклом
Да, ладно! А как же я в последнем примере обрабатывал массив массивов???

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
JayBhagavan, ну, во-первых, я тогда еще не пробовал ваш вариант)) во-вторых вы в своём примере точно также делаете Join по элементам массива массивов и переменными там не пахнет))) видимо, всё-таки, буду ручками  :(
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, Join я делаю для наглядности, что содержимое массива массивов изменилось.
Зачем ещё какие-то переменные мне НЕ понятно, когда можно обращаться к подмассиву по его индексу.
Если Вы про наглядность в имени массива:
Цитата
arrName, arrVal, arrMeas, arrPrice и arrCost
так сделайте индексы подмассивов константами, например:
Код
Const lSubArrName& = 0
Const lSubArrVal& = 1

MsgBox Ubound(arrs(lSubArrName)), Ubound(arrs(lSubArrVal))

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Цитата
Jack Famous написал:
i=-1: For each x in arrArr: i=i+1: arrArr(i)=x: Next x
Все верно так не получится
Вот примитивно на примере удаляются массивы массивов. В функции можно переделать массив как нужно.
Или это не то?
"Все гениальное просто, а все простое гениально!!!"
 
Мужики, ну вы чего в самом деле?)))))
Я же уже столько раз написал, что переменные мне нужны, потому что в них хранятся данные с других листов и после фильтрации прочие процедуры и функции обращаются к заранее известным переменным, а не к элементам массива массивов  :D  вот я и ищу, можно ли как-то "не руками" их после фильтрации переназначить…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Я так и не врубился, что делает массив массивов, но, может, словарь массивов будет удобнее?
 
а так. Только при больших объемах памяти занято будет немало.
Изменено: Nordheim - 09.11.2018 19:33:47
"Все гениальное просто, а все простое гениально!!!"
Страницы: 1 2 След.
Наверх