powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Массивы в VBA
25 сообщений из 69, страница 2 из 3
Массивы в VBA
    #36519903
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexFrPublic Function XFunc(XArrayFunc, StringAddr)
' Массив получаю в XArrayFunc
' Адрес элемента массива получаю в StringAddr, но в текстовом виде, грубо говоря...
' Нужно из массива XArrayFunc извлеч его элемент с адресом StringAddr... Как?

End Function

Ага, стало яснее.
При этом массив совершенно произвольного количества измерений или есть какое-то ограничение?
...
Рейтинг: 0 / 0
Массивы в VBA
    #36519911
AlexFr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hugo121,

А если он двух.. трех.. n-мерный?
...
Рейтинг: 0 / 0
Массивы в VBA
    #36519912
AlexFr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro,

нет ограничений...
...
Рейтинг: 0 / 0
Массивы в VBA
    #36520019
.Михаил.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexFrXElement = XArray1(1, 5, ..., n) и NADO_XElement = XFunc(XArray1, "1,5,...,n") - это одно и тоже значение
голову сломал, пока это придумывал
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Sub myTest()
Dim mass( 1  To  10 ,  1  To  10 ,  1  To  10 ) As Integer ' можно сделать любую размерность
Dim i As Integer, j As Integer, i1 As Integer, pos As Integer
pos =  0 
For i =  1  To  10 
    For j =  1  To  10 
        For i1 =  1  To  10 
            pos = pos +  1 
            mass(i, j, i1) = pos
        Next
    Next
Next
MsgBox XFunc(mass, "1,3,4") & " " & mass( 1 ,  3 ,  4 ) ' для сравнения результатов
End Sub
сама функция
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
Function XFunc(ByRef XArray, ByRef StringAddr As String) As Integer
Dim addr() As String, n As Integer, val2 As Integer, val() As Integer, myItem
Dim i As Integer, pos() As Integer, flag As Byte, m As Integer
n =  1 : addr = Split(StringAddr, ",")
On Error GoTo ErrorHandler
    Do
        val2 = UBound(XArray, n)
        n = n +  1 
    Loop Until False
ErrorHandler:
n = n -  1  ' n - мерность массива XArray
ReDim val( 1  To n): ReDim pos( 1  To n)
For i =  1  To n
    val(i) = UBound(XArray, n)
    pos(i) =  1 
Next
If (UBound(addr) +  1 ) <> n Then ' проверка
    MsgBox "Размерности массива XArray и адресной строки StringAddr неодинаковы"
    XFunc = - 1 
Else
    For Each myItem In XArray
        'MsgBox myItem
        flag =  0 
        For i =  1  To n
            If pos(i) = CInt(addr(i -  1 )) Then flag = flag +  1 
        Next
        If flag = n Then
            XFunc = myItem
            Exit Function
        End If
        For m =  1  To n
            If m =  1  Then pos(m) = pos(m) +  1 
            If pos(m) > val(m) Then
                pos(m) =  1 
                If (m +  1 ) <= n Then pos(m +  1 ) = pos(m +  1 ) +  1 
            End If
        Next
    Next
End If
End Function
может что-то работать неправильно и много воды, но, надеюсь, направит в правильном направлении
...
Рейтинг: 0 / 0
Массивы в VBA
    #36520316
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.Михаил.много воды

Респект, Михаил, хорошая идея.

Я тут попробовал переделать внутренний цикл, потому как не понял всех ваших изысканий:
Код: plaintext
1.
2.
3.
4.
5.
6.
    i =  0 
    m = (addr( 2 ) -  1 ) *  100  + (addr( 1 ) -  1 ) *  10  + addr( 0 )
    For Each myItem In XArray
      i = i +  1 
      If i = m Then Exit For
    Next
    XFunc = myItem
m правда рассчитывается исходя из ваших конкретных данных, но суть понятна, можно переделать на цикл.
...
Рейтинг: 0 / 0
Массивы в VBA
    #36520532
