VSTO用正则表达式解决Excel数值问题

  • 发布时间:2016年11月22日 11:07
  • 作者:杨仕航
  • 分类标签: VSTO
  • 阅读(6305)
  • 评论(0)

用VSTO写Excel的时,会碰到数据类型的问题。


例如,最常见的情况:获取单元格的值。

Excel单元格可能没有值,获取得到null。而null在C#中处理比较麻烦。

而且Excel单元格的值可能是数字、布尔值、日期时间、文本。

一般情况我们只需要将当作字符串处理。这里可能需要写不少判断。

写代码之前,先引用这个。下面的代码没特殊说明,都默认引用了Excel组件。

using Excel = Microsoft.Office.Interop.Excel;

获取单元格的值:

Excel.Range cell = Globals.Application.Cells[1, 1] //A1单元格
string cell_value;

if(string.IsNullOrEmpty(cell.Value))
{
    cell_value = "";
}
else
{
    cell_value = cell.Value.ToString();
}

如果每次获取单元格的值都这么写的话,很麻烦。可以用C#的??运算符,??判断前面的数据是否为null,若为null再取??后面的值:

Excel.Range cell = Globals.Application.Cells[1, 1] //A1单元格
string cell_value = (cell.Value ?? "").ToString();

这样,就解决获取单元格值的问题。但Excel数值问题不仅仅如此而已。


Excel的数据是可以隐式转换,一个文本型数字可以直接计算。而在.net中是不允许的。C#是一门强类型的语言,对数据的类型控制比较严格。那么,至少我们要可以判断一个字符串是否是数值。这里有两种判断方法,一种是将其直接转换数值类型,判断是否会出错;另外一种是用正则表达式判断。

先写写利用错误判断是否是数值的方法:

public bool IsNumberic(string text)
{
    try
    {
        int val = int.Parse(text);
        return true; //顺利转换则说明没有问题
    }
    catch
    {
        return false;
    }    
}

但这种方法效率不是很高,因为需要抛出异常和处理异常。

我们可以用正则表达式的方法判断是否是数值。

使用正则表达式可以判断很多种类型,创建一个静态的类。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions; //正则表达式

namespace Excel_addin //命名空间自行修改
{
    public static class ClsValueCheck
    {
        //判断是否是数值
        public static bool IsNumberic(string text)
        {
            if(string.IsNullOrEmpty(text)) return false;
            Regex rex = new Regex(@"^[+-]?\d*[.]?\d*$");
            return rex.IsMatch(text);
        }
    }
}

该正则表达式可以判断正负号或是否包含一个小数点的数值。

我们可以再把这个方法拓展一下,例如判断是否是纯字母、判断是否包含汉字等等。这里我不再赘述,提供一下正则表达式,可自行测试练习一下。

Regex rex = new Regex(@"^[a-zA-Z]*$"); //判断是否纯字母
Regex rex = new Regex(@"^[a-zA-Z0-9]*$"); //判断是否字母和数字
Regex rex = new Regex(@"^[\u4e00-\u9fa5]*$"); //判断是否纯汉字


当然,正则表达式的作用不仅仅如此。我们还可用于提取我们想要的数据类型,例如提取数字、提取字母、提取汉字。甚至你可以自行写一些规则提取电话、邮编等等。

这里我写一些我经常用的:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;  //正则表达式
//作者:杨仕航
//地址:http://yshblog.com/blog/90

namespace Excel_addin //命名空间自行修改
{
    public static class ClsValueCheck
    {
        /// <summary>
        /// 判断文本是否是数字
        /// </summary>
        /// <param name="text">要判断的文本</param>
        /// <returns>返回判断结果</returns>
        public static bool IsNumberic(string text)
        {
            if (string.IsNullOrEmpty(text)) return false;
            Regex rex = new Regex(@"^[+-]?\d*[.]?\d*$");
            return rex.IsMatch(text);
        }

        /// <summary>
        /// 从文本中提取数字
        /// </summary>
        /// <param name="strText">文本</param>
        /// <returns>返回文本型数字</returns>
        public static string GetNumberFromString(string strText)
        {
            //替换掉非数字和非小数点的文本
            string strResult = Regex.Replace(strText, @"[^\d\.]", "");
            //判断是否是数字,不是数字再替换掉小数点
            if (!IsNumberic(strResult))
                strResult = Regex.Replace(strResult, @"\.", "");

            return strResult;
        }
        
        /// <summary>
        /// 从文本中提取字母
        /// </summary>
        /// <param name="strText">文本</param>
        /// <returns>返回结果</returns>
        public static string GetEnglishCharFromString(String strText)
        {
            //替换掉非字母的文本
            string strResult = Regex.Replace(strText, @"[^{a-z}{A-Z}]", "");
            return strResult;
        }
        
        /// <summary>
        /// 提取文本和小数点
        /// </summary>
        /// <param name="strText">文本</param>
        /// <returns>返回结果</returns>
        public static string GetTextAndPointFromString(string strText)
        {
            //替换掉数字的文本
            string strResult = Regex.Replace(strText, @"[\d]", "");
            return strResult;
        }
        
        /// <summary>
        /// 提取文本(不包括小数点)
        /// </summary>
        /// <param name="strText">文本</param>
        /// <returns>返回结果</returns>
        public static string GetTextNoPointFromString(string strText)
        {
            //替换掉数字和小数点
            string strResult = Regex.Replace(strText, @"[\d\.]", "");
            return strResult;
        }
        
        /// <summary>
        /// 提取汉字
        /// </summary>
        /// <param name="strText">文本</param>
        /// <returns>返回结果</returns>
        public static string GetChineseCharFromString(string strText)
        {
            //替换掉数字和小数点
            string strResult = Regex.Replace(strText, @"[^\u4e00-\u9fa5]", "");
            return strResult;
        }
    }
}


上一篇:UEditor使用prettify.js处理代码高亮

下一篇:VSTO获取公共对象:Word篇

相关专题: VSTO的那些坑   

评论列表

智慧如你,不想发表一下意见吗?

新的评论

清空