中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
淺談Excel開發(fā):九 Excel 開發(fā)中遇到的常見問題及解決方法

Excel開發(fā)過程中有時候會遇到各種奇怪的問題,下面就列出一些本人在開發(fā)中遇到的一些比較典型的問題,并給出了解決方法,希望對大家有所幫助。

一 插件調試不了以及錯誤導致崩潰的問題

在開發(fā)機器上,有時可能會裝有多個版本的.NET運行時,有時候也可能裝有多個版本的Visual Studio,本人的開發(fā)機器上就安裝了3個版本的Visual Studio,在最新的Visual Studio 2013出來之后,就迫不及待的把工程文件遷移到2013上來了,但是在設置了啟動程序之后,調試的時候,斷點根本不能命中,也調試不進去。即使使用Attached to process方式也不行。

該問題是由于在安裝有多個.NET版本的機器上,由于某些原因,會導致Excel不知道為Com Add-in加載哪個版本的Framework導致的。注:這里僅針對是用.NET技術開發(fā)Shared Add-in插件的情況,由于VSTO 中的安裝部署文件.vsto中注明了程序集的版本,所以不存在該問題。

解決方法是新建一個名為EXCEL.EXE.config的配置文件,放到和EXCEL.EXE同級的目錄下,配置如下,在startup節(jié)點下新建supprotedRuntime節(jié)點,指定運行時的版本號,即可解決該問題:

 

在Shared Add-in插件開發(fā)的初期,在測試機器上測試的時候,有時會由于代碼錯誤,導致Excel直接崩潰掉的問題。在開發(fā)機器上,我們只需要將在該配置文件中,將runtime節(jié)點下的legacyUnhandledExceptionPolicy的Enable屬性設置為true,這樣,Excel在出現(xiàn)問題的時候就會彈出提示框,有助于幫助查找錯誤出現(xiàn)的原因。

這其實也是相較于VSTO,Shared Add-in應用程序的缺點之一,VSTO的一個插件是加載到各自的App Domain中的,出現(xiàn)問題不會影響其他的插件。

二 若干Excel方法調用會導致出錯

由于需要兼容不同版本的Excel,但是隨著版本的變化,Excel暴漏出來的API方法的參數(shù)也會發(fā)生變化。有時候采用直接調用的方式在遇到版本不同時會拋出異常,這種COM類型的異常一般很難處理和恢復。在有些時候,通過采用“晚綁定”的方式,采用反射調用方法就可以解決這一問題。

以條件著色功能為例。在使用插件獲取并輸出數(shù)據(jù)的時候,通常需要根據(jù)條件對單元格進行著色,比如,輸出股票的漲跌和漲跌幅的時候,人們一般習慣將漲的標注為紅色,跌的標注為綠色。Excel中對Range進行單元格條件可以使用FormatCoondition對象,該對象有如下方法,以添加漲跌幅的條件著色為例,代碼如下。

object missing = Type.Missing;FormatCondition conditionFall = (FormatCondition)tmpRange.FormatConditions.Add(XlFormatConditionType.xlCellValue, XlFormatConditionOperator.xlLess, "=0", missing);conditionFall.Font.ColorIndex = 10;//GreenFormatCondition conditionRise = (FormatCondition)tmpRange.FormatConditions.Add(XlFormatConditionType.xlCellValue, XlFormatConditionOperator.xlGreater, "=0", missing);conditionRise.Font.ColorIndex = 3;//Green

該方法在Excel07及以上版本中沒有問題,但是在03下就會拋出異常。由于個版本的API中,參數(shù)個數(shù)不一樣。所以采用反射的方法,將參數(shù)以數(shù)組的方式傳入即可解決該問題。

下面這個方法封裝了FoormationCoondition的Add方法。

/// <summary>///兼容Excel 2003-Excel2010的代碼條件著色,如果直接使用FormatConditions.Add方法,則不能兼容///詳情可以參考:http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/8a91d154-f766-427a-963c-16dfa39e154a///使用方法如: tempRange.AddConditionValue(XlFormatConditionOperator.xlLess, "=0");/// </summary>/// <param name="R">待進行條件著色的Range區(qū)域</param>/// <param name="ConditionOperator">找色條件,如,大于,小于</param>/// <param name="Formula">具體的值</param>/// <returns></returns>public static FormatCondition AddConditionValue(Range R, XlFormatConditionOperator ConditionOperator, string Formula){    return (FormatCondition)R.FormatConditions.GetType().InvokeMember("Add", BindingFlags.InvokeMethod, null, (object)R.FormatConditions, new object[] { XlFormatConditionType.xlCellValue, ConditionOperator, Formula });}

使用該方法,上面的代碼改寫為:

FormatCondition conditionFall = AddConditionValue(tempRange, XlFormatConditionOperator.xlLess, "=0");conditionFall.Font.ColorIndex = 10;//GreenFormatCondition conditionRise = AddConditionValue(tempRange, XlFormatConditionOperator.xlGreater, "=0");conditionRise.Font.ColorIndex = 3;//Red

