Страницы: 1
RSS
Проверка массива на наличие в нем элементов
 
Добрый день.  
Как правильно записать строчку кода, чтобы проверить, является ли массив MyArray непустым? Т.е. если в массиве есть хоть один элемент, то погнали дальше, если нет ни одного, то перескочили.  
Спасибо.
 
Sub Arr_Initialize()  
Dim avArr()  
   If (Not Not avArr) = 0 Then  
       MsgBox "массив пуст и записей в нем не было"  
   Else  
       MsgBox "массив заполнен чем-то"  
   End If  
ReDim avArr(1): avArr(1) = 1  
   If (Not Not avArr) = 0 Then  
       MsgBox "массив пуст и записей в нем не было"  
   Else  
       MsgBox "массив заполнен чем-то"  
   End If  
End Sub
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Спасибо большое. Все очень понятно объяснили.  
Правда, не понял смысл двойного отрицания (Not Not).  
Если не затруднит, просветите.
 
Впишите в ячейку А1 формулу:  
=НЕ(НЕ(A1=0))  
 
Вычислите её пошагово и все поймете.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
{quote}{login=The_Prist}{date=06.06.2010 11:30}{thema=}{post}Впишите в ячейку А1 формулу:  
=НЕ(НЕ(A1=0))  
 
Вычислите её пошагово и все поймете.{/post}{/quote}  
 
Вписал в ячейку B1 формулу =НЕ(НЕ(A1=0)),  
в ячейку B2 формулу =A2=0.  
Поигрался с нулями,цифрами и пустотами - разницы в работе обеих формул не увидел.
 
Эх...Простой конструкцией типа avArr = 0 не получиться узнать наполнение массива - такая конструкция недопустима, сначала необходимо переопределить размерность, т.к. VBA считает, что Вы хотите присвоить массиву значение.  
 
В этом выражении:  
Not Not avArr  
 
VBA сначала сравнивает массив, преобразуя его в тип Integer, независимо от данных в нем(на сами данные не влияет), не вызывая ошибку.    
В общем-то можно и так записать для достижения цели:  
(Not avArr) = 0    
 
Но все равно придется добавлять Not, чтобы было вроде как понятней(или поменять условия местами).  
Не знаю, понятно объяснил или нет - по-другому не умею.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Еще раз спасибо огромное.
 
{quote}{login=The_Prist}{date=06.06.2010 12:22}{thema=}{post}  
В общем-то можно и так записать для достижения цели:  
(Not avArr) = 0    
{/post}{/quote}    
Дим, ты наверное хотел сказать  
(Not avArr) = -1 Then массив пустой
Я сам - дурнее всякого примера! ...
 
{quote}{login=KuklP}{date=06.06.2010 01:27}{thema=Re: }{post}{quote}{login=The_Prist}{date=06.06.2010 12:22}{thema=}{post}  
В общем-то можно и так записать для достижения цели:  
(Not avArr) = 0    
{/post}{/quote}    
Дим, ты наверное хотел сказать  
(Not avArr) = -1 Then массив пустой{/post}{/quote}Нет, Сергей, я написал ровно то, что хотел.  
 
"В общем-то можно и так записать для достижения цели:  
(Not avArr) = 0    
Но все равно придется добавлять Not, чтобы было вроде как понятней(или поменять условия местами)."  
 
Это же конструкция сравнения. С нулем как-то смотрится более информативно.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Дим, при (Not avArr) = 0 выдаст, что массив не пустой в обоих случаях.  
при пустом массиве (Not avArr) = -1.  
Проверь.
Я сам - дурнее всякого примера! ...
 
Да, а Not(-1) как раз и дает 0.
Я сам - дурнее всякого примера! ...
 
{quote}{login=KuklP}{date=06.06.2010 02:07}{thema=}{post}Дим, при (Not avArr) = 0 выдаст, что массив не пустой в обоих случаях.  
при пустом массиве (Not avArr) = -1.  
Проверь.{/post}{/quote}Почему?  
 
Sub Arr_Initialize()  
   Dim avArr()  
   If (Not avArr) = 0 Then  
       MsgBox "массив пуст и записей в нем не было"  
   Else  
       MsgBox "массив заполнен чем-то"  
   End If  
   ReDim avArr(1): avArr(1) = 1  
   If (Not avArr) = 0 Then  
       MsgBox "массив пуст и записей в нем не было"  
   Else  
       MsgBox "массив заполнен чем-то"  
   End If  
End Sub  
 
Вот в этой процедуре получиться, что условия перепутаны. Именно про это я и писал: "Но все равно придется добавлять Not, чтобы было вроде как понятней(или поменять условия местами)"  
Ключевая фраза: поменять условия местами
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Да нет же, Дим(вот я не умею так понятно объяснять как ты)  
Это константы:  
true в Exsel = -1  
False=0  
В твоей конструкции  (Not avArr) = 0 никогда не наступит, ибо для пустого массива  
(Not avArr) = -1  
Для непустого напрмер -2390769 (у меня эта цифра меняется).  
Поэтому твоя программа всегда будет выводить МСГ - "массив заполнен чем-то".
Я сам - дурнее всякого примера! ...
 
Во пристал!
 
А, ну да. Чет я сразу не догнал.  
Но первый вариант - (Not Not avArr) = 0 - работает на ура! :-)
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Все, сдаюсь.
Я сам - дурнее всякого примера! ...
 
Извиняюсь, что вклиниваюсь в беседу, но у меня  
первый вариант The_Pristа If (Not Not avArr) = 0 Then  
прошел изумительно.
 
