Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Массив в массиве / 18 сообщений из 18, страница 1 из 1
05.12.2003, 12:37
    #32344663
Vsevolod V
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
Код: 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.
Private Sub btn_Click()
Dim b() As Variant
Dim a1() As Variant
Dim a2() As Variant

a1 = Array(Me!dates, Me!datepo, Me!DIRECTION, Me!ref, Me!Str1, Me!Sr1, Me!n1,  _
           Me!n2, Me!n3, Me!n4, Me!n5, Me!n6, Me!n7, Me!n8)
a2 = Array(Me!dates, Me!datepo, Me!DIRECTION, Me!ref, Me!Str2, Me!Sr2, Me!n9, _
           Me!n10, Me!n11, Me!n12, Me!n13, Me!n14, Me!n15, Me!n16)
b = Array(a1, a2)
Call FillTempSv2(b)
End Sub

Function FillTempSv2(ctlArray() As Variant)
    Dim SVODKA2 As DAO.Recordset
    Dim V As Variant
    Dim V2 As Variant
    
    Set SVODKA2 = CurrentDb.OpenRecordset( "SVODKA2" )
    
    n =  1 
    SVODKA2.MoveFirst
        For Each V In ctlArray
            For Each V2 In V
                If Not n >  14  Then
                    V2.Value = SVODKA2(n)
                End If
                n = n +  1 
            Next V2
        SVODKA2.MoveNext
        Next V
    SVODKA2.Close
End Function

Проблама в том, что заполняется только контролы из a1().
...
Рейтинг: 0 / 0
05.12.2003, 15:40
    #32345045
Vsevolod V
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
Неужели это должно работать и проблема не в коде?
...
Рейтинг: 0 / 0
05.12.2003, 15:50
    #32345073
Senin Viktor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
странный ты..

ф=1
ы=2
ы=ы+1

А пАЧяму ф осталось равно адын? Людииииииииииии! ПаМаГитЕЕЕЕЕЕ!
...
Рейтинг: 0 / 0
05.12.2003, 16:00
    #32345095
Vsevolod V
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
К сожалению, не понял, что есть в моем случае "ф"?
...
Рейтинг: 0 / 0
05.12.2003, 16:10
    #32345120
Массив в массиве
Не рекомендуется для массива использовать цикл For Each Next . Работает медленнее, и (по Гетсу) - только для чтения.
Попробуйте:
For i = LBound(V) To UBound(V)
V2=V(i)
For j =LBound(V2) To UBound(V2)
...
Next J
Next i

Да и вместо:
Dim b() As Variant
b = Array(a1, a2)
Я бы сделал:
Dim b(0 To 1) As Variant
b(0) = a1
b(1) = a2
Но это - дело вкуса.
...
Рейтинг: 0 / 0
05.12.2003, 16:37
    #32345187
Senin Viktor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
>что есть в моем случае "ф"?

Да все. Где у тебя ctlArray() обрабатывется
...
Рейтинг: 0 / 0
05.12.2003, 16:39
    #32345188
Vsevolod V
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
А разве этого не достаточно ?
Код: plaintext
1.
2.
For Each V In ctlArray
...
Next V
...
Рейтинг: 0 / 0
05.12.2003, 16:53
    #32345219
Массив в массиве
Не поленился проверить :))

Dim a1() As Variant, a2() As Variant, b() As Variant
Dim v As Variant, v2 As Variant
a1 = Array(Me.Text0,Me.Text1)
a2 = Array(Me.Text2,Me.Text3)
b = Array(a1, a2)
For Each v In b
For Each v2 In v
v2.Value = "Получилось!" '- РАБОТАЕТ
' v2 = "Получилось!" '- НЕ РАБОТАЕТ
MsgBox v2
Next v2
Next v

V2 содержит объект. В вашем случае объект(Control) заменяется
значением из поля, а в самом Control-е ничего не изменяется. Мало того - его уже нет в массиве.

P.S. Но получается, что моя предыдущая посылка насчет ReadOnly не верна!
Или Гетс не прав, или я не прав. ?! Прийду дамой - перечитаю.
...
Рейтинг: 0 / 0
05.12.2003, 16:59
    #32345235
