Convert between Excel file formats (.XLS, .XLSX, .XLSM) with/without macro option

AID: 8269
  • Status: Published

3095 points

  • Bydlmille
  • TypeGeneral
  • Posted on2011-10-15 at 02:32:05
Convert between Excel file formats (.XLS, .XLSX, .XLSM) with/without macro option
David Miller (dlmille)

Intro
Over this past Fall, I've had the opportunity to see several similar requests and have developed a couple related solutions associated with down-converting Excel 2007/2010 .XLSX files to Excel 2003 .XLS files http:/Q_27289693.html, and also converting Excel 2007/2010 .XLSM files to .XLSX files http:/Q_27323432.html.

After constructing the first solution, it only required a couple tweaks to create the second.  I thought it would be a good idea to take my solution and create a more generic utility to help us navigate between different Excel version (2003, 2007, 2010) and enable elimination of macros, as well.

This article focuses on delivering a utility to convert Excel files in a folder from .XLS, .XLSX, or .XLSM to .XLS, .XLSX, or .XLSM with an option to remove macros as part of the process.  While converting to .XLSX automatically removes all macros, it may be the user's desire to sustain the same file extension without macros (e.g., from .XLS to .XLS or .XLSM to .XLSM).

Credits
To eliminate macros programmatically, and to help out with folder browsing API's, I leveraged tips from Erlandsen Data Consulting, http://www.exceltip.com/show_tip/Modules,_Class_Modules_in_VBA/Delete_all_macros_in_a_workbook/document_using_VBA_in_Microsoft_Excel/505.html, and http://www.exceltip.com/st/Select_folder_names_using_VBA_in_Microsoft_Excel/449.html.  I also leveraged a tip from Ken Puls at http://www.excelguru.ca/node/30 to check for file existance.

How to Use
Just download the attached file, select the Search for file type, and Convert to file type, select from the 3 options:  Remove Macros, Silent mode (auto overwrite), and Silent mode (auto delete), then hit the Loop and Convert command button to initiate the process.
loopAndConvert.png
  • 331 KB
  • Main Interface
Main Interface

You will then be prompted to select a folder.  The application searches that folder for the Search file type.  If you have not selected any of the Silent Mode options, you'll be prompted with the number of files found, and to proceed/cancel.  If the Convert to file exists already, you would be prompted to overwrite that file/cancel, and whether you'd like to delete the old file after conversion.  If you run in silent mode, the application can assume you want to delete old files after conversion, and to overwrite existing files during conversion.
browseFolder.png
  • 21 KB
  • Select Folder
Select Folder

While this app has seen some testing, its always best to make a backup of your folders and test the app out for yourself.  Especially on mass conversions, until you're satisfied everything's working the way you think it should!  There are some "wrinkles" in the conversion process - recall converting Excel 2007 or 2010 files to Excel 2003 files is a down-conversion, hence some of the features, formatting, and capability could be lost in that conversion.  Having a backup, or not choosing the automatic delete feature on the old files during conversion may be a wise choice, which allows you to examine your converted files ahead of a manual delete process.
 
verbosePrompting.png
  • 18 KB
  • Verbose Prompting (not silent mode)
Verbose Prompting (not silent mode)

verbosePrompting2.png
  • 90 KB
  • Verbose Prompting (not silent mode)
Verbose Prompting (not silent mode)

At the end of the process, you will be advised the # of successful conversions.    
success.png
  • 472 KB
  • Success
Success


Here's the primary code:
 
