Macro to Hide Rows that contain specific Values...

diqbal

New Member
Joined
Jan 7, 2004
Messages
25
I need to create a macro that looks at every row in a worksheet and checks to see if columns C-H all have a value of "-" and if this is true it hides the row. It then keeps running for 9 more worksheets that are identical to the first one for all intents and purposes.

The logical reason for this is that I am creating a sheet that pulls in values from an external source and I want to hide all the rows that have no values so as to not have a lot of rows with just dashes in them.

Please help as I am an extreme newbie to Excel Macros. Thanks. :)
 
Yep, that's why the test was baked in there, I realized after posting that I had slightly misplaced it... Nice catch/fix! :) One simply wants to use the first visible dashed cell in C as your marker.

Curious, about the merits/insistence of using Code Names, like it's best-in-class practice. What if I change the code name of a sheet? It's a fine way of doing it, but index numbers and names have their merits to be certain. I rarely use sheet code names, so I suppose that's why I simply do not relate here... So be it. :-D

Also, from a defensive coding standpoint, one should set the lower boundary of an array, did you test the lower boundary? In any case, I might use a [underrated] collection class on a slow-stack or quick-stack an array like the following:

<font face=Courier New><SPAN style="color:darkblue">Sub</SPAN> UseColl()
<SPAN style="color:darkblue">Dim</SPAN> myShts <SPAN style="color:darkblue">As</SPAN> Collection, i <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Long</SPAN>
<SPAN style="color:darkblue">Set</SPAN> myShts = <SPAN style="color:darkblue">New</SPAN> Collection
myShts.Add Sheet1: myShts.Add Sheet2
<SPAN style="color:darkblue">For</SPAN> i = 1 <SPAN style="color:darkblue">To</SPAN> myShts.Count
    MsgBox Sheets(i).Name
<SPAN style="color:darkblue">Next</SPAN>
<SPAN style="color:darkblue">Set</SPAN> myShts = <SPAN style="color:darkblue">Nothing</SPAN>
<SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">Sub</SPAN>

<SPAN style="color:darkblue">Sub</SPAN> UseArr()
<SPAN style="color:darkblue">Dim</SPAN> i <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Long</SPAN>, myArr <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Variant</SPAN>
myArr = Array(Sheet1, Sheet2)
<SPAN style="color:darkblue">For</SPAN> i = <SPAN style="color:darkblue">LBound</SPAN>(myArr) <SPAN style="color:darkblue">To</SPAN> <SPAN style="color:darkblue">UBound</SPAN>(myArr)
    MsgBox myArr(i).Name
<SPAN style="color:darkblue">Next</SPAN>
Rem <SPAN style="color:darkblue">Debug</SPAN>.<SPAN style="color:darkblue">Print</SPAN> <SPAN style="color:darkblue">LBound</SPAN>(myArr)
<SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">Sub</SPAN></FONT>

Fun eh, the variant coerces into an array of initialized objects, like the girl from the McDonalds commercials, I'm lovin' it. :-D Note, the array is 0-based.
 
Upvote 0

Excel Facts

Save Often
If you start asking yourself if now is a good time to save your Excel workbook, the answer is Yes
Thanks for the additional ideas. I like 'em both.:bow:

As for not using LBound(): if I'm loading the array using hardcoded subscripts, I just like starting at one instead of zero. So I normally just code my loops to start at 1 as well. If I didn't hardcode the subscripts, then yeah, gotta use LBound() [And yes, I learned that the hard way.]

As for my predilection for using codenames: I figure if my code blows up 'cause a user renamed or moved a sheet, then I reckon I (half-) deserve to get that annoying call "Your macro doesn't work! Can you come over?" But if he's gone and altered a codename then (a) he shoulda known better :diablo: and (b) he's probably smart enough to debug it himself.

Again, thanks for taking the time to post the collection and array code. Now where did our OP get off to???
 
Upvote 0
Greg Truby said:
Thanks for the additional ideas. I like 'em both.:bow:
You're welcome. The oft-overlooked custom collection is a beaut as they:

1) Allow ynamic size dimensions (and are always 1-based I believe)
2) Allow Variant input
3) Are fast
GT said:
As for not using LBound(): if I'm loading the array using hardcoded subscripts, I just like starting at one instead of zero. So I normally just code my loops to start at 1 as well. If I didn't hardcode the subscripts, then yeah, gotta use LBound() [And yes, I learned that the hard way.]
True, in that the way you are using the array has no real risk. But not true in re: your array starts at 1 (while your loop does), while trivial in this instance, your array is not sized properly because of the lack of boundary dimensioning, which is pretty simple/not really a burden.