Vsevolod V
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
V2 содержит объект. В вашем случае объект(Control) заменяется
значением из поля, а в самом Control-е ничего не изменяется. Мало того - его уже нет в массиве

Ничего не понял... :(
Что значит в самом контроле ничего не изменяется?
Все изменяется вроде. Проблема в том, что не изменяются значения контролов, содержащихся в массиве "a2", а с массивом "а1" все в порядке.
...
Рейтинг: 0 / 0
05.12.2003, 17:43
    #32345305
Senin Viktor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
2Анатолий (Киев )

У Vsevolod V массив двойной размерности. И нигде вторая размерность не учитывается.
Если в цикле добавить переход по размерностям, то м.б. что-то и получиться.
...
Рейтинг: 0 / 0
05.12.2003, 17:49
    #32345310
Shkurenko Alexander
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
2 Всеволод.

Объясни мне пожалуйста смысл переменной n .

Нужна ли эта переменная в данном участке кода, и если нужна почему нет ее объявления?

Нарисуй трассировочную таблицу и с ее помощью попробуй найти ошибку.
Да шучу я, хотя ...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
    n =  1 
    SVODKA2.MoveFirst
        For Each V In ctlArray
            For Each V2 In V
                If Not n >  14  Then
                    V2.Value = SVODKA2(n)
                End If
                n = n +  1  ' увеличивать увеличиваешь, а где n =  1 ?
            Next V2
        SVODKA2.MoveNext
        Next V
    SVODKA2.Close


PS Для откладки предназначены Debug.Print и Debug.Assert. Если уже совсем сложно то можно и запустить в пошаговом режиме.
...
Рейтинг: 0 / 0
05.12.2003, 18:07
    #32345340
Shkurenko Alexander
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
2 Анатолий
Анатолий (Киев )>Не рекомендуется для массива использовать цикл For Each Next. Работает медленнее, и (по Гетсу) - только для чтения.
Как раз этот способ предоставляет универсальный механизм итерации цикла. И еще не ясно, будет бытрее получение элемента по индексу, а если еще в теле цикла происходит несколько обращений к элементу, то тут и спорить нечего.
Насчет только для чтения, то тут вы ошибаетесь, Гетц такого сказать не мог.

2 Senin Viktor
Senin Viktor>У Vsevolod V массив двойной размерности. И нигде вторая размерность не учитывается.
Senin Viktor>Если в цикле добавить переход по размерностям, то м.б. что-то и получиться.


Код: plaintext
1.
2.
3.
4.
5.
        For Each V In ctlArray ' итерация по первому измерению'
            For Each V2 In V ' итерация по второму измерению'
            ...     
            Next V2
        Next V

Тут никакой ошибки нет.
...
Рейтинг: 0 / 0
05.12.2003, 18:09
    #32345343
Vsevolod V
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
Объясни мне пожалуйста смысл переменной n.
А что тут может быть не понятного?
Переменная n есть индекс поля, т.е. значение поля подставляется в контрол.

где n = 1?
Код: plaintext
1.
2.
3.
4.
n =  1  ' Вот n =  1 
    SVODKA2.MoveFirst
        For Each V In ctlArray
            For Each V2 In V
.....

n равно 1 при первом входе в цикл, а далее уже увеличивается.

Нужна ли эта переменная в данном участке кода
А где же еще???

почему нет ее объявления?
толку нет ее объявлять.

Нарисуй трассировочную таблицу
Что это такое?
...
Рейтинг: 0 / 0
05.12.2003, 18:23
    #32345364
Vsevolod V
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
Очень странно, что не работает, так как эта часть кода отрабатывает нормально (так как контролы из массива "а1" заполняются верно):
Код: plaintext
1.
2.
3.
4.
5.
For Each V2 In V
 If Not n >  14  Then
  V2.Value = SVODKA2(n)
 End If
 n = n +  1 
Next V2

Значит проблема возникает здесь:
Код: plaintext
1.
SVODKA2.MoveNext
Next V

Но что тут может быть не так??? Соответствующие записи в рекордсете есть.
...
Рейтинг: 0 / 0
05.12.2003, 18:24
    #32345365
Shkurenko Alexander
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
2 Всевололд.
Всеволод>Переменная n есть индекс поля, т.е. значение поля подставляется в контрол.
ОК, теперь понятно.

SA>почему нет ее объявления?
Всеволод>толку нет ее объявлять.

Толк в объявлении есть, он позволяет избежать "скрытых" ошибок и обыкновенных опечаток c опцией Option Explicit.

SA>где n = 1?
Хорошо объясняю на пальцах

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
        For Each V In ctlArray
            For Each V2 In V
                If Not n >  14  Then '( 1 )
                    V2.Value = SVODKA2(n)
                End If
                n = n +  1 
            Next V2
        SVODKA2.MoveNext
        Next V


После первой итерации внешнего цикла, чему у тебя равна переменная n? Поставь Breakpoint в строке (1) и посмотри.
...
Рейтинг: 0 / 0
05.12.2003, 18:27
    #32345371
Vsevolod V
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
ААА!!!
Точно! Сообразил :)
"Она" равна 15, а полей в рекордсете 14.
Спасибо!
...
Рейтинг: 0 / 0
08.12.2003, 13:55
    #32346415