Option Explicit
Sub loopConvert()
Dim fPath As String
Dim fName As String, fSaveAsFilePath As String, fOriginalFilePath As String
Dim wBook As Workbook, fFilesToProcess() As String
Dim numconverted As Long, cntToConvert As Long, i As Long
Dim killOnSave As Boolean, xMsg As Long, overWrite As Boolean, pOverWrite As Boolean
Dim silentMode As Boolean
Dim removeMacros As Boolean
Dim fromFormat As String, toformat As String
Dim saveFormat As Long
Dim wkb As Workbook, wks As Worksheet

    Set wkb = ThisWorkbook
    Set wks = wkb.Sheets("Control Panel")
    
    removeMacros = IIf(wks.CheckBoxes("Check Box 1").Value = 1, True, False)
    silentMode = IIf(wks.CheckBoxes("Check Box 2").Value = 1, True, False)
    killOnSave = IIf(wks.CheckBoxes("Check Box 3").Value = 1, True, False)
    
    fromFormat = wkb.Names("fromFormat").RefersToRange
    toformat = wkb.Names("toFormat").RefersToRange
    saveFormat = IIf(toformat = ".XLS", xlExcel8, IIf(toformat = ".XLSX", xlOpenXMLWorkbook, xlOpenXMLWorkbookMacroEnabled))

    Application.DisplayAlerts = False 'no user prompting, taking all defaults
    Application.ScreenUpdating = False
    
    fPath = GetFolderName("Select Folder for " & fromFormat & " to " & toformat & " conversion")
    
    If fPath = "" Then
        MsgBox "You didn't select a folder", vbCritical, "Aborting!"
        Exit Sub
    Else
        fName = Dir(fPath & "\*" & fromFormat)
        If fName = "" Then
            MsgBox "There aren't any " & fromFormat & " files in the " & fPath & " directory", vbCritical, "Aborting"
            Exit Sub
        Else 'get a file count of files to be processed, then process them in the next step

            Do
                If UCase(Right(fName, Len(fromFormat))) = UCase(fromFormat) Then 'to differentiate between dir *.xls and inadvertently get *.xls???
                    ReDim Preserve fFilesToProcess(cntToConvert) As String
                    fFilesToProcess(cntToConvert) = fName
                    cntToConvert = cntToConvert + 1
                End If
                
                fName = Dir
                
            Loop Until fName = ""
            
            If cntToConvert = 0 Then 'we were looking for .XLS and there was only .XLS??? or nothing, then abort
                MsgBox "There aren't any " & fromFormat & " files in the " & fPath & " directory", vbCritical, "Aborting"
                Exit Sub
            End If
            
            If Not silentMode Then
                xMsg = MsgBox("There are " & cntToConvert & " " & fromFormat & " files to convert to " & toformat & ".  Do you want to delete the " & fromFormat & " files as they are processed?", vbYesNoCancel, "Select an Option")
                killOnSave = False 'already false, but just a reminder this is in here!
                
                If xMsg = vbYes Then
                    killOnSave = True
                ElseIf xMsg = vbCancel Then
                    GoTo processComplete
                End If
            Else
                pOverWrite = True
            End If
            
            Application.EnableEvents = False 'turn off events so macros don't fire on excel file opens
            
            For i = 0 To cntToConvert - 1 'process each file for conversion, displaying status as progress...
            
                Application.StatusBar = "Processing: " & i + 1 & " of " & cntToConvert & " file: " & fName
                
                fName = fFilesToProcess(i)
                'open and convert file
                On Error GoTo errHandler
                fOriginalFilePath = fPath & "\" & fName
                
                'you could also check to see if the save as file already exists, before you open convert and save on top!
                overWrite = False
                fSaveAsFilePath = fPath & "\" & Mid(fName, 1, Len(fName) - Len(fromFormat)) & toformat
                If Not pOverWrite Then
                    If FileFolderExists(fSaveAsFilePath) Then
                        xMsg = MsgBox("File: " & fSaveAsFilePath & " already exists, overwrite?", vbYesNoCancel, "Hit Yes to Overwrite, No to Skip, Cancel to quit")
                        If xMsg = vbYes Then
                            overWrite = True
                        ElseIf xMsg = vbCancel Then
                            GoTo processComplete
                        End If
                    Else
                        overWrite = True
                    End If
                Else
                    overWrite = pOverWrite
                End If
                If overWrite Then
                    Set wBook = Application.Workbooks.Open(fOriginalFilePath)
                    
                    If removeMacros And (toformat = ".XLS" Or toformat = ".XLSM") And (fromFormat <> ".XLSX") Then
                    'use Remove Macro Helper
                        Call RemoveAllMacros(wBook)
                    End If
                    
                    wBook.SaveAs Filename:=fSaveAsFilePath, FileFormat:=saveFormat
                    wBook.Close savechanges:=False
                    numconverted = numconverted + 1
                    
                    'optionally, you can delete the file you converted from
                    If killOnSave And fromFormat <> toformat Then
                        Kill fOriginalFilePath
                    End If
                End If
                
            Next i
        End If
    End If
    
processComplete:
    On Error GoTo 0
    MsgBox "Completed " & numconverted & " " & fromFormat & " to " & toformat & " conversions", vbOKOnly
    Application.EnableEvents = True 'uncomment if doing other conversions where macros are involved in source workbooks
    Application.StatusBar = False
    Application.DisplayAlerts = True
    Application.ScreenUpdating = False
    Exit Sub
    