<font face=Courier New><SPAN style="color:darkblue">Sub</SPAN> sdhfjks()
<SPAN style="color:darkblue">Dim</SPAN> ws(9) <SPAN style="color:darkblue">As</SPAN> Worksheet  <SPAN style="color:green">' Adjust # in () if # of sheets changes</SPAN>
    
    <SPAN style="color:darkblue">Set</SPAN> ws(1) = Sheet1      <SPAN style="color:green">' On the right of the equals sign</SPAN>
    <SPAN style="color:darkblue">Set</SPAN> ws(2) = Sheet2      <SPAN style="color:green">' put the CODENAMEs of the worksheets</SPAN>
    <SPAN style="color:darkblue">Set</SPAN> ws(3) = Sheet3      <SPAN style="color:green">' you want to process.</SPAN>
                            <SPAN style="color:green">' Add / Delete as needed (don't forget</SPAN>
                            <SPAN style="color:green">' to adjust the DIM statement above).</SPAN>
<SPAN style="color:darkblue">Debug</SPAN>.<SPAN style="color:darkblue">Print</SPAN> <SPAN style="color:darkblue">LBound</SPAN>(ws)
Erase ws
<SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">Sub</SPAN></FONT>

The first element, 0, being gratuitous and the common culprit in naughty array programming, which is why I mention it.

GT said:
As for my predilection for using codenames: I figure if my code blows up 'cause a user renamed or moved a sheet, then I reckon I (half-) deserve to get that annoying call "Your macro doesn't work! Can you come over?" But if he's gone and altered a codename then (a) he shoulda known better :diablo: and (b) he's probably smart enough to debug it himself.
Sure. How about protection? :)

GT said:
Again, thanks for taking the time to post the collection and array code. Now where did our OP get off to???
Based on:

OP said:
Please help as I am an extreme newbie to Excel Macros. Thanks.
{snip}
They probably got a little more than they were bargaining for at this point. :)
 
Upvote 0
Ok, call me a retard. I have employed the various implementations mentioned here and none of them have worked for me. They have worked on simpler worksheets that i made just to test them, but on my particular workbook it's not working. I uploaded the workbook to my website and if you guys could take a look at it and see whats up i'd appreciate it and at this point I know you guys love challenges and YES this is MUCH more than i expected Nate. But thank you. What I need done is for the sheets: Subj. Co. through Guidline Co. 10 with everything in between to hide rows when B:H ALL have dashes in them. In total that's 11 sheets. And yes the requirement has changed from C to B:H.

URL:
http://students.depaul.edu/~diqbal/TESTMOD.xls
 
Upvote 0
:rofl: We all missed an obvious pitfall! They ain't dashes. They're zeros formatted as dashes. (You could also set rngBottom based on column C, which isn't hidden.)

<font face=Courier New>

<SPAN style="color:#00007F">Sub</SPAN> HideRowsWithDashes2()

    <SPAN style="color:#00007F">Dim</SPAN> i <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, r <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>
    <SPAN style="color:#00007F">Dim</SPAN> wsArray <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN>, rngBottom <SPAN style="color:#00007F">As</SPAN> Range, rngCell <SPAN style="color:#00007F">As</SPAN> Range
    
    wsArray = Array(Sheet9, Sheet10, Sheet11, Sheet12, Sheet13, _
                  Sheet14, Sheet15, Sheet16, Sheet17, Sheet18, Sheet8)
    
    Application.ScreenUpdating = <SPAN style="color:#00007F">False</SPAN>
    <SPAN style="color:#00007F">For</SPAN> i = <SPAN style="color:#00007F">LBound</SPAN>(wsArray) <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(wsArray)
        <SPAN style="color:#00007F">Set</SPAN> rngBottom = wsArray(i).Range("B65536").End(xlUp)
<SPAN style="color:#007F00">'        Debug.Print rngBottom.Address</SPAN>
        <SPAN style="color:#00007F">For</SPAN> r = 1 <SPAN style="color:#00007F">To</SPAN> rngBottom.Row
            <SPAN style="color:#00007F">Set</SPAN> rngCell = wsArray(i).Cells(r, 2)
            <SPAN style="color:#00007F">If</SPAN> Application.WorksheetFunction.Sum(rngCell.Resize(, 7)) = 0 _
            And InStr(1, rngCell.NumberFormat, "-") <> 0 <SPAN style="color:#00007F">Then</SPAN> rngCell.EntireRow.Hidden = <SPAN style="color:#00007F">True</SPAN>
        <SPAN style="color:#00007F">Next</SPAN> r
    <SPAN style="color:#00007F">Next</SPAN> i
    Application.ScreenUpdating = <SPAN style="color:#00007F">True</SPAN>
  
<SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Sub</SPAN>


</FONT>
 
Upvote 0
Nate - this seems a bit sluggish on my machine. If you've got a better way to skin this cat, I'd love to see it.
 
Upvote 0
Hello Again,

Greg Truby said:
Nate - this seems a bit sluggish on my machine. If you've got a better way to skin this cat, I'd love to see it.
The procedure's already been crafted per your last two code submissions eh, you've shown yourself the way. 8-)