.Михаил.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro потому как не понял всех ваших изысканий
суть в чем:
1. Для начало надо получить значение n размерности массива, n задается в некой внешней процедуре (функции), мы не знаем значение n :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
n =  1 
On Error GoTo ErrorHandler 
    Do
        val2 = UBound(XArray, n) ' если не произошла ошибка (отлов ошибки) , то
        n = n +  1  ' к n прибавляется +1
    Loop Until False
ErrorHandler:
n = n -  1  ' n - мерность массива XArray
ХЗ, но почему-то получается результат на 1 больше, чем надо, не стал заморачиваться и уменьшил его на -1.

2. Далее "инициализую" две переменные в виде массивов равных n-размерности:
первая, val : максимальное значение элементов массива в каждой n-размерности;
вторая, pos : некий счетчик шагов для каждой n-размерности.
Код: plaintext
1.
2.
3.
4.
5.
ReDim val( 1  To n): ReDim pos( 1  To n)
For i =  1  To n
    val(i) = UBound(XArray, n)
    pos(i) =  1 
Next

3. Далее этот некий счетчик эмитирует прозождение цикла. При совпадении значение счетчика со значениями строки StringAddr цикл останавливается и получается "результат".
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
For Each myItem In XArray
        flag =  0  ' флаг
        For i =  1  To n 
            If pos(i) = CInt(addr(i -  1 )) Then flag = flag +  1  
            ' сравнение значений счетчика с со значениями строки StringAddr
        Next
        If flag = n Then ' если все n совпали, то результат 
            XFunc = myItem
            Exit Function
        End If
        ' это эмитация прохождения цикла
        ' сначало проходит первую размерность (n=1), увеличивая на каждом шаге на +1
        ' при достижении максимального значения в n=1, в n=2 увеличиваю на +1 и так далее до n
        For m =  1  To n
            If m =  1  Then pos(m) = pos(m) +  1 
            If pos(m) > val(m) Then
                pos(m) =  1 
                If (m +  1 ) <= n Then pos(m +  1 ) = pos(m +  1 ) +  1 
            End If
        Next
    Next
Shocker.Pro Я тут попробовал переделать внутренний цикл
на скока я вижу "переделка" для размерности n=3, а также исходный массив иницализировать можно различными способами...
...
Рейтинг: 0 / 0
Массивы в VBA
    #36520569
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.Михаил.
Shocker.Pro Я тут попробовал переделать внутренний цикл
на скока я вижу "переделка" для размерности n=3, а также исходный массив иницализировать можно различными способами...

Ну я написал, что он для фиксированных величин, а на самом деле надо доработать - устроить цикл вычисления "m" по результатам предшествующих проверок размерности. Я просто попробовал вычислить индекс заранее и свести цикл просто к переходу на нужный элемент.
...
Рейтинг: 0 / 0
Массивы в VBA
    #36520635
AlexFr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
.Михаил.,

Вакцина подействовала!!! :)
Спасибо!
Больному лучше..
К вечеру даже "выпишусь", наверно...
Проверка соответствия размерность массива - размерность адреса не требуется, т. к. заведомо по условию задачи верна (уже в другой процедуре сделана), а вот переход к нужному элементу по более короткому пути попробую седня вечером сделать.
...
Рейтинг: 0 / 0
Массивы в VBA
    #36520661
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.Михаил.счетчик эмитирует прохождение цикла

Ну раз все хорошо, то в качестве занудства:
Эмитировать
Имитировать
...
Рейтинг: 0 / 0
Массивы в VBA
    #36520699
.Михаил.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro.Михаил.счетчик эмитирует прохождение цикла

Ну раз все хорошо, то в качестве занудства:
Эмитировать
Имитировать


Сенк за ошибку. Понадеелся на Word, ошибку мне не показал...
-1
...
Рейтинг: 0 / 0
Массивы в VBA
    #36521414
Фотография vlth
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.Михаил.
Код: plaintext
Dim mass( 1  To  10 ,  1  To  10 ,  1  To  10 ) As Integer ' можно сделать любую размерность


Всё хорошо, пока кол-во "строк", "столбцов" и т.д. в массиве совпадают. Проверьте
Код: plaintext
1.
2.
3.
Dim mass( 1  To  5 ,  1  To  10 ,  1  To  10 ) As Integer
...
For i =  1  To  5 
...
...
Рейтинг: 0 / 0
Массивы в VBA
    #36521453
