0

我创建了一对可重用的子例程,它们一起工作以根据场合需要以不同的扩展名保存文件。

第一个 Sub 接收目录路径、文件名和所需的 Excel 扩展名。然后它调用第二个 Sub 以找到正确的 Excel FileFormat 编号并使用它以新格式保存文件:

Sub SaveFileWithNewExtension(DirectoryPath As String, NameOfFile As String, ExtensionToUse As String)
    Dim ExcelFileFormatNumber As String
    GetExcelFormatNumber ExtensionToUse, ExcelFileFormatNumber
    ActiveWorkbook.SaveAs DirectoryPath & "\" & NameOfFile & ExtensionToUse, FileFormat:=ExcelFileFormatNumber
End Sub

第二个子主要是我将使用的 Excel 文件格式的参考。对于 FileFormat 参考,我将 FileFormat Number 和 Name 都存储在一个数组中,这些数组键入不同的文件扩展名,所有这些都存储在我可以根据需要添加到的集合中:

Sub GetExcelFormatNumber(Extension As String, Optional Number As String, Optional ExcelFormat As String)
    'http://msdn.microsoft.com/en-us/library/office/ff198017.aspx
    'http://www.rondebruin.nl/mac/mac020.htm
    Dim ExtensionReference As New Collection
    ExtensionReference.Add Array("51", "xlOpenXMLWorkbook"), ".xlsx"
    ExtensionReference.Add Array("52", "xlOpenXMLWorkbookMacroEnabled"), ".xlsm"
    ExtensionReference.Add Array("50", "xlExcel12"), ".xlsb"
    ExtensionReference.Add Array("56", "xlExcel8"), ".xls"

    On Error GoTo NoMatch:
    ExcelFormat = ExtensionReference.Item(Extension)(1)
    Number = ExtensionReference.Item(Extension)(0)
    Exit Sub

NoMatch:
    msgbox "No Matching Extension was Found in the ExcelExtensionsAndNumbers Collection"

End Sub

将数组保存在这样的集合中似乎相当笨拙和不雅,这让我觉得我已经做到了这一点。

这是我的问题: 有没有更好的方法来存储信息,例如供其他潜艇使用?或者换一种说法:您是否有一种最喜欢的抽象数据的方式(如本例中的 FileFormat 代码),以便可以重复使用而无需每次都记住和重写它?


代码已被修改为使用 Cases 而不是集合,并更好地处理错误(正如 Siddharth Rout 对代码的重写所暗示的那样)。这行得通,并且案例结构对我来说更有意义:

Public Sub SaveFileWithNewExtension(DirectoryPath As String, NameOfFile As String, ExtensionToUse As String)
    Dim ExcelFileFormatNumber As String
    GetExcelFormatNumber ExtensionToUse, ExcelFileFormatNumber
    If ExcelFileFormatNumber <> "" Then
        ActiveWorkbook.SaveAs DirectoryPath & "\" & NameOfFile & ExtensionToUse, FileFormat:=ExcelFileFormatNumber
    Else
        msgbox "Invalid file extension. Case does not exist."
    End If
End Sub


Public Sub GetExcelFormatNumber(ExtensionToFind As String, Optional Number As String, Optional ExcelFormat As String)
    'reference - http://msdn.microsoft.com/en-us/library/office/ff198017.aspx
    'reference - http://www.rondebruin.nl/mac/mac020.htm
        Select Case ExtensionToFind
            Case ".xlsx":   Number = "51"
                            ExcelFormat = "xlOpenXMLWorkbook"
            Case ".xlsm":   Number = "52"
                            ExcelFormat = "xlOpenXMLWorkbookMacroEnabled"
            Case ".xlsb":   Number = "50"
                            ExcelFormat = "xlExcel12"
            Case ".xls":    Number = "56"
                            ExcelFormat = "xlExcel8"
            Case ".csv":    Number = "6"
                            ExcelFormat = "xlCSV"
            Case Else:      Number = ""
                            ExcelFormat = ""
        End Select
End Sub
4

2 回答 2

1

