質問するログイン新規登録

Q&A

3回答

335閲覧

Excelセル内のデータ型を設定する方法

u_zu

総合スコア53

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2025/11/02 15:00

0

0

実現したいこと

Excelのセルに(手動ではなく)数値や文字、どんな値を入れても、それを文字列で表現したい。

発生している問題・分からないこと

少し抽象的な質問なので自分もよくわからなのですが、教えてください。

エクセルのセルに入力される値(基本的には数値)を文字列扱いにしたい場合、

その1 Sub Test1() のようにすると、
このA1セルに代入された100は文字列のように左詰めで表示されるのですが、

Debug.Print TypeName(Range("A1").Value) としてみると、「Double」になります。


その2

Sub Test1() と同じように

cells.NumberFormatLocal = "@" と書式を文字列にしたあとに、

例えばRange("A1")に 100と手入力し、Enterキーを押すと、Range("A1")セルの左上に
緑の三角マークが表示され、

Debug.Print TypeName(Range("A1").Value)

としても「String」になります。

その3

その2で書いたEnterキーと同じ処理をVBA上で表現しようとして、

Sub Test2() のようにと書いてみたのですが、Range("A1")セルの左上に
緑の三角マークが表示されず、TypeName(Range("A1").Value) も「Double」のままでした。

質問1 
Excelは、その2で書いた、Enterキーを押して、初めてセル内のデータ型が確定する、のでしょうか?
また、その2の「手動でEnterキーを押した」処理をコードで表現する方法はありますか?
(Sub Test2内で A1セルとA2セルを選択することで手動Enterキー押下と同じことを表現できると思ったのですが。。。)

質問2 
根本的に「このようにやればよい!」というものがあったら教えてください。
できればコードで表現したいです。
基本的に  ①cells.NumberFormatLocal = "@"
②各セルに値をセット
③値をセットしたセルにEnterキーを押下 
ということが表現できれば可能かと思うのですが。。。

よろしくお願いします。

該当のソースコード

Sub Test1() ’その1のコード cells.NumberFormatLocal = "@" Range("A1").Value = 100 '(100は適当な値) End sub Sub Test2() Range("A1").NumberFormatLocal = "@" Range("A1").Value = 200 Range("A1").Select Range("A2").Select End sub

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

データ型が決まる、「法則」のようなものが分からない

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

エクセルのセルに入力される値(基本的には数値)を文字列扱いにしたい場合、

単純に下記でいいのでは?

Sub Test2() Range("A1").NumberFormatLocal = "@" '書式 文字列 Range("A1").Value = "100" '文字列を代入 Debug.Print TypeName(Range("A1").Value) 'String End Sub Sub Test3() Range("A1").NumberFormatLocal = "@" '書式 文字列 Range("A1").Value = Cstr(100) '文字列に変換して代入 Debug.Print TypeName(Range("A1").Value) 'String End Sub

投稿2025/11/03 03:09

hatena19

総合スコア34375

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

u_zu

2025/11/03 04:18

hatena19さん どうもありがとうございます。 Cstrで変換する、というのはチョット盲点でした。 今回の質問では分かりやすく、 Range("A1").Value = 100 '(100は適当な値) と100を例にしたのですが、この100の位置には 数値型が来るか、どんな型の値が来るのか特定できないのですが、 日付型でも、文字列でもCstrで変換すればいいのか。。。もしれないです。 また、今、思いついたのですが、 cells.NumberFormatLocal = "@" を設定しないSheet(例えばSheet1)のセルに 一旦すべての値を吐き出したあとに、 別Sheet(例えばSheet2)に cells.NumberFormatLocal = "@" を設定し、 Sub tttt() Dim ws1 As Worksheet Dim ws2 As Worksheet Set ws1 = Sheets(1) Set ws2 = Sheets(2) ws2.Cells.NumberFormatLocal = "@" Dim gyou As Integer Dim retsu As Integer For gyou = 1 To 10 For retsu = 1 To 10 ws2.Cells(gyou, retsu).Value = ws1.Cells(gyou, retsu).Text Next retsu Next gyou End Sub のような感じで処理するのもありかな。。。と思いました。
guest

0

VBA

1Sub Test2() 2Range("A1").NumberFormatLocal = "@" 3Range("A1").Value = 200 4Range("A1").Value = Range("A1").text 5End sub