Массив в массиве
Несколько замечаний...
Shkurenko Alexander мне отвечал:
Анатолий (Киев )>Не рекомендуется для массива использовать цикл For Each Next. Работает медленнее, и (по Гетсу) - только для чтения.
Как раз этот способ предоставляет универсальный механизм итерации цикла. И еще не ясно, будет бытрее получение элемента по индексу, а если еще в теле цикла происходит несколько обращений к элементу, то тут и спорить нечего.
Насчет только для чтения, то тут вы ошибаетесь, Гетц такого сказать не мог.

Цитирую:
Гетс, Джилберт "Программирование в Microsoft Office", 1999, BHV, Киев, стр.198
"Примечание: Для просмотра элементов массива можно также воспользоваться конструкцией For Each...Next, однако делать это не рекомендуется. В данном случае процесс будет протекать медленнее, чем при использовании конструкции For...Next, и, кроме того, конструкцию For Each...Next нельзя применять для записи значений в массив - она может использоваться только для выборки данных."
Насчет "только для выборки", то здесь всё ясно. Чтобы изменить значение в массиве, надо знать его индекс, а он-то и не известен.
В обсуждаемом примере значение присваивается переменной, в которую извлечен элемент массива, верней объекту в этой переменной. Но тут я тоже не понимаю, почему у автора это работает.
Вот простенький тест с изменением несвязанного TrxtBox-a в форме:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Private Sub Text2_AfterUpdate()
Dim v As Variant
    Set v = Me.Text2
MsgBox IsObject(v)   
    v.Value =  "!" 
MsgBox IsObject(v) & vbCrLf & v & vbCrLf & Me.Text2 'ПОЛЕ ИЗМЕНИЛОСЬ'
    v =  "!!" 
MsgBox IsObject(v) & vbCrLf & v & vbCrLf & Me.Text2 'ПОЛЕ НЕ ИЗМЕНИЛОСЬ'
    v.Value =  "!!"  'ОШИБКА, в переменной уже не объект.'
    
 'То же - для массива.'   
    v = Array(Me.Text2)
    v( 0 ).Value =  "!!!" 
MsgBox IsObject(v( 0 )) & vbCrLf & v( 0 ) & vbCrLf & Me.Text2
    v( 0 ) =  "!!!!" 
MsgBox IsObject(v( 0 )) & vbCrLf & v( 0 ) & vbCrLf & Me.Text2
End Sub

Обратите внимание, что во всех случаях VarType(v)= 8 - это vbString.

Теперь о скорострельности For Each...Next для массива. Вот тест:
Код: 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.
Public Declare Function SystemTimer Lib  "winmm.dll"  _
        Alias  "timeGetTime"  () As Long

Sub TestArray()
Dim t( 0  To  3 ) As Long
Dim i As Long, j As Long, arr( 1  To  100 ) As Variant, v As Variant
t( 0 ) = SystemTimer
For i =  1  To  1000000 
 For Each v In arr
  v = i
 Next
Next i
t( 1 ) = SystemTimer
Debug.Print t( 1 ) - t( 0 ) 'Время: 22508 ms'

t( 2 ) = SystemTimer
For i =  0  To  1000000 
 For j =  1  To  100 
  v = arr(j)
 Next
