• Excel打开工作簿事件Appevents_Workbookopeneventhandler

    by{ guangboo }, published {2010-06-09}, Tag { Excel / }

    Excel插件编程,当Excel打开文档时候触发某一动作。

    金融行业中Excel做各种数据分析时,一般都有Excel模板,模板里面包含了很多的VBA函数,当然这些VBA函数里面有很多是自定义的,是需要与服务器交互,达到获取即时数据的目的,如股票当前价格等。这些函数需要通过计算(与服务器通信)更新模板中的内容,然后保存当前快照,从而得到一个分析数据。

    这样的需求一般都需要一个重新计算的按钮,这个按钮的事件就是触发重新计算的,当然Excel中有自动的重算设置,但Excel默认的重算设置在这里是不起作用的,因为只有Excel能够捕获到某些值发生变化时才会启动重算(即使你将重算设置设成了自动重算)。

    因为Excel不知道单元格的值有变化,才不会自动重算的,那么我们可以通过将单元格的值设为Dirty,即表示单元格的值发生了变化时,那么Excel就不在拒绝重算了。如:

    // 保存原重算设置
    Microsoft.Office.Interop.Excel.XlCalculation saveXlCalculation = Globals.ThisAddIn.Application.Calculation;
    // 设为手动重算
    Globals.ThisAddIn.Application.Calculation = Microsoft.Office.Interop.Excel.XlCalculation.xlCalculationManual;
    // 获取当前活动工作表
    Microsoft.Office.Interop.Excel.Worksheet sheet = (Excel.Worksheet)Globals.ThisAddIn.Application.ActiveSheet;
    // 重算当前工作表
    sheet.UsedRange.Dirty();
    // 还原重算设置
    Globals.ThisAddIn.Application.Calculation = saveXlCalculation;
    

    你也可以通过变了工作簿,来重算所有工作表。

    另外你可以通过,下面的代码快速计算:

    // 计算所有打开的工作簿
    Globals.ThisAddIn.Application.Calculate()

    或者:

    // 促使对所有打开工作簿中的数据进行完整计算
    Globals.ThisAddIn.Application.CalculateFull();

    或者:

    // 对于所有打开的工作簿,强制数据的完整计算并重建从属关系。
    Globals.ThisAddIn.Application.CalculateFullRebuild();

    重新计算的工作可以实现了。那么很多研究员还希望在打开Excel模板文件的时候能够自动计算,不需要手动点击重算按钮了。

    这是就需要一个WorkbookOpen事件:Microsoft.Office.Interop.Excel.AppEvents_WorkbookOpenEventHandler,该委托需要绑定到Application.WorkbookOpen事件上,如下代码:

    private void ThisAddIn_Startup(object sender, System.EventArgs e){
        Globals.ThisAddIn.Application.WorkbookOpen += new Microsoft.Office.Interop.Excel.AppEvents_WorkbookOpenEventHandler(FExcelApplication_WorkbookOpen);
        // 省略其他代码
    }
    void FExcelApplication_WorkbookOpen(Microsoft.Office.Interop.Excel.Workbook Wb) {
        if((new ConfigClass()).AutoCalcAfterLogih) {
            // 重新计算Wb
        }
    }

    这样,当研究员打开模板后Excel插件就会自动重算打开的工作簿

  • Asp.Net Mvc 2.0部署

    by{ guangboo }, published {2010-04-10}, Tag { ASP.NET MVC / }

    IIS 7

    IIS7自身有对MVC的支持,部署方法同其他web application基本相同,需要注意的是,mvc 2.0 application在Handler Mappings里面会有MvcHttpHandler,如图:

    我使用的是.net 4.0,我看了其他.net 2.0 的web appliation下的Handler Mappings都没有这个handler maping。

    注意:.net 3.5以下(包括)的web application pool都是.net 2.0版本的,当然可能还包括.net 1.0或.net 1.1版本。但在.net 4.0下,提供了asp.net 4.0,因此使用.net 4.0的web application其application pool很有可能需要.net 4.0环境。

    你可以通过查看应用程序池来查看运行的是.net 2.0还是.net 4.0。

    在部署mvc 2.0 application时,如果你使用的是.net 4.0开发的,其所在application pool必须是.net 4.0的,并且managed pipeline mode为integrated。

    IIS 6部署

    IIS6的部署会比IIS7麻烦一些,我以我的实际部署过程来讲吧,当然刚开始也出现404或服务器错误等问题,不过好在最后都解决了,下面是正确的部署方式。
    我是在.net 4.0环境下,使用VS 2010开发的,需要部署到window server 2003上(IIS6)。原系统装的是.net 3.5的,因此从我的机器上VS的安装包目录VS2010Ultimate_RC1\WCU\dotNetFramework下的.net 4.0环境dotNetFx40_Full_x86_x64.exe拷贝到服务器,然后安装。

    MVC 2.0是不包含在.net 4.0里面的,因此需要手动下载安装(其实主要是System.Web.Mvc.dll文件),我的机器上直接装的vs 2010所有都包含在里面了。我没有在服务器上安装mvc 2.0,而是采用了“私有部署”,一般web application添加的.net环境下的dll时,如system.dll等,当你在发布时,这些dll是不会拷贝到发布后的bin目录的,因此我使用“私有部署”,将这些dll文件,包括System.Web.MVC.dll文件已经发布到bin目录下,这样应用程序运行时在GAC中找不到这个dll的时候就可以在bin中找到了。你需要做的就是,在引用的“Copy local”属性设为“true”即可。当然如果你不嫌麻烦也可以手动从GAC中将这些DLL文件拷贝到发布后的bin目录下。其实这话System.web.extension.dll差不多,如果应用程序没有装asp.net ajax时也需要将这个dll拷贝到bin目录。

    下面就是在服务器上创建站点了,站点的创建和其他.net 2.0 web application一样,差别在于配置和asp.net环境上。

    点击“配置”按钮,在“映射”选项卡中的“通配符应用程序映射”点击“插入”,选择.net 4.0目录(C:\Windows\Microsoft.NET\Framework\v4.0.30128)下的aspnet_ispai.dll文件,然后将“确认文件是否存在”前面的勾去掉。这一点很重要,因为MVC 2.0不想传统的asp.net应用程序文件是实际存在磁盘上的。如/func/default.aspx,是实际存在func目录下的default.aspx文件,而mvc应用/func/default,不表示访问的是func目录下的default文件。这一点一定要弄清楚。

    然后在“ASP.NET”选项卡中的“ASP.NET version”选择4.0,如图

    这样就完成了。

    注意:如果使用.net 3.5开发的mvc应用的话,需要在“ASP.NET”选项开中选择asp.net 2.0,并且在“通配符应用程序映射”中选择asp.net 2.0目录(C:\Windows\Microsoft.NET\Framework\v2.0.50727)下的aspnet_isapi.dll,注意.net 3.0,.net 3.5都是使用的asp.net 2.0。

    常见问题

    当ASP.NET 使用2.0,“通配符应用程序映射”也是用asp.net 2.0的,就会出现“配置错误”,可能原因:.net 2.0无法加载.net 4.0下开发dll文件。

    当asp.net 和“通配符应用程序映射”分别使用2.0和4.0时,就出现了“服务器应用程序不可用”的错误。

    当asp.net 和“通配符应用程序映射”分别使用4.0和2.0时,就出现了 “Server Application Unavailable”的错误。这里显示英文提示,是因为我按照的.net 4.0是英文版本的。

  • Jpg文件的Mimetype为Image/Jpeg

    by{ guangboo }, published {2010-03-25}, Tag { HTML / .net / }

    由于项目的原因,开发了几套系统,部署在不同的服务器上,但数据库可以统一的访问,但附件就不太那么容易处理了,如文章里面的图片一般都是存储在磁盘上的,并且都是相对路径,而其他系统访问此文章的时候,图片就获取不到了。

    这里的解决方案是使用DFS,分布式文件服务系统,将文件共享,或可以利用DFS复制,同步这些图片。因为DFS复制需要使用域和AD的方式来创建文件根目录,我使用的是独立根目录创建的,因此访问图片还是要共享的服务器上读取。

    图片的读取时没有问题的,但在IE 6下,文章中显示图片没有问题,但使用IE 6直接访问图片就不行了,在IE 8下面文章中显示图片和直接访问图片都不能显示。后来发现,bmp格式的图片都能访问,无论在IE 6还是IE 8,还是在文章中显示,还是直接访问图片都正常。偏偏是jpg格式的文件出现上述情况。

    原来我去图片的MimeType的时候出的问题,因为,bmp,gif等的MimeType为image/bmp,image/gif,而jpg的MimeType是image/jpeg,因此简单的使用"image/" + extesion,是可靠的。

  • Textbox的Autopostback="True"引起的误会

    by{ guangboo }, published {2010-03-25}, Tag { asp.net / }

    今天一位网友问我一个问题,内容如下:

    “页面上一个保存按钮 我第一次点击他的时候他跑到重写的Render方法里面 第二次点击他的时候才进去click事件”。

    我首先想到的是,onclick事件是在Render方法里面才绑定的。

    然后我继续问一些问题,进一步了解“现场”情况。了解到事件是在<asp:textbox onclick="btnSave_Click".../>这里就已经绑定了。而且看来他贴出来的Render方法的代码,没有任何相关的代码。然后网友远程,让我看了一下他的演示。然后我看了一下代码,发现TextBox中设置了AutoPostBack的属性为true,因此导致了第一次的点击是TextBox的OnTextChanged事件,当然不是btnSave_Click事件,而第二次,才是Click事件。当然保证第二次点击触发的是Click事件的是,TextBox的Text没有发生变化才行。

    因此在TextBox的AutoPostBack属性设为True时,且当TextBox的值发生了变化,那么页面回发的事件就是TextBox的OnTextChange事件。所以出现这次误会的罪魁祸首就是TextBox的AutoPostBack属性。

     

     

  • Asp.Net Datacontrolrowstate简介

    by{ guangboo }, published {2010-03-24}, Tag { .net / asp.net / }

    DataControlRowState 枚举

    该枚举在.net framework 2.0中新增加的,是指定数据控件,如DetailView,GridView中行的状态的。具有FlagAttribute属性,因此允许其成员值按位组合。

     

    [FlagsAttribute] 
    public enum DataControlRowState

    成员

    成员名称 说明
    Alternate 指示该数据控件行是交替行。 Alternate 状态在任何时候都可以与其他状态组合,例如与 NormalEditInsert 组合。这些行可能会受到数据控件的 AlternateRowStyle 属性影响(若已设置)。
    Edit 指示该行处于编辑状态,这通常是单击行的“编辑”按钮的结果。通常,EditInsert 状态互相排斥。
    Insert 指示该行是新行,这通常是单击“插入”按钮添加新行的结果。通常,InsertEdit 状态互相排斥。
    Normal 指示该数据控件行处于正常状态。Normal 状态与其他所有状态互相排斥。
    Selected 指示该行已被用户选定。

    官方介绍

    DataControlRowState 枚举标识数据控件(例如 DetailsViewGridView)中行的状态。行的状态可以是一个 DataControlRowState 值或值的组合,因此使用按位运算来确定该行的状态是否包括一个 DataControlRowState 值而非一个等效测试。DataControlRowState 枚举用于任何行类型,而不只用于 DataRow 行(通常,标头和脚注行的状态设置为 Normal)。

    当枚举整个 GridViewRowCollectionDetailsViewRowCollection 集合时,可以使用 DataControlRowState 枚举来分别标识 GridViewRowDetailsViewRow 对象的状态。如果正在编写使用行的数据控件,您可以使用 DataControlRowState 枚举来标识何时为行呈现不同的颜色(Alternate 值),或者用它来标识为编辑行而启用或禁用的控件(EditInsert 值)。

    示例:

    判断行在Edit模式

    (row.RowState & DataControlRowState.Edit) != 0

    而不能使用

    row.RowState == DataControlRowState.Edit

    判断行在Insert模式

    (row.RowState & DataControlRowState.Insert) != 0
    而不能使用
    row.RowState == DataControlRowState.Insert

    因为DataControlRowState的声明是:

    [Flags]
        public enum DataControlRowState {
            // 摘要:
            //     指示该数据控件行处于正常状态。System.Web.UI.WebControls.DataControlRowState.Normal 状态与其他状态相互排斥,但
            //     System.Web.UI.WebControls.DataControlRowState.Alternate 状态除外。
            Normal = 0,
            //
            // 摘要:
            //     指示该数据控件行是交替行。
            Alternate = 1,
            //
            // 摘要:
            //     指示该行已被用户选定。
            Selected = 2,
            //
            // 摘要:
            //     指示该行处于编辑状态,这通常是单击行的“编辑”按钮的结果。通常,System.Web.UI.WebControls.DataControlRowState.Edit
            //     和 System.Web.UI.WebControls.DataControlRowState.Insert 状态互相排斥。
            Edit = 4,
            //
            // 摘要:
            //     指示该行是新行,这通常是单击“插入”按钮添加新行的结果。通常,System.Web.UI.WebControls.DataControlRowState.Insert
            //     和 System.Web.UI.WebControls.DataControlRowState.Edit 状态互相排斥。
            Insert = 8,
        }

  • Ocienvcreate 失败,返回代码为 -1,但错误消息文本不可用

    by{ guangboo }, published {2010-03-16}, Tag { Oracle / }

    情况:

    本人机器上安装了ORAL10g,并且创建好服务还实例,本机使用PL/SQL及ASP.NET程序连接正常,同事使用PL/SQL连接我的机器也正常。但当asp.net程序连接时就出现“OCIEnvCreate 失败,返回代码为 -1,但错误消息文本不可用”的异常。

    GOOGLE到解决方案是,设置oracle的安装目录,如d:/oracle的权限,添加用户名IIS_USER_的访问权限。重启电脑。