これで大体よさそうに思うけど、大きい数字の時、入力状態⇒Enterで動作が違いました。
以下が動作が似てるようです。

VBA

1Sub Test2() 2Range("A1").NumberFormatLocal = "@" 3Range("A1").Value = 200 4Range("A1").Value = Range("A1").Formula 5End sub

どうでしょうか。
一応入力状態⇒Enterと同様な動きに見えるのですが
日付とか2020/3/2が3/2/2020になりますが、こんなのでいいんですかね・・・
動作は同じようですが。

データ型が決まる、「法則」のようなものが分からない

データ型は
Range("A1").Value = 200
と値をセットしたタイミングで決まるのではないでしょうか。
右側が数値だから数値になっちゃうってことで。

なぜIntegerじゃなくてDoubleになるのかはわかりませんが、そういうものなのでしょう。

なので文字列として設定するには、文字列でvalueに渡さないといけないのでしょう。

Range("A1").FormulaRange("A1").Textは文字列だからRange("A1").Valueに渡すときちんと文字列になると思います。

(追記:u_zuさんの2025/11/03 12:50のコメントに対し)
私の回答やEnterキーの入力でも同じなのですが
日付2023/3/2が3/2/2023となってしまいます。
hatenaさんの回答にありましたが
Cstrや型をチェックしてからのFormat関数を使っての文字列化してのセットの方が見た目は違和感はないと思います。

あと
>例えばRange("A1")に 100と手入力し、 ←ここで、データ型がDouble
>Enterキーを押すと、 ←ここで、データ型がStringに変わる

これは私の環境であれば誤りです。

>例えばRange("A1")に 100と手入力し、 ←ここで、データ型がDouble 
★ 私のOffice365ではこうはなりません。Enterを押下してカレントセルを変えたりフォーカスを外したりして入力モードから確定させないと値をセットしたことにはなりません。
入力状態のときにDoubleになるというのであれば、入力前の値がDoubleだったのではないですか?
入力が確定するまでは、入力前の値で処理されるはずですから。

>Enterキーを押すと、 ←ここで、データ型がStringに変わる
★手入力でEnterキーの場合、ここで初めて値がセットになります。

セルを選択した後、以下のコード(ちょっと乱暴な関数ですが)を実行して
そして値を入力してエンターを押下してみてください。

VBA

1Public Sub TypeCheck() 2 Dim tStr As String 3 Dim tStr2 As String 4 Dim tAddress As String 5 6 ActiveCell.NumberFormatLocal = "@" 7 tAddress = ActiveCell.Address 8 Do While True 9 tStr2 = TypeName(ActiveSheet.Range(tAddress).Value) 10 If tStr <> tStr2 Then 11 Debug.Print tStr2 12 tStr = tStr2 13 End If 14 DoEvents 15 Loop 16End Sub

私の環境だと
Empty
String
とログが出ます。
Doubleは出ません。
Enterを押下するまでは編集状態で値がセットされていないのでDoubleにはならないです。
またEnterを押下するだけでは型は変わりません。
編集状態(入力状態)にしてからEnterを押下して確定したタイミングでStringに変わります。

NumberFormatLocal = "@"していると手入力ではDoubleには一瞬たりともならないと思うので
Doubleに一旦なるというのは、入力前からDoubleの値がセットされていたか
何か思い違いをしているのでは。と思われます。

まぁ。環境の違いによる差異と言う可能性もあり得ますが…

投稿2025/11/02 18:56

編集2025/11/03 07:22
xail2222

総合スコア1534

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

u_zu

2025/11/03 03:50

xail2222さん ありがとうございます。なるほど、Textプロパティというのはありますね。 ただ、表示されたとおりに文字列を返すので、 >大きい数字の時、入力状態⇒Enterで動作が違いました。 というようなところは注意が必要ですね。セル幅を調整するとか。 >データ型は Range("A1").Value = 200 と値をセットしたタイミングで決まるのではないでしょうか。 というところは、私が最初の質問「その2」で書いたように、 ------------------------- cells.NumberFormatLocal = "@" と書式を文字列にしたあとに、 例えばRange("A1")に 100と手入力し、 ←ここで、データ型がDouble Enterキーを押すと、 ←ここで、データ型がStringに変わる ------------------------- となるので、値をセットしたタイミングとは異なるかもしれません。
u_zu

