空の配列を確認したい。 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
は空なので。それを避ける方法はありますか?
文字列配列を処理しているときに、結合を検討しましたか?
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
thisをXOR -1で指定できます。したがって、必要に応じてゼロを返します。
(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
が空でないことを確認するか、Dir
の代わりにFileSystemObject.FileExists
メソッドを使用して、ファイルが存在するかどうかを確認する必要があります。 Dir
は、予期しない動作を行うため、正確に使用するのは困難です。個人的には、面白いビジネスがないので、Dir
ではなくScripting.FileSystemObject
を使用します(ファイルが存在する場合はFileExists
がTrue
を返し、そうでない場合はFalse
を返します)。さらに、FileExists
は、コードのintentを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
偉大なチップピアソンによるコードの下に貼り付けているだけです。それは魅力的です。
ここに彼の 配列関数のページ があります。
これがお役に立てば幸いです。
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の answer ;に基づく
_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
Byte配列が空かどうかを確認するには、VBA関数StrPtr()
を使用するのが最も簡単な方法です。
バイト配列が空の場合、StrPtr()
は0
;それ以外の場合は、ゼロ以外の値を返します(ただし、 じゃない 最初の要素へのアドレス)。
Dim ar() As Byte
Debug.Assert StrPtr(ar) = 0
ReDim ar(0 to 3) As Byte
Debug.Assert StrPtr(ar) <> 0
ただし、Byte配列でのみ機能します。
別の方法は、より早くそれを行うことです。ブール変数を作成し、配列にデータを読み込んだらtrueに設定できます。本当に必要なのは、データを配列にロードするときのifステートメントだけです。
Public Function IsEmptyArray(InputArray As Variant) As Boolean
On Error GoTo ErrHandler:
IsEmptyArray = Not (UBound(InputArray) >= 0)
Exit Function
ErrHandler:
IsEmptyArray = True
End Function
別の方法があります。私はいくつかのケースでそれを使用しましたが、機能しています。
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
Function IsVarArrayEmpty(anArray As Variant) as boolean
On Error Resume Next
IsVarArrayEmpty = true
IsVarArrayEmpty = UBound(anArray) < LBound(anArray)
End Function
たぶんubound
がクラッシュしてtrueのままになることがあり、ubound < lbound
、 空っぽです
その数を確認できます。
ここでcidは配列です。
if (jsonObject("result")("cid").Count) = 0 them
MsgBox "Empty Array"
これがお役に立てば幸いです。ごきげんよう!
JScriptのVBArray()
オブジェクトを使用して合計要素数を取得することにより、配列が空かどうかを確認できます(単一または多次元のバリアント型の配列で動作します)。
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
私にとっては、各要素に約0.3 mksec + 15ミリ秒の初期化が必要なので、10M要素の配列には約3秒かかります。同じ機能をScriptControl
ActiveXを介して実装できます(64ビットMS Officeバージョンでは使用できないため、 this のような回避策を使用できます)。
if Ubound(yourArray)>-1 then
debug.print "The array is not empty"
else
debug.print "EMPTY"
end if
意図したとおりに問題と質問を一般化します。配列の割り当てをテストし、最終的なエラーをキャッチします
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より大きい配列が欠落していることは確かです。奇妙な土地で、はい。
個人的には、上記の答えの1つを変更して、配列に内容があるかどうかを確認できると思います。
if UBound(ar) > LBound(ar) Then
これは負の数の参照を処理し、他のオプションのいくつかよりも時間がかかりません。
以下の関数を使用して、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