Форум программистов, компьютерный форум, киберфорум
Наши страницы
VBA
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
dzug
680 / 220 / 18
Регистрация: 17.01.2011
Сообщений: 553
Записей в блоге: 1
#1

Как проверить заполнен ли массив, объявленный в декларации модуля

31.03.2014, 17:21. Просмотров 1359. Ответов 14
Метки нет (Все метки)

В декларации модуля объявляю массив переменных, для хранения данных между вызовами разных процедур.

Visual Basic
1
Public r()
По ходу работы, разные процедуры заполняют и освобождают этот массив. Между вызовами данные в этом массиве сохранюются. Проверка типа

Visual Basic
1
If IsArray(r) = True
возвращает True независимо от того заполнен или нет этот массив.

Вопрос в том как проверить заполнен ли этот массив?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.03.2014, 17:21
Ответы с готовыми решениями:

Как проверить что массив полностью заполнен?
Как проверить что массив полностью заполнен?

Массив А заполнен случайным образом...
Помогите пожалуйста решить две задачки. 1) Массив A заполнен случайным образом...

Как объявить в MSVBA/Excel массив констант уровня модуля
Как объявить в MSVBA/Excel массив констант уровня модуля? Все получается,...

Как проверить заполнен ли DataReader данными?
как проверить заполнен ли сабж данными ?

Как в массив скопировать массив, который заполнен через указатели
Есть два файла допусти. Суть вопроса в том, что находится во втором файле. Как...

14
mc-black
2759 / 695 / 101
Регистрация: 04.02.2011
Сообщений: 1,421
31.03.2014, 18:24 #2
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Option Explicit
 
Public r()
 
' Функция определяет, объявлен ли массив
Private Function ArrDef(t_arr()) As Boolean
    Dim t As Long
    On Error GoTo err_9
    t = LBound(t_arr)
    ArrDef = True
    Exit Function
err_9:
    ArrDef = False
End Function
 
 
' Проверка работы
Sub test()
    Debug.Print ArrDef(r)
    ReDim r(1 To 1)
    Debug.Print ArrDef(r)
End Sub
1
Казанский
14047 / 5777 / 1503
Регистрация: 24.09.2011
Сообщений: 9,054
31.03.2014, 18:41 #3
В большинстве случаев это работает, но вот дополнение от Пирсона
http://www.cpearson.com/Excel/IsArrayAllocated.aspx

Добавлено через 8 минут
Функцию mc-black можно написать короче
Visual Basic
1
2
3
4
Private Function ArrDef(arr) As Boolean 'arr - массив любого типа
    On Error Resume Next
    If LBound(arr) And 0 Then Else ArrDef = True
End Function
2
mc-black
2759 / 695 / 101
Регистрация: 04.02.2011
Сообщений: 1,421
31.03.2014, 19:11 #4
Из кода по ссылке:
Visual Basic
1
... And LBound(Arr, 1) <= UBound(Arr, 1)
А когда-то может быть FALSE?
0
Апострофф
Заблокирован
31.03.2014, 19:27 #5
Цитата Сообщение от MX
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
Private Declare Function SafeArrayGetDim Lib "oleaut32.dll" (ByRef saArray() As Any) As Long 
 
 Private Sub Form_Load() 
 Dim a() As Long 
 'ReDim a(0) 
 If (SafeArrayGetDim(a) > 0) Then 
  Debug.Print "array as been initialized" 
 Else 
  Debug.Print "array as not been initialized" 
 End If 
 End Sub
И ещё вариант
Visual Basic
1
2
3
Dim a() As Long 
'redim a(0)
 MsgBox Not Not a
но это на свой страх и риск, я рушил систему после подобных экспериментов.
3
Казанский
14047 / 5777 / 1503
Регистрация: 24.09.2011
Сообщений: 9,054
31.03.2014, 19:58 #6
Цитата Сообщение от mc-black Посмотреть сообщение
А когда-то может быть FALSE?
По ссылке упоминается Split:
Visual Basic
1
2
r = Split("")
Debug.Print ArrDef(r), LBound(r), UBound(r)
Результат
Код
True     0            -1
3
The trick
Модератор
7356 / 2576 / 753
Регистрация: 22.02.2013
Сообщений: 3,795
Записей в блоге: 76
31.03.2014, 20:24 #7
Лучший ответ Сообщение было отмечено dzug как решение

Решение

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Option Explicit
 
Private Declare Function GetMem4 Lib "msvbvm60" (Src() As Any, Dst As Any) As Long
 
Private Sub Form_Load()
    Dim D() As Long, l As Long, x As Single
    
    ReDim D(10)
    
    GetMem4 D, l
    
    If l Then
        ' Г€Г*èöèГ*ëèçèðîâГ*Г*
    Else
        ' ГЌГҐГЁГ*èöèГ*ëèçèðîâГ*Г*
    End If
 
