none
在excel中,"将数据有效性应用于单元格",如何在VS2008中,用程序代码来实现? RRS feed

  • 问题

  • 我在用VS2008开发应用软件时,要用到将VS表格控件的数据导入或导出到excel中,这样简单的导入导出我已实现。现在还差一个单元格的数据有效性的问题还没实现。我要用VS2008的程序代码来实现如下图中的操作。我要怎么来实现呢。给点相关的提示。非常感谢!
    • 已编辑 XieYide 2016年11月14日 1:56
    2016年11月14日 1:55

答案

  • MFC的COleDispatchDriver的派生类在调用封装的方法返回对象时已经AddRef你不需要再加个引用计数。另外你用MFC的封装类的话,返回值应该传递给一个COleDispatch的派生类的构造函数,名字应该是CValidation之类。你也可以直接调用返回的IDispatch的Invoke函数,调用其Add方法。 参考Validation对象的文档。


    Visual C++ MVP

    • 已标记为答案 XieYide 2016年11月17日 5:15
    2016年11月16日 12:47
    版主
  • 呃,和你的

    #include "CApplication.h"
    #include "CWorksheets.h"
    #include "CWorksheet.h"
    #include "CWorkbooks.h"
    #include "CWorkbook.h"
    #include "CRange.h"
    #include "CRanges.h"
    #include "CFont0.h"

    这些一样自己产生啊

    你不会创建封装类的时候漏了吧?



    Visual C++ MVP

    • 已标记为答案 XieYide 2016年11月24日 7:54
    2016年11月17日 13:32
    版主
  • 版主,老大:

         你好!

         我终于明白,你的指点了。我忘了把那个CValaidation导入了。非常感谢你的指点。继续努力!

    • 已标记为答案 XieYide 2016年11月24日 7:54
    2016年11月24日 7:54