2025/11/03 08:00

xail2222さん 丁寧な解説ありがとうございます。 >例えばRange("A1")に 100と手入力し、 ←ここで、データ型がDouble >Enterキーを押すと、 ←ここで、データ型がStringに変わる 完全な私のミスでした。色々なパターンを弄っていて、少々混乱してしまっていたようです。 話はちょっとそれますが、よく会計ソフトなどからデータをCSVファイルに吐き出す処理がありますよね。 そのCSVファイルをエクセルで開くときのような処理を想定していて、このような質問をしました。 CSVファイルをエクセルで単純に(ダブルクリックなどで)開くと、型変換などが起こってしまって元のデータが違ってしまうので、最初から文字列でエクセルに転記して型変換などが起きないように。。。などと思っておりました。
guest

0

Excelは、その2で書いた、Enterキーを押して、初めてセル内のデータ型が確定する、のでしょうか?

「手動でEnterキーを押した」処理をコードで表現する方法はありますか?

  1. アクティブセルに対してユーザーが任意のテキスト(値または数式)を直接入力する。

  2. VBA のコードによって任意のセルに対して任意のデータ(数値/文字列/日時)を代入する。

これら 2 つは厳密には似て非なる操作です。必ずしも同じ代入結果になるとは限りません。

上記 1 の場合、ユーザーによって入力されたテキスト自体は編集モード中においてはただの文字列に過ぎず、セルの編集が確定するまでデータ型の区別や型変換のしようがありません。
よって、例示されたマクロのように数値リテラル( 100 )を代入するのではなく、文字列リテラル( "100" )を代入する操作に相当するものと解釈すべきでしょう。

一方、上記 2 の場合はリテラルや式、変数、関数などを用いて数値データ、文字列データ、日時データを明確に区別してコーディングすることが出来るわけですが、「代入するデータの型」と「代入後のセルのデータの型」は必ずしも一致しません。

また自動データ変換オプションが実装されたバージョンにおいて、上記 1 (手入力での編集)の挙動はそれぞれの環境でのオプション設定によって異なりますが、上記 2 (マクロによる値の代入)の挙動は(少なくとも現行のバージョンにおいては)このオプションの影響を受けません。

以下、上記 2 の操作に限った一般的な動作について列挙します。

代入するデータの型が Integer, Long, Single, Double のいずれかである場合

  • 代入時点におけるセルの表示形式が「日時また日付のみを表示する形式」( yyyy/mm/dd hh:mm:ss, yyyy/mm/dd など)であった場合、代入後のセルのデータ型は基本的には Date 型となる。

  • 代入時点におけるセルの表示形式が「時刻のみを表示する形式」( h:mm:ss など)である場合、代入後のセルのデータ型は Double 型となる。

  • 代入時点におけるセルの表示形式が「通貨を表示する形式」だった場合、代入後のセルのデータ型は Currency 型に変換される。

  • 代入時点におけるセルの表示形式が上記以外のものであった場合(「文字列」を含む)、代入後のセルのデータ型は原則的に Double 型となる( Integer, Long, Single のいずれかの型として格納されることはない)。

代入するデータの型が Currency 型である場合

  • 代入時点におけるセルの表示形式が「通貨を表示する形式」であった場合、代入後のセルのデータ型は Currency 型のままである。

  • 代入時点におけるセルの表示形式が「数値を表示する形式」であった場合、代入後のセルのデータ型は Double 型となる。

  • 代入時点におけるセルの表示形式が「日時または日付のみを表示する形式」であった場合、代入後のセルのデータ型は基本的に Date 型となる。

  • 代入時点におけるセルの表示形式が「時刻のみを表示する形式」である場合、代入後のセルの表示形式は「通貨」に変更され、代入後のセルのデータ型は Currency 型となる。

  • 代入時点におけるセルの表示形式が「文字列」( @ )であった場合、代入後のセルの表示形式は「通貨」に変更され、代入後のセルのデータ型は何故か String 型に変換される(特殊ケース)。

