空の配列をチェックしたいのですが。グーグルでは様々な解決策がありましたが、うまくいきませんでした。もしかしたら、正しく適用できていないのかもしれません。
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 Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
空の文字列 (""
) や vbNullString
を Dir
に渡すと、カレントディレクトリのパス (CurDir$
が返すパス) にある最初のファイルの名前を返します。つまり、SigString
が空であれば、Dir
が空ではない文字列 (カレントディレクトリの最初のファイルの名前) を返すので、If
条件は True
と評価され、GetBoiler
が呼び出されます。また、SigString
が空であれば、fso.GetFile
の呼び出しは失敗します。
SigStringが空でないことをチェックするように条件を変更するか、ファイルが存在するかどうかをチェックするのに、
Dirの代わりに
FileSystemObject.FileExistsメソッドを使用する必要があります。
Dirは予想外のことをするので、使いどころが難しいのです。個人的には、
Scripting.FileSystemObjectを
Dirよりも使いたいと思っています。なぜなら、おかしなことが起こらないからです (
FileExistsは、ファイルが存在すれば
Trueを返し、存在しなければ
Falseを返します)。さらに、
FileExistsは
Dir` よりもコードの intent を明確に表現します。
方法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
問題とQuestionを意図通りに一般化します。 配列のアッシングをテストして、最終的なエラーをキャッチする
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を持つ配列を見逃します...それはありそうですか?奇妙な国では、はい。