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

このQ&Aのポイント
  • VBAのEvaluateメソッドを使用する際に、対象シートを最前面に出す必要があるのかどうか疑問があります。
  • コードの一部を加筆して試してみたところ、一定条件下でストップしてしまうことがあります。
  • また、visibleをFalseにすると正しく計算されないことが分かりました。
回答を見る
  • ベストアンサー

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             以上

  • Nouble
  • お礼率91% (1698/1856)

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

  • ベストアンサー
  • SI299792
  • ベストアンサー率48% (709/1465)
回答No.1

Evaluateは、セルに書くべき式を実行するものです。 Evaluateの外でシートを指定しても、反映されません。 最前面以外を計算したければ、Evaluateの中で指定する必要があります。 dummy = Evaluate("Min(" & Ws.Name & "!" & Range(Cells(1, 1), Cells(100, 100)).Address & ")") にしてください。Evalueteの中身は、"Min($A$1:$CV$100)" という文字列を生成しているだけなので、. は無くてもいいです。 Evaluateを使わず、 dummy = WorksheetFunction.Min(.Range(.Cells(1, 1), .Cells(100, 100))) とする方法もあります。

Nouble
質問者

お礼

有り難うございます 文字列に、起こした際 確かに シート指定、されて いません 私、抜け作ですね