errHandler:
    Application.StatusBar = False
    MsgBox "For some reason, could not open/save the file: " & fPath & "\" & fName, vbCritical, "Aborting!"
    Resume processComplete
    
End Sub
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:

Select allOpen in new window



You may note that the primary command handling the conversion is the statement:

saveFormat = IIf(toformat = ".XLS", xlExcel8, IIf(toformat = ".XLSX", xlOpenXMLWorkbook, xlOpenXMLWorkbookMacroEnabled))

To enhance this further to your needs, it should be easy enough to modify this to add additional conversion types (e.g., Excel 97/97, 2000, CSV, etc.), whilst modifying the drop downs on the Control Panel tab of the workbook.

Attachment:  Attached, please find the loopAndConvert.xlsm workbook that contains the entire codeset.  I hope you enjoyed the article, and can get some time-saving benefit from the utility.

Enjoy!

Dave
Asked On
2011-10-15 at 02:32:05ID8269
Tags

Excel

,

File

,

Conversion

Topic

Microsoft Excel Spreadsheet Software

Views
1352

Comments

Expert Comment

by: SiddharthRout on 2011-10-15 at 02:41:50ID: 32490

A great simple utility which will save lot of user time. Great work David as usual :)

Sid

Expert Comment

by: xllvr on 2011-10-17 at 09:18:31ID: 32574

Great idea!  Thanks for posting.

Add your Comment

Please Sign up or Log in to comment on this article.

Join Experts Exchange Today

Gain Access to all our Tech Resources

Get personalized answers

Ask unlimited questions

Access Proven Solutions

Search 3.2 million solutions

Read In-Depth How-To Guides

1000+ articles, demos, & tips

Watch Step by Step Tutorials

Learn direct from top tech pros

And Much More!

Your complete tech resource

See Plans and Pricing

30-day free trial. Register in 60 seconds.

Loading Advertisement...

Top MS Excel Experts

  1. dlmille

    1,351,499

    Genius

    10,680 points yesterday

    Profile
    Rank: Genius
  2. ssaqibh

    542,555

    Sage

    0 points yesterday

    Profile
    Rank: Genius
  3. rorya

    381,757

    Wizard

    4,225 points yesterday

    Profile
    Rank: Savant
  4. imnorie

    334,112

    Wizard

    0 points yesterday

    Profile
    Rank: Genius
  5. teylyn

    282,850

    Guru

    20 points yesterday

    Profile
    Rank: Genius
  6. barryhoudini

    280,460

    Guru

    0 points yesterday

    Profile
    Rank: Genius
  7. redmondb

    235,511

    Guru

    2,000 points yesterday

    Profile
    Rank: Sage
  8. matthewspatrick

    230,947

    Guru

    2,010 points yesterday

    Profile
    Rank: Savant
  9. byundt

    197,840

    Guru

    820 points yesterday

    Profile
    Rank: Savant
  10. zorvek

    144,626

    Master

    0 points yesterday

    Profile
    Rank: Savant
  11. StephenJR

    136,537

    Master

    0 points yesterday

    Profile
    Rank: Genius
  12. nutsch

    117,005

    Master

    0 points yesterday

    Profile
    Rank: Genius
  13. gowflow

    110,036

    Master

    0 points yesterday

    Profile
    Rank: Sage
  14. MartinLiss

    107,333

    Master

    0 points yesterday

    Profile
    Rank: Wizard
  15. GlennLRay

    95,652

    Master

    0 points yesterday

    Profile
    Rank: Guru
  16. robhenson

    90,250

    Master

    0 points yesterday

    Profile
    Rank: Sage
  17. ScriptAddict

    88,470

    Master

    0 points yesterday

    Profile
    Rank: Guru
  18. kgerb

    85,022

    Master

    0 points yesterday

    Profile
    Rank: Wizard
  19. aikimark

    84,456

    Master

    3,310 points yesterday

    Profile
    Rank: Genius
  20. andrewssd3

    80,242

    Master

    0 points yesterday

    Profile
    Rank: Wizard
  21. Wiesje

    69,918

    Master

    0 points yesterday

    Profile
    Rank: Master
  22. Shanan212

    66,418

    Master

    0 points yesterday

    Profile
    Rank: Master
  23. krishnakrkc

    59,548

    Master

    0 points yesterday

    Profile
    Rank: Wizard
  24. Michael74

    54,744

    Master

    0 points yesterday

    Profile
    Rank: Wizard
  25. regmigrant

    51,070

    Master

    0 points yesterday

    Profile
    Rank: Guru

Hall Of Fame