正在做一个报表打印,需要支持预览,使用的MFC框架,有几个方向性的问题请教:
1。多页打印
报表打印产生多页有两种情况:A-记录多,B-宽度超出一页,我不能确定用什么方式处理比较好,一种是用超大的内存缓冲图形,打印用Bilbit方式。或者在OnPrint时处理输出,但不知宽度超出一页时,怎么处理。或者还有其他较好的方式。
2。总页数的计算
似乎只有打印两次才能处理总页数。
3。脚本支持
网上没有找到详细的执行脚本方面的资料。要想做到Office中VBA那样,是不是不可能?
4.合计函数的实现(分组合计、页合计)
是否需要自己实现合计的功能,还是有现成的类和方法,例如借助ADO

解决方案 »

  1.   

    1 自己根据计算结果处理;
    2 似乎是的,如果字体大小固定可以计算,否则最好还是打印两次的方法。
    3 MS提供了VBA引擎支持的。
      

  2.   

    谢谢谢谢,
    可否进一步告知,(3 MS提供了VBA引擎支持的。),因为刚刚接触VC,许多基本概念还在猛啃,
    我希望实现的脚本能够类似于VBA,比如:
    IF this.[NO]="abc" THEN
       this.PageHeader.Visiable=False
    ElSE
       this.PageHeader.Visiable=True
    ENDIF
    如果使用MS 的VBA,是否做得到?
    另外,还有一个不太明了的是:当打印的宽度超出页面宽度,打印超出部分的方法和打印未超出的方法是一样的,只是改变视口起点?
    thanks again
      

  3.   

    具体可以看看微软的网站,
    http://msdn.microsoft.com/isv/technology/vba/default.aspx
    MSDN中就有不少内容。
      

  4.   

    1  直接使用报表打印控件会比较简单。
    2  将数据导出到word, excel中,让用户自己控制打印时机或者微调整。
    3  自己实现打印,我曾经见过一个打印预览类,MFC写的,还不错,你自己找找吧,我很久没有用MFC,忘了。
      

  5.   

    这个纯研究性质,试图作出MS Access的报表模块的效果,可能想的太容易了,不过我打算攻下去。打印的逻辑已经考虑清楚了,比如数据传递、分类汇总等等,只是技术上有许多陌生的领域,慢慢搞吧。
    插一句,大多数第三方控件似乎处理表格比较合适,处理报表就麻烦了,就像水晶报表那样。
      

  6.   

    1、调用gdi函数判断你打印内容的宽度,如果超过打印纸的宽度当然需要分页;
    2、每条记录的宽度高度知道、页宽度高度知道,自然知道有多少页;使用“超大的内容缓存”是最低级的方案;
    3、自己实现脚本引擎比报表本身更复杂,推介使用ms的吧;
    4、如果报表连页计、总计都没有,还是报表吗?当然自己提供了。你选择了一个很艰难的领域,看样子你也不熟悉vc,做这个是对你学习能力和自信心考验。初学一个工具最好不要选择这么复杂的东西。
      

  7.   

    非常感谢yrb,我的确不熟悉VC,一开始就遇到了DOCM方面的内容,脚本引擎更是可怕,不过努力去攻,总会有所感悟,就像VC的指针、字符串等等,做过了以后,大呼“原来如此“,算是一种感悟。
    超出纸张宽度分页应该不是难题,难点就是脚本方面,其实我觉得总计之类的和脚本是有联系的。
    顺便再问一个问题:MSXML文档传递到MFC ACTIVEX中,有没有可能通过LPDISPATCH传递?现在我用的BSTR,然后在内部重新LOAD(),效率比较低下,当记录达到1000条以上,LOAD()的过程很慢,想要改善一下,如果能直接传递文档的LPDISPATCH就好了,不行的话,将改用SAX。
      

  8.   

    可以的,我以前的代码VARIANT_BOOL CYFGridCtrl::LoadFromXmlDOM(IUnknown* pUnknown)
    {
    AFX_MANAGE_STATE(AfxGetStaticModuleState()); try
    {
    MSXML2::IXMLDOMDocument2 *pXmlDoc = NULL;
    HRESULT hr;      
    hr = pUnknown->QueryInterface(__uuidof(MSXML2::IXMLDOMDocument2), (void**)&pXmlDoc);
    if(SUCCEEDED(hr))
    {
    this->m_GridEditor.LoadFromXmlDOM(pXmlDoc);
    pXmlDoc->Release();
    this->m_TabCtrl.DeleteAllItem();
    for(int i = 0; i < this->m_GridEditor.GetSheetCount(); i++)
    {
    this->m_TabCtrl.AppendItem(this->m_GridEditor.GetSheet(i)->m_SheetName);
    }
    this->m_TabCtrl.SetCurTab(0);
    return VARIANT_TRUE;
    }
    else
    {
    return VARIANT_FALSE;
    }
    }
    catch(...)
    {
    return VARIANT_FALSE;
    }
    }