BOOL CXTPReportGroupRow::CalculateByChilds(CXTPReportRow* pPassedRow, int col_start, int col_end, double& dPassedValue)
{
	BOOL bRet = FALSE;

	CXTPReportRow* pRow = NULL;
	CXTPReportRecord* pRec = NULL;
	CXTPReportRecordItem* pItem = NULL;

	for (int row = 0; row < pPassedRow->GetChilds(FALSE)->GetCount(); row++)
	{
		pRow = pPassedRow->GetChilds(FALSE)->GetAt(row);
		if (pRow && !pRow->IsGroupRow())
		{
			pRec = pRow->GetRecord();
			if (pRec)
			{
				bRet = TRUE;
				for (int col = col_start; col < col_end; col++)
				{
					if (col < pRec->GetItemCount())
					{
						pItem = pRec->GetItem(col);
						if (pItem)
						{
							CString s = pItem->GetCaption(NULL);
							dPassedValue += pItem->StringToDouble(s);
						}
					}
				}
			}
		}
		else if (pRow && pRow->IsGroupRow())
		{
			bRet = CalculateByChilds(pRow, col_start, col_end, dPassedValue);
		}
	}
	return bRet;
}
void CXTPReportGroupRow::SetCaption(LPCTSTR lpszCaption)
{
	CString strGroupCaption(lpszCaption);

	if (strGroupCaption ==  _T("x"))
		strGroupCaption.Empty();

	if (m_strFormula.IsEmpty())
	{
		if (m_strGroupText == strGroupCaption)
			return;

		m_strGroupText = strGroupCaption;
		if (m_strGroupLabel.IsEmpty())
			m_strGroupLabel = m_strGroupText;

		XTPMarkupReleaseElement(m_pMarkupUIElement);

		if (m_pControl && (m_pControl->GetMarkupContext()))
			m_pMarkupUIElement = XTPMarkupParseText(m_pControl->GetMarkupContext(), m_strGroupText);
	}
	else
	{
		CString strCaption(strGroupCaption);
		double d(0.0);
		int m(0), M(0), n(0), N(0);
		CString s, t, u, v;
		CString sFormula(m_strFormula);
		sFormula.Replace(_T("(C"), _T("(R*C"));
		sFormula.Replace(_T(":C"), _T("(:R*C"));
		int pos = sFormula.Find(_T("SUMSUB("));
		int nextPos(-1);
//Simplified format for group row formulas - SUMSUB(C#:C#) as R# ignored and dynamically recreated
//For prev ver formulas - clean R# parts
//For multiple formulas case can be SUMSUB(R#Ci1:R#Cl1) SUMSUB(R#Ci2:R#Cl2) ... SUMSUB(R#Cim:R#Clm)
//ROW range ignored as used dynamic based on group row childs
//Space-separated string split between spaces and
//Instead "if (pos > -1)" can use loop "while (pos > -1)"
		//if (pos > -1)
		while (pos > -1)
		{
			CString sNextFormula, strCapt, strCol;
			if (sFormula.GetLength() > pos + 7)
				nextPos = sFormula.Find(_T("SUMSUB("), pos + 7);
			if (nextPos > -1)
				sNextFormula = sFormula.Mid(nextPos);

			if (GetChilds(FALSE) != NULL)
			{
				int mMax = m_pControl->GetRows()->GetCount();
				int nMax = m_pControl->GetColumns()->GetCount();
//CODE FOR RECALC - pattern SUMSUB(R#C#:R#C#) or * instead of # - means all row or column
//ROW range ignored as used dynamic based on group row childs
				sFormula.Replace(_T(" "), _T(""));
				if (sFormula.GetLength() > pos + 7)
					sFormula = sFormula.Mid(pos + 7);
				pos = sFormula.Find(_T(":"));
				if (pos > -1)
				{
					s = sFormula.Left(pos);
					t = sFormula.Mid(pos + 1);
					pos = s.Find(_T("C"));
					if (pos > -1)
					{
						u = s.Left(pos);
						s = s.Mid(pos + 1);
						u.Replace(_T("R"), _T(""));
						if (u == _T("*"))
							m = 0;
						else
							m = _ttoi(u);
						if (s == _T("*"))
							n = 0;
						else
							n = _ttoi(s);

						pos = t.Find(_T("C"));
						if (pos > -1)
						{
							u = t.Left(pos);
							t = t.Mid(pos + 1);
							u.Replace(_T("R"), _T(""));
							if (u == _T("*"))
								M = mMax;
							else
								M = _ttoi(u);
							t.Replace(_T(")"), _T(""));
							if (t == _T("*"))
								N = nMax;
							else
								N = _ttoi(t);

							if (n == N - 1)
								d = 0;
							CalculateByChilds(this, n, N, d);

							CString sFmt = GetFormatString();
							if (sFmt.IsEmpty() || sFmt == _T("%s"))
								sFmt = _T("%f");
							else if (sFmt == _T("%d"))
								sFmt = _T("%.0f");

							strCapt.Format(sFmt, d);
							strCol.Format(_T(" [%d]"), n);
							strCapt = strCol + strCapt;
						}
					}
				}
			}
			if (nextPos > -1)
			{
				sFormula = sNextFormula;
				pos = sFormula.Find(_T("SUMSUB("));
				sNextFormula.Empty();
			}
			strCaption += strCapt;
		}
		if (m_strGroupText == strCaption)
			return;

		m_strGroupText = m_strGroupLabel + strCaption;

		XTPMarkupReleaseElement(m_pMarkupUIElement);

		if (m_pControl && (m_pControl->GetMarkupContext()))
			m_pMarkupUIElement = XTPMarkupParseText(m_pControl->GetMarkupContext(), m_strGroupText);
	}
}