2013-09-28 37 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月)。任何幫助徹底測試將不勝感激。如果發現任何錯誤的轉換,請在此發佈回覆,並將更正。

相關問題