• ベストアンサー

エクセルVBAのEntireRow.Hiddenをスピードアップしたいのですが・・・。

エクセル97です。 9行目から732行までの大きな表があります。一定の条件のとき、U列がaaaでなくV列もbbbではない行を非表示とするために下記のマクロを作ってみました。 一応思ったとおりには動くのですが行数が多いため、開始してから終了するまで5分以上かかってしまいます。このマクロのように9行目から732行まで順にやっていくのではなく、一度に非表示にするような方法はないでしょうか? Sub TEST() Sheets("TEST").Activate For i = 9 To 732 If Cells(i, "U") <> "aaa" And Cells(i, "V") <> "bbb" Then Cells(i, "V").EntireRow.Hidden = True Else Cells(i, "V").EntireRow.Hidden = False End If Next i End Sub よろしくお願いします。

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

  • ベストアンサー
  • papayuka
  • ベストアンサー率45% (1388/3066)
回答No.4

#2です。 > tmp = "=IF(OR(U9=""eee"",V9=""fff""),1,"""")" > としてもダメでした。これはOR条件は使えないのでしょうか? 動くハズですよ、セルに入れる時は =IF(OR(U9="eee",V9="fff"),1,"") というただの条件式ですから。 VBAで文字列に " を使うときは "" としてやらねばならないためちょっと変に見えるだけです。セルにこの関数を入れて 1 が立てば、例のマクロで非表示対象になります。 思い通りにならないとしたら条件を勘違いされているのではないでしょうか? 仕組みの説明 1.テンポラリィ範囲を取あえず表示(条件を変えて実行した場合に必要?) 2.テンポラリィ範囲に関数を一気に代入 3.テンポラリィ範囲の数値セル(行)を非表示 4.テンポラリィ範囲の関数をクリア 3 はExcelの操作でやると、テンポラリィ範囲を選択し、編集-ジャンプ-セル選択の選択オプションで「数式」の「数値」のみにチェックを入れた場合に選択される範囲です。 条件式を入れる列を追加出来るならマクロでやらなくてもオートフィルタで出来る内容ですね。

shishishishi
質問者

お礼

大変くわしくお教えいただきありがとうございました。 OR条件でも出来ました。 ほんとうに助かりました。

その他の回答 (3)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.3

Sub test02() For i = 1 To 732 If i Mod 10 = 1 Or i Mod 10 = 6 Then Cells(i, "U") = "" Cells(i, "V") = "" End If Next i End Sub を実行し、A1:T732に(同じ)データを入れ Cells(i, "V").EntireRow.Hidden = False を省き ●(注!)不要のようです。 Sub TEST() Sheets("sheet1").Activate For i = 9 To 732 If Cells(i, "U") <> "aaa" And Cells(i, "V") <> "bbb" Then Cells(i, "V").EntireRow.Hidden = True End If Next i End Sub を実行してみたところ、2秒ぐらいで終了しました。 Application.ScreenUpdating = TRUE,False も入れていません. 入れると一瞬にして終わります。当方98seでエクセル2000で数年前のCPUです。 ですからなにか別の要因で遅くなるのだと思います。 Cells(i, "V").EntireRow.Hidden = Trueを Rows(i).EntireRow.Hidden = Trueにしてみたりしましたが変りありませんでした。

shishishishi
質問者

お礼

ありがとうございました。 Cells(i, "V").EntireRow.Hidden = False を省きましたらかなり早くなりましたが、数秒というわけにはいきませんでした。

  • papayuka
  • ベストアンサー率45% (1388/3066)
回答No.2

5分は掛かりすぎですね。 こちらの環境ではそのままのコードで実行しても、3~4秒でした。 #1さんの回答にある Application.ScreenUpdating = False でだいぶ改善されると思いますが、、、 例は空いていそうなセルに判定用関数を入れて一気に非表示にしてます。 複雑な計算式を多用している場合はかえって遅くなるかもしれません。 Sub TEST1() Dim tmp As Range  Sheets("TEST").Activate  Set tmp = Range("IV9:IV732")  tmp.EntireRow.Hidden = False  tmp = "=IF(AND(U9<>""aaa"",V9<>""bbb""),1,"""")"  On Error Resume Next  tmp.SpecialCells(xlCellTypeFormulas, 1).EntireRow.Hidden = True  tmp.Clear End Sub

shishishishi
質問者