AlexFr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vlth,
Уже опять все хорошо :-)))

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
Option Base  1 

Sub myTest()
Dim mass( 1  To  10 ,  1  To  10 ,  1  To  10 ) As Integer ' можно сделать любую размерность
Dim i As Integer, j As Integer, i1 As Integer, pos As Integer
pos =  0 
For i =  1  To  10 
    For j =  1  To  10 
        For i1 =  1  To  10 
            pos = pos +  1 
            mass(i, j, i1) = pos
        Next
    Next
Next
MsgBox XFunc(mass, "1,3,4") & Chr( 10 ) & mass( 1 ,  3 ,  4 )   ' для сравнения результатов
Dim XArray1( 8 ,  9 ) As Integer
For X =  1  To  8 
For Y =  1  To  9 
XArray1(X, Y) = Y + X *  10 
Next Y
Next X
MsgBox XFunc(XArray1, "2,5") & Chr( 10 ) & XArray1( 2 ,  5 )  ' для сравнения результатов
Dim arr() As Variant
arr = Array( 11 ,  22 ,  33 ,  44 ,  55 ,  66 ,  77 ,  88 ,  99 )
MsgBox XFunc(arr, "2") & Chr( 10 ) & arr( 2 )   ' для сравнения результатов
End Sub

Function XFunc(ByRef XArray, ByRef StringAddr As String) As Integer
n = UBound(Split(StringAddr, ","))
NN = CInt(Split(StringAddr, ",")( 0 ))
UbxUb =  1 
For n1 =  1  To n
 UbxUb = UbxUb * UBound(XArray, n1)
 NN = NN + (CInt(Split(StringAddr, ",")(n1)) -  1 ) * UbxUb
Next n1
NNN =  0 
For Each myItem In XArray
 NNN = NNN +  1 
 If NNN = NN Then
  XFunc = myItem
  Exit Function
 End If
Next
...
Рейтинг: 0 / 0
Массивы в VBA
    #36521524
AlexFr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И финал будет фантастическим, если есть функция, с родни
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
For Each myItem In XArray
 NNN = NNN +  1 
 If NNN = NN Then
  XFunc = myItem
  Exit Function
 End If
Next
, которая просто возвращает значение порядкового элемента NN из последовательности перебора... 8-)
...
Рейтинг: 0 / 0
Массивы в VBA
    #36532959
AlexFr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток!

Public Function CreateArrayFunc(CreateArrayName, CreateArrayString)
' Имя массива получаю в CreateArrayName
' Размерность массива получаю в CreateArrayString, но в текстовом виде, грубо говоря...
' Нужен массив
End Function

Общий пример: CreateArrayName="CrArr" , CreateArrayString="X1,X2,X3,...,Xn"
X - какие-то целые числа
n - кол-во измерений массива, определяется поступившими данными, заранее не известно

Частный пример аргументов:
CreateArrayName="CrArr"
CreateArrayString="7,5,9,3,6"
'CreateArrayFunc должна выполнить действие: Dim CrArr(7,5,9,3,6) As Double
или
CreateArrayName="CrArr"
CreateArrayString="7,5,9,3,6,45,21,8,1"
'CreateArrayFunc должна выполнить действие: Dim CrArr(7,5,9,3,6,45,21,8,1) As Double

Если кому интересно, то данная необходимость возникла по причине записи данных наблюдения за физическими объектами в различном кол-ве и различного типа, особенно в случае статистического анализа с целью вычисления функции их поведения, где n необходимое кол-во измерений массива или мерности функции (ранг). Значение этой переменной растет до достижения точности соответствия полученной функции фактическому поведению объекта и заранее не известна…
Т. к. я далеко не прошник в VBA, а пользуюсь им для решения технических проблем, то вот и завис…
В прошлый раз Михаил успешно предложил способ последовательного перебора, спасибо ему...
Сейчас задача другая...
Если кто-то отправит меня в нужном направлении – буду признателен, а то сам ничего подобного не нашел…
...
Рейтинг: 0 / 0
Массивы в VBA
    #36533040
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexFr,

