// returns a delegate which will try to call getValue for the first call,
// and decide whether to use getValue or failOver for every subsequent call
function InititializeGetCellCall(getValue : TFunc<OleVariant, OleVariant>;
failOver : TFunc<OleVariant, OleVariant, OleVariant>) : TFunc<OleVariant, OleVariant, OleVariant>;
var
innerCall : TFunc<OleVariant, OleVariant, OleVariant>;
begin
innerCall :=
function(outerShape, outerWorkSheet : OleVariant) : OleVariant
var
dummy : OleVariant;
begin
try
// the first call to "innerCall" tests whether "getValue" thorws an exception
dummy := getValue(outerShape);
// nothing blew up, we can simply return the result of "getValue"
innerCall :=
function(shape, workSheet : OleVariant) : OleVariant
begin
result := getValue(shape);
end;
except
// it did blew up, so we have to use the provided "failOver" delegate
innerCall := failOver;
end;
// this first call has to use the new value of "innerCall" to deliver an actual result
// further calls will go to "innerCall" directly
result := innerCall(outerShape, outerWorkSheet);
end;
result :=
function(shape, workSheet : OleVariant) : OleVariant
begin
result := innerCall(shape, workSheet);
end;
end;
var
getTopLeftCell,
getBottomRightCell : TFunc<OleVariant, OleVariant, OleVariant>;
...
begin
getTopLeftCell := InititializeGetCellCall(
function(shape : OleVariant) : OleVariant
begin
// try getting "TopLeftCell" directly on newer Excel Versions
result := shape.TopLeftCell;
end,
FindTopLeftCellofShape);
getBottomRightCell := InititializeGetCellCall(
function(shape : OleVariant) : OleVariant
begin
// try getting "BottomRightCell" directly on newer Excel Versions
result := shape.BottomRightCell;
end,
FindBottomRightCellOfShape);
...
UseThatTextShape(shape,
getTopLeftCell(shape, workSheet),
getBottomRightCell(shape, workSheet));