VBA Evaluate関数 型が一致しません

このQ&Aのポイント
  • VBAのEvaluateで数式を実行するとエラー「型が一致しません」となる問題に対しての質問です。
  • 参考にした類似の質問を検索しても解決できなかったため、質問させていただいています。
  • 具体的なコードとしては、セルの値に基づいて条件分岐する処理があり、その中でEvaluate関数が使用されています。しかし、該当の行でエラーが発生しています。
回答を見る
  • ベストアンサー

VBA Evaluate関数 型が一致しません

Excel2003 VBAのEvaluateで以下の数式を実行すると エラー「型が一致しません」となってしまいます。 類似の質問を検索していろいろ参考にしてみたのですが 解決できなかったので質問させてください。 Sub test() Dim aa, bb, cc As String Dim y As Byte y = 1 With Sheets("Sheet1") 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 ←ここでエラーになります。 y = 2 End If End With End Sub .Cells(1, 1)には10が入力されています。 宜しくお願い致します。

  • kuzan
  • お礼率100% (24/24)

質問者が選んだベストアンサー

  • ベストアンサー
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.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メソッドなのか、把握できていませんので、 そちらの実際にやりたいことに、擦寄るような回答は書きません。 ご質問文に書かれたお尋ねに対しては、十分にお応え出来たものと思っています。 そちらで尚も不足が残るようでしたらば、スレッドを改め、質問を再構築してください。 以上です。

kuzan
質問者

お礼

ご教示頂いたコードで出来ました! EvaluateがそもそもExcel関数である為、Excelの数式を与えないといけないことやReplaceの方が簡潔であることに加え、コードの書き方に至るまで懇切丁寧に説明して頂き誠にありがとうございました。 Webで質問するのは初めてでしたが、して良かったです。 自分のコードを再度見直したいと思います。

その他の回答 (1)

  • mt2008
  • ベストアンサー率52% (885/1701)
回答No.1

Evaluateメソッドでのセル参照は、A1の様な形式ですRangeやCellsは使えません。 コードを以下の様に変えてみて下さい。 aa = ".Cells(y, 1) > 0" ↓ aa = "Ay > 0"

kuzan
質問者

お礼

ご教示ありがとうございました。 Evaluateメソッドでのセル参照は、A1の様な形式でRangeやCellsは使えないこと、肝に銘じておきます。