Мне кажется, вам надо отказаться от идеи с массивами и воспользовать коллекциями.
прямо будете давать ключи в виде текстовой константы - "1,2,5"
...
Рейтинг: 0 / 0
Массивы в VBA
    #36533166
.Михаил.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexFrДоброго времени суток!

Public Function CreateArrayFunc(CreateArrayName, CreateArrayString)
' Имя массива получаю в CreateArrayName
' Размерность массива получаю в CreateArrayString, но в текстовом виде, грубо говоря...
' Нужен массив
End Function

Общий пример: CreateArrayName="CrArr" , CreateArrayString="X1,X2,X3,...,Xn"
X - какие-то целые числа
n - кол-во измерений массива, определяется поступившими данными, заранее не известно

Частный пример аргументов:
CreateArrayName="CrArr"
CreateArrayString="7,5,9,3,6"
'CreateArrayFunc должна выполнить действие: Dim CrArr(7,5,9,3,6) As Double
или
CreateArrayName="CrArr"
CreateArrayString="7,5,9,3,6,45,21,8,1"
'CreateArrayFunc должна выполнить действие: Dim CrArr(7,5,9,3,6,45,21,8,1) As Double

Задать имя массива через строку как Вы хотите нельзя. Имя массива задается только при его описании: Dim CrArr() As Double; CrArr - это ссылка на начало массива в символьном выражении.
Код: plaintext
1.
2.
3.
4.
...
CreateArrayFunc("CrArr", "7,5,9,3,6,45,21,8,1")
...
MsgBox CrArr( 1 ) ' должно показать 7 или 5
см. пример: у Вас так никогда не получится, забудьте об этом

Для решения Вашей задачи можно создать класс (или структуру - собственный тип дынных), в котором будут содержаться все наименования созданных вами массивов в виде строки, а также ссылки на сами массивы. Можно также создать метод (или процедуру), который будет возвращать тот или иной массив по его названию.
...
Рейтинг: 0 / 0
Массивы в VBA
    #36533195
Фотография vlth
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.Михаил.Задать имя массива через строку как Вы хотите нельзя. Имя массива задается только при его описании: Dim CrArr() As Double; CrArr - это ссылка на начало массива в символьном выражении. Фраза выше на мысль навела: м.б. создавать процедуру или функцию динамически?
...
Рейтинг: 0 / 0
Массивы в VBA
    #36533218
AlexFr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.ProМне кажется, вам надо отказаться от идеи с массивами и воспользовать коллекциями.
прямо будете давать ключи в виде текстовой константы - "1,2,5"
Думал, но последующее использование будет выглядеть громоздко, т. к. в дальнейшем используется матаппарат для обработки матриц. По сути это работа с цифрами. Например,
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Function XFunc(ByRef XArray, ByRef StringAddr As String) As Integer
n = UBound(Split(StringAddr, ","))
NN = CInt(Split(StringAddr, ",")( 0 ))
UbxUb =  1 
For n1 =  1  To n
 UbxUb = UbxUb * UBound(XArray, n1)
 NN = NN + (CInt(Split(StringAddr, ",")(n1)) -  1 ) * UbxUb
Next n1
NNN =  0 
For Each myItem In XArray
 NNN = NNN +  1 
 If NNN = NN Then
  XFunc = myItem
  Exit Function
 End If
Next
которая обсуждалась раньше...
.Михаил.Для решения Вашей задачи можно создать класс (или структуру - собственный тип дынных), в котором будут содержаться все наименования созданных вами массивов в виде строки, а также ссылки на сами массивы. Можно также создать метод (или процедуру), который будет возвращать тот или иной массив по его названию.
т.е., если я правильно понял, нужно создать набор, типа, конструктор, элементы которого уже готовы, а потом их брать и применять ("ссылки на сами массивы")? Но предполагаемое разнообразие убивает... :( Или я не правильно понял...
vlthФраза выше на мысль навела: м.б. создавать процедуру или функцию динамически?
А можно кусочек примера? :) Типа, теряюсь... :))
...
Рейтинг: 0 / 0
Массивы в VBA
    #36533222
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexFrДумал, но последующее использование будет выглядеть громоздко, т. к. в дальнейшем используется матаппарат для обработки матриц.

