実現したいこと
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ページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答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
総合スコア34375
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").FormulaとRange("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総合スコア1534
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
Excelは、その2で書いた、Enterキーを押して、初めてセル内のデータ型が確定する、のでしょうか?
「手動でEnterキーを押した」処理をコードで表現する方法はありますか?
-
アクティブセルに対してユーザーが任意のテキスト(値または数式)を直接入力する。
-
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総合スコア1114
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2025/11/03 04:18