CharactersオブジェクトのCountプロパティのバグ
一般的にCharactersオブジェクトのCountプロパティは文字数を取得するプロパティと紹介されているのですが、それは半分は正しいのですが半分は間違いです。
Charactersオブジェクトを取得するには、ちょっとややこしいのですが同じ名前のCharactersプロパティを利用します。
構文がこれです。
1 |
Charactersオブジェクト = Rangeオブジェクト.Charactersプロパティ(Start, Length) |
StartとLenghtは省略することができます。Startを省略した場合は1、Lengthを省略した場合はStart位置の文字を含めて以降の全ての文字、となります。そのため両方を省略した場合はStartは1で、Lengthは文字数になります。
A1セルに「1234567890abc」という13文字がある場合、であればStart=1、Lenght=13と両方を省略した場合は同じ、になるはずです。しかしそうなりません。
これがバグです。
バグ発生のサンプルコード
バグが発生するパターンは、「Charactersプロパティ(Start, Length)」の形式でコードを書いた場合です。
正常パターン:Range.Characters.Count の場合(Start, Lengthを省略した場合)
Charactersプロパティの開始と文字列長を省略しているため、Startは1、Lengthは1以降の全ての文字列長の6として処理されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Sub CharactersCountTest1() Dim c As Characters '// Charactersオブジェクト Dim iCount As Long '// 文字数 '// A1セルに123abcと入力 Range("A1").Value = "123abc" '// Charactersオブジェクトに格納(StartとLengthを省略) Set c = Range("A1").Characters '// 参照している文字数 iCount = c.Count Debug.Print iCount End Sub |
実行結果は「6」という文字数が返ります。
バグ発生パターン:Range.Characters(Start, Length).Count の場合(Start, Lengthがある場合)
行っている内容は上の内容と変わりません。9行目でCharactersプロパティに開始の1と長さの6を指定していますが、これは省略した場合と同じ値になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Sub CharactersCountTest2() Dim c As Characters '// Charactersオブジェクト Dim iCount As Long '// 文字数 '// A1セルに123abcと入力 Range("A1").Value = "123abc" '// 1文字目から6文字目の"123abc"をCharactersオブジェクトに格納 Set c = Range("A1").Characters(1, 6) '// 参照している文字数(6ではなく1が返される) iCount = c.Count Debug.Print "1回目:" & iCount '// バグってるのでTextの文字数を取る iCount = Len(c.Text) Debug.Print "2回目:" & iCount End Sub |
実行結果は以下のように出力されます。
1回目:1
2回目:6
バグ回避方法
上の2つ目のサンプルのように、Countプロパティでは文字数を取得できないことがあります。
そこで回避方法ですが、2つ目のサンプルの17行目のようにTextプロパティの値をLen関数で取得します。
こうすればCharactersプロパティのStartとLenghtがあるかどうかを気にせずに正しい文字数を取得することが可能です。