- ベストアンサー
VBA Evaluate関数 型が一致しません
- VBAのEvaluateで数式を実行するとエラー「型が一致しません」となる問題に対しての質問です。
- 参考にした類似の質問を検索しても解決できなかったため、質問させていただいています。
- 具体的なコードとしては、セルの値に基づいて条件分岐する処理があり、その中でEvaluate関数が使用されています。しかし、該当の行でエラーが発生しています。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 .Evaluateメソッドの練習でしょうか? .Evaluateメソッドを使う必要も必然性もないですから、 コードの提示だけでは実際に何をしたいのか判断付きませんけれど、 ご提示のコードを(正しくやりたいことを表現できているものとして)素直に読んで 修正を加えるとするば、以下のようになります。 ' ' /// Sub Re8383252() Dim 数式雛型 As String, 数式 As String Dim y As Long 数式雛型 = "A1>0" y = 1 数式 = Replace(数式雛型, "1", y) With Sheets("Sheet1") If .Evaluate(数式) Then y = 2 End If End With End Sub ' ' /// ご提示のコード内の変数の値等を確認してみると、 aa ⇒ ".Cells(y, 1) > 0" bb ⇒ ".Cells(" bb ⇒ ", 1) > 0" bb & y & cc ⇒ ".Cells(1, 1) > 0" (値はすべて 文字列値 ↑) のようになっています。 Evaluate(bb & y & cc) は、 Evaluate(".Cells(1, 1) > 0") を実行していることになり、 Excel側で".Cells(1, 1) > 0"を評価した結果として 「エラー 入力した数式は正しくありません」 が返り、 VBA側では、If文にエラー値を渡すことになるので 「実行時エラー '13' 型が一致しません」 という結果になります。 そもそも.Evaluateメソッドは、文字列式を渡して、 Excelに評価(計算)させる為のメソッドですから、 If Evaluate("A1>0") Then のようにExcel数式を引数に渡してこそ成立しますが、 "Cells"という関数も名前もExcelにはありませんから、必然エラーになります。 ご提示のコードでおかしな点を指摘しておきます。 > Dim aa, bb, cc As String 3つの変数の内、文字列型で宣言されているのは、cc、だけです。 Dim aa As String, bb As String, cc As String と書くのが意図にそった正しい書き方なのではないでしょうか? > Dim y As Byte 行位置を扱う変数には、Long 型を使うのが正解です。 Byte型は本来、バイナリデータの配列を格納する為に用意されているもので、 通常は、数値を格納することはない(間違い)、と覚えてください。 今から20年も前ならば、少しでもメモリを節約する目的で、 無理矢理Byte型を使うような悪いお手本も見かけましたが、 今日的には、如何なる目的であろうとも間違いは間違いです。 > With Sheets("Sheet1") ・・・ > End With Withフレーズを使うのは、 Sheets("Sheet1").Cells(1, 1).Value = 10 Sheets("Sheet1").Cells(1, 2).Value = 20 のような例で、Sheets("Sheet1")への参照を繰り返すのは無駄が多いので、 With Sheets("Sheet1") .Cells(1, 1).Value = 10 .Cells(1, 2).Value = 20 End With のようにオブジェクトへのアクセスを一つにまとめる意味です。 Withフレーズを書いているのに、一度も使っていないのでは意味がありませんし、 読み手は困惑してしまいます。 こちらで提示したコードでは、.Evaluate のように、 Sheets("Sheet1")への参照を一度だけ活用していますが、 そのままなら、わざわざWithブロックを使う必要はありません。 > aa = ".Cells(y, 1) > 0" > bb = Left(aa, InStr(aa, "y") - 1) > cc = Mid(aa, InStr(aa, "y") + 1) > If Evaluate(bb & y & cc) Then 元の数式としてのaaは間違いですが、 それ以外の処理のしかたは間違っていません。 ただ、Replace関数を使って数式の一部(行位置)を置換する方が簡単です。 > .Cells(1, 1)には10が入力されています。 具体的なシートの状況を説明する時は、 「数値 10 」なのか、「文字列値 "10" 」なのか、明示的に書き分けるのがベターです。 「数値 10 」のような書き方ならば、見やすく全角で書いたものとして伝わりますが、 「10」のようにただ全角で書くのは誤解の元です。 VBAを扱うのならば、データ型には注意しましょう。 やりたいことは何となく想像は付くのですが、 何故.Evaluateメソッドなのか、把握できていませんので、 そちらの実際にやりたいことに、擦寄るような回答は書きません。 ご質問文に書かれたお尋ねに対しては、十分にお応え出来たものと思っています。 そちらで尚も不足が残るようでしたらば、スレッドを改め、質問を再構築してください。 以上です。
その他の回答 (1)
- mt2008
- ベストアンサー率52% (885/1701)
Evaluateメソッドでのセル参照は、A1の様な形式ですRangeやCellsは使えません。 コードを以下の様に変えてみて下さい。 aa = ".Cells(y, 1) > 0" ↓ aa = "Ay > 0"
お礼
ご教示ありがとうございました。 Evaluateメソッドでのセル参照は、A1の様な形式でRangeやCellsは使えないこと、肝に銘じておきます。
お礼
ご教示頂いたコードで出来ました! EvaluateがそもそもExcel関数である為、Excelの数式を与えないといけないことやReplaceの方が簡潔であることに加え、コードの書き方に至るまで懇切丁寧に説明して頂き誠にありがとうございました。 Webで質問するのは初めてでしたが、して良かったです。 自分のコードを再度見直したいと思います。