Nee,
As I said, I've also had situations at work where I have distributed spreadsheets with custom toolbars and then I would like to get rid of them. So (as workload permitted) I put together a tool for myself to use to solve this problem. The tool could be placed on a network drive or else set up the values and then e-mail to users for them to open and run. There's a custom button underneath the input cells that runs the main macro. Alas COLO's gem of a utility didn't capture it. But you could launch w/ Alt+F8 or, if confident inputs are well-defined, use the WB_Open() method to launch Sub KillCustomToolbars().
Input cells are C2:C4. In the code I reference via named ranges on the small chance that I'd ever change the layout of the input sheet.
Input Sheet:
Toolbar Killer.xls |
---|
|
---|
| A | B | C | D |
---|
1 | | | | |
---|
2 | | NameofToolbartoKill | Custom1 | |
---|
3 | | NameofFiletoSeek(Dirty)(Canusewildcards) | *deletete?t*.xls | |
---|
4 | | Name&PathofNetworkReplacement(Clean) | u:\buttondeletetest-clean.xls | |
---|
5 | | | | |
---|
6 | | | | |
---|
7 | | | | |
---|
8 | | | | |
---|
|
---|
The code itself is in a module and is as follows:<font face=Courier New><SPAN style="color:#00007F">Option</SPAN><SPAN style="color:#00007F">Explicit</SPAN><SPAN style="color:#007F00">' Written by: Greg Truby</SPAN><SPAN style="color:#007F00">' Last Revision: 04 Nov 2003</SPAN><SPAN style="color:#007F00">' Revision History:</SPAN><SPAN style="color:#007F00">'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯</SPAN><SPAN style="color:#00007F">Sub</SPAN> KillCustomToolBars()<SPAN style="color:#007F00">'______________________________________________________________________________</SPAN><SPAN style="color:#007F00">' Procedure to attempt to kill off obsolete custom toolbars that were</SPAN><SPAN style="color:#007F00">' attached to spreadsheets distributed to others.</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> strToolbarToKill<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">String</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> strDirtyFile<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">String</SPAN>, strCleanFile<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">String</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> strMsgOptions<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">String</SPAN>, strMsgInstruct<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">String</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> booShowInstruct<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Boolean</SPAN>, intMsgResult<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Integer</SPAN>, intChoice<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Integer</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> varFileList<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Variant</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> objFileSystem<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Object</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> wbDirty<SPAN style="color:#00007F">As</SPAN> Workbook, wbActive<SPAN style="color:#00007F">As</SPAN> Workbook, wbOther<SPAN style="color:#00007F">As</SPAN> Workbook
<SPAN style="color:#00007F">Dim</SPAN> i%
strToolbarToKill = [TargetToolbar] <SPAN style="color:#007F00">' Named Range</SPAN>
strDirtyFile = [FileNameDirty] <SPAN style="color:#007F00">' Named Range</SPAN>
strCleanFile = [FileNameClean] <SPAN style="color:#007F00">' Named Range</SPAN>
<SPAN style="color:#007F00">' _____Ready to go?</SPAN>
<SPAN style="color:#00007F">If</SPAN> strToolbarToKill = "" _
<SPAN style="color:#00007F">Or</SPAN> strDirtyFile = "" _
<SPAN style="color:#00007F">Or</SPAN> strCleanFile = ""<SPAN style="color:#00007F">Then</SPAN>
MsgBox "One or more required fields are blank.", vbCritical, "Missing Required Field"
<SPAN style="color:#00007F">Exit</SPAN><SPAN style="color:#00007F">Sub</SPAN>
<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">If</SPAN>
<SPAN style="color:#00007F">If</SPAN> Dir(strCleanFile) = ""<SPAN style="color:#00007F">Then</SPAN>
MsgBox strCleanFile & " not found.", vbCritical, "File Not Found"
<SPAN style="color:#00007F">Exit</SPAN><SPAN style="color:#00007F">Sub</SPAN>
<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">If</SPAN>
<SPAN style="color:#007F00">' _____Variable setup</SPAN>
<SPAN style="color:#00007F">Set</SPAN> objFileSystem = CreateObject("Scripting.FileSystemObject")
<SPAN style="color:#00007F">Set</SPAN> wbActive = ActiveWorkbook
booShowInstruct =<SPAN style="color:#00007F">True</SPAN>
strMsgInstruct = "In order to clean " & UCase(strToolbarToKill) & " from this file you must " & _
"use the Customize Toolbar dialog box." & vbCr & _
"(Customize Toolbar dialog will be displayed after " & _
"this Instructions box is closed.)" & vbCr & vbCr & _
"1. Click the ATTACH... button." & vbCr & _
"2. Click " & UCase(str<SPAN style="color:#00007F">To</SPAN>olbarToKill) & " in the righthand list." & vbCr & _
"3. Click the DELETE button in between the two lists." & vbCr & _
"4. Click OK." & vbCr & _
"5. Click CLOSE." & vbCr & vbCr & _
"-- Close this Instruction box using OK to see these instructions " & _
"if another file is found." & vbCr & _
"-- Close this<SPAN style="color:#00007F">In</SPAN>struction box using CANCEL to avoid seeing these " & _
"instructions again."
<SPAN style="color:#007F00">' _____Close all other open wb prior to clean up</SPAN>
<SPAN style="color:#00007F">For</SPAN><SPAN style="color:#00007F">Each</SPAN> wbOther In Workbooks
<SPAN style="color:#00007F">If</SPAN> wbOther.Name<> wbActive.Name _
And UCase(wbOther.Name)<> "PERSONAL.XLS"<SPAN style="color:#00007F">Then</SPAN>
wbOther.Close
<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">If</SPAN>
<SPAN style="color:#00007F">Next</SPAN> wbOther
<SPAN style="color:#007F00">' _____Delete "General" Instance of Toolbar</SPAN>
<SPAN style="color:#00007F">If</SPAN> LookForToolbar(strToolbarToKill)<SPAN style="color:#00007F">Then</SPAN>
Application.CommandBars(strToolbarToKill).Delete
<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">If</SPAN>
<SPAN style="color:#007F00">' _____Look for files that match DirtyFile spec</SPAN>
<SPAN style="color:#007F00">' _____(load names and paths into array)</SPAN>
varFileList = LookForFile(strDirtyFile)
<SPAN style="color:#00007F">If</SPAN> TypeName(varFileList) = "String"<SPAN style="color:#00007F">Then</SPAN> <SPAN style="color:#007F00">' will return "String()" if found any</SPAN>
<SPAN style="color:#00007F">If</SPAN> varFileList = "Error"<SPAN style="color:#00007F">Then</SPAN>
MsgBox "Execution Canceled", vbCritical, "Error"
<SPAN style="color:#00007F">ElseIf</SPAN> varFileList = "False"<SPAN style="color:#00007F">Then</SPAN>
MsgBox "No instances of " & strDirtyFile & " found.", vbInformation
<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">If</SPAN>
<SPAN style="color:#00007F">GoTo</SPAN> Exit_KillCustomToolbars
<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">If</SPAN>
<SPAN style="color:#007F00">' _____do the cleanup</SPAN>
<SPAN style="color:#00007F">For</SPAN> i = 1 To<SPAN style="color:#00007F">UBound</SPAN>(varFileList)
<SPAN style="color:#00007F">Set</SPAN> wbDirty = Workbooks.Open(Filename:=varFileList(i))
<SPAN style="color:#00007F">If</SPAN> LookFor<SPAN style="color:#00007F">To</SPAN>olbar(strToolbarToKill)<SPAN style="color:#00007F">Then</SPAN>
strMsgOptions = UCase(strToolbarToKill) & " is attached to file:" & vbCr & _
<SPAN style="color:#00007F">String</SPAN>(80, "-") & vbCr & _
varFileList(i) & vbCr & _
<SPAN style="color:#00007F">String</SPAN>(80, "-") & vbCr & vbCr & _
"Would you like to?" & vbCr & vbCr & _
"1. OVERWRITE this file with the clean copy from the network." & vbCr & _
"2. CLEAN " & UCase(strToolbarToKill) & _
" from this file (preserve any data in [" & wbDirty.Name & "])." & vbCr & _
"3. DELETE [" & wbDirty.Name & "] from this directory."
intChoice = 0
<SPAN style="color:#00007F">Do</SPAN>
intChoice = Val(InputBox(strMsgOptions, "Select Cleanup Option", "1"))
<SPAN style="color:#00007F">Loop</SPAN><SPAN style="color:#00007F">Until</SPAN> intChoice > 0 And intChoice< 4
<SPAN style="color:#00007F">Select</SPAN><SPAN style="color:#00007F">Case</SPAN> intChoice
<SPAN style="color:#00007F">Case</SPAN> 1 <SPAN style="color:#007F00">' Overwrite</SPAN>
wbDirty.Close SaveChanges:=<SPAN style="color:#00007F">False</SPAN>
objFileSystem.CopyFile Source:=strCleanFile, _
Destination:=varFileList(i)
<SPAN style="color:#00007F">Case</SPAN> 2 <SPAN style="color:#007F00">' Clean</SPAN>
<SPAN style="color:#00007F">If</SPAN> booShowInstruct<SPAN style="color:#00007F">Then</SPAN>
intMsgResult = MsgBox(strMsgInstruct, vbOKCancel, "Instructions")
booShowInstruct = (intMsgResult = vbOK)
<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">If</SPAN>
Application.Dialogs(xlDialogCustomizeToolbar).Show
wbDirty.Close SaveChanges:=<SPAN style="color:#00007F">True</SPAN>
<SPAN style="color:#00007F">Case</SPAN> 3 <SPAN style="color:#007F00">' Kill</SPAN>
wbDirty.Close<SPAN style="color:#00007F">False</SPAN>
Kill varFileList(i)
<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">Select</SPAN>
<SPAN style="color:#00007F">Else</SPAN>
wbDirty.Close<SPAN style="color:#00007F">False</SPAN>
<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">If</SPAN>
<SPAN style="color:#00007F">Next</SPAN> i
<SPAN style="color:#007F00">' _____One last time...</SPAN>
<SPAN style="color:#00007F">If</SPAN> LookForToolbar(strToolbarToKill)<SPAN style="color:#00007F">Then</SPAN>
Application.CommandBars(strToolbarToKill).Delete
<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">If</SPAN>
Exit_KillCustomToolbars:<SPAN style="color:#007F00">'"""""""""""""""""""""""</SPAN>
<SPAN style="color:#00007F">Set</SPAN> objFileSystem =<SPAN style="color:#00007F">Nothing</SPAN>
<SPAN style="color:#00007F">Set</SPAN> wbActive =<SPAN style="color:#00007F">Nothing</SPAN>
<SPAN style="color:#00007F">Set</SPAN> wbDirty =<SPAN style="color:#00007F">Nothing</SPAN>
<SPAN style="color:#00007F">Set</SPAN> wbOther =<SPAN style="color:#00007F">Nothing</SPAN><SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">Sub</SPAN><SPAN style="color:#007F00">'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯</SPAN><SPAN style="color:#00007F">Function</SPAN> LookForFile(strFileName)<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Variant</SPAN><SPAN style="color:#007F00">'______________________________________________________________________________</SPAN>
<SPAN style="color:#007F00">' Search through all files on drive C:\ looking for strFileName</SPAN><SPAN style="color:#007F00">' Return an array of filenames (and paths) if found</SPAN><SPAN style="color:#007F00">' Return "False" (string) if not found, "Error" if hit error.</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> strPath<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">String</SPAN>, strLongName<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">String</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> strDirResult<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">String</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> varShellRetVal<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Variant</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> intHandle<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Integer</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> strRetVal()<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">String</SPAN>
<SPAN style="color:#00007F">ReDim</SPAN> strRetVal(0)
<SPAN style="color:#00007F">On</SPAN><SPAN style="color:#00007F">Error</SPAN><SPAN style="color:#00007F">GoTo</SPAN> ErrorLookForFile
<SPAN style="color:#007F00">' _____Run a batch file that lists all directories on C:</SPAN>
<SPAN style="color:#007F00">' _____(if this batch file does not yet exist, create it).</SPAN>
intHandle = FreeFile
<SPAN style="color:#00007F">If</SPAN> Dir("C:\DirList.bat") = ""<SPAN style="color:#00007F">Then</SPAN> CreateBatchDirectoryLister
<SPAN style="color:#00007F">If</SPAN> Dir("C:\Directories.txt")<> ""<SPAN style="color:#00007F">Then</SPAN> Kill "C:\Directories.txt"
varShellRetVal = Shell("C:\DirList.bat", vbMaximizedFocus)
<SPAN style="color:#00007F">If</SPAN> varShellRetVal = 0<SPAN style="color:#00007F">Then</SPAN> Err.Raise vbObjectError + 1, "LookForFile", "Bad DOS Dir Return"
<SPAN style="color:#007F00">' _____VB trying to open the file before DOS is closing</SPAN>
<SPAN style="color:#007F00">' _____its output file, so slow it down just a bit.</SPAN>
Loiter 3
<SPAN style="color:#007F00">' _____Run through the text file created by the batch file</SPAN>
<SPAN style="color:#007F00">' _____looking for files that meet specs in strFileName</SPAN>
<SPAN style="color:#00007F">Open</SPAN> "C:\Directories.txt"<SPAN style="color:#00007F">For</SPAN><SPAN style="color:#00007F">Input</SPAN><SPAN style="color:#00007F">As</SPAN> #intHandle
<SPAN style="color:#00007F">Do</SPAN><SPAN style="color:#00007F">While</SPAN><SPAN style="color:#00007F">Not</SPAN> EOF(intHandle)
Line<SPAN style="color:#00007F">Input</SPAN> #intHandle, strPath
strLongName = strPath & "\" & strFileName
strDirResult = Dir(strLongName)
<SPAN style="color:#00007F">Do</SPAN><SPAN style="color:#00007F">While</SPAN> strDirResult<> ""
<SPAN style="color:#00007F">ReDim</SPAN><SPAN style="color:#00007F">Preserve</SPAN> strRetVal(UBound(strRetVal) + 1)
strRetVal(UBound(strRetVal)) = strPath & "\" & strDirResult
strDirResult = Dir()
<SPAN style="color:#00007F">Loop</SPAN>
<SPAN style="color:#00007F">Loop</SPAN>
<SPAN style="color:#00007F">Close</SPAN> #intHandle
<SPAN style="color:#00007F">If</SPAN><SPAN style="color:#00007F">UBound</SPAN>(strRetVal) > 0<SPAN style="color:#00007F">Then</SPAN>
LookForFile = strRetVal
<SPAN style="color:#00007F">Else</SPAN>
LookForFile = "False"
<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">If</SPAN>
<SPAN style="color:#00007F">Exit</SPAN><SPAN style="color:#00007F">Function</SPAN>
ErrorLookForFile:<SPAN style="color:#007F00">'""""""""""""""""</SPAN>
MsgBox "Error: " & Err.Number & vbCrLf & _
"Desc: " & Err.Description & vbCrLf & _
"Source: " & Err.Source, _
vbCritical, "Error"
LookForFile = "Error"<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">Function</SPAN><SPAN style="color:#007F00">'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯</SPAN><SPAN style="color:#00007F">Private</SPAN><SPAN style="color:#00007F">Sub</SPAN> CreateBatchDirectoryLister()<SPAN style="color:#007F00">'______________________________________________________________________________</SPAN><SPAN style="color:#007F00">' Create a DOS Batch file that will list all directories into a text file</SPAN><SPAN style="color:#007F00">' Then use SHELL to execute the batch file and create C:\Directories.txt</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> intHandle<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Integer</SPAN>
intHandle = FreeFile
<SPAN style="color:#00007F">Open</SPAN> "C:\DirList.bat"<SPAN style="color:#00007F">For</SPAN><SPAN style="color:#00007F">Output</SPAN><SPAN style="color:#00007F">As</SPAN> #intHandle
<SPAN style="color:#007F00">' _____Use PRINT command because WRITE command embeds quotation marks</SPAN>
<SPAN style="color:#00007F">Print</SPAN> #intHandle, "cls"
<SPAN style="color:#00007F">Print</SPAN> #intHandle, "C:"
<SPAN style="color:#00007F">Print</SPAN> #intHandle, "echo Creating List of All Directories"
<SPAN style="color:#00007F">Print</SPAN> #intHandle, "dir c:\ /a:d /b /s > c:\Directories.txt"
<SPAN style="color:#00007F">Close</SPAN> #intHandle<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">Sub</SPAN><SPAN style="color:#007F00">'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯</SPAN><SPAN style="color:#00007F">Function</SPAN> LookForToolbar(strBarSought)<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Boolean</SPAN><SPAN style="color:#007F00">'______________________________________________________________________________</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> i%
LookForToolbar =<SPAN style="color:#00007F">False</SPAN> <SPAN style="color:#007F00">' Default return value</SPAN>
<SPAN style="color:#00007F">For</SPAN> i = 1 To Application.CommandBars.Count
<SPAN style="color:#00007F">If</SPAN> Application.CommandBars(i).Name = strBarSought<SPAN style="color:#00007F">Then</SPAN>
LookForToolbar =<SPAN style="color:#00007F">True</SPAN>
<SPAN style="color:#00007F">Exit</SPAN><SPAN style="color:#00007F">For</SPAN>
<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">If</SPAN>
<SPAN style="color:#00007F">Next</SPAN> i<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">Function</SPAN><SPAN style="color:#007F00">'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯</SPAN><SPAN style="color:#00007F">Sub</SPAN> Loiter(intSecToWait<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Integer</SPAN>)<SPAN style="color:#007F00">'______________________________________________________________________________</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> newHour<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Integer</SPAN>, newMinute<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Integer</SPAN>, newSecond<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Integer</SPAN>, WaitTime<SPAN style="color:#00007F">As</SPAN><SPAN style="color:#00007F">Date</SPAN>
newHour = Hour(Now())
newMinute = Minute(Now())
newSecond = Second(Now()) + intSecToWait
WaitTime = TimeSerial(newHour, newMinute, newSecond)
Application.Wait WaitTime<SPAN style="color:#00007F">End</SPAN><SPAN style="color:#00007F">Sub</SPAN></FONT>
Hope this is of any help to you.
Regards,