vba 매크로에서 빈 배열을 확인하는 방법
이 질문에 이미 답변이 있습니다.
빈 배열을 확인하고 싶습니다. Google은 저에게 다양한 솔루션을 제공했지만 효과가 없었습니다. 아마도 나는 그것들을 올바르게 적용하지 않을 것입니다.
Function GetBoiler(ByVal sFile As String) As String
'Email Signature
Dim fso As Object
Dim ts As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)
GetBoiler = ts.ReadAll
ts.Close
End Function
Dim FileNamesList As Variant, i As Integer
' activate the desired startfolder for the filesearch
FileNamesList = CreateFileList("*.*", False) ' Returns File names
' performs the filesearch, includes any subfolders
' present the result
' If there are Signatures then populate SigString
Range("A:A").ClearContents
For i = 1 To UBound(FileNamesList)
Cells(i + 1, 1).Formula = FileNamesList(i)
Next i
SigString = FileNamesList(3)
If Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
여기서 FileNamesList
배열이 비어 있으면 GetBoiler(SigString)
전혀 호출되지 않아야합니다. FileNamesList
배열이 비어 있을 SigString
때도 비어 있으며 GetBoiler()
빈 문자열로 함수를 호출 합니다. 줄에서 오류가 발생합니다.
Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)
sFile
비어 있기 때문에 . 그것을 피할 방법이 있습니까?
string 형 배열을 다룰 때 Join을 고려해 보셨습니까?
If Len(Join(FileNamesList)) > 0 Then
트리플 네거티브로 이동 :
If (Not Not FileNamesList) <> 0 Then
' Array has been initialized, so you're good to go.
Else
' Array has NOT been initialized
End If
아니면 그냥 :
If (Not FileNamesList) = -1 Then
' Array has NOT been initialized
Else
' Array has been initialized, so you're good to go.
End If
VB에서는 어떤 이유로 든 Not myArray
SafeArray 포인터를 반환합니다. 초기화되지 않은 배열의 경우 -1을 반환합니다. 당신은 할 수 있습니다 Not
이 원하는 경우 따라서, 제로를 반환 -1을 XOR합니다.
(Not myArray) (Not Not myArray)
Uninitialized -1 0
Initialized -someBigNumber someOtherBigNumber
배열 함수를 테스트하면 모든 범위에서 작동합니다.
Function IsVarArrayEmpty(anArray As Variant)
Dim i As Integer
On Error Resume Next
i = UBound(anArray,1)
If Err.number = 0 Then
IsVarArrayEmpty = False
Else
IsVarArrayEmpty = True
End If
End Function
나는 여기에서 비슷한 대답을 볼 수 있지만 내 것은 아닙니다 ...
이것이 내가 불행하게 대처할 방법입니다 ... 나는 len (join (arr))> 0 접근 방식을 좋아하지만 배열이 빈 문자열의 배열이면 작동하지 않습니다 ...
Public Function arrayLength(arr As Variant) As Long
On Error GoTo handler
Dim lngLower As Long
Dim lngUpper As Long
lngLower = LBound(arr)
lngUpper = UBound(arr)
arrayLength = (lngUpper - lngLower) + 1
Exit Function
handler:
arrayLength = 0 'error occured. must be zero length
End Function
VBA를 작성할 때 내 머릿속에 "이렇게 쉬울 수는 있지만 ..."라는 문장이 있습니다.
내가 그것을 채택한 것은 다음과 같습니다.
Private Function IsArrayEmpty(arr As Variant)
' This function returns true if array is empty
Dim l As Long
On Error Resume Next
l = Len(Join(arr))
If l = 0 Then
IsArrayEmpty = True
Else
IsArrayEmpty = False
End If
If Err.Number > 0 Then
IsArrayEmpty = True
End If
On Error GoTo 0
End Function
Private Sub IsArrayEmptyTest()
Dim a As Variant
a = Array()
Debug.Print "Array is Empty is " & IsArrayEmpty(a)
If IsArrayEmpty(a) = False Then
Debug.Print " " & Join(a)
End If
End Sub
이 코드는 예상대로 작동하지 않습니다.
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
over를 사용할 것입니다 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
나는 위대한 Chip Pearson의 코드 아래에 단순히 붙여넣고 있습니다. 그것은 매력적입니다.
다음 은 배열 함수에 대한 그의 페이지입니다 .
이게 도움이 되길 바란다.
Public Function IsArrayEmpty(Arr As Variant) As Boolean
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' IsArrayEmpty
' This function tests whether the array is empty (unallocated). Returns TRUE or FALSE.
'
' The VBA IsArray function indicates whether a variable is an array, but it does not
' distinguish between allocated and unallocated arrays. It will return TRUE for both
' allocated and unallocated arrays. This function tests whether the array has actually
' been allocated.
'
' This function is really the reverse of IsArrayAllocated.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim LB As Long
Dim UB As Long
err.Clear
On Error Resume Next
If IsArray(Arr) = False Then
' we weren't passed an array, return True
IsArrayEmpty = True
End If
' Attempt to get the UBound of the array. If the array is
' unallocated, an error will occur.
UB = UBound(Arr, 1)
If (err.Number <> 0) Then
IsArrayEmpty = True
Else
''''''''''''''''''''''''''''''''''''''''''
' On rare occasion, under circumstances I
' cannot reliably replicate, Err.Number
' will be 0 for an unallocated, empty array.
' On these occasions, LBound is 0 and
' UBound is -1.
' To accommodate the weird behavior, test to
' see if LB > UB. If so, the array is not
' allocated.
''''''''''''''''''''''''''''''''''''''''''
err.Clear
LB = LBound(Arr)
If LB > UB Then
IsArrayEmpty = True
Else
IsArrayEmpty = False
End If
End If
End Function
Auth가 가장 가깝지만 그의 대답은 유형 불일치 오류를 발생시킵니다.
다른 답변에 관해서는 오류를 사용하여 조건을 테스트하는 것을 피해야합니다. 가능한 경우 디버깅이 매우 복잡하기 때문입니다 (다른 것이 해당 오류를 일으키는 경우).
다음은 간단하고 완전한 솔루션입니다.
option explicit
Function foo() As Variant
Dim bar() As String
If (Not Not bar) Then
ReDim Preserve bar(0 To UBound(bar) + 1)
Else
ReDim Preserve bar(0 To 0)
End If
bar(UBound(bar)) = "it works!"
foo = bar
End Function
빈 배열에 대한 간단한 검사 :
Dim exampleArray() As Variant 'Any Type
If ((Not Not exampleArray) = 0) Then
'Array is Empty
Else
'Array is Not Empty
End If
ahuth의 답변에 따라 ;
Function AryLen(ary() As Variant, Optional idx_dim As Long = 1) As Long
If (Not ary) = -1 Then
AryLen = 0
Else
AryLen = UBound(ary, idx_dim) - LBound(ary, idx_dim) + 1
End If
End Function
빈 배열을 확인하십시오. is_empty = AryLen(some_array)=0
Public Function IsEmptyArray(InputArray As Variant) As Boolean
On Error GoTo ErrHandler:
IsEmptyArray = Not (UBound(InputArray) >= 0)
Exit Function
ErrHandler:
IsEmptyArray = True
End Function
아래 함수를 사용하여 vba에서 변형 또는 문자열 배열이 비어 있는지 확인할 수 있습니다.
Function IsArrayAllocated(Arr As Variant) As Boolean
On Error Resume Next
IsArrayAllocated = IsArray(Arr) And _
Not IsError(LBound(Arr, 1)) And _
LBound(Arr, 1) <= UBound(Arr, 1)
End Function
샘플 사용법
Public Function test()
Dim Arr(1) As String
Arr(0) = "d"
Dim x As Boolean
x = IsArrayAllocated(Arr)
End Function
또 다른 방법은 더 빨리하는 것입니다. 부울 변수를 만들고 데이터를 배열에로드 한 후 true로 설정할 수 있습니다. 그래서 정말 필요한 것은 데이터를 배열에로드 할 때 간단한 if 문입니다.
여기에 다른 방법이 있습니다. 나는 그것을 어떤 경우에 사용했고 작동하고 있습니다.
Function IsArrayEmpty(arr As Variant) As Boolean
Dim index As Integer
index = -1
On Error Resume Next
index = UBound(arr)
On Error GoTo 0
If (index = -1) Then IsArrayEmpty = True Else IsArrayEmpty = False
End Function
Byte 배열이 비어 있는지 확인하려면 가장 간단한 방법은 VBA 함수를 사용하는 것 StrPtr()
입니다.
바이트 배열이 비어있는 경우 StrPtr()
반환 0
; 그렇지 않으면 0이 아닌 값을 반환합니다 (그러나 첫 번째 요소의 주소는 아님 ).
Dim ar() As Byte
Debug.Assert StrPtr(ar) = 0
ReDim ar(0 to 3) As Byte
Debug.Assert StrPtr(ar) <> 0
그러나 Byte 배열에서만 작동합니다.
Function IsVarArrayEmpty(anArray As Variant) as boolean
On Error Resume Next
IsVarArrayEmpty = true
IsVarArrayEmpty = UBound(anArray) < LBound(anArray)
End Function
아마도 ubound
충돌하고 true로 유지되고 만약이면 ubound < lbound
비어 있습니다.
의도 한대로 문제와 질문을 일반화하겠습니다. 어레이에 대한 평가 테스트 및 최종 오류 포착
Function IsVarArrayEmpty(anArray as Variant)
Dim aVar as Variant
IsVarArrayEmpty=False
On error resume next
aVar=anArray(1)
If Err.number then '...still, it might not start at this index
aVar=anArray(0)
If Err.number then IsVarArrayEmpty=True ' neither 0 or 1 yields good assignment
EndIF
End Function
확실히 그것은 모든 음수 인덱스 또는 모두> 1을 가진 배열을 놓친 것입니까? 이상한 나라에서, 네.
개인적으로 위의 답변 중 하나를 수정하여 배열에 내용이 있는지 확인할 수 있다고 생각합니다.
if UBound(ar) > LBound(ar) Then
이것은 음수 참조를 처리하고 다른 옵션 중 일부보다 시간이 덜 걸립니다.
You can check if the array is empty by retrieving total elements count using JScript's VBArray()
object (works with arrays of variant type, single or multidimensional):
Sub Test()
Dim a() As Variant
Dim b As Variant
Dim c As Long
' Uninitialized array of variant
' MsgBox UBound(a) ' gives 'Subscript out of range' error
MsgBox GetElementsCount(a) ' 0
' Variant containing an empty array
b = Array()
MsgBox GetElementsCount(b) ' 0
' Any other types, eg Long or not Variant type arrays
MsgBox GetElementsCount(c) ' -1
End Sub
Function GetElementsCount(aSample) As Long
Static oHtmlfile As Object ' instantiate once
If oHtmlfile Is Nothing Then
Set oHtmlfile = CreateObject("htmlfile")
oHtmlfile.parentWindow.execScript ("function arrlength(arr) {try {return (new VBArray(arr)).toArray().length} catch(e) {return -1}}"), "jscript"
End If
GetElementsCount = oHtmlfile.parentWindow.arrlength(aSample)
End Function
For me it takes about 0.3 mksec for each element + 15 msec initialization, so the array of 10M elements takes about 3 sec. The same functionality could be implemented via ScriptControl
ActiveX (it is not available in 64-bit MS Office versions, so you can use workaround like this).
if Ubound(yourArray)>-1 then
debug.print "The array is not empty"
else
debug.print "EMPTY"
end if
You can check its count.
Here cid is an array.
if (jsonObject("result")("cid").Count) = 0 them
MsgBox "Empty Array"
I hope this helps. Have a nice day!
Another solution to test for empty array
if UBound(ar) < LBound(ar) then msgbox "Your array is empty!"
Or, if you already know that LBound is 0
if -1 = UBound(ar) then msgbox "Your array is empty!"
This may be faster than join(). (And I didn't check with negative indexes)
Here is my sample to filter 2 string arrays so they do not share same strings.
' Filtering ar2 out of strings that exists in ar1
For i = 0 To UBound(ar1)
' filter out any ar2.string that exists in ar1
ar2 = Filter(ar2 , ar1(i), False)
If UBound(ar2) < LBound(ar2) Then
MsgBox "All strings are the same.", vbExclamation, "Operation ignored":
Exit Sub
End If
Next
' At this point, we know that ar2 is not empty and it is filtered
'
Public Function arrayIsEmpty(arrayToCheck() As Variant) As Boolean
On Error GoTo Err:
Dim forCheck
forCheck = arrayToCheck(0)
arrayIsEmpty = False
Exit Function
Err:
arrayIsEmpty = True
End Function
참고URL : https://stackoverflow.com/questions/206324/how-to-check-for-empty-array-in-vba-macro
'Nice programing' 카테고리의 다른 글
프로그래밍 방식으로 UITextView 포커스를 어떻게 제공합니까? (0) | 2020.12.13 |
---|---|
Django : 페이지가 원하는 URL로 리디렉션되었는지 테스트 (0) | 2020.12.13 |
Java의 문자열에서 숫자가 아닌 문자를 어떻게 제거합니까? (0) | 2020.12.13 |
HTML / CSS 회색으로 표시된 텍스트가있는 텍스트 상자를 만들고 정보를 입력하기 위해 클릭하면 사라지는 방법은 무엇입니까? (0) | 2020.12.13 |
Java에서 Calendar를 java.sql.Date로 변환하는 방법? (0) | 2020.12.13 |