お礼

ありがとうございました! 一瞬でできました!! ただ、理屈がよくわからないのです。 U9<>"aaa"かつV9<>"bbb"のとき、そのIV列に1をいれてるのはわかりましたが・・・・。 理屈がよくわからないので別な表のOR条件に応用できませんでした。 ANDをORにかえてもだめなんですね?

shishishishi
質問者

補足

本来は別の質問としなければいけないのかも知れませんが・・・・。 上記でU列が"eee"、またはV列が"fff"のときのみ、その行を非表示とする場合、 tmp = "=IF(OR(U9=""eee"",V9=""fff""),1,"""")" としてもダメでした。これはOR条件は使えないのでしょうか?

  • popesyu
  • ベストアンサー率36% (1782/4883)
回答No.1

行単位で表示非表示の判別をせざるを得ない以上、一度にする方法はないでしょうが、まぁアルゴリズムを見直すなら。 最初にソートさせて、U列がaaa、V列もbbbの行をまとめてしまい、それ以外を非表示させるというのが早そうかなと思います。 まず行番号を振っていつでも元に戻せるようにしておく必要がありますが。 でそれ以外の最適化のコツとしては ・メモリリソースを節約 各変数は必ず最適な型で宣言しましょう。 dim i as Long ・描画の省略 その手の作業をする場合は真っ先に Application.ScreenUpdating = False と画面表示を更新させないようにします。最後に Application.ScreenUpdating = true としておくのを忘れないように。 ・分岐の最適化 IF文よりはSELECT文の方が多少効率が良いので、判定はSELECT文でネストさせたらどうかなと。 ・With...End With 構文による高速化 同じオブジェクトの処理が続く場合 With Cells(i, "V") End With と包みましょう。

shishishishi
質問者

お礼

ありがとうございました。

関連するQ&A

  • エクセルVBAで複数シートにマクロ実行

    エクセル2000です。 Sub 行列非表示() For i = 2 To 120 If Cells(i, "A").Interior.ColorIndex = 3 Then Cells(i, "A").EntireRow.Hidden = True End If Next i For n = 1 To 50 If Cells(1, n).Interior.ColorIndex = 3 Then Cells(1, n).EntireColumn.Hidden = True End If Next n End Sub 上記マクロを、シートAAAとCCCとEEEに実行する場合、 Sub test() Sheets("AAA").Activate Call 行列非表示 Sheets("CCC").Activate Call 行列非表示 Sheets("EEE").Activate Call 行列非表示 End Sub と書くよりももっとすっきり実行する方法は無いでしょうか? 各シートの非表示対象の行や列はそれぞれことなります。 また Sub 行列非表示 自体も、もっと効率的にやる方法はないでしょうか?

  • この場合エクセルVBAでどう書けばいいでしょうか?

    あるシートのH列で、H21からH46のあいだで"False"がある行を非表示にしたいのです。 下記の冗長なマクロでもそうなりますが、For Nextというのを使うともっと簡潔に記述できると思うのですが、初心者のためよくわかりません。ご教示ください。 また、下記の式はシートが保護されていると働きませんが、保護したシートでも動く方法があればそれもあわせて教えていただけると幸いです。 エクセルは95です。 Sub 空白行非表示() G% = Sheets("見積書").Range("H48").Value With Sheets("見積書") Rows("19:47").RowHeight = G% If Range("H21") = False Then Rows("21").EntireRow.Hidden = True End If If Range("H22") = False Then Rows("22").EntireRow.Hidden = True End If If Range("H23") = False Then Rows("23").EntireRow.Hidden = True End If If Range("H24") = False Then Rows("24").EntireRow.Hidden = True End If 途中、繰り返しのため省略 If Range("H42") = False Then Rows("42").EntireRow.Hidden = True End If If Range("H43") = False Then Rows("43").EntireRow.Hidden = True End If If Range("H44") = False Then Rows("44").EntireRow.Hidden = True End If If Range("H45") = False Then Rows("45").EntireRow.Hidden = True End If If Range("H46") = False Then Rows("46").EntireRow.Hidden = True End If End With End Sub

  • エクセルのVBA

    AB列に複数行データがありB列の条件でその行のABのデータ を抽出し特定の場所に貼り付けたいのですが貼付け場所が 任意に選択できません。今はデータの無いA列から貼り付けていますが できればD列の1行目か2行目から貼り付ける方法を教えてください。 また今のコードでは貼付けたいデータの順番が下のデータからになってしまいます。 これも元のデータ順にしたいのでよろしくお願いします。 今使っているコードは下記の通りです。 For i = Cells(Rows.Count, 2).End(xlUp).Row To 1 Step -1 If Cells(u, 2) < "96" And Cells(u, 2) <> "0" And Cells(u, 2) <> " " Then Range(Cells(u, 1), Cells(u, 2)).Select Selection.Copy Range("A1").End(xlDown).Offset(1, 0).Activate Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False End If Next

  • 13行目のセルの値が0のとき、その列を非表示にする

    Windows7 Excel2007でマクロ作成中の初心者です。 13行目のセルの値が、0のときは、その列を非表示にするというマクロを作ろうとしましたが なかなか難しくておてあげです。探したら次のようなコードがでてきました。 ボタンを押すとK列の値を参照して「A」と表示されている行を隠し、「表示する」ボタンを押すと、 解除するという処理。 Option Explicit Private Sub Cmd隠す_Click()  Dim 行番号 As Long  '行を隠す  For 行番号 = 4 To 13   If Cells(行番号, 11).Value = "A" Then    Cells(行番号, 1).EntireRow.Hidden = True   End If  Next 行番号 End Sub Private Sub Cmd表示する_Click()  '表全体を再表示する  Cells.Select  Selection.EntireRow.Hidden = False  Selection.EntireColumn.Hidden = False  Cells(1, 1).Select End Sub このコードを利用して、13行目のセルの値が、0のときは、その列を非表示にするというコードにしたいのです。 よろしくおねがいします。

  • 助けてください! EXCELのセルが表示されなくなりました

    マクロを作成しようと、簡単な記述をテストしたところ、セルが全部表示されなくなりました。 行番号も見えません。列のアルファベットは表示されていますが、選択することもできません。 どうしたら元に戻るでしょうか? テストしたマクロの記述は以下のとおりです。 If Range("P74").Value = 0 Then Columns("P:P").Select Selection.EntireRow.Hidden = True End If End Sub 非常に困っています。どうか助けてください。

  • エクセルVBAの質問です。

    次のようなマクロを作ったのですがエラーにはならないのですが、うまく働きません。 Else if の行が悪いと思うのですがどうなおせばいいのかわかりません。 どなたか教えてください、よろしくお願いします。 Sub 判定() Application.ScreenUpdating = False '処理中の表示をさせない lastrow = (Range("B4").End(xlDown).Row) 'B列の一番最後の行番号を代入 length(1) = Range("S2") For i = length(1) + 4 + 1 To lastrow If Cells(i - 1, 8) = "" And Cells(i - 1, 15) = "GC3" Or Cells(i - 1, 15) = "GC2" Then Cells(i, 8) = Cells(i, 2) * Cells(1, 5) + Cells(1, 7) ElseIf Cells(i - 1, 8) <> "" And Cells(i - 1, 15) = "DC3" Or Cells(i - 1, 15) = "DC2" Or Cells(i - 1, 15) = "DC1" Then Cells(i, 9) = Cells(i, 2) * Cells(1, 5) - Cells(1, 7) Else: Cells(i, 8) = Cells(i - 1, 8) End If     Next End Sub

  • エクセル2002のVBAで太文字を検索したいのですが、

    エクセル2002のVBAで太文字を検索したいのですが、 <状況> B列にチェックしたい文字が入力されています <やりたいこと> B列に入力されている文字の中から、太文字のみを抜き出して、 太字の見つかった行のG列に太文字のみを抜き出して複写したい <自作マクロの現状> セル全体の太文字検索は下記のマクロ「太字検索チェック1」で完成しましたが、 セルに記載してある文字の中で「一部は普通文字、のこり一部は太文字」と混在 しているセルの中身から太文字部分のみを別のセルに抜き出したいのですが、 そのマクロを「太字検索チェック2」のように書きました。 しかし「太字検索チェック2」の「 If dat.Font.Bold = True Then」の部分で 「型が違う・・・」のエラーで先に進みません。 どなたか、セルの中身の太文字のみを抜き出すマクロを教えてください よろしくお願いします   Sub 太字検索チェック1() i = 3 Worksheets("テスト").Activate For Each myRng In Range("B:B") セル = "b" & i If Range(セル).Font.Bold = True Then Cells(i, 7) = Cells(i, 2) ’太字のCells(i, 2)を Cells(i, 7) にコピー End If i = i + 1 If i = 1703 Then ’1703番地で終了 Exit For End If Next End Sub Sub 太字検索チェック2() i = 3 Worksheets("テスト").Activate For Each myRng In Range("B:B") 内容 = Cells(i, 2) 文字数 = Len(内容) For p = 1 To 文字数 dat = Mid(内容, p, 1)       X=8+P If dat.Font.Bold = True Then  ’1文字づつ太字を検索 Cells(i, X) = dat        ’太字なら→Cells(i, X) にコピー End If Next i = i + 1 If i = 1703 Then Exit For End If Next End Sub

  • エクセルVBA

    アクティブ「セル」のある「行」をコピーし、そのアクティブセルの下へ挿入するマクロに、複数「セル」を選択している場合は、複数行を挿入するように追記するには、どうしたらいいでしょうか? Sub Macro1() Rows(1).Copy ActiveCell.EntireRow.Insert Shift:=xlDown Application.CutCopyMode = False ActiveCell.EntireRow.Hidden = False End Sub よろしくお願いします。m(_ _)m

  • エクセルVBAで無限ループ

    教えてください。 以下の2つのエクセルマクロはまったく同じことをさせようとしているのですが、test02の方は.Offset(1).Activateが働かないのか、無限ループに陥ってしまいます。 単にActiveCell.という記述をWith~End Withでまとめただけなのになぜこうなるのでしょうか? Sub test01() ActiveSheet.Cells(1, 1).Activate Do While ActiveCell.Value <> "" If Not IsNumeric(ActiveCell.Value) Then ActiveCell.Offset(0, 1).Value = "文字" ElseIf ActiveCell.Value > 0 Then ActiveCell.Offset(0, 1).Value = "正数" ElseIf ActiveCell.Value < 0 Then ActiveCell.Offset(0, 1).Value = "負数" Else ActiveCell.Offset(0, 1).Value = "その他" End If ActiveCell.Offset(1).Activate i = i + 1 Application.StatusBar = i Loop End Sub Sub test02() ActiveSheet.Cells(1, 1).Activate With ActiveCell Do While .Value <> "" If Not IsNumeric(.Value) Then .Offset(0, 1).Value = "文字" ElseIf .Value > 0 Then .Offset(0, 1).Value = "正数" ElseIf ActiveCell.Value < 0 Then .Offset(0, 1).Value = "負数" Else .Offset(0, 1).Value = "その他" End If .Offset(1).Activate i = i + 1 Application.StatusBar = i Loop End With End Sub

  • 二つの行のうち、どちらかが、セルの値がゼロのとき、その列を非表示にする

    二つの行のうち、どちらかが、セルの値がゼロのとき、その列を非表示にする windows7 excelでマクロ作成中の初心者です。 以下のコードで27行目のセルの値が0のとき列を非表示にします。 Private Sub 列非表示_Click() Dim 列番号 As Long 'シートが保護されていたら保護を解除 Worksheets("最新明細").Activate If ActiveSheet.ProtectContents = True Then ActiveSheet.Unprotect End If For 列番号 = 4 To 33 If Cells(27, 列番号).Value = 0 Then Cells(27, 列番号).EntireColumn.Hidden = True End If Next 列番号 ActiveSheet.Protect End Sub ------------------------------------------------- Private Sub 列表示_Click() Dim 列番号 As Long 'シートが保護されていたら保護を解除 Worksheets("最新明細").Activate If ActiveSheet.ProtectContents = True Then ActiveSheet.Unprotect End If For 列番号 = 4 To 33 If Cells(27, 列番号).Value = 0 Then Cells(27, 列番号).EntireColumn.Hidden = False End If Next 列番号 ActiveSheet.Protect End Sub この27行と、もう一行の28行、どちらかの行が、0のときに列を非表示・表示したいのですが、出来ません。 試行錯誤してもできないのです。どうかよろしくおねがいします。 For 列番号 = 4 To 33 If Cells(27, 列番号).Value = 0 or Cells(28, 列番号).Value = 0 Then or( Cells(27, 列番号).EntireColumn.Hidden = True, Cells(27, 列番号).EntireColumn.Hidden = True) End If

専門家に質問してみよう