我同意。对于仅 4 个分机,阵列将是一个矫枉过正。我宁愿在函数中使用 Select Case。见下文

未经测试

Sub SaveFileWithNewExtension(DirectoryPath As String, _
                             NameOfFile As String, _
                             ExtensionToUse As String)
    Dim ExcelFileFormatNumber As Long
    ExcelFileFormatNumber = GetExcelFormatNumber(ExtensionToUse)

    If ExcelFileFormatNumber <> 0 Then
        ActiveWorkbook.SaveAs _
        DirectoryPath & _
        "\" & _
        NameOfFile & ExtensionToUse, _
        FileFormat:=ExcelFileFormatNumber
    Else
        MsgBox "Invalid Extenstion:"
    End If
End Sub

Function GetExcelFormatNumber(Extn As String) As Long
    '~~> FileFormat
    Select Case UCase(Extn)
        Case "XLS": GetExcelFormatNumber = 56
        Case "XLSX": GetExcelFormatNumber = 51
        Case "XLSM": GetExcelFormatNumber = 52
        Case "XLSB": GetExcelFormatNumber = 56
        '~~> Add for more... like csv etc
    End Select
End Function
于 2013-09-28T05:46:39.780 回答
0

这是一个相当通用的解决方案(从 Excel 2010 开始):