全部回复

  • range.validation.add


    Visual C++ MVP

    2016年11月14日 22:06
    版主
  • 感谢版主。现在按你指点的试试。
    2016年11月16日 0:55
  • 版主:

           您好!

            上午按你说的那样我试了下。我没有你说的这个方法。“range.validation.add”。

            我的开发环境是,VS2008+EXCEL2013,用的是OLE库。

            请见如下代码块。。请版主帮我看看。我还要添加些什么吗?实在是不知道怎么办了。都没有你说的那个方法。请再指点我。再详细点。谢谢啊。

            我加载的头文件有“

    #include "CApplication.h"
    #include "CWorksheets.h"
    #include "CWorksheet.h"
    #include "CWorkbooks.h"
    #include "CWorkbook.h"
    #include "CRange.h"
    #include "CRanges.h"
    #include "CFont0.h"

    *
       Function:SetCellFormatFormulaSequence
       Discription:设置某一列的格式有效性条件为序列 个呼  组呼  全呼
       Input: NONE   

       return:无
    */
    void CExcelInterface::SetCellFormatFormulaSequence(CString sDataSource,int startRow, int endRow, int nCol)//设置单元格公式格式
    {
    //int col = 3;
    CStringArray arrstr;
    int i;
    arrstr.Add(_T("个呼"));
    arrstr.Add(_T("组呼"));
    arrstr.Add(_T("全呼"));

    m_range = m_Worksheet.get_Range(COleVariant(IndexToString(startRow,nCol)),COleVariant(IndexToString(endRow,nCol)));

    m_range.get_Validation()->AddRef();
    m_range.put_FormulaR1C1Local(COleVariant(arrstr.GetAt(0)));
    //m_range.get_Validation()


    }

    /////////////////////////////////////////////

    CExcelInterface::CExcelInterface(void)
    {
    if(AfxOleGetMessageFilter() == NULL)
    {
    if(!AfxOleInit())
    {
    m_ExcelOLEValid = FALSE;
    //AfxMessageBox(_T("初始化OLE库失败!"));
    return;
    }

    }

    /*if(!OpenExcelEngine())
    {
    return;
    }*/

    //设置EXCEL可见或隐藏
    m_ExcelAPP.put_Visible(FALSE);
    m_ExcelAPP.put_UserControl(TRUE);
    m_ExcelAPP.put_DisplayFullScreen(FALSE);
    m_ExcelAPP.put_DisplayAlerts(FALSE);
    lpDisp = NULL;
    m_ExcelOLEValid = TRUE;
    }

    CExcelInterface::~CExcelInterface(void)
    {
    CloseExcelEngine();
    }
    BOOL CExcelInterface::ExcelInterfaceisValid()//EXCEL服务器是否可用
    {

    return (m_ExcelOLEValid);
    }

    BOOL CExcelInterface::OpenExcelEngine(BOOL bExcelWorkMode, CString cstrfilename)//打开EXCEL服务器
    {
    if(!m_ExcelAPP.CreateDispatch(_T("Excel.Application"),NULL))
    {
    AfxMessageBox(_T("启动Excel服务器失败!"));
    return FALSE;
    }
    if(bExcelWorkMode == EXCEL_IMPORT)
    {
    m_Workbooks.AttachDispatch(m_ExcelAPP.get_Workbooks(),TRUE);
    COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
    lpDisp = m_Workbooks.Open(cstrfilename,covOptional,covOptional,covOptional,covOptional,
    covOptional,covOptional,covOptional,covOptional,covOptional,
    covOptional,covOptional,covOptional,covOptional,covOptional);
    if(lpDisp)
    {
    //得到Workbook
    m_Workbook.AttachDispatch(lpDisp);
    //得到Worksheets
    m_Worksheets.AttachDispatch((m_Workbook.get_Worksheets()));
    //得到当前活跃sheet
    //此操作如果单元格正处于编辑状态中,此操作不能返回,会一直等待
    lpDisp = m_Workbook.get_ActiveSheet();
    m_Worksheet.AttachDispatch(lpDisp);
    }
    else
    {
    return FALSE;
    }
    }

    return TRUE;
    }


    2016年11月16日 5:26
  • MFC的COleDispatchDriver的派生类在调用封装的方法返回对象时已经AddRef你不需要再加个引用计数。另外你用MFC的封装类的话,返回值应该传递给一个COleDispatch的派生类的构造函数,名字应该是CValidation之类。你也可以直接调用返回的IDispatch的Invoke函数,调用其Add方法。 参考Validation对象的文档。


    Visual C++ MVP

    • 已标记为答案 XieYide 2016年11月17日 5:15
    2016年11月16日 12:47
    版主
  • 版主,非常感谢你的帮助。给我指明了一条明路。
    2016年11月17日 0:59
  • 版主:

           您好!

          我的基础差, 对于,你给我的指点,

            “另外你用MFC的封装类的话,返回值应该传递给一个COleDispatch的派生类的构造函数,名字应该是CValidation之类。

          我还是晕啊。帮我再说得详细点啊。这个是如何构造的。我没有找到啊。版主。请再帮我指点下啊。

          

           

    2016年11月17日 5:28
  • 呃,和你的

    #include "CApplication.h"
    #include "CWorksheets.h"
    #include "CWorksheet.h"
    #include "CWorkbooks.h"
    #include "CWorkbook.h"
    #include "CRange.h"
    #include "CRanges.h"
    #include "CFont0.h"

    这些一样自己产生啊

    你不会创建封装类的时候漏了吧?



    Visual C++ MVP

    • 已标记为答案 XieYide 2016年11月24日 7:54
    2016年11月17日 13:32
    版主
  • 版主:

           您好!

          我实在是没有明白你的意思。

          你能帮我举个例子吗?   

           搞晕了。

    2016年11月19日 6:52
  • 版主:

          我要如何去构造这个函数啊。

    外你用MFC的封装类的话,返回值应该传递给一个COleDispatch的派生类的构造函数,名字应该是CValidation之类

    CValidation之类这个类我不知道怎么实现啊。望给出提示。非常感谢。!

    2016年11月19日 6:55
  • 版主,老大:

         你好!

         我终于明白,你的指点了。我忘了把那个CValaidation导入了。非常感谢你的指点。继续努力!

    • 已标记为答案 XieYide 2016年11月24日 7:54
    2016年11月24日 7:54
  • 版主:

         您好!

         我还有一个问题。还望你解答。代码段如下:

    #include "CApplication.h"
    #include "CWorksheets.h"
    #include "CWorksheet.h"
    #include "CWorkbooks.h"
    #include "CWorkbook.h"
    #include "CValidation.h"
    #include "CRange.h"
    #include "CRanges.h"
    #include "CFont0.h"

    //
    typedef enum {
    xlValidateInputOnly = 0x00,
    xlValidateWholeNumber = 0x01,
    xlValidateDecimal = 0x02,
    xlValidateList = 0x03,
    xlValidateDate   = 0x04,
    xlValidateTime   = 0x05,
    xlValidateTextLength = 0x06,
    xlValidateCustom     = 0x07
    }XIDVTYPE;

    typedef enum {
    xlValidAlertStop = 0x01,
    xlValidAlertWarning   = 0x02,
    xlValidAlertInformation = 0x03
    }XIDVAlertStyle;

    typedef enum {
    xlBetween = 0x01,
    xlNotBetween = 0x02,
    xlEqual = 0x03,
    xlNotEqual     = 0x04,
    xlGreater = 0x05,
    xlGreaterEqual = 0x07,
    xlLess   = 0x06,
    xlLessEqual   = 0x08
    }XIFormatConditionOperatorType;
    //

    下面的黑体是我的数据有效性为序列的数据源,此数据源在另一表为‘数据项’的A2:A4。分别为个呼,组呼,全呼。这个表已经生成了。没有问题。你帮我看看。这个数据源作为参数传进去到如下函数时有个问题。断言出错。
    sDataSource = _T("=INDIRECT(数据项!$A$2:$A$4)");
    m_ExcelInterface.SetCellFormatFormulaSequence(xlValidateList,sDataSource,2,1000,3);

    /*
       Function:SetCellFormatFormulaSequence
       Discription:设置某一列的格式有效性条件为序列 个呼  组呼  全呼
       Input: NONE   
      
       return:无
    */
    void CExcelInterface::SetCellFormatFormulaSequence(XIDVTYPE nXIDVType, CString sFormula1, int startRow, int endRow, int nCol)//设置单元格公式格式
    {
    LPDISPATCH lpValidRange;

    m_range = m_Worksheet.get_Range(COleVariant(IndexToString(startRow,nCol)),COleVariant(IndexToString(endRow,nCol)));
    lpValidRange = m_range.get_Validation();

    m_WorkRangeValid.AttachDispatch(lpValidRange);
    m_WorkRangeValid.Delete();
    m_WorkRangeValid.Modify(COleVariant((long)nXIDVType),COleVariant((long)xlValidAlertStop),COleVariant((long)xlBetween),COleVariant(sFormula1),COleVariant(sFormula1));
    }

    Modify的Formula2我没有参数,那我要设置为什么。程序运行到这一句时出错 。

    请帮我看看。

    2016年11月25日 3:44