Val関数はデータ型不一致の解決策。文字列型から数値型へ

VBAValeyecatch

エクセルVBAのデータ型関数のVal関数の使い方についてです。
「値を文字列型から数値型へ変換する」という機能があります。
データ型が不一致の場合、プログラムエラーでコード停止が発生することが良くあります。

こんにちは、じゅんぱ店長(@junpa33)です。

今回のテーマは、値のデータ型を「文字列型から数値型」へ変換してくれるVal関数についてです。

どういった時に使うかというとですが、

エクセルにおいての四則計算などでは、エクセルが融通を効かして

数値とみなせる文字列は『それは数値』として自動的に四則計算をしてくれます。

なので、いらない(気にしない)ことも多いかもしれません。

けれども・・・

・・・この関数を知っておかないと不都合な時が結構あります。

Val関数はデータ型不一致の解決策になる

vbavalp006

Val関数は、文字列を数値に変換する関数です。

データ処理時に、文字列化した数字を演算してしまうとエラーストップしてしまいます。

また、同じ数字であっても数値型と文字列型では、データのソート、並び替えや抽出の処理の時には

想定している結果が得られないことが多くあります。

Val関数とはそういった困ったことが無いように、

データ型を変換することによって、問題を起こさないための関数です。

文字列型化した数字と数値型の数字は非常に見極めが難しいです。

数値として演算するデータは、流れの中で文字列に変換利用することがあっても、

基本は数値型として常に元のデータ型に戻しておくことをおススメします。

Val関数の構文

Val関数の構文

  • Val(文字列)

指定した文字列に含まれる数値をInteger型やDouble型など、変換する文字列によって適切に変換します。

文字列の左端の文字から右へ順に数値に変換していきます。

数値化の対象は数字と、記号の中で「半角スペース」「タブ」「.(ドット)」になります。

それ以外の文字・記号が含まれていた時は、

左から順にその文字・記号が出てきた時点でストップし、そこまでの数値として変換、終了します。

変換対象文字列 →戻り値
13001300
¥13000 最初の「¥」で変換停止
1,300円1 「,」カンマは変換しない
1300円1300
りんご0 変換できない場合は「0」を返す

Val関数の使い方とデータ型変換に関連したサンプルコード

vbavalp007

「値を文字列型から数値型へ変換する」ことに関連しての例題を説明します。

例題の事前設定

vbaval002a

元のデータベースとして「商品IDと商品名」があります。

「商品ID」はよくある「文字列型の数字データ」になっています。「商品名」はもちろん文字列型のデータです。

商品IDから検索して商品名を抽出するというプログラムを考えます。

検索商品IDに入力するセルの表示形式はデフォルトの「標準」にしています。

「データベースの商品IDの文字列型」のデータと「検索商品IDの数値型」のデータを

正常に参照することが出来るかというところがポイントになります。

Val関数テスト

テスト1

任意の商品IDを指定してそこから下へ任意個数の商品名を抽出します。
「データベースの商品IDの文字列型」と「検索商品IDの数値型」を
データ型変換せずにそのまま対比参照します。

テスト2

Match関数を使って検索商品IDから商品名を抽出します。
一番素直な考え方(コードの組み立て)で、
検索商品ID側のデータ形式をデータベース側のデータ型に合わせて対比参照します。

テスト3

Match関数を使って検索商品IDから商品名を抽出します。
データベース側のデータ形式を検索商品ID側のデータ形式に変更して対比参照します。

Val関数のサンプルコード

テスト1

「データベースの商品IDの文字列型」と「検索商品IDの数値型」をそのままで変換せずに使います。

設定した変数
  • 検索商品ID・・・SeleIDa
  • リストアップ個数・・・EC
  • データベースにSeleIDが掲載されている行NO・・・s
  • ループ回数を表す変数・・・t
If Range("A" & s).Value = SeleIDa Then

はデータ型が違う者同士の参照となるコードになっています。

VBA
Option Explicit

Sub Val関数テスト1()
    Dim SeleIDa As Long
    Dim EC As Long
    Dim s As Long, t As Long
        SeleIDa = Range("D3").Value
        EC = Range("E3").Value
            For s = 5 To 22
                If Range("A" & s).Value = SeleIDa Then
                    Exit For
                End If
            Next s
            For t = 0 To EC - 1
                Range("D" & 6 + t) = Range("A" & s + t)
                Range("E" & 6 + t) = Range("B" & s + t)
            Next t
End Sub

実行結果

今回の場合は、結果、エクセル側で自動的に数字の文字列を数値と判断して、エラーストップを起こさずに実行完了してくれました。

たまたま的で、ノーマルなコード記述方法ではないと言えます。

vbaval003a

参考記事

  • For ~ Next ・・・指定回数だけ同じ作業を繰り返す
fornextirekoeyecatch For~Nextのループと入れ子構造をVBA最速理解
テスト2

このテストでは、Val関数を使わずに行います。

「データベースの商品IDの文字列型」に「検索商品IDの数値型」を合わす。

「検索商品IDの数値型」を文字列型に変換するという方法をとります。

『調べる側を元データの型に合わせる。』という一番ノーマルな方法です。

設定した変数
  • 検索商品ID・・・SeleIDb
  • 検索商品のデータベース掲載位置の行NO(相対位置)・・・MR
  • 検索商品IDの文字列化したデータ・・・StrID
  • ループ回数を表す変数・・・q

