数値を表す文字列を数値型に変換する

 数値が数値型ではなくテキスト型のフィールドに記録されている場合があります。 
 それが例えば「\2,300」とか「5,000」(全角)といった形式であれば必要に応じて数値型のデータと同じように計算に用いることもできます。しかし、形式によってはそうもいかず困る場合があります。
 以下では、テキスト型のフィールドに記録されているさまざまな形式の文字列を、数値とみなされる形式に改め、実際に数値とみなされることを示すためにCDbl関数などにより数値型(正確には倍精度浮動小数点型など)に変換する例を見てみます。

数値型に直接変換できる例

f:id:accs2014:20180923002047p:plain:right:w400

 一見変わった形式でも、数値としてみなされる、つまりそのまま数値型に変換できる形式があります。
 右の例の「数値テキスト」列(テキスト型。以下同様)の値は、いずれも数値としてみなされる形式です。\やカンマが含まれていてもよいこと、全角でもよいこと、さらに全角半角混合でもよいことがポイントです。ちなみにマイナスと\はどちらが先でもよいです。
 これらの文字列はそのまま四則演算や関数による集計の対象とすることができますし、Sum関数などのSQL関数の集計対象とすることも可能です。


CDbl関数による変換

f:id:accs2014:20180923002043p:plain:right:w550

 数値型に変換できる証拠として、クエリでCDbl関数を用いて上記の文字列を数値型(倍精度浮動小数点型)に変換してみます。
 設ける列は次のとおりです。

CDbl変換後: CDbl([数値テキスト])


f:id:accs2014:20180923002040p:plain:right:w400

 データシートビューです。
 いずれも正しく変換されています。


CLng関数、Val関数による変換

f:id:accs2014:20180923002038p:plain:right:w600

 さて、上記の文字列を、CLng関数(長整数型に変換する)やVal関数(文字列中の一定部分を倍精度浮動小数点型に変換する)で変換するとどうなるでしょうか。
 クエリで次の2つの列を設けてみます。

CLng変換後: CLng([数値テキスト])
Val変換後: Val([数値テキスト])


f:id:accs2014:20180923002036p:plain:right:w400

 データシートビューです。
 いずれもエラーにはなりませんが、CLng関数では整数への丸め(偶数丸め)が行われます。
 また、Val関数ではカンマが現れるとその直前までしか変換されないため注意する必要があります。\についても同様ですが通常\は先頭につきますので結果的に0に変換されます。また、全角数字も0に変換されてしまいます。数値に変換、というとまずVal関数が思いつきますが、案外融通がききませんので注意してください。


f:id:accs2014:20180923002123p:plain:right:w450

 さて、Val関数が正しく効果的に機能するのは、このように数字(及びマイナス、小数点)からはじまって後に漢字や英字等が続く、という文字列の場合です。
 これらを先ほどのようにVal関数で変換すると…


f:id:accs2014:20180923002118p:plain:right:w400

 期待される結果となりました。


f:id:accs2014:20180923002116p:plain:right:w400

 繰り返しになりますが、一方でこのように\やカンマ、全角数字が含まれる文字列の場合は通常期待されるような結果とはなりません。注意してください。


「三〇九一二」といった漢数字の場合

f:id:accs2014:20180923002114p:plain:right:w400

 数字が漢数字である場合(億や万といった単位を含まず、単に数字が漢数字であるもの)です。


f:id:accs2014:20180923002222p:plain:right:w600

 これは地道にReplace関数を重ねて半角数字に置き換えたうえでCDbl関数により変換することとします。
 クエリに次のような列を設けます。



変換後: CDbl(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace([数値テキスト],"〇","0"),"一","1"),"二","2"),"三","3"),"四","4"),"五","5"),"六","6"),"七","7"),"八","8"),"九","9"))

f:id:accs2014:20180923002220p:plain:right:w400

 データシートビューです。
 なお、「三億五千十二万二千八百一」といったように億や万といった単位を含む表記の場合はちょっと困難ですので割愛します;-o-)


各種文字列から数字のみを抽出する場合

f:id:accs2014:20180923002218p:plain:right:w450

 数字の前後に漢字や英字等が並んでいて、そこから数字だけを取り出したいというケースです。さらに数字は全角の場合もあります。
 これだと普通にCDbl関数やCLng関数、Val関数などを用いてもうまくいきません。


f:id:accs2014:20180923002216p:plain:right:w600

 そこで1文字ずつ分解して数字(半角または全角)かどうか評価して数字以外を消し、最後にくっつけてCDbl関数で変換するという方法をとります。
 クエリに次のような列を設けます。



変換後: CDbl(Eval(Replace(Replace(Format([数値テキスト],Replace(String(Len([数値テキスト]),"&"),"&","{&}")),"{","Mid(Val(1 & StrConv('"),"}","',8)),2)&") & "''"))

f:id:accs2014:20180923002214p:plain:right:w450

 奇天烈な式でしたが、無事に変換できました;-o-)


f:id:accs2014:20180923002306p:plain:right:w450

 ただし、このやり方では文字と一緒に小数点も消えるため、小数点がある場合は正しくない出力結果となります。また、数値が2回以上現れる場合は、それらをそのまま文字列としてつなげたような数値が出力されます。
 さらに文字列が長い(57文字以上)とエラーになります;-o-)

 なお、この式については下記の記事とほぼ同じ内容となっています。若干補足説明もしていますので興味のある方は参照ください。
 (下記の記事ではCDbl関数による変換までせず、数字は文字列のまま)

www.accessdbstudy.net