End Sub
3
mc-black
2759 / 695 / 101
Регистрация: 04.02.2011
Сообщений: 1,421
01.04.2014, 07:28 #8
The trick, а есть официальный Reference на API msvbvm60.dll? Или неофициальный? Что там ещё интересное можно узнать? Меня раньше как-то интересовала возможность в Runtime получить стек вызовов, как при вызове View-Call Stack в режиме трассировки кода. Может ещё какие-то интересные возможности имеются?
0
The trick
Модератор
7356 / 2576 / 753
Регистрация: 22.02.2013
Сообщений: 3,795
Записей в блоге: 76
05.04.2014, 21:20 #9
Цитата Сообщение от mc-black Посмотреть сообщение
The trick, а есть официальный Reference на API msvbvm60.dll? Или неофициальный? Что там ещё интересное можно узнать?
Не знаю, я в дизассемблере просматриваю нужные функции и анализирую их изнутри. В P-code практически вся работа идет через vbaX.dll. Интересного очень много, некоторые функии широко известны в сети, например EbMode, другие нет. Но при внутреннем изучении их роль интуитивно понятна.
Цитата Сообщение от mc-black Посмотреть сообщение
Меня раньше как-то интересовала возможность в Runtime получить стек вызовов, как при вызове View-Call Stack в режиме трассировки кода.
Это тоже делается просто. Используя функции EbGetCallstackCount, EbGetCallstackFunction можешь вытянуть нужные данные (могут быть ньюансы при вызове API и т.п.), также нужно знать что эти функции работают при остановленном проекте (EbMode = 2):
Visual Basic
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 Declare Function EbSetMode Lib "vba6" (ByVal Mode As Long) As Long
Private Declare Function EbGetCallstackCount Lib "vba6" (ByRef Count As Long) As Long
Private Declare Function EbGetCallstackFunction Lib "vba6" ( _
    ByVal Index As Long, P As Any, M As Any, F As Any, _
    Ret As Long) As Long
    
Private Sub Command1_Click()
    X 5
End Sub
 
Private Sub X(ByVal Z As Long)
    Dim Ct As Long, i As Long, c As Long
    Dim prj As String, mdl As String, func As String
    Dim r As String
    
    If Z Then
        X Z - 1
    Else
        EbSetMode 2
        EbGetCallstackCount Ct
        
        For i = Ct - 1 To 0 Step -1
            EbGetCallstackFunction i, ByVal VarPtr(prj), _
                                      ByVal VarPtr(mdl), _
                                      ByVal VarPtr(func), c
            r = r & prj & "." & mdl & "." & func & vbNewLine
        Next
        
        EbSetMode 1
        
        MsgBox r
    End If
End Sub
1
mc-black
2759 / 695 / 101
Регистрация: 04.02.2011
Сообщений: 1,421
06.04.2014, 21:56 #10
The trick, ты крут! У себя (Win8.1x64+XL2010x32) не нашел, чем заменить VBA6.DLL VBE-Help-About показывает 7-ю версию, но файла vba7.dll на компе не найдено - есть некие VBAJET32.DLL и VBAME.DLL, но это видно не те. А чем можно дизассемблировать офис на моей платформе, можно воспользоваться каким-то отладчиком?
0
The trick
Модератор
7356 / 2576 / 753
Регистрация: 22.02.2013
Сообщений: 3,795
Записей в блоге: 76
08.04.2014, 15:55 #11
Цитата Сообщение от mc-black Посмотреть сообщение
чем заменить VBA6.DLL
У меня 2007 офис, там есть библиотека VBE6.dll, но она не экспортирует функции. Возможно (не проверял) это COM библиотека, тогда к ней можно получить доступ и стек вызовов.
0
mc-black
2759 / 695 / 101
Регистрация: 04.02.2011
Сообщений: 1,421
09.04.2014, 05:49 #12
Цитата Сообщение от The trick Посмотреть сообщение
она не экспортирует функции
Также проверял в 2010x32 текстовым поиском, тоже не экспортируется ни одной из библиотек. А где тогда будет работать код, что написан выше?
0
The trick
Модератор
7356 / 2576 / 753
Регистрация: 22.02.2013
Сообщений: 3,795
Записей в блоге: 76
12.04.2014, 16:51 #13
Цитата Сообщение от mc-black Посмотреть сообщение
А где тогда будет работать код, что написан выше?
Это для VB6. Как будет время я посмотрю как работает VBE6.
0
AndreA SN
1001 / 105 / 2
Регистрация: 26.08.2011
Сообщений: 806
Записей в блоге: 2
10.07.2015, 11:47 #14
мамонты вы))) Зверские звери)))
моё понимание отказывается вас понимать)))
0
AndreA SN
1001 / 105 / 2
Регистрация: 26.08.2011
Сообщений: 806
Записей в блоге: 2
24.07.2015, 09:57 #15
Цитата Сообщение от dzug Посмотреть сообщение
If IsArray(r) = True
тут очень даже понятно почему всегда True
Потому что это определение типа данных. А оно - сразу объявлено как массив, а не как Variant. Поэтому будет всегда True. А "пусто-не пусто" - кошмар из другой оперы
0
24.07.2015, 09:57
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.07.2015, 09:57

Массив, объявленный как двумерный, является одномерным
Сабж в теме. Объявляю двумерный массив 5х5 строкой float mas; Затем заполняю...

Массив: Массив из 100эл заполнен случайными числами в диапазоне от 2 до 98 упорядочить в порядке возрастания
Помогите решить пожайлуста задачу: Массив из 100эл заполнен случайными числами...

Дан массив m на n. Создать второй массив который был бы заполнен числами в порядке возрастания по спирали
Здравствуйте. Дан массив m на n целых чисел.Получиь массив каторый был бы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru