2013-09-28 38 views
0

我已经创建了一对可重用的子例程,它们一起工作以保存不同扩展名中的文件。创建通用参考表:是一个正确的方法吗?

第一个Sub接收目录路径,文件名和所需的Excel扩展名。然后,它调用第二次找到了正确的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 FileFormats我会用一个参考。对于参考的FileFormat我同时存储在的FileFormat号码和名称中键入到不同的文件扩展的阵列中,所有存储在一个集合,我可以添加到根据需要:

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代码),因此可以反复使用它,而无需每次都记住和重写它?


代码进行了修订,使用情况,而不是一个集合,以更好地处理错误(由代码亚洲时报Siddharth溃败的重写轻轻建议)。这工作,和案例结构使我的眼睛更有意义:

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 
+1

您的方式是正确的。看看http://stackoverflow.com/questions/9178177以通过类实例替换这些数组。 –

+0

@amadeus:谢谢!我一直在想关于类对象,现在看起来是我开始学习的机会。我显然必须稍微学习一下如何调用类对象,但是一旦我做了,它似乎会更好。 –

回答

1

我同意。对于只有4个Extns来说,数组将是一个矫枉过正的问题。我宁愿在一个函数中使用Select Case。请参见下面的

UNTESTED

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 
+0

谢谢。 '选择案例'确实效果更好,尤其是一旦我意识到我可以用相同的案例设置多个值。有道理,但我从未做过。 –

+0

一个问题:我注意到您将GetExcelFormatNumber定义为函数而不是Sub。你对此的推理是什么?我并不完全清楚什么时候定义函数与公有子函数是合理的,在@amadeus提到类之后,我将类定义添加到该列表中。 –

+0

函数返回值,Sub不。因此我使用了一个函数来返回FileFormat。关于你的其他观点,像Arrays,Classes对于这个也是一个矫枉过正的问题:) –

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月)。任何帮助彻底测试将不胜感激。如果发现任何错误的转换,请在此发布回复,并将更正。

相关问题