View Single Post
  #2   Report Post  
Posted to microsoft.public.excel.programming
keepITcool keepITcool is offline
external usenet poster
 
Posts: 2,253
Default Leo Heuser format cleanup code, and a question


I've reworked Leo's code:

- skipped the documentation part...
- rather than add a worksheet I've tried to remain within VBA
as much as possible.
- reduced window jittering

To make it perfect I should expand UsedFormats to search for
numberformat's used in Styles,Pivots and Graphs..

(coding for xlXP+ it could more efficient... cause FindFormats can be
used)


I haven't extensively tested it...
but let me know what you think..




Option Explicit
Option Base 0

'USER32
Private Declare Function GetDesktopWindow _
Lib "user32" () As Long
Private Declare Function LockWindowUpdate _
Lib "user32" (ByVal hwndLock As Long) As Long


Sub ClearUnusedNumberFormats()
Dim cUsed As Collection
Dim cDefi As Collection
Dim cKill As Collection
Dim cSkip As Collection

Dim vItm As Variant
Dim sMsg As String

Set cUsed = UsedNumberFormats
Set cDefi = DefinedNumberFormats
Set cKill = New Collection
Set cSkip = New Collection

On Error Resume Next
For Each vItm In cDefi
If IsError(cUsed(vItm(1))) Then
Err.Clear
ActiveWorkbook.DeleteNumberFormat vItm(0)
If Err = 0 Then cKill.Add vItm Else cSkip.Add vItm
End If
Next

For Each vItm In cKill
sMsg = sMsg & vItm(1) & vbNewLine
Next
If sMsg = "" Then sMsg = "None..."
MsgBox sMsg, , "Deleted NumberFormats"


End Sub


Function UsedNumberFormats( _
Optional wkb As Workbook) As Collection
Dim cRes As Collection
Dim wks As Worksheet
Dim rng As Range


If wkb Is Nothing Then Set wkb = ActiveWorkbook

Set cRes = New Collection

On Error Resume Next
For Each wks In wkb.Worksheets
For Each rng In wks.UsedRange.Cells
cRes.Add Array(rng.NumberFormat, _
rng.NumberFormatLocal), rng.NumberFormatLocal
Next
Next
Set UsedNumberFormats = cRes
End Function


Function DefinedNumberFormats( _
Optional wkb As Workbook) As Collection
'Reworked from Leo Heusers original approach :)

Dim cRes As Collection
Dim rng(0 To 1) As Range
Dim sGen As String

Set cRes = New Collection
sGen = Application.International(xlGeneralFormatName)

If wkb Is Nothing Then Set wkb = ActiveWorkbook Else _
wkb.Activate

'Find a blank cell with General numberformat
With ActiveSheet.Cells
Set rng(0) = ActiveCell
Set rng(1) = .Find("", rng(0))
If rng(1) Is Nothing Then Set rng(1) = rng(0)
While rng(0).Address < rng(1).Address And rng( _
1).NumberFormatLocal < sGen
Set rng(1) = .FindNext(rng(1))
Wend
End With
If rng(1).NumberFormatLocal < sGen Then Exit Function
rng(1).Select

'Loop Thru the Dialog
cRes.Add Array(rng(1).NumberFormat, _
rng(1).NumberFormatLocal), rng(1).NumberFormatLocal
Application.Top = Application.Top - 5000
LockWindowUpdate GetDesktopWindow

On Error GoTo done
Do
DoEvents
SendKeys "{tab 3}{down}{enter}"
Application.Dialogs(xlDialogFormatNumber).Show cRes( _
cRes.Count)(1)
cRes.Add Array(rng(1).NumberFormat, _
rng(1).NumberFormatLocal), rng(1).NumberFormatLocal
Loop

done:

rng(1).NumberFormat = "General"
Set DefinedNumberFormats = cRes
LockWindowUpdate False
Application.Top = Application.Top + 5000


End Function




keepITcool

< email : keepitcool chello nl (with @ and .)
< homepage: http://members.chello.nl/keepitcool


GatesAntichrist wrote:

( DeleteUnusedCustomNumberFormats() , May 6.
2001)
Leo's fine code seems to still hold up but has a killer problem,
simulated below:
In XL2002, start a fresh sheet. "General" should be the default cell
format.
Type the mere digit 0 in cell A1. It ought to look like a 0, and be
General format.
A2 =COUNTIF(A1:A1,"0.0%")
A2 gets a 1 … ouch.

Those of you USENET vets who are in harmony with the code and Leo can
see how this gives a false negative, ruining the results. The
Application.COUNTIF here "tells" the code that "0.0%" is already shown
in the "formats being used" column list, though it isn't; it never
makes it in the "used" column and ultimately shows as unused. It is
not warm and fuzzy when you delete the format relying on that info!

Now for those of you that don't have the code or don't recall it or
don't follow along with the above paragraph:
1. Is this behavior new with XL2002? (that the countif returns 1 and
not 0)
2. Is COUNTIF really looking for text, or is it cleverly
type-converting? Can I "cast" somehow to subvert that?
3. Is the way out of this mess to use .Find method? Or
Application.[something else]?

TIA


---
Message posted from http://www.ExcelForum.com/