Next i
t( 3 ) = SystemTimer
Debug.Print t( 3 ) - t( 2 ) 'Время: 14192 ms'
End Sub

На 100 млн. итераций, разница - более 8 секунд.
...
Рейтинг: 0 / 0
08.12.2003, 16:41
    #32346769
Shkurenko Alexander
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив в массиве
А>Несколько замечаний...
А>Shkurenko Alexander мне отвечал:

[пропущено]
SA>>Насчет только для чтения, то тут вы ошибаетесь, Гетц такого сказать не мог.

Цитирую:
А>Гетс, Джилберт "Программирование в Microsoft Office", 1999, BHV, Киев, стр.198
"Примечание: Для просмотра элементов массива можно также воспользоваться конструкцией For Each...Next, однако делать это не рекомендуется. В данном случае процесс будет протекать медленнее, чем при использовании конструкции For...Next, и, кроме того, конструкцию For Each...Next нельзя применять для записи значений в массив - она может использоваться только для выборки данных."


Приношу свои извинения, я оказался неправ. Действительно
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Sub d()
    Dim a( 2 ), v, i&
    
    For i = LBound(a) To UBound(a)
        a(i) =  1 
    Next
    
    For Each v In a
        v =  2 
    Next
    
    For Each v In a
        Debug.Print v
    Next
End Sub

На выходе получим: 1 1 1

А>Насчет "только для выборки", то здесь всё ясно. Чтобы изменить значение в массиве, надо знать его индекс, а он-то и не известен.
А>В обсуждаемом примере значение присваивается переменной, в которую извлечен элемент массива, верней объекту в этой переменной. Но тут я тоже не понимаю, почему у автора это работает.


Дело в том, что при использовании цикла For Each elem In ... в elem помещается копия элемента массива, но за несколькими исключениями. Одним из них и является объект, который нельзя полностью упаковать в Variant, поэтому они передаются по ссылке, в результате чего у автора это работает.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Private Sub Text2_AfterUpdate()
Dim v As Variant
    Set v = Me.Text2
MsgBox IsObject(v)   
    v.Value =  "!"  
MsgBox IsObject(v) & vbCrLf & v & vbCrLf & Me.Text2 'ПОЛЕ ИЗМЕНИЛОСЬ'
    v =  "!!"  '(1)
MsgBox IsObject(v) & vbCrLf & v & vbCrLf & Me.Text2 'ПОЛЕ НЕ ИЗМЕНИЛОСЬ'
    v.Value = "!!" 'ОШИБКА, в переменной уже не объект.'
[пропущено]


Довольно трудноуловимая ошибка, связанная так называемыми "свойствами по умолчанию"
строку (1), VBA трактует так: переменной v присвоить строковой литерал "!!"
а не как хотелось тебе: свойству по умолчанию объекта, содержащегося в переменной v присвоить строковой литерал "!!".
Как говориться, почувствуйте разницу. Вообще эти свойства по умолчанию от лукавого. Ни к чему хорошему они привести не могут.
То же самое, можно сказать и про все сокращенные записи вроде этой recordset("name_field"). На эту тему вообще нужно отдельно говорить.
Кстати, посмотри здесь , многое прояснится.

А>Теперь о скорострельности For Each...Next для массива. Вот тест:
[пропущено]

Не совсем корректный тест. Вот этот будет правильнее.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
Sub Test()
Dim t( 0  To  3 ) As Long
Dim i&, j&, arr( 1  To  100000 ) As Variant, v, v1
    t( 0 ) = SystemTimer
    For Each v In arr
        For i =  0  To  2 
            v1 = v
        Next
    Next
    t( 1 ) = SystemTimer
    Debug.Print t( 1 ) - t( 0 ) '36'
    t( 2 ) = SystemTimer
    For i = LBound(arr) To UBound(arr)
        For j =  0  To  2 
            v1 = arr(i)
        Next
    Next
    t( 3 ) = SystemTimer
    Debug.Print t( 3 ) - t( 2 ) '41'
End Sub

Который подтверждает сказанное мною:
а если еще в теле цикла происходит несколько обращений к элементу, то тут и спорить нечего.
...
Рейтинг: 0 / 0
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Массив в массиве / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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