Here's what the compilation of the thread's efforts-to-date looks like:

<font face=Courier New><SPAN style="color:darkblue">Sub</SPAN> fubar3()
<SPAN style="color:darkblue">Dim</SPAN> ws <SPAN style="color:darkblue">As</SPAN> Worksheet, cl <SPAN style="color:darkblue">As</SPAN> Range, OrigCl <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">String</SPAN>, z <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Boolean</SPAN>
Application.ScreenUpdating = <SPAN style="color:darkblue">False</SPAN>

<SPAN style="color:darkblue">For</SPAN> <SPAN style="color:darkblue">Each</SPAN> ws <SPAN style="color:darkblue">In</SPAN> Worksheets([transpose(row(8:19))])
    <SPAN style="color:darkblue">Set</SPAN> cl = ws.[c:c].Find("0", lookat:=xlWhole, LookIn:=xlFormulas)
    <SPAN style="color:darkblue">If</SPAN> <SPAN style="color:darkblue">Not</SPAN> cl <SPAN style="color:darkblue">Is</SPAN> <SPAN style="color:darkblue">Nothing</SPAN> <SPAN style="color:darkblue">Then</SPAN>
        <SPAN style="color:darkblue">Let</SPAN> OrigCl = cl.Address
        <SPAN style="color:darkblue">If</SPAN> <SPAN style="color:darkblue">Not</SPAN> <SPAN style="color:darkblue">CBool</SPAN>(WorksheetFunction.Sum(cl(, 0).Resize(, 7))) <SPAN style="color:darkblue">Then</SPAN>
            z = <SPAN style="color:darkblue">Not</SPAN> z:  cl.EntireRow.Hidden = z
        <SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">If</SPAN>
        Do: <SPAN style="color:darkblue">Set</SPAN> cl = ws.[c:c].FindNext(cl)
            <SPAN style="color:darkblue">If</SPAN> cl <SPAN style="color:darkblue">Is</SPAN> <SPAN style="color:darkblue">Nothing</SPAN> <SPAN style="color:darkblue">Then</SPAN> <SPAN style="color:darkblue">Exit</SPAN> <SPAN style="color:darkblue">Do</SPAN>
            <SPAN style="color:darkblue">If</SPAN> cl.Address = OrigCl <SPAN style="color:darkblue">Then</SPAN> <SPAN style="color:darkblue">Exit</SPAN> <SPAN style="color:darkblue">Do</SPAN>
            <SPAN style="color:darkblue">If</SPAN> <SPAN style="color:darkblue">Not</SPAN> <SPAN style="color:darkblue">CBool</SPAN>(WorksheetFunction.Sum(cl(, 0).Resize(, 7))) <SPAN style="color:darkblue">Then</SPAN>
                cl.EntireRow.Hidden = <SPAN style="color:darkblue">True</SPAN>
            <SPAN style="color:darkblue">ElseIf</SPAN> z <SPAN style="color:darkblue">Then</SPAN>
                OrigCl = cl.Address: z = <SPAN style="color:darkblue">Not</SPAN> z
            <SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">If</SPAN>
        <SPAN style="color:darkblue">Loop</SPAN>
        <SPAN style="color:darkblue">Set</SPAN> cl = Nothing: <SPAN style="color:darkblue">Let</SPAN> OrigCl = <SPAN style="color:darkblue">Empty</SPAN>
    <SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">If</SPAN>
<SPAN style="color:darkblue">Next</SPAN>

Application.ScreenUpdating = <SPAN style="color:darkblue">True</SPAN>
<SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">Sub</SPAN></FONT>

This processes Subject Co.:Sheet9. I didn't time it, but it felt like less than minute... It is quite a bit of looping, despite the fact that the Find Method drastically reduces the loop. Still, probably faster than doing it by hand eh. :-D

Hope this helps. :)
 
