You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

VSTO Excel AutoFilter:获取日期筛选条件(年/月/日)时抛出异常

解决Excel日期列筛选器获取异常的问题

看起来你遇到的问题是Excel日期列使用动态日期筛选(比如按年、月、日快速筛选)时,直接访问Criteria1/Criteria2会抛出异常——这是因为这类筛选根本不依赖Criteria属性,而是用专门的动态筛选对象来存储规则。

问题根源

当你对日期列选择“本年”“本月”“最近7天”这类预设筛选时,Excel会创建动态筛选器(DynamicFilter),而非普通的比较筛选。此时filters[i].Criteria1Criteria2是未初始化的,直接访问自然会抛出异常。只有当你使用自定义日期范围(比如“介于2023/1/1和2023/12/31之间”)时,Criteria1Criteria2才会有值。

修复方案

修改你的代码,先判断筛选器的操作符类型,区分普通筛选和动态日期筛选,分别处理:

// 记得先引用Excel互操作的命名空间
using Microsoft.Office.Interop.Excel;

for (int i = 1; i <= filters.Count; i++) { 
    FilterTemp f = new FilterTemp(); 
    f.On = filters[i].On; 
    if (f.On) { 
        f.Field = i; 
        var currentFilter = filters[i];
        f.Operator = (int)currentFilter.Operator;

        // 根据筛选操作符类型分情况处理
        var filterOperator = (XlFilterOperator)currentFilter.Operator;
        if (filterOperator == XlFilterOperator.xlFilterDynamic)
        {
            // 动态日期筛选:获取动态筛选类型,比如本年/本月/本日等
            f.DynamicFilterType = (int)currentFilter.DynamicFilter.Type;
        }
        else if (IsDateSpecificOperator(filterOperator))
        {
            // 针对日期的特定操作符,比如xlFilterLastYear、xlFilterThisMonth等
            // 这类操作符不需要Criteria,直接记录Operator即可
        }
        else
        {
            // 普通筛选:尝试获取Criteria1和Criteria2
            try { f.Criteria1 = currentFilter.Criteria1; } catch { } 
            try { f.Criteria2 = currentFilter.Criteria2; } catch { } 
        }
    } 
    fs.Add(f); 
}

// 辅助方法:判断是否为日期特定的筛选操作符
private bool IsDateSpecificOperator(XlFilterOperator op)
{
    return op == XlFilterOperator.xlFilterLastYear ||
           op == XlFilterOperator.xlFilterThisYear ||
           op == XlFilterOperator.xlFilterLastMonth ||
           op == XlFilterOperator.xlFilterThisMonth ||
           op == XlFilterOperator.xlFilterLastWeek ||
           op == XlFilterOperator.xlFilterThisWeek ||
           op == XlFilterOperator.xlFilterToday ||
           op == XlFilterOperator.xlFilterYesterday;
}

后续重新应用筛选的注意点

当你要重新应用筛选时,也要对应处理:

  • 如果是动态筛选类型,不要设置Criteria1/Criteria2,而是设置currentFilter.DynamicFilter.Type = (XlDynamicFilterType)f.DynamicFilterType
  • 如果是普通日期范围筛选,直接用Criteria1/Criteria2即可;
  • 日期特定操作符(比如xlFilterLastYear)直接设置Operator即可。

这样就能完整捕获所有日期筛选的规则,不会再抛出异常了。

内容的提问来源于stack exchange,提问作者Eric Milaneze

火山引擎 最新活动