Function GetFileFormat(FileExt As String) As Long
    'Converts the specified file-extension string to its corresponding file-format code value, if known.  If the
    'file-format value for the specified extension is unknown, then a zero value is returned.
    '
    'WARNING: some extension strings map to multiple possible file-format values.  Such ambiguous specifications
    'are handled according to the following priority:
    '
    '   1) If the ambiguity is related to older vs. more recent versions of the file type, such as xlDBF4
    '      vs. xlDBF3 vs. xlDBF2, the most recent version is returned (xlDBF4).
    '
    '   2) If the ambiguity is related to more general vs. more specific versions of the file type, such as
    '       xlCurrentPlatformText vs. xlTextMSDOS vs. xlTextWindows and there is a Excel version-specific default
    '       option (xlCurrentPlatformText in this case) then the version-specific default is returned.
    '
    '   3) If the ambiguity is related to more general vs. more specific versions and there is no Excel version-
    '      specific default, such as xlCSV vs. xlCSVMSDOS vs. xlCSVWindows, the most general version is returned
    '      (xlCSV).
    '
    '   4) "xls" files present a special case of all of the above.  See the code commentary for that
    '      case, below.
    '
    '   If you need a different default conversion, then edit the code accordingly.
    '
    'NOTE: Though they should all work in theory, based on the available reference documentation, not all of
    '      these conversions have been tested (as of August 2014)!
    '
    'AUTHOR: Peter Straton
    '
    '*************************************************************************************************************

    'The following FileFormat constants are available in all versions from Excel 2003 onward, so they are listed
    'here for reference but there is no need to actually declare them.  If there is a possibility of running this
    'code under an earlier version of Excel, then experiment and un-comment any undefined constants.

    'Const xlAddIn                       As Long = 18    '.xla
    'Const xlAddIn8                      As Long = 18    '.xla
    'Const xlCSV                         As Long = 6     '.csv
    'Const xlCSVMac                      As Long = 22    '.csv
    'Const xlCSVMSDOS                    As Long = 24    '.csv
    'Const xlCSVWindows                  As Long = 23    '.csv
    'Const xlCurrentPlatformText         As Long = -4158 '.txt
    'Const xlDBF2                        As Long = 7     '.dbf
    'Const xlDBF3                        As Long = 8     '.dbf
    'Const xlDBF4                        As Long = 11    '.dbf
    'Const xlDIF                         As Long = 9     '.dif
    'Const xlExcel12                     As Long = 50    '.xlsb
    'Const xlExcel2                      As Long = 16    '.xls
    'Const xlExcel2FarEAst               As Long = 27    '.xls
    'Const xlExcel3                      As Long = 29    '.xls
    'Const xlExcel4                      As Long = 33    '.xls
    'Const xlExcel4Workbook              As Long = 35    '.xlw
    'Const xlExcel5                      As Long = 39    '.xls
    'Const xlExcel7                      As Long = 39    '.xls
    'Const xlExcel8                      As Long = 56    '.xls
    'Const xlExcel9795                   As Long = 43    '.xls
    'Const xlHtml                        As Long = 44    '.htm, .html
    'Const xlIntlAddIn                   As Long = 26    '
    'Const xlIntlMacro                   As Long = 25    '
    'Const xlNormal                      As Long = -4143 '
    'Const xlOpenDocumentSpreadsheet     As Long = 60    '.ods
    'Const xlOpenXMLAddIn                As Long = 55    '.xlam
    'Const xlOpenXMLTemplate             As Long = 54    '.xltx
    'Const xlOpenXMLTemplateMacroEnabled As Long = 53    '.xltm
    'Const xlOpenXMLWorkbook             As Long = 51    '.xlsx
    'Const xlOpenXMLWorkbookMacroEnabled As Long = 52    '.xlsm
    'Const xlSYLK                        As Long = 2     '.slk
    'Const xlTemplate                    As Long = 17    '.xlt
    'Const xlTemplate8                   As Long = 17    '.xlt
    'Const xlTextMac                     As Long = 19    '.txt
    'Const xlTextMSDOS                   As Long = 21    '.txt
    'Const xlTextPrinter                 As Long = 36    '.prn
    'Const xlTextWindows                 As Long = 20    '.txt
    'Const xlUnicodeText                 As Long = 42    '.txt
    'Const xlWebArchive                  As Long = 45    '.mht, .mhtml
    'Const xlWJ2WD1                      As Long = 14    '
    'Const xlWJ3                         As Long = 40    '
    'Const xlWJ3FJ3                      As Long = 41    '
    'Const xlWK1                         As Long = 5     '.wk1
    'Const xlWK1ALL                      As Long = 31    '.wk1
    'Const xlWK1FMT                      As Long = 30    '.wk1
    'Const xlWK3                         As Long = 15    '.wk3
    'Const xlWK3FM3                      As Long = 32    '.wk3
    'Const xlWK4                         As Long = 38    '.wk4
    'Const xlWKS                         As Long = 4     '.wks
    'Const xlWorkbookDefault             As Long = 51    '.xlsx
    'Const xlWorkbookNormal              As Long = -4143 '
    'Const xlWorks2FarEAst               As Long = 28    '.wks
    'Const xlWQ1                         As Long = 34    '.wq1
    'Const xlXMLData                     As Long = 47    '.xml
    'Const xlXMLSpreadsheet              As Long = 46    '.xml

    'The following FileFormat constants are not available in any versions of Excel up to and including Excel 2010,
    '(VBA7) so declare them in all cases.

    Const xlOpenXMLStrictWorkbook       As Long = 61    '.??? (Exists in Excel 2013 and later versions)
    Const UnsupportedPDF                As Long = 57    'As of 8/2014, this value works while debugging in VBE but
                                                        'fails otherwise!

    'The following FileFormat constants are not available in versions of Excel prior to Excel 2007 (VBA7),
    'so declare them in all versions earlier than VBA7.

    #If VBA7 = 0 Then   'Can't use the "Not" operator since defined built-in compiler constants evaluate
                        'to 1 (&H0001), not True (&HFFFF).  So (Not 1) = &HFFFE, which is also True since it
                        'isn't &H0000 (False).

        Const xlAddIn8                      As Long = 18    '.xla
        Const xlExcel12                     As Long = 50    '.xlsb
        Const xlExcel8                      As Long = 56    '.xls
        Const xlOpenDocumentSpreadsheet     As Long = 60    '.ods
        Const xlOpenXMLAddIn                As Long = 55    '.xlam
        Const xlOpenXMLTemplate             As Long = 54    '.xltx
        Const xlOpenXMLTemplateMacroEnabled As Long = 53    '.xltm
        Const xlOpenXMLWorkbook             As Long = 51    '.xlsx
        Const xlOpenXMLWorkbookMacroEnabled As Long = 52    '.xlsm
        Const xlTemplate8                   As Long = 17    '.xlt
        Const xlWorkbookDefault             As Long = 51    '.xlsx
    #End If

    'Though web references suggest xlXMLData should be defined in Excel 2003 (VBA6) only, it isn't actually
    'defined in my copy of VBA6, running under Excel 2003.  So don't actually restrict this declaration to
    'versions later than Excel 2003.

