セルの横幅に収まらない数値は「###」のように表示されます。
ちなみに、「#」は"シャープ記号"ではありません。
シャープは「♯」です。五線譜と見間違わないように横線が傾いています。
セルに表示されるのは「#」のように縦線が傾いている"ナンバー記号"です。
まぁ、そんなトリビアはともかく「###」表示には、多くのユーザーが苦しめられた経験を持っているはずです。
ここはひとつ、「###」表示されているセルを見つけるマクロを作ってみましょう。
まず、アクティブセルに適当な数値を入力して、列幅を狭くします。
数値が表示しきれないほどの列幅になると、アクティブセルは「###」のように表示されるはずです。
この状態で、アクティブセルのValueプロパティを調べてみましょう。
Sub Sample1()
MsgBox ActiveCell.Value
End Sub
RangeオブジェクトのValueプロパティは、セルに入力されている値を返します。
「###」は値ではなく、表示されているだけですから、Valueプロパティでは判定できません。
もちろん、表示形式を表すNumberFormatプロパティや、数式を表すFormulaプロパティを使っても「###」かどうかを調べることはできません。
「###」と表示されるのは、セルに入力した数値の桁数が、セルの横幅よりも小さいときですから、数値の桁数とフォントの幅から数値全体の横幅を計算してさらに列の横幅と比較して小さかったら・・・などと難しく考える必要はありません。
Textプロパティを使えばいいんです。
Sub Sample2()
MsgBox ActiveCell.Text
End Sub
Textプロパティは、セルに表示されている文字列をそのまま返します。
たとえば、セルに「1234」と入力して「#,##0円」の表示形式を設定した場合、Valueプロパティは「1234」を返しますが、Textプロパティはセルに表示されている「1,234円」を返します。なお、Textプロパティは読み取り専用です。
Textプロパティを使って、セルに表示されている文字列の左1文字が「#」かどうかを判定すればいいのですが、「ちょっと待てよ、セルに"###"と入力されていたら、区別がつかないじゃないか」という疑問を持たれた方もいることでしょう。
安心してください。それも簡単に判別できます。
先に解説したとおり、列幅不足が原因の「###」は、実際にはセルに数値が入力されています。
ここでは、どんな数値かは問題ではありません。
実際には「###」というデータが入力されているのではないのですから、ValueプロパティとTextプロパティが異なっているはずです。
Sub Sample3()
With ActiveCell
If .Value <> .Text Then
If Left(.Text, 1) = "#" Then
MsgBox "セルの横幅が足りません"
End If
End If
End With
End Sub
しかし、これで完璧ではありません。
「#NAME?」や「#DIV/0!」などの数式エラーも、セル内のデータと表示が異なり、かつ左1文字が"#"で始まっています。
こうした数式エラーの場合は、IsError関数がTrueを返しますので、その判定も追加しましょう。
Sub Sample4()
With ActiveCell
If IsError(.Value) Then
MsgBox "数式エラーです"
Else
If .Value <> .Text And Left(.Text, 1) = "#" Then
MsgBox "セルの横幅が足りません"
End If
End If
End With
End Sub
数式エラーが発生しているセルのValueプロパティを「Value <> Text」のように判定してはいけません。
数式エラーセルのValueプロパティは、セル内のデータではなくエラー値を返します。
エラー値は正常な数値や文字列ではありませんから、Textプロパティと比較しようとすると、マクロが実行時エラーを起こします。
さて、Sample4の判定を利用して、列幅不足によって「###」のように表示されているセルを探してみましょう。
せっかくですから、見つかったら列幅の自動調整を実行してセル内の数値がすべて表示されるようにしてみます。
任意のセル範囲を選択した状態で、下記のマクロを実行してください。
Sub Sample5()
Dim c As Range
If TypeName(Selection) <> "Range" Then
MsgBox "セル範囲を選択してから実行してください"
Exit Sub
End If
For Each c In Selection
If Not IsError(c.Value) Then
If c.Value <> c.Text And Left(c.Text, 1) = "#" Then
Debug.Print c.Address(False, False) & "の列幅を自動調整します"
c.Columns.AutoFit
End If
End If
Next c
End Sub