// There MUST be exactly one reference per range token and nothing // else, and it MUST be a valid reference, not some #REF!
sal_uInt16 nLen = pArray->GetLen(); if (!nLen) continue; // Should a missing range really be allowed? if (nLen != 1)
{
bFailure = true; break;
}
const FormulaToken* p = pArray->FirstToken(); if (!p)
{
bFailure = true; break;
}
switch (p->GetType())
{ case svSingleRef:
{ const ScSingleRefData& rRef = *p->GetSingleRef(); if (!rRef.Valid(rDoc))
bFailure = true; elseif (bOnly3DRef && !rRef.IsFlag3D())
bFailure = true;
} break; case svDoubleRef:
{ const ScComplexRefData& rRef = *p->GetDoubleRef(); if (!rRef.Valid(rDoc))
bFailure = true; elseif (bOnly3DRef && !rRef.Ref1.IsFlag3D())
bFailure = true;
} break; case svExternalSingleRef:
{ if (!p->GetSingleRef()->ValidExternal(rDoc))
bFailure = true;
} break; case svExternalDoubleRef:
{ if (!p->GetDoubleRef()->ValidExternal(rDoc))
bFailure = true;
} break; case svString: if (p->GetString().isEmpty())
bFailure = true; break; case svIndex:
{ if (p->GetOpCode() == ocName)
{
ScRangeData* pNameRange = rDoc.FindRangeNameBySheetAndIndex(p->GetSheet(), p->GetIndex()); if (!pNameRange->HasReferences())
bFailure = true;
}
} break; default:
bFailure = true; break;
} if (!bFailure)
rRefTokens.emplace_back(p->Clone());
// Display sheet name on 2nd reference only when the 1st and 2nd refs are on // different sheets.
aData.Ref2.SetFlag3D(rRange.aStart.Tab() != rRange.aEnd.Tab());
/** *Checktwo1-dimensionalrangestoseeiftheyoverlapeachother. * *@paramnMin1minvalueofrange1 *@paramnMax1maxvalueofrange1 *@paramnMin2minvalueofrange2 *@paramnMax2maxvalueofrange2 *@paramrNewMinminvalueofnewrangeincasetheyoverlap *@paramrNewMaxmaxvalueofnewrangeincasetheyoverlap
*/ template<typename T> staticbool overlaps(T nMin1, T nMax1, T nMin2, T nMax2, T& rNewMin, T& rNewMax)
{ bool bDisjoint1 = (nMin1 > nMax2) && (nMin1 - nMax2 > 1); bool bDisjoint2 = (nMin2 > nMax1) && (nMin2 - nMax1 > 1); if (bDisjoint1 || bDisjoint2) // These two ranges cannot be joined. Move on. returnfalse;
T nMin = std::min(nMin1, nMin2);
T nMax = std::max(nMax1, nMax2);
rNewMin = nMin;
rNewMax = nMax;
returntrue;
}
void join(const ScDocument* pDoc, vector<ScTokenRef>& rTokens, const ScTokenRef& pToken, const ScAddress& rPos)
{ // Normalize the token to a double reference.
ScComplexRefData aData; if (!ScRefTokenHelper::getDoubleRefDataFromToken(aData, pToken)) return;
// Get the information of the new token. bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
sal_uInt16 nFileId = bExternal ? pToken->GetIndex() : 0;
svl::SharedString aTabName = bExternal ? pToken->GetString() : svl::SharedString::getEmptyString();
bool bJoined = false; for (ScTokenRef& pOldToken : rTokens)
{ if (!ScRefTokenHelper::isRef(pOldToken)) // A non-ref token should not have been added here in the first // place! continue;
if (bExternal != ScRefTokenHelper::isExternalRef(pOldToken)) // External and internal refs don't mix. continue;
if (bExternal)
{ if (nFileId != pOldToken->GetIndex()) // Different external files. continue;
if (aTabName != pOldToken->GetString()) // Different table names. continue;
}
ScComplexRefData aOldData; if (!ScRefTokenHelper::getDoubleRefDataFromToken(aOldData, pOldToken)) continue;
if (bJoinRanges)
{
aNew.aStart.SetRow(nNewMin);
aNew.aEnd.SetRow(nNewMax);
aNewData.SetRange(pDoc->GetSheetLimits(), aNew, rPos);
}
}
if (bJoinRanges)
{ if (bExternal)
pOldToken.reset(new ScExternalDoubleRefToken(nFileId, aTabName, aNewData)); else
pOldToken.reset(new ScDoubleRefToken(pDoc->GetSheetLimits(), aNewData));
bJoined = true; break;
}
}
if (bJoined)
{ if (rTokens.size() == 1) // There is only one left. No need to do more joining. return;
// Pop the last token from the list, and keep joining recursively.
ScTokenRef p = rTokens.back();
rTokens.pop_back();
join(pDoc, rTokens, p, rPos);
} else
rTokens.push_back(pToken);
}
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.