On sobering up, this last solution from Mr xladept, looks like a nice solution to look at to get a bit of knowledge about what this “AutoFilter” is about.
So for the benefit of any novices catching this Thread , here is my “take” on what the “AutoFilter” is about, and in particular what we can learn from the last routines..
I haven’t used stuff like “AutoFilter” much myself: It seems to be one of those things that profis, use, but which can be a bit daunting to the novice VBA user..
Here is the last routine in a slightly SAlanitised form.
Rem 1 is the main part of the code concerned with “AutoFilter”. ( Typically a code line such as this would form about half of the important code lines related to a use of “AutoFilter” )Code:Sub NormanXLFoxAfterASecondThink_2() ' xladept http://www.excelfox.com/forum/showthread.php/2293-Move-values-in-rows-at-the-end-of-the-preceding-row?p=10878#post10878 Rem 0 Dim wa As Worksheet, wb As Worksheet: Set wb = Sheets("Before"): Set wa = Sheets("AfterASecondThink") wb.Activate ' We are working on wb, which means the the Range stuff beow should probably better be wb.Range , as it they arent, then it might be best to activate that worksheet because usually an unqualifed Range call will go to the active worksheet Rem 1 "The Filter thing" Part 1 wb.UsedRange.AutoFilter Field:=1, Criteria1:="=2018*" Rem 2 Loop all rows, "Hidden" and "Visible" Dim r As Long For r = 2 To Range("A" & Rows.Count).End(xlUp).Row + 1 ' For this code we must +1 to be sure to catch any last rouge number, beacus looking at this point, VBA will go back up to the last now "visible" row. This is just how VBA is wired to work. VBA uses and sees both "visible" and "invisible" rows, but .End(xlUp) is the VBA equivalent to keys Ctrl+Up which takes us to the last "visible" cell in a row If Rows(r).RowHeight = 0 And Rows(r - 1).RowHeight <> 0 And IsNumeric(Left(Range("A" & r), 1)) Then Range("A" & r - 1) = Range("A" & r - 1) & "," & Range("A" & r) Else End If Next r Rem 3 "The Filter thing" Part 2 wb.UsedRange.Offset(1, 0).SpecialCells(xlCellTypeVisible).Copy Destination:=wa.Cells(1, 1) wb.UsedRange.AutoFilter Rem 4 wa.Activate wa.Columns("A:A").AutoFit End Sub
The main “AutoFilter” bit in this code line is
______.AutoFilter Field:=1, Criteria:="=2018*"
( There are more optional arguments available, but I don’t understand them all yet ( https://docs.microsoft.com/en-us/off...nge.autofilter ) )
This “AutoFilter” thing is a Method of a Range. In this example it is applied to UsedRange. UsedRange is a bit of a dodgy thing to use, as it often does not give you what you expect. In this example we will get the range A1 : A40 if we are .
Field:=__ is column of the range that we are interests in. In our case we only have 1, but if we had a couple of columns then we could use 1 or 2 etc. This determines where VBA is going to look for the criteria you give it in the next argument.
Criteria:=__ is what is looked for. This argument will take “wild cards” , which in this example means basically that VBA will look in the first column of our range for a text which starts with "=2018". The * is taken as meaning anything.
Take look at the code….
( Hit Alt+F11 from the spreadsheet and look for it in a code module,
or
_1 Hit Alt+F8 to get the routine dialogue window )
_2 Select the routine
_3 Select to edit or work on the code
Alt8 SelectRoutine EditCode .JPG : https://imgur.com/aRHLZbC
)
Click anywhere in the routine.
Run it in F8 debug mode and stop close after wb.UsedRange.AutoFilter Field:=1, Criteria:="=2018*" ,
or
Click in the margin close after wb.UsedRange.AutoFilter Field:=1, Criteria:="=2018*" to put a stop in , and run using the play button
Stop Play.JPG : https://imgur.com/9M9uQlU
So you want to get at the point where the routine is paused something like this
Paused.JPG : https://imgur.com/alAqyS4
At this part of the routine progression, if you look at the main data sheet, you will now see that it has changed from the original , ( Worksheets: BEFORE http://www.excelfox.com/forum/showth...-row#post10870 ) , and now looks lIke
_____ Workbook: Data Sample.xlsm ( Using Excel 2007 32 bit )
Worksheet: BEFORE
Row\Col A B 1Configurable Alerts blabla: 112018, 1, 90515, 10024515, G9, SBlabla (HQ), CHE, BLABLA, blabla, 10012098, 12003.5 122018, 1, 90629, 10022334, P3, BLABLA blabla (blablabla), CHE, BLABLA,blabla, 10033609, 13941.72 132018, 1, 90709, 10020009, P4, Blabla og Blalala (NY), CHE, Blabla,Bla-ah, 152018, 1, 90765, 10012123, P4, Ch of Blabla(Blabla of Blabla), CHE, BLA-BLA,Bla Blabla, 172018, 1, 90712, 10022908, P4, Snr BLA Off (Strat BLa, BLA), CHE, BLABLA,Bla BLabla, 10023234, 192018, 1, 90919, 10020984, P2, Ass BLA Balbla, CHE, BLA,Blabla, 10033098, 10486.33 202018, 1, 95706, 10023098, NB, Assc BLA Blabal (LatBLAa), BLA, BLABLABLA,Blabla, 10034318, 292018, 1, 95716, 10018763, NA, Asst BLA Off (Blabla & Multi-BLa), BLA, BLA,Bla, 10097776, 8607.96 302018, 1, 99716, 10026132, G5, Snr BLA Asst (Bla Blabla), BLA, BLABLA,bla BLa, 18767043, 5477.44 312018, 1, 99716, 10016545, G6, Blabla Blabla (BLA), BLA, BLABLABLA,Blabla, 1097029, 41
That screen shot and the next code sections illustrate a lot of what / how the “AutoFilter” is.
When talking in Excel jargon about a spreadsheet looking like that last screenshot we might often say that we have the lines 11, 12, 13 , 15, 17, 19, 20 , 29, 30 , 31 as “visible” in the range A1:A40.
Or we might say the Range A1:A40 has “visible cells” of cells A11, A12, A13 , A15, A17, A19, A20 , A29, A30 , A31. Or we might say something similar, but the word “visible” will likely be used somehow.
Rem 2 This section gives a nice insight as to how the “AutoFilter” works.
( The Looping of this section is not so typically seen in coding using “AutoFilter” ).
Because of the particular requirement of this Thread, we need to check if we had any “rouge numbers”, which seem to have slipped off the line they were likely intended to be on and appear in the next line.
So the question is, having used the “AutoFilter” effectively to do the main filtering out of the lines we did not want, how do we now check the lines above our “visible” lines. … Well, the fact that the row height is checked and the complete routine seems to do what we want, illustrates to us that what “AutoFilter” appears to do: It appears to reduce the height of the rows which we do not want to 0 height. As far as we Humans perceive this, we regard such lines as “invisible”. To VBA they are not invisible. To VBA they are lines similar to any others. One of the VBA range properties of what we regard as “invisible” is a row height of 0. In other words our “invisible” row is a “row of zero height” to VBA.
We might say that the routine has at this point “filtered out” lines other than those with the text bit of “2018,” at the start. VBA has actually reduced the row height to 0 of all but the cells with “2018,” at the start.
The section of coding here in Rem 2 is similar to the looping in my original code in post #7, except that we no longer need to check for the bit of “2018,”. We simply look at lines of zero height in the now filtered range which also have a row above which has not been “filtered out” . In other words those two criteria are satisfied by
____If Rows(r).RowHeight = 0 And Rows(r - 1).RowHeight <> 0
With that condition met, then the “rogue numbers” are tacked on in a similar way as in my routine.
Here we have
Range("A" & r - 1).Value = Range("A" & r - 1).Value & Range("A" & r).Value
Because this routine differs in general from mine, in that it works directly with the spreadsheet, this step is somewhat more obvious than in my routine. ( My routine uses what is called a VBA arrays type coding, which puts all data in an internal array, manipulates that to produce a final output array which is then pasted into the worksheet in one go. Using “AutoFilter” ) is strictly called the using “Range AutoFilter Method” , and as such comes under the general heading of Worksheet functions which are mostly applied to worksheets. My code does more traditional elementary coding and mathematics internally to achieve similar final results )
Rem 3
The lines here would be typical of the second part the coding in a simple usage of “AutoFilter”
Usually we would like to have what is to us “visible” after the filtering, to be in some “normal” form.
Doing a simple .Copy of the range of what we “see” will probably give us copied in the clipboard some form of a total range of discontinuous cells, in our case something like A1,A11:A13,A15,A17,A19:A20,A29:A31. VBA tends in such a case of all the cells being “in line” to actual Hold that as if it was single 11 row range. So copying and pasting will likely get us near what we finally want.
There tends in the practice to be odd things that might catch you out doing that simple copy and paste. One thing to note is that the “AutoFilter” often catches the first row whether it meats the criteria or not. ( This is generally regarded as an option to keep the header row in any filtering work, which is often practically useful ). Sometimes adding a bit in a code line to be sure of copying just our “visible” rows is often a good idea. Taking these things into account, and knowing what you are doing, ( which I don’t too well here ) , will mean that rather than a simple line like
wb.UsedRange.Copy Destination:=wa.Cells(1, 1)
Instead something like this would be used to be sure to get what you want
wb.UsedRange.Offset(1, 0).SpecialCells(xlCellTypeVisible).Copy Destination:=wa.Cells(1, 1)
The .Offset(1, 0) is perhaps easy to understand as this will mean that we will not get the header row copied.
The .SpecialCells(xlCellTypeVisible) in one function is easy to Understand: it will limit us to not going too far down the worksheet with our copying. Copying to our last row would probably often do the same, but there are likely subtle reasons only to gained by experience to make the use of .SpecialCells(xlCellTypeVisible).
The things talked about, in particular in this Rem 3 code section, are the subtleties that can trip up the inexperienced. That is why “AutoFilter” way tends to be the way a profi might do it. So it is probably better left to them to do it. I tend to avoid it for fear of getting it wrong.
( Mr xladept of course, is, in reality, not quite what you might call a “Junior” thing, so he likely by now should know what he is doing …. :-) )
Bookmarks