zoukankan      html  css  js  c++  java
  • 【MFC/C++ 操作Excel】

    【MFC/C++ 操作Excel】将数字格式单元格转为文本格式

           首先,请您先阅读 MFC操作office通用分析方法一篇,或者你需要了解本文的分析方法是按如下进行的:

    1.       将我们的处理过程用宏记录下来

    2.       将这一过程从VB翻译为VC

    正文

    当我们在用MFC操作excel时,为了操作的方便性,常常需要将数据转为文本格式来保存,这一过程怎样用C++来实现呢?

    第一步:我们可以使用以下方法将文本转为文本格式:选中要转为文本格式的单元格,右键-》设置单元格格式-》文本-》确定。

     

    第二步:上面这一过程用宏记录下来是这样的,下面选择的是从A5J64之间的单元格:

    [vb] view plaincopy
     
    1. Range("A5:J64").Select  
    2.   
    3. Selection.NumberFormatLocal = "@"  


     

    第三步:将上述VB转为VC实现:

    //beginSendS之间的单元格转为文本格式存储

    [cpp] view plaincopy
     
    1. BOOL SetTextFormat(CString beginS, CString endS)  
    2.   
    3. {  
    4.   
    5.        //注意,这里的m_ecSheet是_Worksheet的对象,你之前要先得到worksheet  
    6.   
    7. Range m_ecRange = m_ecSheet.GetRange(COleVariant(beginS), COleVariant(endS));  
    8.   
    9.        if(m_ecRange.m_lpDispatch)  
    10.   
    11.        {  
    12.   
    13.               //选择beginS, endS  
    14.   
    15.               m_ecRange.Select();  
    16.   
    17. //设置为文本格式  
    18.   
    19.               m_ecRange.SetNumberFormatLocal(COleVariant("@"));  
    20.   
    21.               return TRUE;  
    22.   
    23.        }  
    24.   
    25.        return FALSE;  
    26.   
    27. }  

    调用方法:SetTextFormat(“A5”, “J64”)

           

           但是用上面的方法设置之后,原来是数字格式的单元格仍然不是文本格式,如果直接用VC操作会出错,这里有一种区分数字是否真正转为文本格式的方法:

    下图左是按照上述方法设置后的结果,此时,数字仍然不是真正的文本,下图右则是真正的文本,它的特点是每个数字格左上角都有一个绿色的小三角。

     

    那么如果将数字设置为真正的文本呢?我们按如下步骤进行。

    第一步:手动设置方法

    选中一列,按数据-》分列

     

    直接按下一步

     

    直接按下一步

     

    这里要选择文本,红笔标出,然后按完成,此时,数字就变成真正的文本了。

    第二步:上述过程用宏记录下来是这样的:

    [vb] view plaincopy
     
    1. Range("A5:A64").Select  
    2.   
    3.     Selection.TextToColumns Destination:=Range("A5"), DataType:=xlDelimited, _  
    4.   
    5.         TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _  
    6.   
    7.         Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _  
    8.   
    9.         :=Array(1, 2), TrailingMinusNumbers:=True  

    第三步:将其转为VC来实现

     

    [cpp] view plaincopy
     
      1. _Worksheet m_ecSheet;//首先你要自己初始化哦!!!!  
      2.   
      3. Range m_ecRange;  
      4.   
      5. BOOL CExcelOperate::GetRangeAndValue(CString begin, CString end)  
      6.   
      7. {  
      8.   
      9.        if(!m_ecSheet.m_lpDispatch)  
      10.   
      11.        {  
      12.   
      13.               AfxMessageBox("Sheet获取失败!", MB_OK|MB_ICONWARNING);  
      14.   
      15.               return FALSE;  
      16.   
      17.        }  
      18.   
      19.        m_ecRange = m_ecSheet.GetRange(COleVariant(begin), COleVariant(end));  
      20.   
      21.        if(!m_ecRange.m_lpDispatch)  
      22.   
      23.        {  
      24.   
      25.               AfxMessageBox("Range获取失败!", MB_OK|MB_ICONWARNING);  
      26.   
      27.               return FALSE;  
      28.   
      29.        }  
      30.   
      31.        ret = m_ecRange.GetValue2();//得到表格中的值  
      32.   
      33.        return TRUE;  
      34.   
      35. }  
      36.   
      37. BOOL CExcelOperate::SetRowToTextFormat(CString &beginS, CString &endS)  
      38.   
      39. {  
      40.   
      41.        if(GetRangeAndValue(beginS, endS))  
      42.   
      43.        {  
      44.   
      45.               m_ecRange.Select();  
      46.   
      47.               Range m_tempRange = m_ecSheet.GetRange(COleVariant(beginS), COleVariant(beginS));  
      48.   
      49.               if(!m_tempRange.m_lpDispatch) return FALSE;  
      50.   
      51.               COleVariant vTrue((short)TRUE),      
      52.   
      53.                 vFalse((short)FALSE);  
      54.   
      55.               int tempArray[2] = {1, 2};  
      56.   
      57.               COleSafeArray saRet;  
      58.   
      59.               DWORD numElements = {2};  
      60.   
      61.               saRet.Create(VT_I4, 1, &numElements);  
      62.   
      63.               long index = 0;  
      64.   
      65.               int val = 1;  
      66.   
      67.               saRet.PutElement(&index, &val);  
      68.   
      69.               index++;  
      70.   
      71.               val = 2;  
      72.   
      73.               saRet.PutElement(&index, &val);  
      74.   
      75.               //m_tempRange.GetItem(COleVariant((short)5),COleVariant("A"));  
      76.   
      77.               m_ecRange.TextToColumns(m_tempRange.GetItem(COleVariant((short)1),COleVariant((short)1)), 1, 1, vFalse, vTrue, vFalse, vFalse, vFalse, vFalse, vFalse, saRet, vFalse, vFalse, vTrue);  
      78.   
      79.               m_tempRange.ReleaseDispatch();  
      80.   
      81.               return TRUE;  
      82.   
      83.        }  
      84.   
      85.        return FALSE;  
      86.   
      87. }  

    【MFC/C++ 操作Excel】C++下TextToColumns函数的参数

    我们在使用excel的分列将数字转为文本时,用宏记录的vb代码如下:

    [vb] view plaincopy
     
    1. Range("A5:A64").Select  
    2.     Selection.TextToColumns Destination:=Range("A5"), DataType:=xlDelimited, _  
    3.         TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _  
    4.         Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _  
    5.         :=Array(1, 2), TrailingMinusNumbers:=True  


    如果我们想将其转为VC代码,过程如下:

    第一句:

    [vb] view plaincopy
     
    1. Range("A5:A64").Select  

    这一句表示选中A5:A64,翻译为C++,就是

    [cpp] view plaincopy
     
    1. m_ecRange.Select();  

    其中m_ecRange是Range的对象。

    第二句:

    [vb] view plaincopy
     
    1. Selection.TextToColumns Destination:=Range("A5"), DataType:=xlDelimited, _ TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _ Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _ :=Array(1, 2), TrailingMinusNumbers:=True  

    其对应的是Range类的TextToColumns函数,其C++函数原型是

    [cpp] view plaincopy
     
    1. VARIANT TextToColumns(const VARIANT& Destination, long DataType, long TextQualifier, const VARIANT& ConsecutiveDelimiter, const VARIANT& Tab, const VARIANT& Semicolon, const VARIANT& Comma, const VARIANT& Space, const VARIANT& Other,   
    2.   const VARIANT& OtherChar, const VARIANT& FieldInfo, const VARIANT& DecimalSeparator, const VARIANT& ThousandsSeparator, const VARIANT& TrailingMinusNumbers);  


    各个参数的意思可以参见:

    http://bbs.csdn.net/topics/390285992

    这里的参数只有第1个const VARIANT& Destination和第11个const VARIANT& FieldInfo比较难确定,其他参数都可以通过在宏中用MsgBox得到,下面说明这两个参数:

    第1个参数(const VARIANT& Destination):

    MSDN解释:指定 Microsoft Excel 放置结果的位置的 Range 对象。如果该区域大于一个单元格,请使用左上角的单元格。

    所以这里我们设置为A5单元格,我们可以使用:

    [cpp] view plaincopy
     
    1. CString beginS = “A5”;//将beginS设置为这一列左上角的单元格  
    2.   
    3. Range m_tempRange = m_ecSheet.GetRange(COleVariant(beginS), COleVariant(beginS));//得到该单元格的range  
    4.   
    5. m_tempRange.GetItem(COleVariant((short)1),COleVariant((short)1));//返回的值就是要传入的值,也就是左上角单元格,这里一定是1,1,因为range只有一个单元格  


     

    第11个参数(const VARIANT& FieldInfo)

    MSDN解释:包含单列数据拆分信息的数组。对本参数的解释取决于 DataType 的值。如果此数据由分隔符分隔,则本参数为由两元素数组组成的数组,其中每个两元素数组指定一个特定列的转换选项。第一个元素为列标(从 1 开始),第二个元素是 xlColumnDataType 常量之一,用以指定该列的拆分方式。
    我们可以看到VB代码是Array(1, 2),是一个一维数组,数组有2个元素,数组的第一个元素是1,第二个元素是2;在MFC中,我们要使用
    COleSafeArray来代表数组,初始化这样一个数组如下:

    [cpp] view plaincopy
     
    1. COleSafeArray saRet;  
    2. DWORD numElements = {2};//数组中有2个元素  
    3. saRet.Create(VT_I4, 1, &numElements);//第一个参数表示存入int,第二个参数表示是一维数组,第三个参数表示数组中有2个元素  
    4. long index = 0;//数组下标  
    5. int val = 1;//值  
    6. saRet.PutElement(&index, &val);//将0下标的值设置为1  
    [cpp] view plaincopy
     
    1. index++;  
    2. val = 2;  
    3. saRet.PutElement(&index, &val);//将1下标的值设置为2<p> </p>  


    整个函数如下:

    [cpp] view plaincopy
     
    1. BOOL CExcelOperate::SetRowToTextFormat(CString &beginS, CString &endS)  
    2. {  
    3.     if(GetRangeAndValue(beginS, endS))  
    4.     {  
    5.         m_ecRange.Select();  
    6.         Range m_tempRange = m_ecSheet.GetRange(COleVariant(beginS), COleVariant(beginS));  
    7.         if(!m_tempRange.m_lpDispatch) return FALSE;  
    8.         COleVariant vTrue((short)TRUE),      
    9.                 vFalse((short)FALSE);  
    10.         //int tempArray[2] = {1, 2};  
    11.         COleSafeArray saRet;  
    12.         DWORD numElements = {2};  
    13.         saRet.Create(VT_I4, 1, &numElements);  
    14.         long index = 0;  
    15.         int val = 1;  
    16.         saRet.PutElement(&index, &val);  
    17.         index++;  
    18.         val = 2;  
    19.         saRet.PutElement(&index, &val);  
    20.         //m_tempRange.GetItem(COleVariant((short)5),COleVariant("A"));  
    21.         m_ecRange.TextToColumns(m_tempRange.GetItem(COleVariant((short)1),COleVariant((short)1)), 1, 1, vFalse, vTrue, vFalse, vFalse, vFalse, vFalse, vFalse, saRet, vFalse, vFalse, vTrue);  
    22.         m_tempRange.ReleaseDispatch();  
    23.         return TRUE;  
    24.     }  
    25.     return FALSE;  
    26. }  


     

    [cpp] view plaincopy
     
      1. BOOL CExcelOperate::GetRangeAndValue(CString begin, CString end)  
      2. {  
      3.     if(!m_ecSheet.m_lpDispatch)  
      4.     {  
      5.         AfxMessageBox("Sheet获取失败!", MB_OK|MB_ICONWARNING);  
      6.         return FALSE;  
      7.     }  
      8.     m_ecRange = m_ecSheet.GetRange(COleVariant(begin), COleVariant(end));  
      9.     if(!m_ecRange.m_lpDispatch)  
      10.     {  
      11.         AfxMessageBox("Range获取失败!", MB_OK|MB_ICONWARNING);  
      12.         return FALSE;  
      13.     }  
      14.     ret = m_ecRange.GetValue2();//得到表格中的值  
      15.     return TRUE;  
      16. }  
  • 相关阅读:
    logstash Codec
    mysql 插入前 锁表问题
    数据统一管理--企业决策分析之刚需
    数据统一管理--企业决策分析之刚需
    MySQL RR隔离 读一致性
    java HashTable
    mysl lock table read
    mysql DBI 事务控制
    Fiddler模拟http请求
    haproxy hdr_beg 配置
  • 原文地址:https://www.cnblogs.com/For-her/p/3499881.html
Copyright © 2011-2022 走看看