dingsir的个人博客分享 http://blog.sciencenet.cn/u/dingsir

博文

EXCEL 分列 (TextToColumns) 的C#代码

已有 3371 次阅读 2017-12-15 00:43 |个人分类:软件杂谈|系统分类:科研笔记|关键词:C#,TextToColumns,分列,格式控制,数组,VBA| VBA, 数组, TextToColumns, 分列, 格式控制

EXCEL中有一个有用的功能,叫做“分列”,顾名思义,EXCEL中将一串文本根据选择的分隔符对文本进行分解,从而产生几列数据。这个功能最常用的地方应该是导入一些文本形式的数据时,特别有用。比如导入CSV格式的数据。

举个简单的例子,假设有一行数据是这样的,LIPF6:13%:Salt  

原来的数据表示 第1列为LIPF6,是物质名称,文本性质; 第2列为该物质的含量,用13%表示;第3列为该物质的归类,Salt类。

导入到EXCEL中时,如果不分列,这样的一个文本串不便于计算。因此,选中这(些)个单元格,再点击“数据”菜单下的分列,根据向导,选择冒号作为分隔符,就可以将它分为三列了。

EXCEL的这个操作,正是Range对象的一个方法TextToColumns完成的。我们来看一下录制宏时记录下的代码

Selection.TextToColumns Destination:=Range("A1"), DataType:=xlDelimited, _

 TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _

 Semicolon:=False, Comma:=False, Space:=False, Other:=True, OtherChar:=":",_  

FieldInfo:=Array(Array(1, 2), Array(2, 1),Array(3,2)), TrailingMinusNumbers:=True


Selection表示我们选中的单元格对象,类型即Range, Destination参数指定拆解后的数据左上角的位置,此处为A1格;DataType表明数据为分隔类型(xlDelimited), 还有一种是定宽类型(xlFixedWidth表示)TextQualifier 参数 指定文本边界的符号为双引号类型; ConsecutiveDelimiter参数指定是否把连续的多个某分隔符视为一个,此处为否(false); Tab参数说明是否选用制表符作为分隔符,如果是则此参数为True,不是则为False. 后面几个参数是同样的意思: Semicolon 即分号;Comma为逗号,Space为空格,这几个的用法都是一样的,它们作为分隔符,则该参数指定为True,否则为False.    因为我们的例子中用冒号作为分隔符,不在这几个之列,因此后面的Other参数设置为True,表示使用其它字符作为分隔符,同时我们必须指定紧接着的OtherChar 参数为冒号.

再后面这个FieldInfo参数比较难理解,我研究了好久才弄明白,多写一点。

它是一个数组的数组,用于指定分列之后的各列的内容类型。这个例 子里数组有三个元素,每个元素为一对值。拿第一个元素Array(1,2)来说吧,第一个参数1代表说明这是拆解后的第1列的内容。 第二个参数2代表该列(即第1列)的内容类型。这个2对应是什么类型呢? 见下面的定义:

public enum XlColumnDataType

   {

      xlGeneralFormat = 1, //通用类型

       xlTextFormat = 2,   //文本

       xlMDYFormat = 3, //月日年

       xlDMYFormat = 4, //日月年

       xlYMDFormat = 5, //年月日

       xlMYDFormat = 6,

       xlDYMFormat = 7,

       xlYDMFormat = 8,

      xlSkipColumn = 9, //忽略此列

       xlEMDFormat = 10

}

原来2代表分列后的内容是文本  (xlTextFormat = 2)

类似的,第2个元素Array(2,1)代表分列后第2列为通用类型即xlGeneralFormat( xlGeneralFormat = 1).

上述3~8均为日期的不同格式,D为日,M为月,Y为年,按顺序排列就明白了。

这里面比较有意思的有几点:

1.列的内容类型如果没有指定,就按通用类型解析(类型1)。

2.列的顺序可以可以打乱。比如上面的写成 FieldInfo:=Array( Array(2, 1),Array(3,2), Array(1, 2)) 也是可以的。

3.如果你不想解析出这一列的内容,指定其类型为9也就是xlSkipColumn就可以。这样看来,所谓的第几列是根据文本的内容来推算的,不是实际解析完成后的列数。

接下来后面还有几个参数:

DecimalSeparator 为字符串,表示小数点的分隔符,默认为系统设置,你也可以不设(缺着就行);ThousandsSeparator也是字符串,指定千分位分隔符,默认也是系统设置。TrailingMinusNumbers为逻辑值,True表示认可负号开始的数字,False表示不接受负号开始的数字。


在C#中这样写的。

private void button1_Click(object sender, EventArgs e)

{

Excel.Worksheet asht = Globals.ThisWorkbook.Application.ActiveSheet;

asht.get_Range("A1:A6").Select();

Excel.Range selection = Globals.ThisWorkbook.Application.Selection;

int[,] myField = { { 1, 2 }, { 2, 1 },{ 3, 2 } };

selection.TextToColumns(asht.get_Range("A1"), Excel.XlTextParsingType.xlDelimited, Excel.XlTextQualifier.xlTextQualifierDoubleQuote, false, false, false, false, false, true, ":",myField,".",",",true);

}


针对上面的例子,比如说字串 “LIPF6:13%:Salt", 使用上面的方法进行分列,得到的13%被视为通用类型(对应中间的那个{2,1}即第2列为类型1即通用类型,分列之后的15% EXCEL会视为数字。如果你将{2,1} 改成{2,2},即第2列当成类型2(文本),EXCEL就会显示 提示这是以文本形式存储的数字。见下图的对比。


最后是EXCEL的文件例子(需要运行宏的权限才能)分列示例.rar




http://blog.sciencenet.cn/blog-1213210-1089734.html

上一篇:一个实用的电解液配方解析及中控计算小工具
下一篇:低温下电解液的粘度

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...
扫一扫,分享此博文

Archiver|手机版|科学网 ( 京ICP备14006957 )

GMT+8, 2020-1-20 12:26

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部