for(int i=1;i<=pRepObjects->GetCount();i++) { VARIANT var2; VariantInit(&var2); var2.vt = VT_I2; var2.lVal = i; // pass the value of i to get the i-th section pRepObject = pRepObjects->GetItem(var2); pRepObject->QueryInterface(&m_pBaseReportPerson); }这个QueryInterface();这个参数是一个QueryInterface(IUnknown* pUnknown) 你可以这样得到你的子报表的接口...
//得到表头
_bstr_t section("RH");
pSection = m_Report->Sections->GetItem(section);
::SysFreeString(section);
//得到这个节里的所有的对象
IReportObjectsPtr pRepObjects = pSection->GetReportObjects();
IReportObjectPtr pRepObject = NULL;
for(int i=1;i<=pRepObjects->GetCount();i++)
{
VARIANT var2;
VariantInit(&var2);
var2.vt = VT_I2;
var2.lVal = i;
// pass the value of i to get the i-th section
pRepObject = pRepObjects->GetItem(var2);
pRepObject->QueryInterface(&m_pBaseReportPerson);
}这个QueryInterface();这个参数是一个QueryInterface(IUnknown* pUnknown)
你可以这样得到你的子报表的接口...
2、用VC来调用显示abc.rpt就可以了。
我自己用VC编了一个EXE的程序,支持将报表名、参数用命令行的方式来打开报表。
附部分源代码:
IApplicationPtr m_Application; IReportPtr m_Report;
CCrystalReportViewer9 m_Viewer
variant_t* m_pVarArray //存报表参数的数组
/*---------------------------------------*/ if (!AfxOleInit())
{
AfxMessageBox("Ole库创建失败!");
return FALSE;
}
HRESULT hr = m_Application.CreateInstance (__uuidof(Application));
if(FAILED(hr))
{
AfxMessageBox("水晶报表初始化出错!", MB_ICONINFORMATION);
return false;
}
try{
m_Report = m_Application->OpenReport (bstr_t(m_strReportFileName));
m_Report->Database->Tables->Item[1]->SetLogOnInfo(
bstr_t(m_strServer),bstr_t(m_strDatabase),bstr_t(m_strUser),bstr_t(m_strPwd));
IParameterFieldDefinitionPtr ptrItem;
bstr_t bName;
CString strParam;
for(int i=0 ; i<m_nParam; i++)
{
ptrItem = m_Report->ParameterFields->Item[i+1];
ptrItem->AddCurrentValue(m_pVarArray[i]); //variant_t* m_pVarArray 存报表参数
}
m_Viewer.SetReportSource(m_Report); //显示报表工具条
m_Viewer.SetDisplayToolbar (true);
//显示报表左边的分组树
m_Viewer.SetDisplayGroupTree(false);
//显示控件边框
m_Viewer.SetDisplayBorder (true);
//显示Tabs
m_Viewer.SetDisplayTabs(true);
//显示工具栏上导出按钮
m_Viewer.SetEnableExportButton(true);
//显示工具栏上刷新按钮
m_Viewer.SetEnableRefreshButton(false);
//刷新数据
// m_Viewer.Refresh();m_Viewer.ViewReport();
m_Viewer.Zoom(1);
}
catch(_com_error &ce)
{
AfxMessageBox(ce.Description() , MB_ICONINFORMATION);
}
catch(CException* pEx)
{
pEx->ReportError();
}
if(m_Report)
{
m_Report->Release();
m_Report = NULL;
}
if(m_Application)
{
m_Application->Release();
m_Application = NULL;
}
return true; //成功返回
if(m_Report)
{
m_Report->Release();
m_Report = NULL;
}
if(m_Application)
{
m_Application->Release();
m_Application = NULL;
}
return true; //成功返回
整个报表有两个部分. 主报表部分与子报表部分.假设主报表打印在第1页.子报表可能跨越几张纸(如1,2,3,4),在第1页主报表下方和2,3,4页中显示子报表. 到第5张重新开始打印主报表部分.接着又是几张连接的子报表. 依此下去. 我无法处理子报表的跨页与主报表的衔接.