商品ID番号は、文字列化して桁数を統一していることが多く、今回は7桁に統一しています。
数値データを文字列化するときには、桁数の調整に注意します。

StrID = "0" & CStr(SeleIDb)
VBA
Sub Val関数テスト2()
    Dim SeleIDb As Long
    Dim MR As Long
    Dim StrID As String
    Dim q As Long, r As Long
        For q = 0 To 4
            SeleIDb = Range("D" & 16 + q).Value
            StrID = CStr(SeleIDb)
                If Len(StrID) = 6 Then
                    StrID = "0" & CStr(SeleIDb)
                End If
                On Error Resume Next
                MR = WorksheetFunction.Match(StrID, Range("A5:A22"), 0)
                Range("E" & 16 + q) = Range("B" & MR + 4)
        Next q
End Sub

実行結果

調べる側のデータ型をデータベースの方に合わせて変換し、問題なく商品名を抽出することが出来ました。

数値型を文字列型に変換するCStr関数を利用しました。

Match関数を利用する場合は、セットのコードとして、

On Error Resume Next

というエラー回避のコードも記述しておきます。

vbaval004_1a

参考記事

  • CStr関数・・・「数値型」を「文字列型」に変換する
vbastrcstreyecatch Str関数とCStr関数 データ型変換の知るべき違いと使い方
  • Len関数・・・対象の文字列の文字数を調べる
vbaleneyecatch Len関数・LenB関数で文字列の文字数を調べる
  • Match関数・・・データを検索しその存在位置の行または列番号を返す。
vbamatcheyecatch001 VBAで使うMatch関数 活用度アップでテッパン関数に!
テスト3

Val関数を使い数値型データに変換して、「データベースの商品ID」と「検索商品ID」を比較します。

実務的には大量のデータベースがある場合にはあまり適していません。

設定した変数
  • 検索商品ID・・・SeleIDc
  • 検索商品のデータベース掲載位置の行NO(相対位置)・・・MR
  • ループ回数を表す変数・・・m、n

元のデータベースを数値型に変換したデータをG列に記述していきます。

「検索商品ID」はG列に記述されたデータと比較参照することになります。

Range("G" & m) = Val(Range("A" & m))
VBA
Sub Val関数テスト3()
    Dim SeleIDc As Long
    Dim MR As Long
    Dim StrID As String
    Dim m As Long, n As Long
'元のデータベースを数値型に変換する
'数値型に変換したデータを新たな列に並べる
        For m = 5 To 22
            Range("G" & m) = val(Range("A" & m))
        Next m
        Range("G4") = "商品ID(数値)"
        For n = 0 To 4
            SeleIDc = Range("H" & 16 + n).Value
'Match関数でデータを参照する
            On Error Resume Next
            MR = WorksheetFunction.Match(SeleIDc, Range("G5:G22"), 0)
            Range("I" & 16 + n) = Range("B" & MR + 4)
        Next n
End Sub

実行結果

Val関数が数値変換できずにエラーを起こした時の戻り値は、

エラーコードではなく「0」を返すことになります。

もしエラーコードを返すのであれば、次のコード進行でエラーストップになりますが、

「0」を返しますので、次のコード進行でエラーストップを回避することが出来ます。

条件分岐で、「0」や「桁数」をチェックしていれば、「処理ミス」弾き出すことが出来ます。

vbaval005_1a

Val関数の使い方のまとめ

vbavalp008

エクセルVBAコードの進行の中で、データ同士を比較参照させるという流れは多くあります。

その中で発生するエラーの少なくない部分で「データ型の不一致によるエラー」があります。

このようなエラーに陥りやすいケースで、ほかにも、インプットボックスからデータ入力する場合もよくあります。

数値型を文字列型に変換するStr関数やCStr関数があり、

文字列型を数値型に変換するものにVai関数があります。

この2種類はエラー回復のための必須の関数といっても言い過ぎではありません。

このVal関数以外にも同じような働きをするValue関数、ClLng関数、CDbl関数などがあります。

いずれも、「ある種の文字列」では数値変換時に「エラーコード(メッセージ)」を吐き出します。

つまり、VBAコードを停止させてしまいます。

Val関数では、数値変換不能時には「0」を吐き出しますので、

「0」を監視していれば、条件式でエラー回避することが出来ます。

また、数字の間に数値変換不可の文字が混ざっていても、

「InStr関数」や「Replace関数」などで文字ゴミを取り除くこともできます。

このような理由で、オールラウンダーのVal関数を知っていれば大丈夫かと思います。

参考記事

エクセルVBAを独習するのに参考書は欠かせません。 参考書選びは自分に合った「相棒」にできるものを選んでいきたいです。

vbastudyeyecatch2 エクセルVBAの独習でおすすめ参考書を7冊選ぶ。良書との出会いは大切です

今回の記事はここまでです。   最後までご覧いただき有難うございました。

エクセルVBA最速理解で必要な知識を集めよう!

エクセルVBA業務ツールで日常の業務改善を行いましょう。

VBAコードの記述記事においては、その記述には細心の注意をしたつもりですが、掲載のVBAコードは動作を保証するものではりません。 あくまでVBAの情報の一例として掲載しています。 掲載のVBAコードのご使用は、自己責任でご判断ください。 万一データ破損等の損害が発生しても当方では責任は負いません。

アンケートでポイ活しよう!!

アンケートに答えれば答えるほど ”使える” ポイントがたまります。

NTTコム サーチ

af_banner01

Dstyle web

dstyleweb_logo
dstyle_320x50-min