'    #If VBA6 = 0 And VBA7 = 1 Then 'All versions later than Excel 2003 (See note about "Not" operator, above)

        Const xlXMLData                     As Long = 47    '.xml
'    #End If

    Select Case UCase(Replace(FileExt, ".", ""))
        Case "CSV": GetFileFormat = xlCSV
        Case "DBF": GetFileFormat = xlDBF4
        Case "DIF": GetFileFormat = xlDIF
        Case "HTM": GetFileFormat = xlHtml
        Case "HTML": GetFileFormat = xlHtml
        Case "MHT": GetFileFormat = xlWebArchive
        Case "MHTML": GetFileFormat = xlWebArchive
        Case "ODS": GetFileFormat = xlOpenDocumentSpreadsheet
        Case "PDF": GetFileFormat = UnsupportedPDF
        Case "PRN": GetFileFormat = xlTextPrinter
        Case "SLK": GetFileFormat = xlSYLK
        Case "TXT": GetFileFormat = xlCurrentPlatformText
        Case "WK1": GetFileFormat = xlWK1ALL
        Case "WK3": GetFileFormat = xlWK3FM3
        Case "WK4": GetFileFormat = xlWK4
        Case "WKS": GetFileFormat = xlWKS
        Case "WQ1": GetFileFormat = xlWQ1
        Case "XLA": GetFileFormat = xlAddIn
        Case "XLAM": GetFileFormat = xlOpenXMLAddIn
        Case "XLS"
            If CInt(Application.Version) >= Excel_2007_VNum Then
                'Excel 2007 and later versions:

                GetFileFormat = xlExcel8                   '= 56, an ".xls" file
            Else
                'Excel 2003:

                'The xlExcel8 value (56) isn't actually recognized by Excel versions 8 through 11 (Excel 97
                'through 2003), so use of it will fail.  And, the default used when the SaveAs method's
                'FileFormat argument isn't defined (for either a new file or existing) is the file format
                'of the last successfully saved file, whatever that might be!  (Note that Excel VBA Help is
                'misleading on this point.)  So, in this case, return xlNormal (-4143) which always defaults
                'to an ".xls" file type when the code is run under Excel 2003 and earlier versions.

                GetFileFormat = xlNormal                   'defaults to an ".xls" file
            End If
        Case "XLSB": GetFileFormat = xlExcel12
        Case "XLSM": GetFileFormat = xlOpenXMLWorkbookMacroEnabled
        Case "XLSX": GetFileFormat = xlOpenXMLWorkbook
        Case "XLT": GetFileFormat = xlTemplate
        Case "XLTM": GetFileFormat = xlOpenXMLTemplateMacroEnabled
        Case "XLTX": GetFileFormat = xlOpenXMLTemplate
        Case "XLW": GetFileFormat = xlExcel4Workbook
'        Case "XML": GetFileFormat = xlXMLData          'Which would be the best default?
        Case "XML": GetFileFormat = xlXMLSpreadsheet    '   "
    End Select

    #If Mac Then
        If CInt(Application.Version) > Excel_Mac2011_VNum Then
            'This code is running on a Mac and this is Excel 2011 or a later version

            'Per Ron de Bruin @http://www.rondebruin.nl/mac/mac020.htm, in Excel 2011 (Mac) you must add 1 to
            'each FileFormat value. [Untested]

            FileFormatCode = FileFormatCode + 1
        End If
    #End If
End Function

如代码中所述,根据可用的参考文档,理论上所有转换都应该有效,但并非所有转换都经过测试(截至 2014 年 8 月)。对彻底测试的任何帮助将不胜感激。如果发现任何错误的转换,请在此处回复,并将更正并入。

于 2014-08-11T16:29:40.903 回答