Upvote 0
Holy ****! I didn't notice the percentage calcs below, I ran a second procedure:

<font face=Courier New><SPAN style="color:darkblue">Sub</SPAN> fubar4()
<SPAN style="color:darkblue">Dim</SPAN> ws <SPAN style="color:darkblue">As</SPAN> Worksheet, cl <SPAN style="color:darkblue">As</SPAN> Range, OrigCl <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">String</SPAN>, z <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Boolean</SPAN>
Application.ScreenUpdating = <SPAN style="color:darkblue">False</SPAN>

<SPAN style="color:darkblue">For</SPAN> <SPAN style="color:darkblue">Each</SPAN> ws <SPAN style="color:darkblue">In</SPAN> Worksheets([transpose(row(8:19))])
    <SPAN style="color:darkblue">Set</SPAN> cl = ws.[c:c].Find("0.0%", lookat:=xlWhole, LookIn:=xlValues)
    <SPAN style="color:darkblue">If</SPAN> <SPAN style="color:darkblue">Not</SPAN> cl <SPAN style="color:darkblue">Is</SPAN> <SPAN style="color:darkblue">Nothing</SPAN> <SPAN style="color:darkblue">Then</SPAN>
        <SPAN style="color:darkblue">Let</SPAN> OrigCl = cl.Address
        <SPAN style="color:darkblue">If</SPAN> <SPAN style="color:darkblue">Not</SPAN> <SPAN style="color:darkblue">CBool</SPAN>(WorksheetFunction.Sum(cl(, 0).Resize(, 7))) <SPAN style="color:darkblue">Then</SPAN>
            z = <SPAN style="color:darkblue">Not</SPAN> z:  cl.EntireRow.Hidden = z
        <SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">If</SPAN>
        Do: <SPAN style="color:darkblue">Set</SPAN> cl = ws.[c:c].FindNext(cl)
            <SPAN style="color:darkblue">If</SPAN> cl <SPAN style="color:darkblue">Is</SPAN> <SPAN style="color:darkblue">Nothing</SPAN> <SPAN style="color:darkblue">Then</SPAN> <SPAN style="color:darkblue">Exit</SPAN> <SPAN style="color:darkblue">Do</SPAN>
            <SPAN style="color:darkblue">If</SPAN> cl.Address = OrigCl <SPAN style="color:darkblue">Then</SPAN> <SPAN style="color:darkblue">Exit</SPAN> <SPAN style="color:darkblue">Do</SPAN>
            <SPAN style="color:darkblue">If</SPAN> <SPAN style="color:darkblue">Not</SPAN> <SPAN style="color:darkblue">CBool</SPAN>(WorksheetFunction.Sum(cl(, 0).Resize(, 7))) <SPAN style="color:darkblue">Then</SPAN>
                cl.EntireRow.Hidden = <SPAN style="color:darkblue">True</SPAN>
            <SPAN style="color:darkblue">ElseIf</SPAN> z <SPAN style="color:darkblue">Then</SPAN>
                OrigCl = cl.Address: z = <SPAN style="color:darkblue">Not</SPAN> z
            <SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">If</SPAN>
        <SPAN style="color:darkblue">Loop</SPAN>
        <SPAN style="color:darkblue">Set</SPAN> cl = Nothing: <SPAN style="color:darkblue">Let</SPAN> OrigCl = <SPAN style="color:darkblue">Empty</SPAN>
    <SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">If</SPAN>
<SPAN style="color:darkblue">Next</SPAN>

Application.ScreenUpdating = <SPAN style="color:darkblue">True</SPAN>
<SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">Sub</SPAN></FONT>
 
Upvote 0
:lol: I was wondering about that. I actually was scanning the number format to NOT hide them.

And [transpose(row(8:19))] ??? I'm completed stumped as to how or why this works. If'n you've the patience to explain, I'm curious. :bow:
 
Upvote 0
Well, not running numero 4 gets you there. But, I figure what's good for the goose is good for the gander eh, so hide 'em! You could combine the two and end up looping through the sheets once, but this isn't going to drastically alter performance at this point (I think...), might as well call #4 at the end of #3.

Why z = not z you ask? :lol: Because we've read our Ken Getz, and we took note of -> implemented sound advice presented in test 5.

The quick-stack array trickery has been commented on here:
http://www.mrexcel.com/board2/viewtopic.php?t=70907&start=3 8-)

Enjoy! :-D
 
Upvote 0

Forum statistics

Threads
1,222,703
Messages
6,167,738
Members
452,135
Latest member
Lugen

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top