代入するデータの型が Date 型である場合

  • 代入時点におけるセルの表示形式が「日付/時刻を表示する形式」であった場合、代入後のセルのデータ型は基本的に Date 型となる。

  • 代入時点におけるセルの表示形式が「時刻のみを表示する形式」であり、かつ代入する値が時刻成分のみを持つ場合、代入後のセルのデータ型は Double 型となる。

  • 代入時点におけるセルの表示形式が「通貨を表示する形式」であり、かつ代入する値が日付成分と時刻成分の両方を含む場合、代入後のセルの表示形式は「日時を表示する形式」に変更され、代入後のセルのデータ型は Date 型となる。

  • 代入時点におけるセルの表示形式が「通貨を表示する形式」であり、かつ代入する値が日付成分のみを含む場合、代入後のセルの表示形式は「日付のみを表示する形式」に変更され、代入後のセルのデータ型は Date 型となる。

  • 代入時点におけるセルの表示形式が「通貨を表示する形式」であり、かつ代入する値が時刻成分のみを含む場合、代入後のセルの表示形式は「時刻のみを表示する形式」に変更され、代入後のセルのデータ型は Double 型となる。

  • 以上の動作は、代入する Date 型データの日付/時刻が Excel ワークシート上で扱うことの出来る日付範囲に含まれる場合のみ有効である。

  • 代入時点におけるセルの表示形式が「数値を表示する形式」であった場合、代入後のセルのデータ型は Double 型となる。

  • 代入時点におけるセルの表示形式が「文字列」( @ )であった場合、代入後のセルのデータ型は String 型となる。

代入するデータの型が String 型である場合

  • 代入時点におけるセルの表示形式が「文字列」( @ )であった場合、代入後のセルのデータ型は必ず String 型となる。

  • 代入時点におけるセルの表示形式が「数値を表示する形式」であり、かつ代入される文字列が「数値データまたは日時データに変換可能なパターン」であった場合、代入後のセルのデータ型は基本的に Double 型となる。

  • 代入時点におけるセルの表示形式が「日時または日付のみを表示する形式」であり、かつ代入される文字列が「数値データまたは日時データに変換可能なパターン」に該当する場合、代入後のセルのデータ型は基本的に Date 型となる。

  • 代入時点におけるセルの表示形式が「時刻のみを表示する形式」であり、かつ代入される文字列が「数値データまたは日時データに変換可能なパターン」に該当する場合、代入後のセルのデータ型は基本的に Double 型となる。

  • 代入時点におけるセルの表示形式が「時刻のみを表示する形式」であり、かつ代入される文字列が「数値データに変換可能なパターン」に該当し、かつその文字列に通貨記号(通常は "$" )が含まれている場合、代入後のセルの表示形式は「通貨」に変更され、代入後のセルのデータ型は Currency 型となる(特殊ケース)。

  • 代入時点におけるセルの表示形式が「文字列」( @ )ではなく、かつ代入される文字列が「 Excel の数式として解釈し、計算を実行することが可能な文字列」であった場合は、暗黙的にそのセルの Formula プロパティの設定が行われ、その数式の計算結果が Value プロパティから取得可能となる。代入後のセルの表示形式とデータ型は、代入前の表示形式と数式の戻り値によって異なる。

代入するデータの型が Boolean 型である場合

  • 代入後のセルのデータ型は全て Boolean 型となる。代入前の表示形式の影響を受けず、また代入後に表示形式を変更しない。

代入時点におけるセルの表示形式が「標準」であった場合

  • 代入するデータが「 Excel の数式として解釈し、計算を実行することが可能な文字列」であった場合、暗黙的に Formula プロパティの設定が行われ、代入後のセルの表示形式はその数式の戻り値のデータ型や値に沿った形式に変換される(本来は Value プロパティではなく Formula プロパティを直接設定すべきである。また、代入する式の構文に問題がある場合は実行時エラーが発生する)。

  • 代入するデータが数値データまたは「数値データに変換可能な文字列( "5E04" のような指数形式なども含む)」であった場合、代入後のセルの表示形式は必要に応じてその文字列パターンに沿った形式に変更され(必要がなければ「標準」のままとし)、代入後のセルのデータ型は基本的に Double 型となる。また、その文字列に通貨記号が含まれていることによって Currency 型となる場合もある。

  • 代入するデータが日時データまたは「日時データに変換可能な文字列」であった場合、代入後のセルの表示形式は基本的にその文字列パターンに沿った「日時/日付/時刻を表示する形式」に変換され、代入後のセルのデータ型は Date 型(日時または日付)と Double 型(時刻)のいずれかとなる。

  • 代入するデータが Currency 型である場合、代入後のセルの表示形式は「通貨」に変更され、代入後のセルのデータ型は Currency 型のままとなる。

  • 代入するデータが上記のいずれのケースにも該当しない文字列である( String 以外の型への変換が不可能である)場合、代入後のセルの表示形式は「標準」のまま、代入後のセルのデータ型は String 型となる。

