
Originally Posted by
Doc.AElstein
......
. However there are some very strange “quirks” I found, such as using the UsedRange.Row or UsedRange.Rows.Count method after emptying the cells sometimes reset the Used Range in the sheet to nothing which then prevented my code from working…....
. Hi Alan,
. 1) It would appear that any reference to UsedRange forces Excel to update its memory of the Used range. Again documentation appears imprecise on this one.
.
. Presumably in your experimenting with the .SpecialCells where you placed something in a cell and deleted it, VBA remembered this entry, taking it then as part of the used Range. Your results tended to prove this. Unfortunately you cannot prove it through use of a UsedRange property such as .Rows.Count, or .Row etc. , as the use of the UsedRange Method updates to the current Used Range. We can however find the last Row ( or Column ) used from .Cells.SpecialCells(xlCellTypeLastCell).Row - As this does not appear to update the memory of the last Used Range
. Here a code to step through ( applied to a fresh sheet ) to demonstrate the above points:
…………………………………….
. Final conclusions:
If rng is some specified range in a worksheet, then for .Rng.SpecialCells
. 1 ). - the lower limit is set by that of rng lower limit ( provided there is a used range anywhere in the sheet )
. 2) – the upper limit is set by either
. 2a) rng upper limit
or
. 2b) the Last UsedRange upper limit of the sheet. ( except in cases noted in .7) below
. Which of the above a) or b) applies is that which is the smallest. ( except in cases noted in .7) below )
. Note: The UsedRange of the sheet must intersect the rng, or else the upper limit is zero and .SpecialCells will not work.
.
. 3a) The VBA memory of the last Used Range is not reset by .UsedRange.Clear, which sets the used range to nothing
. 3b) The VBA memory of the last Used Range is usually ( see .7) below ) reset by use of the UsedRange Properties
.Rows.Count / Row / Column / Columns.Count
. 3c) The VBA memory of the last Used Range upper limit can be found by
.SpecialCells(xlCellTypeLastCell).Row
and
.SpecialCells(xlCellTypeLastCell).Column
. ( These two statement do not reset the VBA memory of the last Used Range )
. 3d) After using .UsedRange.Clear , if an entry or entries made anywhere in the sheet , then the VBA memory will be reset to the "Box" including the cells with those entries in them
. 4) The actual Used Range is the "box" including cells with any entries in them.
. 5 ) The last Used Range, ( held in memory) remains this range from . 4) until
. 5a) an entry or entries are made in cells outside this "box" which increases the Used Range to a new bigger "box" to include the new cells
or
. 5b) The Used Range is cleared to nothing AND a new entry or entries are made
( . 6) note / reminder:- "Entries" can also be formatting such as text type of a cell ( even if no actual text is written in the cell ), or color etc. Etc. These formatting can only be reset to nothing, or rather to “as it was before any entry was made” by .Clear or by deleting the row or column in which that cell with a new entry is in )
. 7) As always a last bit of VBA “madness” that defies all sane reasoning: . If the sheet has a row with a format change of the sort such as row height, this will not be cleared by .Clear.
.UsedRange will recognise this row. So will .SpecialCells(xlCellTypeLastCell).Row and this will return a value equal to the row with this changed height. ( This memory will in this case not be reset by the UsedRange Properties .Rows.Count / Row / Column / Columns.Count – this is expected as .Clear for example does not remove it and .UsedRange still recognises it )
. However in this case, strangely, it will not be used to set the upper bound of .SpecialCells ..... But wait for it.... If there is or was any other entry or entries in the sheet anywhere resulting in a sheet Used Range intersecting the defined rng for .SpecialCells that were not cleared then it will be used as the upper bound of .SpecialCells !!! AARRRRGGGHHHHH!
. Alan
. P.s.: Another couple of last small “anomalies”: UsedRange.Row or UsedRange.Column Or UsedRange.Rows.Count etc. Return 1 rather than zero for no Used Range., ( either from a “virgin” sheet or a sheet emptied through .Clear ) Similarly things like .SpecialCells(xlCellTypeLastCell).Row return 1 rather than zero after the VBA Used Range has been reset to nothing
Bookmarks