Excel中遇到同一方法由于不同API版本參數(shù)不同導致出現(xiàn)問題,都可以采取上面的采用反射方法調用來解決問題。

三 Excel自定義函數(shù)中包含.xla或者.xll文件路徑的問題

一般地通常的插件都會開發(fā)相應的自定義函數(shù) (UDF),除了使用C#類庫編寫自定義函數(shù),大部分都是將自定義函數(shù)寫在Excel的.xla或者xll文件中,有時候也會使用自定義函數(shù)編寫一些標準的模板供用戶調用。當這些模板中包含有自定義函數(shù),當用戶將該模板保存到其他位置之后,再次打開,這些單元格中的函數(shù)就會包含.xla或者.xll的路徑。比如"C:\Program Files\Installation folder\MyUDFs.xla!MyUDF"等,原因是Excel在內部會包含自定義函數(shù)文件的完整路徑。

這會導致一些問題,比如說,改自定義函數(shù)不能夠正確的執(zhí)行,不能求值等等。

就解決方法就是在vba中,在SheetOpen事件中,將所有包含函數(shù)的路徑進行重新定向到系統(tǒng)指標的自定義函數(shù)類庫的目錄下即可。VBA代碼如下,主要的方法為_Workbook.ChangeLink 方法,VBA的代碼如下。將該部分代碼寫到vba類庫中即可。

Private Sub ExcelApp_WorkbookOpen(ByVal Wb As Workbook)     ReLink WbEnd SubPublic Sub ReLink(ByVal oBook As Workbook)    If IsEmpty(oBook.LinkSources(xlLinkTypeExcelLinks)) Then Exit Sub        Dim lk As Variant        For Each lk In oBook.LinkSources(xlLinkTypeExcelLinks)        If lk Like "*" & ThisWorkbook.Name And lk <> ThisWorkbook.FullName Then                oBook.ChangeLink lk, ThisWorkbook.FullName, xlLinkTypeExcelLinks        End If    Next lkEnd Sub

四 自定義函數(shù)加載的問題

還是UDF加載的問題,如果是采用.xla或者xll承載自定義函數(shù)的話,在插件啟動的時候需要加載改文件到Excel中,這樣Excel才能夠使用這里面的自定義函數(shù),并在Excel 2007及以上版本中會給出函數(shù)的智能提示。

一般地,在Shared Add-ins中加載自定義函數(shù)我們可以在OnConnection方法中,調用如下方法:

MSExcel.AddIn excelFunc = null;try{    excelFunc = applicationObject.AddIns.Add(“your .xla file path“, true);}catch (System.IO.IOException exception){    LogHelper.Error("IOException:未發(fā)現(xiàn)xla文件在所設置路徑", exception);}catch (Exception exception){    LogHelper.Error(exception);}

在大多數(shù)情況下,如果用戶直接打開Excel應用程序,插件加載就會執(zhí)行OnConnect方法,就會執(zhí)行加載.xla函數(shù)的邏輯。

但是,更多的情況是,用戶會直接雙擊一個之前保存過的,包含有我們的.xla文件中的自定義函數(shù)的excel文件,通過這種方式打開excel,插件的加載.xla在某些情況下回出現(xiàn)加載不了的情況。出現(xiàn)該問題的原因在于,我們再加載.xla文件的時候,必須要確保當前Excel中有一個空白的Sheet頁處于打開狀態(tài)。在用戶通過雙擊現(xiàn)有的excel文件的時候,在文檔打開之前,并沒有可用的Sheet頁處于打開狀態(tài),這是我們的插件加載.xla文件的時候就會出現(xiàn)加載不上的問題。

解決方法就是在OnConnect中調用RegisterOpenEvent方法注冊WorkbookActivate事件,在該事件回調方法中去注冊.xla文件。這樣在文件被打開的時候就可以加載.xla或者.xll函數(shù)了,在加載完函數(shù)之后,我們需要注銷該事件以防止重復加載。如下

private void RegisterOpenEvent(){    applicationObject.WorkbookActivate += new MSExcel.AppEvents_WorkbookActivateEventHandler(applicationObject_WorkbookActivate);}/// <summary>/// This active evevt was designed to be trigged only once to load xla file/// </summary>/// <param name="Wb"></param>void applicationObject_WorkbookActivate(MSExcel.Workbook Wb){    MSExcel.AddIn excelFunc = null;    try    {        excelFunc = applicationObject.AddIns.Add(RuntimeHelper.MapRootPath(EmOfficeCore.Helper.PathHelper.Instance.EMFuncPath), true);    }    catch (System.IO.IOException exception)    {        LogHelper.Error("IOException:未發(fā)現(xiàn)xla文件在所設置路徑", exception);    }    catch (Exception exception)    {        LogHelper.Error(exception);    }    if (excelFunc.Installed == true)    {        applicationObject.WorkbookActivate -= new MSExcel.AppEvents_WorkbookActivateEventHandler(applicationObject_WorkbookActivate);    }    else    {        applicationObject.WorkbookActivate -= new MSExcel.AppEvents_WorkbookActivateEventHandler(applicationObject_WorkbookActivate);        excelFunc.Installed = true;    }}