関連するQ&A

  • 型が一致しません

    下記はセルが0の時、行全体を表示しないにするようにするVBAですが、型が一致しませんとエラーになります、どこを直せばいいのですか。 Dim I As Integer Sub Macro4() For I = 4 To 76 If Cells(I, 8) = 0 Then Rows("I:I").Select Selection.EntireRow.Hidden = True End If Next I End Sub

  • VBA   Evaluateはアクティブセル向け?

    度々、お世話になります Evaluateなのですが 対象シートを、最前面に 出して、おかないと 駄目 とは、 聞いた事が、ない の、ですが 出して、おかないと ダメ なのですか? 下記コードは 以前、頂いたものに 加筆した、もの ですが 動かして、みると なんか、変です 一定条件下で ☆印の、所の ストップに、引っかかります 条件とは visibleを、FALSに すると 当然の、如く ダメだし それどころか、アクティブに しておかないと どうやら 正しく、計算しなかった のです また、何か 私、しでかしている で、しょうか? お教えください               記 Option Explicit Option Base 0 Dim Ch As Long, s1 As Long, s2 As Long, Data(100, 100) As Long, Ws As Worksheet Dim dummy, i As Long, j As Long, t(8) As Long, 項試験回数 As Long Sub testMain() ' 簡易テスト Dim 現状保存 As Worksheet, シート名 As String  Let シート名 = ActiveSheet.Name Application.ScreenUpdating = False  Set Ws = Worksheets.Add()  Worksheets(シート名).Copy after:=Worksheets(Worksheets.Count)  Set 現状保存 = ActiveSheet  Worksheets(シート名).Select  現状保存.Visible = False '  Ws.Visible = False     ’此れを、戻すと 以ての外、です    Ws.Select           ’此れを、外すと ダメです Application.ScreenUpdating = True Application.Calculation = xlCalculationManual  Call ダミーデータ作成  Call 項試験回数設定 For j = 1 To 100  Call ダミーデータ作成  t(0) = Timer  Call AWF  t(1) = Timer  t(1) = t(1) - t(0)  t(5) = t(5) + t(1)  t(0) = Timer  Call Eva  t(2) = Timer  t(2) = t(2) - t(0)  t(6) = t(6) + t(2)  t(0) = Timer  Call RuC  t(3) = Timer  t(3) = t(3) - t(0)  t(7) = t(7) + t(3)    t(0) = Timer  Call RuV  t(4) = Timer  t(4) = t(4) - t(0)  t(8) = t(8) + t(4) Next Application.Calculation = xlCalculationAutomatic Debug.Print "Worksheet..Minメソッド", Format(1, "0000.000"), "/", Format(t(5), "###,##0.###") Debug.Print "Evaluateメソッド  ", Format(t(6) / t(5), "0000.000"), "/", Format(t(6), "###,##0.###") Debug.Print "Loop Range  ", Format(t(7) / t(5), "0000.000"), "/", Format(t(7), "###,##0.###") Debug.Print "Loop Valiant  ", Format(t(8) / t(5), "0000.000"), "/", Format(t(8), "###,##0.###") With 現状保存 .Range(.Cells(1, 1), .Cells(1, 1).SpecialCells(xlLastCell)).Copy Worksheets(シート名).Cells(1, 1) End With Application.DisplayAlerts = False 現状保存.Delete Ws.Delete Application.DisplayAlerts = True End Sub Sub ダミーデータ作成()  With Ws.Range("a1:cv100")   .Formula = "=RANDBETWEEN(1,10000)"   .Calculate   .Value = .Value  End With  Let Ws.Cells(1, 101).Formula = "=MIN(" & Ws.Name & "!" & Ws.Range("a1:cv100").Address & ")"  Ws.Cells(1, 101).Calculate  For s2 = 1 To 100   For s1 = 1 To 100    Data(s1, s2) = Ws.Cells(s1, s2).Value   Next s1  Next s2  Let Data(0, 0) = Ws.Cells(1, 101).Value End Sub Sub 項試験回数設定()  Let t(0) = Timer  Let Ch = 0  Do   Call testW   Ch = Ch + 1   Let t(1) = Timer - t(0)  Loop While t(1) < 1  項試験回数 = Ch    Let t(0) = Timer  Let Ch = 0  Do   Call testE   Ch = Ch + 1   Let t(1) = Timer - t(0)  Loop While t(1) < 1  If 項試験回数 < Ch Then Let 項試験回数 = Ch    Let t(0) = Timer  Let Ch = 0  Do   Call testC   Ch = Ch + 1   Let t(1) = Timer - t(0)  Loop While t(1) < 1  If 項試験回数 < Ch Then Let 項試験回数 = Ch    Let t(0) = Timer  Let Ch = 0  Do   Call testV   Ch = Ch + 1   Let t(1) = Timer - t(0)  Loop While t(1) < 1  If 項試験回数 < Ch Then Let 項試験回数 = Ch    Let 項試験回数 = Application.WorksheetFunction.Ceiling(項試験回数 * 1.05, 1) End Sub Sub RuV()  For i = 1 To 項試験回数   Call testC  Next i End Sub Sub RuC()  For i = 1 To 項試験回数   Call testV  Next i End Sub Sub Eva()  For i = 1 To 項試験回数   Call testW  Next i End Sub Sub AWF()  For i = 1 To 項試験回数   Call testE  Next i End Sub Sub testC()  Ch = 10000  With Ws   For s2 = 1 To 100    For s1 = 1 To 100     If Ch > .Cells(s1, s2).Value Then Ch = .Cells(s1, s2).Value    Next   Next   dummy = Ch   If dummy <> .Cells(1, 101).Value Then Stop  End With End Sub Sub testV()  Ch = 10000  For s2 = 1 To 100   For s1 = 1 To 100    If Ch > Data(s1, s2) Then Ch = Data(s1, s2)   Next  Next  dummy = Ch  If dummy <> Data(0, 0) Then Stop End Sub Sub testW()  With Ws   dummy = Application.WorksheetFunction.Min(.Range(.Cells(1, 1), .Cells(100, 100)).Value)   If dummy <> .Cells(1, 101).Value Then Stop  End With End Sub Sub testE()  With Ws   dummy = Evaluate("Min(" & .Range(.Cells(1, 1), .Cells(100, 100)).Address & ")")   If dummy <> .Cells(1, 101).Value Then Stop’←☆此処で止まり、ダミーが-1000等に…  End With End Sub             以上

  • エクセルVBAでの質問

    お世話になります。 エクセルVBAのプログラムコードをコピーし、 エクセルの通常シートへ貼り付けした際、 「’」で始まる説明分または注釈をプロシージャ画面の 様に色づけしたいと思い下記の様なコードを書きました。 しかし、VBA実行後、元のコードが行によって、空白 から始まって行の途中に「’」がある場合など、 少し手前の文字から着色されたりしていました。 何故なのでしょうか。 どこがおかしいのでしょうか。 空白が半角か全角になっている為にこのような現象に なっているのでしょうか。 しかしその解決方法が分からなく、 どなたかご教授頂きたく宜しくお願い致します。   記 Sub サンプル() Dim x As Integer Dim y As Integer Dim z As Integer Dim myrng As String Dim zz As Integer For y = 1 To 10 For x = 1 To Cells(Rows.Count, y).End(xlUp).Row If InStr(Trim(Cells(x, y).Value), "'") = 1 Then Cells(x, y).Font.ColorIndex = 10 ElseIf InStr(Trim(Cells(x, y).Value), "'") = 0 Then Else z = InStr(Trim(Cells(x, y).Value), "'") myrng = Cells(x, y) zz = Len(myrng) Cells(x, y).Characters(z, zz).Font.ColorIndex = 10 End If Next x Next y End Sub

  • VBA「型が一致しません」とエラーが出ます

    下記記事の関連質問です。 Excel 文字列抜き出しについて https://okwave.jp/qa/q9979633.html 記事を参考に複数行にマッチするように下記のようにコードを考えましたが msplit(mRng, " ", iii)で「型が一致しません」とエラーが出ます。 なぜでしょうか? テスト用のA4セル 1 01 45124422 ミント 09/01~03/01 108 98 01/05~02/01 Option Explicit Sub test() Dim msplit As Variant Dim buf As String, i As Long, ii As Long, iii As Long, cnt As Long Dim mRng As Range For ii = 4 To Cells(Rows.Count, 1).End(xlUp).Row buf = Cells(ii, "A") For i = 1 To Len(Cells(ii, "A")) If Mid(buf, i, 1) = " " Then cnt = cnt + 1 Next For iii = 1 To cnt Set mRng = Cells(ii, "A") ’Stop Cells(iii + 1, ii) = msplit(mRng, " ", iii) Next Next Set mRng = Nothing End Sub Function msplit(ByRef mRng As Range, ByVal Spstr As String, ByVal num As Long) As Variant msplit = Split(mRng, Spstr)(num - 1) End Function

  • ※VBA配列

    http://oshiete1.goo.ne.jp/qa5196795.htmlで 質問させてもらった者です。質問不足だったため 質問の内容を追加したかったのですが、追加の方法がわからず またこちらで質問させていただきました Dim time1 As Integer, time As Integer Dim X As Integer, Y As Integer Dim X1 As Integer, Y1 As Integer Dim X2 As Integer, Y2 As Integer Dim maru As String, yoko As String, tate As String Dim sankaku As String, shikaku As String Sub 描画() Cells(Y2, X2).Value = shikaku Cells(Y1, X1).Value = sankaku Cells(Y, X).Value = maru End Sub Sub 削除() Cells(Y2, X2).Value = "" End Sub Sub 待機() For time1 = 0 To 1000 For time2 = 0 To 1000 Next Next End Sub Sub 座標移動() X2 = X1 Y2 = Y1 X1 = X Y1 = Y If yoko = "右" Then X = X + 1 Else X = X - 1 End If If X = 30 Then yoko = "左" ElseIf X = 1 Then yoko = "右" End If If tate = "上" Then Y = Y + 1 Else Y = Y - 1 End If If Y = 20 Then tate = "下" ElseIf Y = 1 Then tate = "上" End If End Sub Sub main() maru = "●" sankaku = "▲" shikaku = "■" X = 1 Y = 1 X1 = 1 Y1 = 1 X2 = 1 Y2 = 1 yoko = "右" tate = "上" Do 描画 待機 削除 待機 座標移動 Loop End Sub a~tの文字が、上記のような動きをする プログラムを作成するにはどのように配列を活かせばいいですか? 配列がよくわかっておらず勉強したのですが…使えずにいます;;

  • Excel VBA ・・・教えてください

    何度も質問させて頂いてます。すみません、 下記のプログラムはこの場で教えて頂いたプログラムで、 実行すると●の後を▲や■が追いかける動きをします。 下記のプログラムをある程度使用して 1~20の数字が順々で追いかけっこする プログラムを作成するにはどのようにすればいいのでしょうか… できればプログラムは長めにならず 20の数字から簡単に増やすことのできるような そんなプログラムが作成したいです… どなたかアドバイスお持ちの方 教えて下さいお願いします... Dim time1 As Integer, time As Integer Dim X As Integer, Y As Integer Dim X1 As Integer, Y1 As Integer Dim X2 As Integer, Y2 As Integer Dim maru As String, yoko As String, tate As String Dim sankaku As String, shikaku As String Sub 描画() Cells(Y2, X2).Value = shikaku Cells(Y1, X1).Value = sankaku Cells(Y, X).Value = maru End Sub Sub 削除() Cells(Y2, X2).Value = "" End Sub Sub 待機() For time1 = 0 To 1000 For time2 = 0 To 1000 Next Next End Sub Sub 座標移動() X2 = X1 Y2 = Y1 X1 = X Y1 = Y If yoko = "右" Then X = X + 1 Else X = X - 1 End If If X = 30 Then yoko = "左" ElseIf X = 1 Then yoko = "右" End If If tate = "上" Then Y = Y + 1 Else Y = Y - 1 End If If Y = 20 Then tate = "下" ElseIf Y = 1 Then tate = "上" End If End Sub Sub main() maru = "●" sankaku = "▲" shikaku = "■" X = 1 Y = 1 X1 = 1 Y1 = 1 X2 = 1 Y2 = 1 yoko = "右" tate = "上" Do 描画 待機 削除 待機 座標移動 Loop End Sub

  • VBAで行列を作る方法

    次のようなプログラミングで1,0,-1の要素で作られる3×3行列を全通り調べています。 この場合3の9乗通り調べることができます。 これを4×4や5×5行列など数を大きくして調べたいのですが、このプログラムを配列を使うなどして 簡単にできる方法を教えてください。 よろしくおねがいします。 Sub test() Dim a As Integer '行 Dim b As Integer '列 Dim c As Integer, i As Integer, j As Integer, d As Integer, e As Integer Dim 内積 As Integer, step As Integer Dim f As Integer, g As Integer, h As Integer, l As Integer, m As Integer, n As Integer, k As Integer, x As Integer Dim sum As Integer, total As Integer Dim aa As Integer, aaa As Integer, aaaa As Integer, bb As Integer, bbb As Integer, bbbb As Integer a = 3 '行 b = 3 '列 c = 0 内積 = 0 con = 0 sum = 0 tatal = 0 aa = 0 aaa = 0 aaaa = 0 bb = 0 bbb = 0 bbbb = 0 x = 0 For n = 0 To 2 For m = 0 To 2 For l = 0 To 2 For k = 0 To 2 For h = 0 To 2 For g = 0 To 2 For f = 0 To 2 For e = 0 To 2 For d = 0 To 2 '要素がすべて1 For i = 1 To a For j = 1 To b Cells(i, j) = 1 Next j Next i If bbbb = 1 Then Cells(a - 2, b - 2) = 0 ElseIf bbbb = 2 Then Cells(a - 2, b - 2) = -1 End If If bbb = 1 Then Cells(a - 1, b - 2) = 0 ElseIf bbb = 2 Then Cells(a - 1, b - 2) = -1 End If If bb = 1 Then Cells(a, b - 2) = 0 ElseIf bb = 2 Then Cells(a, b - 2) = -1 End If If aaaa = 1 Then Cells(a - 2, b - 1) = 0 ElseIf aaaa = 2 Then Cells(a - 2, b - 1) = -1 End If If aaa = 1 Then Cells(a - 1, b - 1) = 0 ElseIf aaa = 2 Then Cells(a - 1, b - 1) = -1 End If If aa = 1 Then Cells(a, b - 1) = 0 ElseIf aa = 2 Then Cells(a, b - 1) = -1 End If If total = 1 Then Cells(a - 2, b) = 0 ElseIf total = 2 Then Cells(a - 2, b) = -1 End If If sum = 1 Then Cells(a - 1, b) = 0 ElseIf sum = 2 Then Cells(a - 1, b) = -1 End If If con = 1 Then Cells(a, b) = 0 ElseIf con = 2 Then Cells(a, b) = -1 End If con = con + 1 Next d con = 0 sum = sum + 1 Next e sum = 0 total = total + 1 Next f total = 0 aa = aa + 1 Next g aa= 0 aaa = aaa + 1 Next h aaa = 0 aaaa = aaaa + 1 Next k aaaa = 0 bb = bb + 1 Next l bb = 0 bbb = bbb + 1 Next m bbb = 0 bbbb = bbbb + 1 Next n End Sub

  • VBAでの質問

    お世話になります。 下記の記述で、「←」の矢印の記述で、 Cells.(5,2)がブランクでなければ、 「→」から進めたいのですが、 どの様に記述すれば宜しいでしょうか ご教示お願いします。 Sub 表記入() Dim Data As Range Dim i As Integer Dim j As Integer Dim k As Integer Set Data = Sheets("集計").Range("A2").CurrentRegion j = 16 k = 0 With Sheets("表") For i = 3 To Data.Rows.Count If Data.Cells(i, 51) <> "" Then .Cells(5, 2) = Data.Cells(i, 3)  ← .Cells(5, 7) = Data.Cells(i, 4) → .Cells(j, 2) = Data.Cells(i, 10) .Cells(j, 6) = Data.Cells(i, 11) & Data.Cells(i, 12) .Cells(j, 14) = Data.Cells(i, 51) Else End If k = k + 1 If k = 10 Then j = j + 18 k = 0 Else j = j + 1 End If End If Next i End With End Sub

  • EXCEL VBA Byte型に"0"を付けたい

    EXCEL VBAにてあるセルの値をByte型の16進数に 変換していますが、変換後の値の頭に"0"が付かなくて 困っています。 Dim a As String Dim aa As String Dim b As Byte Dim bb As Byte a = Val("&H" & Cells(1, 1)) aa = Format(a, "00") b = aa bb = Format(b, "00") 変数など簡略化していますが、こんな感じです。 最後の"bb"の中身が、例えば"01"ではなく"1"と なってしまっています。 バイナリエディタで表示した時に、"111"ではなく "010101"と表示させたいのですが、、、 この方法にこだわっている訳ではないので 他の方法も含めて、ご教示お願いします。

  • ▲ExcelのVBA▼困っています

    何度もVBAで質問させてもらい助けてもらっています。 懲りずにまた質問ですが… 下のプログラムは"●"が跳ね返るものなのですが… ●の後を■と▲が追うようなプログラムにするには なにを追加すればいいのでしょうか…?; どなたか教えて下さい;;お願いします;; Dim time1 As Integer, time As Integer Dim X As Integer, Y As Integer Dim maru As String, yoko As String, tate As String Sub 描画() Cells(X, Y).Value = maru End Sub Sub 削除() Cells(X, Y).Value = "" End Sub Sub 待機() For time1 = 0 To 1000 For time2 = 0 To 1000 Next Next End Sub Sub 座標移動() If yoko = "右" Then Y = Y + 1 Else Y = Y - 1 End If If Y = 30 Then yoko = "左" ElseIf Y = 1 Then yoko = "右" End If If tate = "上" Then X = X + 1 Else X = X - 1 End If If X = 20 Then tate = "下" ElseIf X = 1 Then tate = "上" End If End Sub Sub main() maru = "●" X = 1 Y = 1 yoko = "右" tate = "上" Do 描画 待機 削除 待機 座標移動 Loop End Sub

専門家に質問してみよう