{quote}{login=Егор}{date=06.06.2010 02:36}{thema=}{post}Извиняюсь, что вклиниваюсь в беседу, но у меня  
первый вариант The_Pristа If (Not Not avArr) = 0 Then  
прошел изумительно.{/post}{/quote}  
Егор, это же Вам не понравилось двойное отрицание. Из-за этого и весь этот диспут.  
Прграмма The_Prist работает на ура и без двойного отрицания при  (Not avArr) = -1.
Я сам - дурнее всякого примера! ...
 
Вообще главная фишка такой проверки в том, что можно проверить даже неинициализированный массив. Т.к. неинициализированный массив при помощи UBound() не проверить - выдаст ошибку.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
{quote}{login=KuklP}{date=06.06.2010 02:43}{thema=Re: }{post}{quote}{login=Егор}{date=06.06.2010 02:36}{thema=}{post}Извиняюсь, что вклиниваюсь в беседу, но у меня  
первый вариант The_Pristа If (Not Not avArr) = 0 Then  
прошел изумительно.{/post}{/quote}  
Егор, это же Вам не понравилось двойное отрицание. Из-за этого и весь этот диспут.  
Прграмма The_Prist работает на ура и без двойного отрицания при  (Not avArr) = -1.{/post}{/quote}  
 
мне двойное отрицание не не понравилось, а просто я не знал, что ему может быть  
логичное применение.  
А из вашей беседы я вынес много для себя поучительного, за что вам всем  
очень признателен.
 
Массивы бывают разные.  
В частности, переменная типа Variant тоже может стать массивом,  
и в таком случае (Not Not Arr) = 0 глюканет.  
Пример:  
 
Sub Test1()  
 Dim a(), b  
 Debug.Print "a", (Not Not a) = 0  
 Debug.Print "b", (Not Not b) = 0  
 ReDim a(1 To 1)  
 ReDim b(1 To 1)  
 Debug.Print "a1", (Not Not a) = 0  
 Debug.Print "b1", (Not Not b) = 0 ‘ <-- выдает ошибку  
End Sub  
 
Это потому, что в переменной типа Variant хранится не указатель на массив, а указатель на указатель на массив :-)  
 
Поэтому надежнее так:  
 
Function IsArrayEmpty(x) As Boolean  
 Dim i&  
 On Error Resume Next  
 i = LBound(x)  
 IsArrayEmpty = Err <> 0  
End Function  
 
Sub Test2()  
 Dim a(), b  
 Debug.Print "a", IsArrayEmpty(a)  
 Debug.Print "b", IsArrayEmpty(b)  
 ReDim a(1 To 1)  
 ReDim b(1 To 1)  
 Debug.Print "a1", IsArrayEmpty(a)  
 Debug.Print "b1", IsArrayEmpty(b)  
End Sub
 
В моем массиве каждый элемент это название,состоящее из 2-10 букв.  
(Not Not Arr) = 0 Когда-нибудь глюканет или не глюканет?
 
{quote}{login=ZVI}{date=06.06.2010 03:34}{thema=}{post}Массивы бывают разные.  
Поэтому надежнее так:  
{/post}{/quote}  
Тоже вкусно. Имхо такие фишки как:  
(Not Not avArr) = 0 (The_Prist)  
IsArrayEmpty = Err <> 0 (Ваша ZVI)  
If wsSh.Cells(1, 1).End(xlDown) <> "" (проверка на пустую строку от Слэн)  
и им подобные должны быть в приемах.  
Или, на худой конец, как писал вчера kim:  
"Пора копать землянку макросописателей/(писцев)...". Но это будет не так доступно(разве что беседку, избушку и землянку прилепить в начало форума. Мож как-то к тем 300 советам добавить(это я к модераторам)?
Я сам - дурнее всякого примера! ...
 
{quote}{login=Егор}{date=06.06.2010 04:20}{thema=}{post}В моем массиве каждый элемент это название,состоящее из 2-10 букв.  
(Not Not Arr) = 0 Когда-нибудь глюканет или не глюканет?{/post}{/quote}  
Не глюканет, если переменная Arr объявлена так: Dim Arr()  
Глюканет, если переменная Arr не будет никак объявлена, или если будет объявлена так: Dim Arr
 
{quote}{login=ZVI}{date=06.06.2010 04:26}{thema=}{post}{quote}{login=Егор}{date=06.06.2010 04:20}{thema=}{post}В моем массиве каждый элемент это название,состоящее из 2-10 букв.  
(Not Not Arr) = 0 Когда-нибудь глюканет или не глюканет?{/post}{/quote}  
Не глюканет, если переменная Arr объявлена так: Dim Arr()  
Глюканет, если переменная Arr не будет никак объявлена, или если будет объявлена так: Dim Arr{/post}{/quote}  
 
Я объявил массив Dim Arr() As Variant в процедуре обработки события в юзерформе, а затем передал его в качестве аргумента в другую процедуру, которая находится в модуле. В модуле делаю проверку на пустой\непустой.  
Так считается , что я его объявил?
 
{quote}{login=}{date=06.06.2010 05:00}{thema=Re: }{post}Я объявил массив Dim Arr() As Variant в процедуре обработки события в юзерформе, а затем передал его в качестве аргумента в другую процедуру, которая находится в модуле. В модуле делаю проверку на пустой\непустой.  
Так считается , что я его объявил?{/post}{/quote}  
Dim Arr() As Variant - это то же самое, что Dim Arr()  
Если в объявлении переменной присутствуют круглые скобки, то это явное объявление переменной массива. При этом проблемы с (Not Not Arr) = 0 не будет.  
Если же круглых скобок нет: Dim Arr  
то возникнет указанная проблема с (Not Not Arr) = 0  
Ещё раз - важны именно круглые скобки при объявлении, а As ЛюбойТип - не имеет значения для метода (Not Not Arr) = 0
 
Ясно. Спасибо.
Страницы: 1
Читают тему
Наверх