這樣就能解決加載不上的問題。

五 資源釋放不掉的問題

在使用Shared Add-ins開發(fā)插件的時候,通常如果資源釋放處理不好,會存在關閉Excel后,任務管理器中的Excel.exe這個進程沒有關閉。這是由于我們在.NET中引用了非托管代碼 ,但是有沒有手動釋放,導致資源沒有被回收導致的。該問題在StackOverflow上有很詳細的討論,按照msdn上的解決方法。我們只需要在OnDisConnection 方法中對資源進行釋放即可:

/// <summary>///     Implements the OnDisconnection method of the IDTExtensibility2 interface.///     Receives notification that the Add-in is being unloaded./// </summary>/// <param term='disconnectMode'>///      Describes how the Add-in is being unloaded./// </param>/// <param term='custom'>///      Array of parameters that are host application specific./// </param>/// <seealso class='IDTExtensibility2' />public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom){    try    {        GC.Collect();        Marshal.FinalReleaseComObject(applicationObject);        GC.Collect();    }    catch (Exception ex)    {        LogHelper.Error(ex);    }}

六 正確的創(chuàng)建和使用Excel實例

在應用程序開發(fā)中,通常我們需要在Winform中導出到Excel或者對Excel文件進行讀寫,如果您選擇使用Excel API的話(當然更好的方式是直接使用OpenXML或者相似的技術直接生成Excel文件),通常的做法是直接創(chuàng)建一個Excel實例:

Microsoft.Office.Interop.Excel.Application m_objExcel = new Microsoft.Office.Interop.Excel.Application();

但是這種方式過于簡單粗暴, 他相當于直接在后臺創(chuàng)建一個Excel的實例。當您導出多次的時候會創(chuàng)建多個這樣的應用程序,并且在關閉程序的時候很可能導致這些資源不能釋放,最明顯的是您會發(fā)現(xiàn)在資源管理器中會出現(xiàn)很多個Excel的進程沒有被關閉。

還有一個場景就是插件的自動升級。 通常我們的插件需要升級,如果發(fā)現(xiàn)新的版本,則回去下載,然后對現(xiàn)有的dll進行覆蓋。通常,改升級程序時一個獨立于excel的插件,覆蓋之前通常需要關閉當前打開的Excel才能進行覆蓋。在檢測到升級并下載完新的升級包時,需要提示用戶關閉Excel,點擊確定的時候,一般的做法是強制終止任務管理器中的Excel進行,再執(zhí)行覆蓋,這樣做的問題在于:Excel會認為插件導致了Excel的意外關閉,在下次打開的時候,會直接提示改插件存在嚴重問題,是否禁用。通常一般的用戶會去點擊禁用。這樣顯然不好。

打開或者獲取Office產(chǎn)品實例的方法有很9種,比較友好的方式是,如果當前已經(jīng)有Excel的實例在運行,則不要去new新的實例,而是通過一些方法直接從現(xiàn)有的實例中去獲取和創(chuàng)建,比如可以通過Marshal.GetActiveObject方法傳入想要獲取實例的ProgID即可。對于上面的方法,更友好的版本是:

public Microsoft.Office.Interop.Excel.Application StartExcel(){    Microsoft.Office.Interop.Excel.Application instance = null;    try    {        instance = (Microsoft.Office.Interop.Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");    }    catch (System.Runtime.InteropServices.COMException ex)    {        instance = new Microsoft.Office.Interop.Excel.Application();    }    return instance;}

該方法首先嘗試使用GetActiveObject從當前活動的Excel實例獲取實例,如果沒有活動的Excel,則再新建一個Excel實例。這樣就避免了肯能的資源浪費。

在升級程序中,我們可以直接調用該方法返回的實例,然后調用它的Quit方法就可以。

七 Excel 2003上安裝部署不上的問題

使用Shared Com Add-in創(chuàng)建的程序在Office 2003上有可能安裝不上, 該問題在前一篇有關Excel安裝部署中 提到過,需要安裝兩個針對Office 2003的補丁。這篇文章Deploying a Shared COM add-in for Office 2003 (Visual Studio 2008 SP1) [and how to work around a known issue which causes the add-in to fail to load if KB908002 is not installed.] 有詳細介紹該補丁如何在部署時打包及安裝,這里就不在贅述了。

本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
編寫你自己的EXCEL函數(shù)
EXCEL加載宏基礎
使用c 開發(fā)excel插件(第1章 準備知識)
Excel拓展功能
Excel中xla是什么文件
根據(jù)身份證求所屬省份、性別、出生日期的宏
更多類似文章 >>
生活服務
熱點新聞
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服