関連するQ&A

  • EXCEL2011 Objectに入れたWork…

    お世話になります。 どうも よく、解らない の、ですが 下記で コメントアウト、させている ラインの、内 *印を、付けている どの行、をも コメントアウトから、戻すと ☆で、添付映像の エラーに、なります コメントアウトの、ままだと エラーには、なりません 察するに Wsが ActiveSheetで、無いと with Ws に、対する .Range(cells(… が、嫌っぽい の、ですが こんな事、当たり前 なのか 疑問、なのです お教え下さい。     記 Option Explicit Option Base 0 Dim Data(100, 100) As Long, Ch As Long, s1 As Long, s2 As Long, Ws As Worksheet, すとり As Range Sub testMain() ' 簡易テスト Dim 現状保存 As Worksheet, シート名 As String  Let シート名 = ActiveSheet.Name Application.ScreenUpdating = False  Worksheets(シート名).Copy after:=Worksheets(Worksheets.Count)  '■  Set 現状保存 = ActiveSheet                            '■  Set Ws = Worksheets.Add() ' Worksheets(シート名).Copy after:=Worksheets(Worksheets.Count)  '*□ ' Set 現状保存 = ActiveSheet                      ’□ ' Worksheets(シート名).Select                    '*  現状保存.Visible = False ' Ws.Visible = False                       '* Application.ScreenUpdating = True  Call ダミーデータ作成  Call testC  Call testV  Call testE 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 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  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 End Sub Sub testE()  With Ws   すとり = .Range(Cells(1, 1))                 '☆  End With End Sub (※注:□の2行を コメントから 外す、時は  同、■の2行を コメントアウトして、下さい)                       以上

  • EXCEL2011 Objectに入れたWor…改

    お世話になります。 どうも なんと言って 良いのか 本当に、済みません スレットを、変えよう と、して 念の、ため 確認に、再度 走らせて、みた の、ですが コメントアウト、させていても ☆で、添付映像の エラーに、なります もう頭が ?????? です 兎に角 エラー理由が、解りません 申し訳、ありませんが お教え下さい。     記 Option Explicit Option Base 0 Dim Data(100, 100) As Long, Ch As Long, s1 As Long, s2 As Long, Ws As Worksheet, ランゲ As Range Sub testMain() ' 簡易テスト Dim 現状保存 As Worksheet, シート名 As String  Let シート名 = ActiveSheet.Name Application.ScreenUpdating = False  Worksheets(シート名).Copy after:=Worksheets(Worksheets.Count)  '■  Set 現状保存 = ActiveSheet                            '■  Set Ws = Worksheets.Add() ' Worksheets(シート名).Copy after:=Worksheets(Worksheets.Count)  '*□ ' Set 現状保存 = ActiveSheet                      ’□ ' Worksheets(シート名).Select                    '*  現状保存.Visible = False ' Ws.Visible = False                       '* Application.ScreenUpdating = True  Call ダミーデータ作成  Call testC  Call testV  Call testE 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 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  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 End Sub Sub testE()  With Ws   Set ランゲ = .Range(Cells(1, 1))               '☆  End With End Sub (※注:□の2行を コメントから 外す、時は  同、■の2行を コメントアウトして、下さい)                       以上

  • VBAの解説

    お世話になります 値、セルの操作ですが列数等の変更が生じたため変更を求められています。 下記VBA判りやすく説明できる方お願い致します。 Sub Macro1() Dim idxR, idxC, ptr As Integer Dim ws As Worksheet Set ws = ActiveSheet Worksheets.Add after:=ws ptr = 2 With ws .Rows(1).Copy Destination:=Range("A1") For idxR = 2 To .Range("A65536").End(xlUp).Row Cells(ptr, "A").Value = .Cells(idxR, "A").Value For idxC = 2 To 255 Step 2 If .Cells(idxR, idxC) = "" Then Exit For Else .Cells(idxR, idxC).Resize(1, 2).Copy Destination:=Cells(ptr, "B") ptr = ptr + 1 End If Next idxC Next idxR End With End Sub

  • エクセルVBAの記述の違い

    下記の2つともA1:B2の中身を削除するものですが、test1の書き方だと対象となるシートがアクティブではないとエラーになります。test2は問題なし。 Cellsの書き方のほうが変数を使う時に便利なのですが、なんでこんな違いがでてしまうのでしょうか? Sub test1() Set ws1 = Worksheets("Sheet1") Set ws2 = Worksheets("Sheet2") ws1.Range(Cells(1, 1), Cells(2, 2)).ClearContents ws2.Range(Cells(1, 1), Cells(2, 2)).ClearContents End Sub Sub test2() Set ws1 = Worksheets("Sheet1") Set ws2 = Worksheets("Sheet2") ws1.Range("a1:b2").ClearContents ws2.Range("a1:b2").ClearContents End Sub

  • Excel VBA 連番印刷

    昨日以下の質問をさせていただいた者です。 http://okwave.jp/qa/q8349562.html こちらで教えていただいた以下のコードに、 J2のセルに連番を振るコードを付け足したいと思い、 同じくこちらのサイトの過去の履歴にあった以下コードを参考にとやってみているのですが、 Next で指定された変数の参照が無効です。と言われてしまいます… 印刷部数の指定はいらず、sheet印刷のJ2セルに1から始まる連番を振りたいのです。 どのように修正をしたらいいのかご教示願います。 Sub Sample4() Dim i As Long, endRow1 As Long, endRow2 As Long, myArea1 As Range, myArea2 As Range Dim wS1 As Worksheet, wS2 As Worksheet, wS3 As Worksheet Set wS1 = Worksheets("DB") Set wS2 = Worksheets("印刷") Set wS3 = Worksheets("Sheet3") endRow1 = wS1.Cells(Rows.Count, "A").End(xlUp).Row Range(wS1.Cells(1, "A"), wS1.Cells(endRow1, "A")).AdvancedFilter Action:=xlFilterInPlace, unique:=True wS1.Range("A:A").Copy wS3.Range("A1") wS1.ShowAllData For i = 2 To wS3.Cells(Rows.Count, "A").End(xlUp).Row endRow2 = wS2.Cells(Rows.Count, "B").End(xlUp).Row If endRow2 > 9 Then Range(wS2.Cells(10, "B"), wS2.Cells(endRow2, "H")).ClearContents Range(wS2.Cells(10, "J"), wS2.Cells(endRow2, "J")).ClearContents End If wS1.Range("A1").AutoFilter field:=1, Criteria1:=wS3.Cells(i, "A") wS2.Range("B6") = wS3.Cells(i, "A") Set myArea1 = Range(wS1.Cells(2, "B"), wS1.Cells(endRow1, "H")).SpecialCells(xlCellTypeVisible) Set myArea2 = Range(wS1.Cells(2, "I"), wS1.Cells(endRow1, "I")).SpecialCells(xlCellTypeVisible) myArea1.Copy wS2.Activate ActiveSheet.Range("B10").Select Selection.PasteSpecial Paste:=xlPasteValues myArea2.Copy wS2.Activate ActiveSheet.Range("J10").Select Selection.PasteSpecial Paste:=xlPasteValues endRow2 = wS2.Cells(Rows.Count, "B").End(xlUp).Row 'Range(wS2.Cells(1, "A"), wS2.Cells(endRow2, "J")).PrintOut Next i wS1.AutoFilterMode = False wS3.Cells.Clear End Sub 連番印刷のコード Sub NumberPrint() Dim idx As Integer Dim res  res = Application.InputBox("印刷部数を入力してください", Type:=1)  If res > 0 Then   For idx = 1 To res    Range("AW3").Value = idx    ActiveSheet.PrintOut   Next idx  End If End Sub

  • VBAで複数のシート名を置換する処理

    Dim ws As Worksheet Dim i As Long For i = 1 To ThisWorkbook.Sheets.Count For Each ws In ThisWorkbook.Sheets If ws.name Like "*T*" Then ws.name = Replace(ws.name, "T", "S") End If Next Next End Sub この処理をするとnameメソッド失敗worksheetオブジェクト 処理できるようにするにはどうすればいいんでしょうか

  • VBA 高速化

    以下のコードを改良して早く処理できるようにしたいです。素因数分解をして、素因数の数を数えるプログラムです。 Sub 素因数を数える() Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Dim I As Long, j As Long, cnt As Long, wS As Worksheet, k As Long, Set wS = Worksheets("Sheet2") k = Worksheets("Sheet1").Range("A100010").End(xlUp).Row - 1 For dd = 3 To k Call aaa(Range("A" & dd)) Next dd Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub Private Sub aaa(ByVal Target As Range) Set wS = Worksheets("Sheet2") If Intersect(Target, Range("A:A")) Is Nothing Or Target.Count > 1 Then Exit Sub With Target If Not IsNumeric(.Value) Then Exit Sub If .Value Mod 1 = 0 Then Range("D1") = .Value For I = 1 To wS.Cells(Rows.Count, "A").End(xlUp).Row Do While Cells(Rows.Count, "D").End(xlUp) Mod wS.Cells(I, 1) = 0 cnt = cnt + 1 Cells(Rows.Count, "D").End(xlUp).Offset(1) = Cells(Rows.Count, "D").End(xlUp) / wS.Cells(I, 1) Loop If Cells(Rows.Count, "D").End(xlUp) = 1 Then Exit For Next I End If .Offset(, 1) = cnt End With Range("D:D").Clear End Sub 以前教えていただいたコードを使って書きました。 どういう状況で使っているかといいますと、シート1のA列に自然数を2から順番に並べ、シート2のA列に素数を並べておき、プログラムを実行すると、B列に素数の数が表示されるという具合です。 大変役に立っていたのですが、10萬ほどのデータを扱おうとすると、自分のコンピュータでは時間がかかりすぎます。そこでコードを改良して高速化をしたいのです。 いま考えられる改良点は、 1、D列を使って行っている処理をメモリで行うようにして、セルへのアクセスを省けないか 2、aaaの5行目の、"wS.Cells(Rows.Count, "A").End(xlUp).Row"この処理を簡単な変数の処理で代用できないか ということです。他にも高速化できる方法があれば教えてください。 よろしくお願いします。

  • VBA どこでもセル選択

    教えて頂いたVBAなのですがもう一つ Sub Macro1() Dim Ws01 As Worksheet Dim Counter As Long, i As Long, j As Long Dim INP As String Set wS = Worksheets("Sheet4") wS.Cells.ClearContents For i = 3 To ActiveSheet.UsedRange.Rows.Count INP = "" For j = Selection(1).Column To Selection(Selection.Count).Column If Cells(i, j) = 1 Then INP = INP & Cells(2, j) & "," End If Next j Counter = Counter + 1 If INP <> "" Then wS.Cells(Counter, "A") = Left(INP, Len(INP) - 1) End If Next i End Sub -------------------------------------------------------------- For i = 3 のところを3としないでどのセル(行)にも対応させたいのですが どうすればいいでしょうか?

  • VBAでxlSheetVeryHiddenにしたい

    エクセル2010です。 VBAでワークシートをxlSheetVeryHiddenにしたいのです。 Sub TEST01() Dim t As Single t = Timer For Each ws In Worksheets If ws.Name <> Sheet1.Name Then ws.Visible = xlSheetVeryHidden Next Debug.Print Timer - t End Sub これで出来ますが、シート数が多いので1秒以上かかります。 まとめてやれば早いかと、以下を試しました。 しかし、xlSheetHiddenならすんなり出来ましたが、なぜかxlSheetVeryHiddenではエラーになります。 どうすれば早くできるでしょうか?(実際のシート名は下記のような規則性はありません。) Sub TEST02() Dim t As Single t = Timer Application.ScreenUpdating = False Sheets(Array("TEST002", "TEST003", "TEST004", "TEST005", "TEST006", "TEST007", "TEST008", "TEST009", "TEST010", "TEST011", "TEST012", "TEST013", "TEST014", "TEST015", "TEST016", "TEST017", "TEST018", "TEST019", "TEST020", "TEST021", "TEST022", "TEST023", "TEST024", "TEST025", "TEST026", "TEST027", "TEST028", "TEST029", "TEST030", "TEST031", "TEST032", "TEST033", "TEST034", "TEST035", "TEST036", "TEST037", "TEST038", "TEST039", "TEST040", "TEST041", "TEST042", "TEST043", "TEST044", "TEST045", "TEST046", "TEST047", "TEST048", "TEST049", "TEST050", "TEST051", "TEST052", "TEST053", "TEST054", "TEST055", "TEST056", "TEST057", "TEST058", "TEST059", "TEST060", "TEST061", "TEST062", "TEST063", "TEST064", "TEST065", "TEST066", "TEST067", "TEST068", "TEST069", "TEST070")).Select ActiveWindow.SelectedSheets.Visible = xlSheetVeryHidden Application.ScreenUpdating = True Debug.Print Timer - t End Sub

  • VBA 値、セル操作

    お世話になります [現状] 実行させると 1列目を残して2列づつ処理をさせています Sub Macro1() Dim idxR, idxC, ptr As Integer Dim ws As Worksheet Set ws = ActiveSheet Worksheets.Add after:=ws ptr = 2 With ws .Rows(1).Copy Destination:=Range("A1") For idxR = 2 To .Range("A65536").End(xlUp).Row Cells(ptr, "A").Value = .Cells(idxR, "A").Value For idxC = 2 To 255 Step 2 If .Cells(idxR, idxC) = "" Then Exit For Else .Cells(idxR, idxC).Resize(1, 2).Copy Destination:=Cells(ptr, "B") ptr = ptr + 1 End If Next idxC Next idxR End With End Sub [判らないこと] 前7列を残して(A:G) 8列目から(H列)より9列づつ処理をさせたいのですが判らなく大変困っております。 どなたかご教授よろしくお願いします。

専門家に質問してみよう