Почему? Это наоборот - упрощает дело, поскольку для доступа к определенному элементу массива, вам вообще не нужен будет приведенный кусок кода. То есть переменную StringAddr вы будете использовать "как есть" - MyCollection(StringAddr) без всякого разбора на индексы.
...
Рейтинг: 0 / 0
Массивы в VBA
    #36533232
AlexFr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro,

Да, но как автоматом создать произвольную MyCollection(StringAddr) для дальнейшего использования, еслия знаю тока размерность (ранг)...
...
Рейтинг: 0 / 0
Массивы в VBA
    #36533247
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
Dim MyCollection As New Collection
"размер не имеет значения" (с)
"они безразмерные!" (с)
...
Рейтинг: 0 / 0
Массивы в VBA
    #36533251
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Dim i As Integer, j As Integer, k As Integer
Dim MyCollection As New Collection

For i =  1  To  5 
  For j =  1  To  10 
    For k =  1  To  18 
      MyCollection.Add Rnd( 0 ), CStr(i) + "," + CStr(j) + "," + CStr(k)
    Next
  Next
Next

MsgBox MyCollection("3,4,8")
...
Рейтинг: 0 / 0
Массивы в VBA
    #36533269
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А далее, чтобы иметь набор именованных массивов вы можете создавать коллекцию коллекций.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Dim GlobalColl As New Collection
Dim j As Collection

Set j = New Collection
GlobalColl.Add j, "ложки"
Set j = Nothing
Set j = New Collection
GlobalColl.Add j, "вилки"
Set j = Nothing
Set j = New Collection
GlobalColl.Add j, "поварешки"
Set j = Nothing

'обращение к элементу нужного массива (после инициализации)
GlobalColl("вилки")("2,3,7")
...
Рейтинг: 0 / 0
Массивы в VBA
    #36533277
AlexFr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro,

Да-да-да я понял, просто хотелось чего-то структурированного, тем более уменя ужо машина налажена, но работала тупо по трехмеркам, например... Поентому я пытался пробить развитие системы в томже духе, но похоже придется все переделывать, апргрейд не удался... :))
...
Рейтинг: 0 / 0
Массивы в VBA
    #36533320
Фотография vlth
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexFrА можно кусочек примера? :) Типа, теряюсь... :))
Ну вот и "кусочек"... Программно создаётся модуль basTwo, в нём запускается процедура TMP(), выводящая в цикле элементы массива в окно отладки. Наверное, сие можно довести до ума.
Только не забудьте поставить ссылку на Microsoft Visual Basic xx Extensibility. И доверие для доступа к Visual Basic Project, наверное, надо поставить.
Для удаления basTwo запускайте test2 (из процедуры test удалить его не получилось)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
Public Sub CreateArray(CreateArrayName As String, CreateArrayString As String)
With Application.VBE.ActiveVBProject
    With .VBComponents.Add(vbext_ct_StdModule)
        .Name = "basTwo"
        With .CodeModule
            .AddFromString "Public " & CreateArrayName & "() As Variant"
            .AddFromString "Sub TMP()" & vbCrLf & CreateArrayName & _
                "= Array(" & CreateArrayString & ")" & vbCrLf & _
                "For i = 0 To UBound(" & CreateArrayName & ")" & vbCrLf & _
                "Debug.Print " & CreateArrayName & "(i)" & vbCrLf & _
                "Next" & vbCrLf & _
                "End Sub"
        End With
    End With
End With
End Sub
Sub test()
CreateArray "CrArr", "7,5,9,3,6"
Application.OnTime Now + TimeValue("00:00:01"), "TMP"
End Sub
Sub test2()
RemoveModule "basTwo"
End Sub
Private Sub RemoveModule(NameOfModule)
With ThisWorkbook.VBProject
    .VBComponents.Remove .VBComponents(NameOfModule)
End With
End Sub
...
Рейтинг: 0 / 0
25 сообщений из 69, страница 2 из 3
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Массивы в VBA
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]