You've already forked lazarus-ccr
fpspreadsheet: Initial version of TsWorkbookChartSource (will replace TsWorksheetChartSource)
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3865 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@@ -97,6 +97,7 @@ type
|
||||
{@@ These tokens identify basic operations in RPN formulas. }
|
||||
TBasicOperationTokens = fekAdd..fekParen;
|
||||
|
||||
type
|
||||
{@@ Flags to mark the address or a cell or a range of cells to be <b>absolute</b>
|
||||
or <b>relative</b>. They are used in the set TsRelFlags. }
|
||||
TsRelFlag = (rfRelRow, rfRelCol, rfRelRow2, rfRelCol2);
|
||||
@@ -105,6 +106,14 @@ type
|
||||
or <b>relative</b>. It is a set consisting of TsRelFlag elements. }
|
||||
TsRelFlags = set of TsRelFlag;
|
||||
|
||||
const
|
||||
{@@ Abbreviation of all-relative cell reference flags }
|
||||
rfAllRel = [rfRelRow, rfRelCol, rfRelRow2, rfRelCol2];
|
||||
|
||||
{@@ Separator between worksheet name and cell (range) reference in an address }
|
||||
SHEETSEPARATOR = '!';
|
||||
|
||||
type
|
||||
{@@ Elements of an expanded formula.
|
||||
Note: If ElementKind is fekCellOffset, "Row" and "Col" have to be cast
|
||||
to signed integers! }
|
||||
@@ -591,6 +600,7 @@ type
|
||||
destructor Destroy; override;
|
||||
|
||||
{ Utils }
|
||||
class function CellInRange(ARow, ACol: Cardinal; ARange: TsCellRange): Boolean;
|
||||
class function CellPosToText(ARow, ACol: Cardinal): string;
|
||||
procedure RemoveAllCells;
|
||||
procedure UpdateCaches;
|
||||
@@ -1840,6 +1850,17 @@ begin
|
||||
cell^.CalcState := csNotCalculated;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Checks whether a cell given by its row and column indexes belongs to a
|
||||
specified rectangular cell range.
|
||||
-------------------------------------------------------------------------------}
|
||||
class function TsWorksheet.CellInRange(ARow, ACol: Cardinal;
|
||||
ARange: TsCellRange): Boolean;
|
||||
begin
|
||||
Result := (ARow >= ARange.Row1) and (ARow <= ARange.Row2) and
|
||||
(ACol >= ARange.Col1) and (ACol <= ARange.Col2);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Converts a FPSpreadsheet cell position, which is Row, Col in numbers
|
||||
and zero based - e.g. 0,0 - to a textual representation which is [Col][Row],
|
||||
|
@@ -17,7 +17,7 @@ uses
|
||||
// TChart
|
||||
{tasources,} TACustomSource,
|
||||
// FPSpreadsheet Visual
|
||||
fpspreadsheetgrid,
|
||||
fpspreadsheetctrls, fpspreadsheetgrid,
|
||||
// FPSpreadsheet
|
||||
fpspreadsheet, fpsutils;
|
||||
|
||||
@@ -31,6 +31,8 @@ type
|
||||
|
||||
{ TsWorksheetChartSource }
|
||||
|
||||
{ DEPRECTATED - use TsWorkbookChartSource instead! }
|
||||
|
||||
TsWorksheetChartSource = class(TCustomChartSource)
|
||||
private
|
||||
FInternalWorksheet: TsWorksheet;
|
||||
@@ -71,15 +73,60 @@ type
|
||||
property YSelectionDirection: TsSelectionDirection read FYSelectionDirection write SetYSelectionDirection;
|
||||
end;
|
||||
|
||||
|
||||
{ TsWorkbookChartSource }
|
||||
|
||||
TsXYRange = (rngX, rngY);
|
||||
|
||||
TsWorkbookChartSource = class(TCustomChartSource)
|
||||
private
|
||||
FWorkbookSource: TsWorkbookSource;
|
||||
FWorkbook: TsWorkbook;
|
||||
FWorksheets: array[TsXYRange] of TsWorksheet;
|
||||
FRanges: array[TsXYRange] of TsCellRangeArray;
|
||||
FDirections: array[TsXYRange] of TsSelectionDirection;
|
||||
FPointsNumber: Cardinal;
|
||||
function GetRange(AIndex: TsXYRange): String;
|
||||
function GetWorkbook: TsWorkbook;
|
||||
procedure GetXYItem(XOrY:TsXYRange; APointIndex: Integer;
|
||||
out ANumber: Double; out AText: String);
|
||||
procedure SetRange(AIndex: TsXYRange; const AValue: String);
|
||||
procedure SetWorkbookSource(AValue: TsWorkbookSource);
|
||||
protected
|
||||
FCurItem: TChartDataItem;
|
||||
function CountValues(AIndex: TsXYRange): Integer;
|
||||
function GetCount: Integer; override;
|
||||
function GetItem(AIndex: Integer): PChartDataItem; override;
|
||||
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
||||
procedure SetYCount(AValue: Cardinal); override;
|
||||
public
|
||||
destructor Destroy; override;
|
||||
procedure ListenerNotification(AChangedItems: TsNotificationItems; AData: Pointer = nil);
|
||||
procedure Reset;
|
||||
property PointsNumber: Cardinal read FPointsNumber;
|
||||
property Workbook: TsWorkbook read GetWorkbook;
|
||||
published
|
||||
property WorkbookSource: TsWorkbookSource read FWorkbookSource write SetWorkbookSource;
|
||||
property XRange: String index rngX read GetRange write SetRange;
|
||||
property YRange: String index rngY read GetRange write SetRange;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
procedure Register;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
Math;
|
||||
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterComponents('Chart', [TsWorksheetChartSource]);
|
||||
RegisterComponents('Chart', [TsWorksheetChartSource, TsWorkbookChartSource]);
|
||||
end;
|
||||
|
||||
|
||||
{ TsWorksheetChartSource }
|
||||
|
||||
procedure TsWorksheetChartSource.SetPointsNumber(const AValue: Integer);
|
||||
@@ -218,4 +265,312 @@ begin
|
||||
FPointsNumber := lXCount;
|
||||
end;
|
||||
|
||||
|
||||
{------------------------------------------------------------------------------}
|
||||
{ TsWorkbookChartSource }
|
||||
{------------------------------------------------------------------------------}
|
||||
|
||||
destructor TsWorkbookChartSource.Destroy;
|
||||
begin
|
||||
if FWorkbookSource <> nil then FWorkbookSource.RemoveListener(self);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Counts the number of x or y values contained in the x/y ranges
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsWorkbookChartSource.CountValues(AIndex: TsXYRange): Integer;
|
||||
var
|
||||
ir: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
case FDirections[AIndex] of
|
||||
fpsVerticalSelection:
|
||||
for ir:=0 to High(FRanges[AIndex]) do
|
||||
inc(Result, FRanges[AIndex, ir].Row2 - FRanges[AIndex, ir].Row1 + 1);
|
||||
fpsHorizontalSelection:
|
||||
for ir:=0 to High(FRanges[AIndex]) do
|
||||
inc(Result, FRanges[AIndex, ir].Col2 - FRanges[AIndex, ir].Col1 + 1);
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Inherited ChartSource method telling the series how many data points are
|
||||
available
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsWorkbookChartSource.GetCount: Integer;
|
||||
begin
|
||||
Result := FPointsNumber;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Main ChartSource method called from the series requiring data for plotting.
|
||||
Retrieves the data from the workbook.
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsWorkbookChartSource.GetItem(AIndex: Integer): PChartDataItem;
|
||||
var
|
||||
dummy: String;
|
||||
begin
|
||||
GetXYItem(rngX, AIndex, FCurItem.X, FCurItem.Text);
|
||||
GetXYItem(rngY, AIndex, FCurItem.Y, dummy);
|
||||
Result := @FCurItem;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Getter method for the cell range used for x or y coordinates (or x labels)
|
||||
|
||||
@param AIndex Determines whether the methods deals with x or y values
|
||||
@return An Excel string containing workbookname and cell block(s) in A1
|
||||
notation. Multiple blocks are separated by the ListSeparator defined
|
||||
by the workbook's FormatSettings.
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsWorkbookChartsource.GetRange(AIndex: TsXYRange): String;
|
||||
var
|
||||
L: TStrings;
|
||||
ir: Integer;
|
||||
begin
|
||||
if FWorksheets[AIndex] = nil then
|
||||
begin
|
||||
Result := '';
|
||||
exit;
|
||||
end;
|
||||
|
||||
L := TStringList.Create;
|
||||
try
|
||||
L.Delimiter := Workbook.FormatSettings.ListSeparator;
|
||||
for ir:=0 to High(FRanges[AIndex]) do
|
||||
L.Add(GetCellRangeString(FRanges[AIndex, ir], rfAllRel, true));
|
||||
Result := FWorksheets[AIndex].Name + SHEETSEPARATOR + L.DelimitedText;
|
||||
finally
|
||||
L.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Getter method for the linked workbook
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsWorkbookChartSource.GetWorkbook: TsWorkbook;
|
||||
begin
|
||||
if FWorkbookSource <> nil then
|
||||
Result := WorkbookSource.Workbook
|
||||
else
|
||||
Result := nil;
|
||||
FWorkbook := Result;
|
||||
end;
|
||||
|
||||
procedure TsWorkbookChartSource.GetXYItem(XOrY:TsXYRange; APointIndex: Integer;
|
||||
out ANumber: Double; out AText: String);
|
||||
var
|
||||
range: TsCellRange;
|
||||
i, j: Integer;
|
||||
len: Integer;
|
||||
row, col: Cardinal;
|
||||
cell: PCell;
|
||||
begin
|
||||
cell := nil;
|
||||
i := 0;
|
||||
case FDirections[XOrY] of
|
||||
fpsVerticalSelection:
|
||||
for j:=0 to High(FRanges[XOrY]) do begin
|
||||
range := FRanges[XOrY, j];
|
||||
len := range.Row2 - range.Row1 + 1;
|
||||
if (APointIndex >= i) and (APointIndex < i + len) then begin
|
||||
row := range.Row1 + APointIndex - i;
|
||||
col := range.Col1;
|
||||
cell := FWorksheets[XOrY].FindCell(row, col);
|
||||
break;
|
||||
end;
|
||||
inc(i, len);
|
||||
end;
|
||||
|
||||
fpsHorizontalSelection:
|
||||
for j:=0 to High(FRanges[XOrY]) do begin
|
||||
range := FRanges[XOrY, j];
|
||||
len := range.Col2 - range.Col1 + 1;
|
||||
if (APointIndex >= i) and (APointIndex < i + len) then begin
|
||||
row := range.Row1;
|
||||
col := range.Col1 + APointIndex - i;
|
||||
cell := FWorksheets[XOrY].FindCell(row, col);
|
||||
break;
|
||||
end;
|
||||
inc(i, len);
|
||||
end;
|
||||
end;
|
||||
if cell = nil then begin
|
||||
ANumber := NaN;
|
||||
AText := '';
|
||||
end else
|
||||
if cell^.ContentType = cctUTF8String then begin
|
||||
ANumber := APointIndex;
|
||||
AText := FWorksheets[rngX].ReadAsUTF8Text(cell);
|
||||
end else
|
||||
begin
|
||||
ANumber := FWorksheets[rngX].ReadAsNumber(cell);
|
||||
AText := '';
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Notification message received from the WorkbookSource telling which
|
||||
spreadsheet item has changed.
|
||||
Responds to workbook changes by reading the worksheet names into the tabs,
|
||||
and to worksheet changes by selecting the tab corresponding to the selected
|
||||
worksheet.
|
||||
|
||||
@param AChangedItems Set with elements identifying whether workbook, worksheet
|
||||
cell content or cell formatting has changed
|
||||
@param AData Additional data, not used here
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsWorkbookChartSource.ListenerNotification(
|
||||
AChangedItems: TsNotificationItems; AData: Pointer = nil);
|
||||
var
|
||||
ir: Integer;
|
||||
cell: PCell;
|
||||
ResetDone: Boolean;
|
||||
xy: TsXYRange;
|
||||
begin
|
||||
Unused(AData);
|
||||
|
||||
// Worksheet changes
|
||||
if (lniWorksheet in AChangedItems) and (Workbook <> nil) then
|
||||
Reset;
|
||||
|
||||
// Cell changes: Enforce recalculation of axes if modified cell is within the
|
||||
// x or y range(s).
|
||||
if (lniCell in AChangedItems) and (Workbook <> nil) then
|
||||
begin
|
||||
cell := PCell(AData);
|
||||
if (cell <> nil) then begin
|
||||
ResetDone := false;
|
||||
for xy in TsXYrange do
|
||||
for ir:=0 to High(FRanges[xy]) do
|
||||
begin
|
||||
if FWorksheets[xy].CellInRange(cell^.Row, cell^.Col, FRanges[xy, ir]) then
|
||||
begin
|
||||
Reset;
|
||||
ResetDone := true;
|
||||
break;
|
||||
end;
|
||||
if ResetDone then break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Standard component notification: The ChartSource is notified that the
|
||||
WorkbookSource is being removed.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsWorkbookChartSource.Notification(AComponent: TComponent;
|
||||
Operation: TOperation);
|
||||
begin
|
||||
inherited Notification(AComponent, Operation);
|
||||
if (Operation = opRemove) and (AComponent = FWorkbookSource) then
|
||||
SetWorkbookSource(nil);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Resets internal buffers and notfies chart elements of the changes,
|
||||
in particular, enforces recalculation of axis limits
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsWorkbookChartSource.Reset;
|
||||
begin
|
||||
InvalidateCaches;
|
||||
Notify;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Setter method for the cell range used for x or y data (or labels) in the chart
|
||||
If it does not contain the worksheet name the currently active worksheet of
|
||||
the WorkbookSource is assumed.
|
||||
|
||||
@param AIndex Distinguishes whether the method deals with x or y ranges
|
||||
@param AValue String in Excel syntax containing the cell range to be
|
||||
used for x or y (depending on AIndex). Can contain multiple
|
||||
cell blocks which must be separator by the ListSeparator
|
||||
character defined in the Workbook's FormatSettings.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsWorkbookChartSource.SetRange(AIndex: TsXYRange; const AValue: String);
|
||||
var
|
||||
s: String;
|
||||
p, i: Integer;
|
||||
L: TStrings;
|
||||
sd: TsSelectionDirection;
|
||||
sd0: TsSelectionDirection;
|
||||
begin
|
||||
if (FWorkbook = nil) then
|
||||
exit;
|
||||
|
||||
p := pos(SHEETSEPARATOR, AValue);
|
||||
if p = 0 then
|
||||
begin
|
||||
FWorksheets[AIndex] := FWorkbook.ActiveWorksheet;
|
||||
s := AValue;
|
||||
end else
|
||||
begin
|
||||
s := Copy(AValue, 1, p-1);
|
||||
FWorksheets[AIndex] := FWorkbook.GetWorksheetByName(s);
|
||||
if FWorksheets[AIndex] = nil then
|
||||
raise Exception.CreateFmt('%s cell range "%s" is in a non-existing '+
|
||||
'worksheet.', [''+char(ord('x')+ord(AIndex)), AValue]);
|
||||
s := Copy(AValue, p+1, Length(AValue));
|
||||
end;
|
||||
L := TStringList.Create;
|
||||
try
|
||||
L.Delimiter := FWorkbook.FormatSettings.ListSeparator;
|
||||
L.DelimitedText := s;
|
||||
if L.Count = 0 then
|
||||
raise Exception.CreateFmt('No %s cell range contained in "%s".',
|
||||
[''+char(ord('x')+ord(AIndex)), AValue]
|
||||
);
|
||||
sd := fpsVerticalSelection;
|
||||
SetLength(FRanges[AIndex], L.Count);
|
||||
for i:=0 to L.Count-1 do
|
||||
if ParseCellRangeString(L[i], FRanges[AIndex, i]) then begin
|
||||
if FRanges[AIndex, i].Col1 = FRanges[AIndex, i].Col2 then
|
||||
sd := fpsVerticalSelection
|
||||
else
|
||||
if FRanges[AIndex, i].Row1 = FRanges[AIndex, i].Row2 then
|
||||
sd := fpsHorizontalSelection
|
||||
else
|
||||
raise Exception.Create('Selection can only be 1 column wide or 1 row high');
|
||||
end else
|
||||
raise Exception.CreateFmt('No valid %s cell range in "%s".',
|
||||
[''+char(ord('x')+ord(AIndex)), L[i]]
|
||||
);
|
||||
FPointsNumber := Max(CountValues(rngX), CountValues(rngY));
|
||||
// If x and y ranges are of different size empty data points will be plotted.
|
||||
Reset;
|
||||
finally
|
||||
L.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Setter method for the WorkbookSource
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsWorkbookChartSource.SetWorkbookSource(AValue: TsWorkbookSource);
|
||||
begin
|
||||
if AValue = FWorkbookSource then
|
||||
exit;
|
||||
if FWorkbookSource <> nil then
|
||||
FWorkbookSource.RemoveListener(self);
|
||||
FWorkbookSource := AValue;
|
||||
if FWorkbookSource <> nil then
|
||||
FWorkbookSource.AddListener(self);
|
||||
FWorkbook := GetWorkbook;
|
||||
ListenerNotification([lniWorkbook, lniWorksheet]);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Inherited ChartSource method telling the series how many y values are used.
|
||||
Currently we support only single valued data
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsWorkbookChartSource.SetYCount(AValue: Cardinal);
|
||||
begin
|
||||
FYCount := AValue;
|
||||
// currently not used
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
@@ -423,7 +423,7 @@ implementation
|
||||
|
||||
uses
|
||||
Types, Math, TypInfo, LCLType, Dialogs, Forms,
|
||||
fpsStrings, fpsUtils, fpSpreadsheetGrid;
|
||||
fpsStrings, fpsUtils, fpSpreadsheetGrid, fpSpreadsheetChart;
|
||||
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
@@ -898,7 +898,11 @@ begin
|
||||
else
|
||||
if TObject(FListeners[i]) is TsSpreadsheetInspector then
|
||||
TsSpreadsheetInspector(FListeners[i]).ListenerNotification(AChangedItems, AData)
|
||||
else {
|
||||
else
|
||||
if TObject(FListeners[i]) is TsWorkbookChartSource then
|
||||
TsWorkbookChartSource(FListeners[i]).ListenerNotification(AChangedItems, AData)
|
||||
else
|
||||
{
|
||||
if TObject(FListeners[i]) is TsSpreadsheetAction then
|
||||
TsSpreadsheetAction(FListeners[i]).ListenerNotifiation(AChangedItems, AData)
|
||||
else }
|
||||
@@ -937,7 +941,11 @@ begin
|
||||
else
|
||||
if (AListener is TsSpreadsheetInspector) then
|
||||
TsSpreadsheetInspector(AListener).WorkbookSource := nil
|
||||
else {
|
||||
else
|
||||
if (AListener is TsWorkbookChartSource) then
|
||||
TsWorkbookChartSource(AListener).WorkbookSource := nil
|
||||
else
|
||||
{
|
||||
if (AListener is TsSpreadsheetAction) then
|
||||
TsSpreadsheetAction(AListener).WorksheetLink := nil
|
||||
else }
|
||||
|
@@ -72,6 +72,10 @@ function ParseCellRangeString(const AStr: string;
|
||||
out AFlags: TsRelFlags): Boolean; overload;
|
||||
function ParseCellRangeString(const AStr: string;
|
||||
out AFirstCellRow, AFirstCellCol, ALastCellRow, ALastCellCol: Cardinal): Boolean; overload;
|
||||
function ParseCellRangeString(const AStr: String;
|
||||
out ARange: TsCellRange; out AFlags: TsRelFlags): Boolean; overload;
|
||||
function ParseCellRangeString(const AStr: String;
|
||||
out ARange: TsCellRange): Boolean; overload;
|
||||
function ParseCellString(const AStr: string;
|
||||
out ACellRow, ACellCol: Cardinal; out AFlags: TsRelFlags): Boolean; overload;
|
||||
function ParseCellString(const AStr: string;
|
||||
@@ -82,11 +86,13 @@ function ParseCellColString(const AStr: string;
|
||||
out AResult: Cardinal): Boolean;
|
||||
|
||||
function GetColString(AColIndex: Integer): String;
|
||||
|
||||
function GetCellString(ARow,ACol: Cardinal;
|
||||
AFlags: TsRelFlags = [rfRelRow, rfRelCol]): String;
|
||||
function GetCellRangeString(ARow1, ACol1, ARow2, ACol2: Cardinal;
|
||||
AFlags: TsRelFlags = [rfRelRow, rfRelCol, rfRelRow2, rfRelCol2];
|
||||
Compact: Boolean = false): String;
|
||||
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String; overload;
|
||||
function GetCellRangeString(ARange: TsCellRange;
|
||||
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String; overload;
|
||||
|
||||
function GetErrorValueStr(AErrorValue: TsErrorValue): String;
|
||||
|
||||
@@ -509,6 +515,43 @@ begin
|
||||
);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Parses strings like A5:C10 into a range selection information.
|
||||
Returns in AFlags also information on relative/absolute cells.
|
||||
|
||||
@param AStr Cell range string, such as A5:C10
|
||||
@param ARange TsCellRange record of the zero-based row and column
|
||||
indexes of the top/left and right/bottom corrners
|
||||
@param AFlags a set containing an element for ARange.Row1 (top row),
|
||||
ARange.Col1 (left column), ARange.Row2 (bottom row),
|
||||
ARange.Col2 (right column) if they represent relative
|
||||
cell addresses.
|
||||
@return false if the string is not a valid cell range
|
||||
--------------------------------------------------------------------------------}
|
||||
function ParseCellRangeString(const AStr: String;
|
||||
out ARange: TsCellRange; out AFlags: TsRelFlags): Boolean;
|
||||
begin
|
||||
Result := ParseCelLRangeString(AStr, ARange.Row1, ARange.Col1, ARange.Row2,
|
||||
ARange.Col2, AFlags);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Parses strings like A5:C10 into a range selection information.
|
||||
Information on relative/absolute cells is ignored.
|
||||
|
||||
@param AStr Cell range string, such as A5:C10
|
||||
@param ARange TsCellRange record of the zero-based row and column
|
||||
indexes of the top/left and right/bottom corrners
|
||||
@return false if the string is not a valid cell range
|
||||
--------------------------------------------------------------------------------}
|
||||
function ParseCellRangeString(const AStr: String;
|
||||
out ARange: TsCellRange): Boolean;
|
||||
begin
|
||||
Result := ParseCellRangeString(AStr, ARange.Row1, ARange.Col1, ARange.Row2,
|
||||
ARange.Col2);
|
||||
end;
|
||||
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Parses a cell string, like 'A1' into zero-based column and row numbers
|
||||
Note that there can be several letters to address for more than 26 columns.
|
||||
@@ -744,8 +787,7 @@ end;
|
||||
--> $A1:$B3
|
||||
-------------------------------------------------------------------------------}
|
||||
function GetCellRangeString(ARow1, ACol1, ARow2, ACol2: Cardinal;
|
||||
AFlags: TsRelFlags = [rfRelRow, rfRelCol, rfRelRow2, rfRelCol2];
|
||||
Compact: Boolean = false): String;
|
||||
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String;
|
||||
begin
|
||||
if Compact and (ARow1 = ARow2) and (ACol1 = ACol2) then
|
||||
Result := GetCellString(ARow1, ACol1, AFlags)
|
||||
@@ -758,6 +800,28 @@ begin
|
||||
]);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Calculates a cell range address string from a TsCellRange record
|
||||
and the relative address state flags.
|
||||
|
||||
@param ARange TsCellRange record containing the zero-based indexes of
|
||||
the first and last row and columns of the range
|
||||
@param AFlags A set containing an entry for first and last column and
|
||||
row if their addresses are relative.
|
||||
@param Compact If the range consists only of a single cell and compact
|
||||
is true then the simple cell string is returned (e.g. A1).
|
||||
If compact is false then the cell is repeated (e.g. A1:A1)
|
||||
@return Excel type of cell address range containing '$' characters for absolute
|
||||
address parts and a ':' to separate the first and last cells of the
|
||||
range
|
||||
-------------------------------------------------------------------------------}
|
||||
function GetCellRangeString(ARange: TsCellRange;
|
||||
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String;
|
||||
begin
|
||||
Result := GetCellRangeString(ARange.Row1, ARange.Col1, ARange.Row2, ARange.Col2,
|
||||
AFlags, Compact);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Returns the message text assigned to an error value
|
||||
|
||||
|
Reference in New Issue
Block a user