検証用マクロ

vba

1Sub Test1() 2 3 Dim wsNew As Excel.Worksheet 4 5 Set wsNew = Workbooks.Add.Worksheets(1) 6 wsNew.Name = "代入前後の比較結果" 7 8 Dim rngTargetRow As Excel.Range 9 10 Set rngTargetRow = wsNew.Rows(1).Resize(1, 8) 11 12 With rngTargetRow 13 .Columns(1).Value = "代入するデータ" 14 .Columns(2).Value = "代入するデータの型" 15 .Columns(3).Value = "代入先のセル" 16 .Columns(4).Value = "代入前のセルの NumberFormat" 17 .Columns(5).Value = "代入前のセルの NumberFormatLocal" 18 .Columns(6).Value = "代入後のセルの NumberFormat" 19 .Columns(7).Value = "代入後のセルの NumberFormatLocal" 20 .Columns(8).Value = "代入後のセルのデータ型" 21 .Borders(xlBottom).LineStyle = xlDouble 22 End With 23 24 Dim aryValues As Variant 25 26 aryValues = Array(#11/4/2025 12:00:00 PM#, #11/4/2025#, #12:00:00 PM#, "2025/11/04 ", "1-1", "12:00", 0, 0.5, 100, "100", 45965, "45965", CSng(1000.5), CDbl(1000.5), CCur(0), CCur(0.5), CCur(1000), CCur(1000.5), CDec(1000.5), "1000.5", "01234", "5E04", "$1000", "$1,000", "ABC", True, "=NOW()", "=TODAY()", "=TIME(HOUR(NOW()),MINUTE(NOW()),SECOND(NOW()))", "=ROW()") 27 28 Dim aryFormats As Variant 29 30 aryFormats = Array("yyyy/m/d", "h:mm:ss", "yyyy/mm/dd hh:mm:ss", "0", "#,##0.00", "$#,##0.00_);($#,##0.00)", "0.E+00", "@", "General") 31 32 Dim varValue As Variant 33 Dim varFormat As Variant 34 35 For Each varValue In aryValues 36 For Each varFormat In aryFormats 37 Set rngTargetRow = rngTargetRow.Offset(1, 0) 38 AssignValueToCell rngTargetRow, varValue, varFormat 39 Next 40 rngTargetRow.Borders(xlBottom).LineStyle = xlContinuous 41 Next 42 43 wsNew.Columns.EntireColumn.AutoFit 44 wsNew.Parent.Activate 45 ActiveWindow.SplitRow = 1 46 ActiveWindow.FreezePanes = True 47 48 Set wsNew = Nothing 49 50End Sub 51 52Private Sub AssignValueToCell(TargetRange As Excel.Range, Value As Variant, NumberFormat As Variant) 53 54 Dim rngTargetCell As Excel.Range 55 56 With TargetRange 57 58 .NumberFormat = "@" 59 .Columns(3).NumberFormat = NumberFormat 60 61 .Columns(1).Value = CStr(Value) 62 .Columns(2).Value = TypeName(Value) 63 .Columns(4).Value = .Columns(3).NumberFormat 64 .Columns(5).Value = .Columns(3).NumberFormatLocal 65 66 .Columns(3).Value = Value 67 Application.Calculate 68 .Columns(6).Value = .Columns(3).NumberFormat 69 .Columns(7).Value = .Columns(3).NumberFormatLocal 70 .Columns(8).Value = TypeName(.Columns(3).Value) 71 72 End With 73 74End Sub

今回の場合はあまり関係がないでしょうが、代入時点でのセルの表示形式を「通貨を表示する形式」や「時刻のみを表示する形式」にした場合はやや結果が読みづらい挙動となります。

投稿2025/11/04 03:46

編集2025/11/04 11:13
sk.exe

総合スコア1114

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

u_zu

2025/11/04 11:38

sk.exeさん  濃密なご説明ありがとうございます。 これから熟読します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.29%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問