AndreA SN 1014 / 118 / 2 Регистрация: 26.08.2011 Сообщений: 1,113 Записей в блоге: 2 |
||||
1 |
||||
Как проверить пуст ли массив?22.07.2015, 09:47. Показов 29863. Ответов 42 Метки нет (Все метки)
это продолжение темы. интересует грамотность записи
Добавлено через 1 минуту
0 |
3827 / 2254 / 751 Регистрация: 02.11.2012 Сообщений: 5,928 |
|
22.07.2015, 10:13 |
2 |
чтобы не было нулевой позиции перед внесением проверять.
0 |
1014 / 118 / 2 Регистрация: 26.08.2011 Сообщений: 1,113 Записей в блоге: 2 |
|
22.07.2015, 11:12 [ТС] |
3 |
Vlad999, согласен. Я постоянно так и делаю. Но проверять постоянно есть-ли запись в первой строке — это увеличение операций по заполнению массива в 2 раза. Вот я и спрашиваю: какие технологии заполнения массивов спецами используются. Чтобы не было лишних проверок состояния массива на «полный, пустой»
0 |
1337 / 308 / 74 Регистрация: 13.11.2008 Сообщений: 635 |
|
22.07.2015, 11:53 |
4 |
Трудно что-то советовать, когда не видно как Вы этот массив заполнять собрались.
0 |
AndreA SN 1014 / 118 / 2 Регистрация: 26.08.2011 Сообщений: 1,113 Записей в блоге: 2 |
||||
22.07.2015, 12:37 [ТС] |
5 |
|||
The_Prist, привожу пример
В первой части If заполняю первую позицию массива, а в части Else — постоянно проверяю на заполненность первую строку. Вот эта необходимость постоянной проверки вызывает вопрос.
0 |
The_Prist 1337 / 308 / 74 Регистрация: 13.11.2008 Сообщений: 635 |
||||
22.07.2015, 12:50 |
6 |
|||
Решение И все же не видно как объявлен этот массив. Где строка объявления Iskl2?
1 |
AndreA SN 1014 / 118 / 2 Регистрация: 26.08.2011 Сообщений: 1,113 Записей в блоге: 2 |
||||
22.07.2015, 13:00 [ТС] |
7 |
|||
The_Prist, извиняюсь… проглядел ответный вопрос об объявлении массива
в связке с этим вопросом интересует просто вопрос грамотной проверки массива на непустотность Добавлено через 2 минуты
0 |
Dragokas 17991 / 7617 / 890 Регистрация: 25.12.2011 Сообщений: 11,351 Записей в блоге: 17 |
||||
22.07.2015, 13:44 |
8 |
|||
Смотря что считать пустым массивом…
2 |
4038 / 1423 / 394 Регистрация: 07.08.2013 Сообщений: 3,541 |
|
22.07.2015, 13:51 |
9 |
а массивы большие
0 |
1014 / 118 / 2 Регистрация: 26.08.2011 Сообщений: 1,113 Записей в блоге: 2 |
|
22.07.2015, 13:52 [ТС] |
10 |
Dragokas, спасибо)))
0 |
Dragokas 17991 / 7617 / 890 Регистрация: 25.12.2011 Сообщений: 11,351 Записей в блоге: 17 |
||||
22.07.2015, 14:31 |
11 |
|||
AndreA SN, только не забывайте, что результат операции — это не BOOL, а указатель на SAFEARRAY.
2 |
AndreA SN 1014 / 118 / 2 Регистрация: 26.08.2011 Сообщений: 1,113 Записей в блоге: 2 |
||||
22.07.2015, 14:45 [ТС] |
12 |
|||
snipe, опять же смотря из какого объема действий исходить.
в итоге получаем за счет суммирования 6000000 а по максимальному размеру цикла — читай по Ubound(массив) разница составила 300 раз… Добавлено через 13 минут
If Not Cbool(Not Not arr) Then очень прошу (хотя понимаю, что мой вопрос кошмарит грамотных людей), объяснить все эти Not понятным языком — что за что отвечает.
0 |
Dragokas 17991 / 7617 / 890 Регистрация: 25.12.2011 Сообщений: 11,351 Записей в блоге: 17 |
||||
22.07.2015, 22:31 |
13 |
|||
РешениеAndreA SN, да. Вы правы. Перемудрил. Можно проще.
Если кратко, то оператор Not кроме основной функции (побитовое отрицание) умеет разыменовывать указатель,
1 |
snipe 4038 / 1423 / 394 Регистрация: 07.08.2013 Сообщений: 3,541 |
||||
23.07.2015, 04:02 |
14 |
|||
AndreA SN, есть 2 функции Join и Split
1 |
4038 / 1423 / 394 Регистрация: 07.08.2013 Сообщений: 3,541 |
|
23.07.2015, 04:09 |
15 |
Dragokas, Миниатюры
0 |
2670 / 786 / 176 Регистрация: 14.01.2013 Сообщений: 3,672 |
|
23.07.2015, 06:54 |
16 |
В Опере всё норм выглядит. Миниатюры
1 |
snipe |
23.07.2015, 09:01
|
Не по теме: так я тоже в опере делал
0 |
1014 / 118 / 2 Регистрация: 26.08.2011 Сообщений: 1,113 Записей в блоге: 2 |
|
23.07.2015, 10:54 [ТС] |
18 |
snipe,
из много массивов сделать один нет… у меня задача другая… я делаю маленький реплик-массив из большого массива. причем оба они двумерны. реплик-массив как правило варьирует от 2 до нескольких десятков записей (встречаются редко случаи и до 2500), а большой массив может включать десятки тысяч записей. Постоянная перезапись реплик-массива с изменяющимися исходными условиями вынуждают при последующей работе проверять : а записалось ли чего-то в реплик-массив, или он при изменившихся условиях отбора записей остался пустым? Вот последнее хочется грамотно проверять, что Dragokas и подсказал как делать. Добавлено через 11 минут
0 |
4038 / 1423 / 394 Регистрация: 07.08.2013 Сообщений: 3,541 |
|
23.07.2015, 11:01 |
19 |
AndreA SN, вы тему разместили в разделе VBA, а в какой программе вы все это делаете?
0 |
1014 / 118 / 2 Регистрация: 26.08.2011 Сообщений: 1,113 Записей в блоге: 2 |
|
23.07.2015, 11:25 [ТС] |
20 |
snipe, толковый вопрос))) мне уже столько людей у виска пальцем крутит по поводу моего проекта в VBA))) И Вы почуяли, что моя задача монстрифицирована. Добавлено через 9 минут
0 |
Добрый день. |
|
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
Sub Arr_Initialize() Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
Спасибо большое. Все очень понятно объяснили. |
|
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
Впишите в ячейку А1 формулу: Вычислите её пошагово и все поймете. Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
{quote}{login=The_Prist}{date=06.06.2010 11:30}{thema=}{post}Впишите в ячейку А1 формулу: Вычислите её пошагово и все поймете.{/post}{/quote} Вписал в ячейку B1 формулу =НЕ(НЕ(A1=0)), |
|
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
Эх…Простой конструкцией типа avArr = 0 не получиться узнать наполнение массива — такая конструкция недопустима, сначала необходимо переопределить размерность, т.к. VBA считает, что Вы хотите присвоить массиву значение. В этом выражении: VBA сначала сравнивает массив, преобразуя его в тип Integer, независимо от данных в нем(на сами данные не влияет), не вызывая ошибку. Но все равно придется добавлять Not, чтобы было вроде как понятней(или поменять условия местами). Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
Еще раз спасибо огромное. |
|
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
{quote}{login=The_Prist}{date=06.06.2010 12:22}{thema=}{post} Я сам — дурнее всякого примера! … |
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
{quote}{login=KuklP}{date=06.06.2010 01:27}{thema=Re: }{post}{quote}{login=The_Prist}{date=06.06.2010 12:22}{thema=}{post} «В общем-то можно и так записать для достижения цели: Это же конструкция сравнения. С нулем как-то смотрится более информативно. Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
Дим, при (Not avArr) = 0 выдаст, что массив не пустой в обоих случаях. Я сам — дурнее всякого примера! … |
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
Да, а Not(-1) как раз и дает 0. Я сам — дурнее всякого примера! … |
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
{quote}{login=KuklP}{date=06.06.2010 02:07}{thema=}{post}Дим, при (Not avArr) = 0 выдаст, что массив не пустой в обоих случаях. Sub Arr_Initialize() Вот в этой процедуре получиться, что условия перепутаны. Именно про это я и писал: «Но все равно придется добавлять Not, чтобы было вроде как понятней(или поменять условия местами)» Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
Да нет же, Дим(вот я не умею так понятно объяснять как ты) Я сам — дурнее всякого примера! … |
Юрий М Модератор Сообщений: 60570 Контакты см. в профиле |
|
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
А, ну да. Чет я сразу не догнал. Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
Все, сдаюсь. Я сам — дурнее всякого примера! … |
Извиняюсь, что вклиниваюсь в беседу, но у меня |
|
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
{quote}{login=Егор}{date=06.06.2010 02:36}{thema=}{post}Извиняюсь, что вклиниваюсь в беседу, но у меня Я сам — дурнее всякого примера! … |
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
Вообще главная фишка такой проверки в том, что можно проверить даже неинициализированный массив. Т.к. неинициализированный массив при помощи UBound() не проверить — выдаст ошибку. Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
{quote}{login=KuklP}{date=06.06.2010 02:43}{thema=Re: }{post}{quote}{login=Егор}{date=06.06.2010 02:36}{thema=}{post}Извиняюсь, что вклиниваюсь в беседу, но у меня мне двойное отрицание не не понравилось, а просто я не знал, что ему может быть |
|
ZVI Пользователь Сообщений: 4328 |
Массивы бывают разные. Sub Test1() Это потому, что в переменной типа Variant хранится не указатель на массив, а указатель на указатель на массив Поэтому надежнее так: Function IsArrayEmpty(x) As Boolean Sub Test2() |
В моем массиве каждый элемент это название,состоящее из 2-10 букв. |
|
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
{quote}{login=ZVI}{date=06.06.2010 03:34}{thema=}{post}Массивы бывают разные. Я сам — дурнее всякого примера! … |
ZVI Пользователь Сообщений: 4328 |
{quote}{login=Егор}{date=06.06.2010 04:20}{thema=}{post}В моем массиве каждый элемент это название,состоящее из 2-10 букв. |
{quote}{login=ZVI}{date=06.06.2010 04:26}{thema=}{post}{quote}{login=Егор}{date=06.06.2010 04:20}{thema=}{post}В моем массиве каждый элемент это название,состоящее из 2-10 букв. Я объявил массив Dim Arr() As Variant в процедуре обработки события в юзерформе, а затем передал его в качестве аргумента в другую процедуру, которая находится в модуле. В модуле делаю проверку на пустойнепустой. |
|
ZVI Пользователь Сообщений: 4328 |
{quote}{login=}{date=06.06.2010 05:00}{thema=Re: }{post}Я объявил массив Dim Arr() As Variant в процедуре обработки события в юзерформе, а затем передал его в качестве аргумента в другую процедуру, которая находится в модуле. В модуле делаю проверку на пустойнепустой. |
Егор Гость |
#27 06.06.2010 17:55:42 Ясно. Спасибо. |
When a list or collection of items that are the same data type are stored in continuous memory locations, we call it an array. Arrays are useful objects that are widely used in software development to organize data. Some real examples of where you might use them might include:
- Online games, like chess, make use of two dimensional arrays.
- An ECG waveform is a realtime example of array usage.
I’ll show you a couple array examples, then we’ll get into how to check if one is empty.
Sub array_demo() 'Declaration of array variable Dim arr() As String 'Defining length of array ReDim arr(8) For i = 0 To 8 'Allocate data for each array item through a loop arr(i) = Cells(i + 2, 1).Value 'Print each item Debug.Print arr(i) Next End Sub
Here is another example that creates an array as a result of using the Split function.
Sub array_split_demo() 'list of days in a string separated by a single space days_string = "sunday monday tuesday wednesday thursday friday saturday" 'splitting the string into an array using a delimiter weekdays = Split(days_string, " ") 'printing them all For i = LBound(weekdays) To UBound(weekdays) Debug.Print weekdays(i) Next End Sub
The above code prints a list of days while iterating through the array in that was created when the string was split and stored.
Types of arrays
In VBA arrays can either be static or dynamic.
Static arrays
The size of the array is fixed and cannot be changed.
Dynamic arrays
The size of the array is not fixed and can be modified based on your requirements.
Check if an array is empty or contains data
In VBA, unless we first define the size of an array, we cannot use the Lbound() and UBound functions. It will throw an error. So, we need to use the Redim keyword and define a size as soon as we declare an array.
Also there isn’t a specific function that can validate the existence of data in an array. So, we have to make use pf other available functions, along with some logic, to determine if an array is empty or not.
Below are a few methods you can utilize.
Join function
Just like how we used the split function to split a string into an array, a Join function can be used to concatenate all elements of an array into a single string.
Syntax:
Join ( <source array> , [ < Delimiter > ] )
Where
Source array
is the name of the array whose elements need to be joined.
Delimiter
is the character that is going to be placed between the concatenation of every two elements while joining the array elements. This is an optional parameter and if it’s not provided, a space “ “ is used by default.
If a zero length string “” is provided as a delimiter, the joining happens without inserting any characters during concatenation.
For example:
Sub join_arraydemo() ' Join together the strings "Orange", "Apple" and "Mango". Dim all_fruits As String Dim fruits(0 To 2) As String 'assign values for all fruits fruits(0) = "Orange" fruits(1) = "Apple" fruits(2) = "Mango" 'Join using the built-in function all_fruits = Join(fruits) ' The variable all_fruits is now set to "Orange Apple Mango" Debug.Print all_fruits End Sub
So, first all the elements of the array are concatenated using the Join function, then the resulting string’s length can be checked to check if the array is empty or not.
The below piece of code can be added to the above code sample to notify you if the array is empty or not.
If Len(all_fruits) &amp;amp;gt; 0 Then Debug.Print "fruits array is not empty" Else Debug.Print "Fruits array is empty" End If
In short, we can use the below line to achieve the same results.
If Len(Join(all_fruits)) &amp;amp;gt; 0 Then
Iterate through all the items in the array
Using a For loop, we can iterate through each element in an array to validate whether the array has some data or it is completely empty. Here’s a ready to use function for you.
Function IsEmptyArray(arr) 'a normal flag variable flag = 0 'loop to check if atleast one element of te array has data For i = LBound(arr) To UBound(arr) If IsEmpty(arr(i)) = False Then Debug.Print "The array has data" flag = 1 Exit For End If Next 'Check if flag value has changed because data is present If flag = 0 Then Debug.Print "The array is empty" End If End Function
UBound function + bypass an error
Because an error will be thrown if we use the Ubound or Lbound function on an empty array, we are going to use the “On Error Resume Next” statement and catch the error number to test if the array is empty. Here the array is considered empty if it doesn’t have a size defined. I created a function to help you better understand and use the code.
Sub array_check_demo() 'Declaration of array variable Dim arr() As Variant 'The array should be empty now Debug.Print Is_Var_Array_Empty(arr) 'Defining length of array ReDim arr(8) 'The array has a size . So, as per this logic, it is not empty Debug.Print Is_Var_Array_Empty(arr) 'We check if the array is empty before assigning values 'Assign values to array elements For i = 0 To 8 'Allocate data for each array item through a loop arr(i) = Cells(i + 2, 1).Value Next 'validate if array is empty again Debug.Print Is_Var_Array_Empty(arr) End Sub Function Is_Var_Array_Empty(arr_var As Variant) Dim p As Integer On Error Resume Next p = UBound(arr_var, 1) If Err.Number = 0 Then Is_Var_Array_Empty = False Else Is_Var_Array_Empty = True End If End Function
StrPtr() function for a byte array
A byte array is nothing but a series or characters. A string can directly be assigned to a byte array. Two elements of an array are used to allocate space for a character from a string. The below code should help you understand further.
Sub byte_array_demo() 'declare a byte array and a string Dim arr1() As Byte Dim samplestr As String 'initiate the string samplestr = "Coffee" 'Check if the array is empty. StrPtr(&amp;amp;lt;arrname&amp;amp;gt;) would return 0 if the array is empty. Debug.Print StrPtr(arr1) = 0 'allocate the string directly to the byte array arr1() = samplestr 'View what has been stored in the array For i = LBound(arr1) To UBound(arr1) Debug.Print arr1(i) Next 'Check if the array is empty. StrPtr(&amp;amp;lt;arrname&amp;amp;gt;) would return 0 if the array is empty. Debug.Print StrPtr(arr1) = 0 End Sub
Explaining the output:
Initially the array is empty , so StrPtr(arr1)
returns true.
Ascii value of “C” is 67
Ascii null character
Ascii value of “o” is 111
Ascii null character
Ascii value of “f” is 102
Ascii null character
Ascii value of “f” is 102
Ascii null character
Ascii value of “e” is 101
Ascii null character
Ascii value of “e” is 101
Ascii null character
Finally the array is not empty , so StrPtr(arr1)
returns false.
Conclusion
In VBA, other than StrPtr() function for byte arrays , there are no direct methods to find if an array is empty or not. However our best friend, Magical VBA, offers flexible functions that can be combined with your own logic to check the size of an array or the existence or non-existence of data in an array of any datatype.
The meaning of “EMPTY” here lies with the user. It could either be an array that does not have a size defined or an array that has a specific size but no data in it.
Of the above methods, I recommend just grabbing a user-defined function that you can easily use to check if an array is empty or not.
If you’re looking to see how to check if a cell is empty, check out our article here.
Tagged with: Arrays, Concatenating, Lbound, Loop, redim, Size, Split, Strings, StrPtr, Ubound, VBA
Этот код не выполняет то, что вы ожидаете:
If Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
Если вы передадите пустую строку (""
) или vbNullString
в Dir
, она вернет имя первого файла в текущем пути к каталогу (путь, возвращаемый CurDir$
). Итак, если SigString
пусто, ваше условие If
будет оцениваться как True
, потому что Dir
вернет непустую строку (имя первого файла в текущем каталоге), а GetBoiler
будет называется. И если SigString
пуст, вызов fso.GetFile
завершится с ошибкой.
Вы должны либо изменить свое условие, чтобы проверить, что SigString
не пусто, либо использовать FileSystemObject.FileExists
вместо Dir
для проверки наличия файла. Dir
сложно использовать именно потому, что он делает то, чего вы не ожидаете от него. Лично я использовал бы Scripting.FileSystemObject
над Dir
, потому что нет смешного бизнеса (FileExists
возвращает True
, если файл существует, и, ну, False
, если он этого не делает). Что еще, FileExists
выражает намерение вашего кода намного ясно, чем Dir
.
Способ 1. Убедитесь, что SigString
не является пустым первым
If SigString <> "" And Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
Метод 2: используйте метод FileSystemObject.FileExists
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(SigString) Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
Этот код делает не то, что вы ожидаете:
Если вы передадите пустую строку ("""
) или vbNullString
в Dir
, он вернет имя первого файла в текущем пути к каталогу (путь, возвращаемый CurDir$
). Таким образом, если SigString
пуст, ваше условие If
будет оценено как True
, потому что Dir
вернет непустую строку (имя первого файла в текущем каталоге), и будет вызван GetBoiler
. Если же SigString
будет пустым, вызов fso.GetFile
завершится неудачей.
Вам следует либо изменить условие, чтобы проверить, что SigString
не пуст, либо использовать метод FileSystemObject.FileExists
вместо Dir
для проверки существования файла. Метод Dir
сложен в использовании именно потому, что он делает то, чего вы, возможно, не ожидаете от него. Лично я бы использовал Scripting.FileSystemObject
вместо Dir
, потому что здесь нет ничего смешного (FileExists
возвращает True
, если файл существует, и False
, если не существует). Более того, FileExists
выражает намерение вашего кода гораздо яснее, чем Dir
.
Метод 1: Сначала проверьте, что SigString
не является пустым.
Метод 2: Используйте метод FileSystemObject.FileExists
.