|
楼主 |
发表于 2015-12-17 16:55
|
显示全部楼层
本帖最后由 excelhomesnake 于 2015-12-18 14:22 编辑
2,如何通过封装,达到通用处理二维数组的处理.(例如,各种排序,汇总等操作)
prod_2过程:已经把二维数组封装到一个类来管理,实现可枚举接口.让这个对象可以按照行来foreach遍历.代表进一步简化
prod_3过程:由于可用foreach遍历,也意味可以用linq查询,轻易实现各种过滤,排序,汇总等操作.
个人觉得,这个是vsto(.net)比vba更优胜的地方.如果使用.net平台,也只是换了界面,换了语言,来写着一样的code,是没有多大意义.毕竟在.net上可以写出更通用,更容易维护的东西,不好好利用,还不如继续用vba好了.
关键代码如下:
1,创建一个ArrayManager类,负责单元格区域和二维数组的互相转换,并保存这个二维数组.
2,创建一个ArrayRow结构体,代表数组数据中的一行.里面只保存行索引,当然要保存ArrayManager的引用.
3,让ArrayManager类实现IEnumerable<ArrayRow>接口.这个接口是.net上所有可枚举遍历的关键所在.这样,就可以让ArrayManager的对象,可以用foreach直接遍历,遍历的每个元素类型就是ArrayRow
接口方法的代码:注意
1,此代码在ArrayManager类中定义
2,里面的this,代表当前正在执行代码中的ArrayManager的一个实例引用(就像vba的me,和vb.net的Me)
- /// <summary>
- /// 让此对象可foreach遍历
- /// </summary>
- /// <returns></returns>
- public IEnumerator<ArrayRow> GetEnumerator()
- {
- for (int i = 1; i <= this.RowsCount; i++)
- {
- yield return new ArrayRow
- {
- ArrayManager = this,
- RowIndex = i
- };
- }
- }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
复制代码
这样就可以直接foreach一个ArrayManager类的实例
- var am = new ArrayManager(wrk.get_Range("A1").CurrentRegion);
- //现在可以foreach遍历了
- foreach (ArrayRow row in am)
- {
- //分类名称列中,内容是以"普通"开头的行,获取下来
- if (row.GetValueToString(2).StartsWith("普通"))
- {
- resultList.Add(row);
- }
- }
复制代码
因为实现了可枚举的接口,因此就可以使用linq来查询,下面的代码与你遍历是一样(当然,性能上有一些损失,因为后台实际是调用了几个静态扩展方法和保存了几个委托类型)
但linq查询很多都是延迟执行,意味你可以组合多个查询,把逻辑分块写出,但执行顺序与普通的镶嵌遍历一致.本身linq直接有许多有用的汇总,连接的关键字和方法(很像sql,是一种声明形式的表达)
- //由于am可foreach遍历,意味可以用linq查询am
- var query = from row in am.Skip(1)//跳过第一行
- where row.GetValueToString(2).StartsWith("普通")
- orderby row.GetValueToNumber(4) descending //第4列降序
- select row;
复制代码
|
评分
-
1
查看全部评分
-
|