【问题标题】:C# Excel dropdown eventC# Excel 下拉事件
【发布时间】:2013-01-29 05:06:30
【问题描述】:

我有一个 Excel 电子表格,它位于一个用 C# 编写的自动化测试应用程序中。测试应用程序使用最终统计数据填充工作表,然后使用电子表格生成指标。该过程的一部分是将下拉列表放入电子表格的 L 列,并将其关联的 VBA 更改事件从应用程序写入工作表中。

这是将下拉列表写入电子表格的代码 Excel.DropDown xlDropDown;

//set range for insert cell
 range = wrkSheet.get_Range("L" + (x + 9).ToString() + ":L" + (x + 9).ToString());

//insert the dropdown into the cell
xlDropDown = xlDropDowns.Add((double)range.Left, (double)range.Top, (double)range.Width, (double)range.Height, true);

//set the nbame of the new dropdown
xlDropDown.Name = "expFail" + (x + 1).ToString();

//assign dropdown name to cmbName 
cmbName = xlDropDown.Name;

 //call function to write change macro for this box 
 cmbWriteMacro(cmbName, xlApp, xlBook, wrkSheet); 

cmbWrite 函数:

    StringBuilder sb;
    VBA.VBComponent xlModule;
    VBA.VBProject prj;
    string modName;
    int modExists;

    prj = wrkBook.VBProject;
    modExists = 0;

    sb = new StringBuilder();

    //build string with module code 
    sb.Append("Sub " + cmbName + "_Change()" + "\n");
    sb.Append("\t" + "Call lstBox_Update(" + cmbName + ")" + "\n");
    sb.Append("End Sub");

    foreach (VBA.VBComponent comp in prj.VBComponents)
    {
        modName = comp.Name;

        if (modName == "Module2")
        {
            modExists = 1;
            break;
        }
    }

     //check to see if module already exists
     if (modExists != 1)
     {
        //set an object for the new module to create
        xlModule = wrkBook.VBProject.VBComponents.Add(VBA.vbext_ComponentType.vbext_ct_StdModule);
     }
     else
     {
        xlModule = wrkBook.VBProject.VBComponents.Item("Module2");
     }

     //add the cmbbox macro to the spreadsheet
     xlModule.CodeModule.AddFromString(sb.ToString());

这会将以下 VBA 事件写入电子表格,以便在记录失败时在工作表中执行操作。

Sub expFail1_Change(ByVal Target As Range)
    Call lstBox_Update("expFail1")
End Sub

所有下拉菜单都会根据选择的内容调用相同的函数 (lstBox_Update)。

一切正常。下拉菜单显示在它们应该出现的位置,并且宏正在正确地写入电子表格中。问题似乎是在更改选择时触发相关的更改事件。解决方案可能很简单,但我翻遍了,似乎找不到答案

【问题讨论】:

    标签: c# excel vba dropdownbox


    【解决方案1】:

    我只是根据您的代码做了一个小例子。经过一番谷歌搜索和测试一些源代码片段后,它归结为一行代码

    xlDropDown.Name = "expFail" + (x + 1).ToString(); // your code
    xlDropDown.OnAction = xlDropDown.Name + "_Change"; // new code: IMPORTANT
    

    Microsoft KB article 中找到此代码如何使用 Visual C# .NET 中的自动化创建 Excel 宏

    您似乎需要这行代码来设置某种委托指向您的自定义 vba 代码。

    如果您需要我的完整来源,请告诉我,我会邮寄给您。

    【讨论】:

    • 是的!而已。我刚刚花了一个小时研究这个并且找不到将宏分配给控件的方法。我没有想到,简单地输入它,而不是期待 IntelliSense 找到它,会起作用。
    • 附带说明,如果您将宏代码存储在 Worksheet 模块中,而不是 VBA 模块 Module1,那么您需要在事件名称前加上工作表名称,所以"Sheet1." + xlDropDown.Name + "_Change";.
    【解决方案2】:

    基于this article,您需要将代码写入Worksheet_Change 事件,而不是ComboBox_Change 事件:

    Sub Worksheet_Change(ByVal Target As Range)
        Call lstBoxUpdate("expFail1")
    End Sub
    

    【讨论】:

    • 我编写的代码仅在更新包含下拉列表的单元格时触发 Worksheet_Change 事件 If Intersect(Target, failRange) Is Nothing Then Exit Sub Else Call lstBox_Update() End If 。当我更新工作表并退出时,它会按原样触发,因为更新不在failRange(有下拉菜单的单元格范围)中。即使下拉列表通过其 .LinkedCells 属性链接到它们所在的单元格,当对新选择的索引进行选择时,单元格的值也会更新,Worksheet_Change 事件不会触发
    【解决方案3】:

    您必须将更改事件写入创建组合框的工作表(而不是 VBA 模块“module2”。 组合框是 Worksheet(object) 的一部分,所有事件处理程序都必须在那里。

    【讨论】:

    • 对不起,那是在试图解决这个问题时使用的代码版本。我最初将宏写入 Sheet1(电子表格上唯一的工作表),但仍然没有乐趣。不过,很好的收获。这是应用程序编写的 Sheet1 中的代码 Sub expFail2_Change() Call lstBox_Update(expFail2) End Sub Sub expFail1_Change() Call lstBox_Update(expFail1) End Sub Sub lstBox_Update() [Do Something] End Sub
    • 您的输出也与代码不匹配。 expFail1_Change 子程序不应有参数(根据您的示例代码,它没有参数)。也许你更新你的代码?
    • 好消息——你是对的。我已经改变了它,所以没有参数。坏消息——仍然没有快乐。不幸的是,我正在尝试在 Excel 中做一些我以前没有尝试过的东西,并且一直在试图解决这个问题,所以我对不一致之处表示歉意
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 2021-01-23
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多