fpspreadsheet: Prepare TsWorksheetGrid for multiselection of ranges (not activated by default, requires the patch of issue #0027000). Add information on selected cell and selected ranges to TsWorksheet (stored/restored on changes of active sheet). Some more information in TsSpreadsheetInspector.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3704 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-11-05 23:45:48 +00:00
parent 2b4925f0a8
commit 1b86c7e3dd
7 changed files with 385 additions and 120 deletions

View File

@ -28,7 +28,7 @@ object Form1: TForm1
end end
object CellIndicator: TsCellIndicator object CellIndicator: TsCellIndicator
Left = 95 Left = 95
Height = 28 Height = 23
Top = 9 Top = 9
Width = 80 Width = 80
TabOrder = 1 TabOrder = 1
@ -37,7 +37,7 @@ object Form1: TForm1
end end
object CellEdit: TsCellEdit object CellEdit: TsCellEdit
Left = 184 Left = 184
Height = 28 Height = 23
Top = 9 Top = 9
Width = 731 Width = 731
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
@ -60,12 +60,13 @@ object Form1: TForm1
WorkbookSource = WorkbookSource WorkbookSource = WorkbookSource
object WorksheetGrid: TsWorksheetGrid object WorksheetGrid: TsWorksheetGrid
Left = 2 Left = 2
Height = 528 Height = 533
Top = 28 Top = 23
Width = 668 Width = 668
FrozenCols = 0 FrozenCols = 0
FrozenRows = 0 FrozenRows = 0
ReadFormulas = False ReadFormulas = False
TextOverflow = True
WorkbookSource = WorkbookSource WorkbookSource = WorkbookSource
Align = alClient Align = alClient
AutoAdvance = aaDown AutoAdvance = aaDown
@ -127,8 +128,8 @@ object Form1: TForm1
TabOrder = 2 TabOrder = 2
object Inspector: TsSpreadsheetInspector object Inspector: TsSpreadsheetInspector
Left = 2 Left = 2
Height = 528 Height = 533
Top = 28 Top = 23
Width = 244 Width = 244
Align = alClient Align = alClient
RowCount = 24 RowCount = 24
@ -136,10 +137,10 @@ object Form1: TForm1
Strings.Strings = ( Strings.Strings = (
'FileName=' 'FileName='
'FileFormat=sfExcel8' 'FileFormat=sfExcel8'
'Options=' 'Options=boAutoCalc, boCalcBeforeSaving, boReadFormulas'
'FormatSettings=' 'FormatSettings='
' ThousandSeparator=.' ' ThousandSeparator=.'
' DecimalSeparator=,' ' DecimalSeparator=.'
' ListSeparator=;' ' ListSeparator=;'
' DateSeparator=.' ' DateSeparator=.'
' TimeSeparator=:' ' TimeSeparator=:'
@ -165,8 +166,8 @@ object Form1: TForm1
WorkbookSource = WorkbookSource WorkbookSource = WorkbookSource
Mode = imWorkbook Mode = imWorkbook
ColWidths = ( ColWidths = (
109 120
110 120
) )
end end
end end

View File

@ -125,11 +125,11 @@ object Form1: TForm1
end end
object CbLoader: TComboBox object CbLoader: TComboBox
Left = 104 Left = 104
Height = 28 Height = 23
Top = 8 Top = 8
Width = 148 Width = 148
ItemHeight = 20 ItemHeight = 15
ItemIndex = 0 ItemIndex = 1
Items.Strings = ( Items.Strings = (
'Workbook' 'Workbook'
'WorkbookSource' 'WorkbookSource'
@ -137,13 +137,13 @@ object Form1: TForm1
) )
Style = csDropDownList Style = csDropDownList
TabOrder = 1 TabOrder = 1
Text = 'Workbook' Text = 'WorkbookSource'
end end
object Label1: TLabel object Label1: TLabel
Left = 13 Left = 13
Height = 20 Height = 15
Top = 11 Top = 11
Width = 73 Width = 58
Caption = 'Loaded by:' Caption = 'Loaded by:'
ParentColor = False ParentColor = False
end end

View File

@ -157,18 +157,18 @@ begin
if MessageDlg('Do you really want to delete this worksheet?', mtConfirmation, if MessageDlg('Do you really want to delete this worksheet?', mtConfirmation,
[mbYes, mbNo], 0) = mrYes [mbYes, mbNo], 0) = mrYes
then then
WorkbookSource.Workbook.RemoveWorksheet(WorkbookSource.SelectedWorksheet); WorkbookSource.Workbook.RemoveWorksheet(WorkbookSource.Worksheet);
end; end;
procedure TForm1.SpeedButton3Click(Sender: TObject); procedure TForm1.SpeedButton3Click(Sender: TObject);
var var
s: String; s: String;
begin begin
s := WorkbookSource.SelectedWorksheet.Name; s := WorkbookSource.Worksheet.Name;
if InputQuery('Edit worksheet name', 'New name', s) then if InputQuery('Edit worksheet name', 'New name', s) then
begin begin
if WorkbookSource.Workbook.ValidWorksheetName(s) then if WorkbookSource.Workbook.ValidWorksheetName(s) then
WorkbookSource.SelectedWorksheet.Name := s WorkbookSource.Worksheet.Name := s
else else
MessageDlg('Invalid worksheet name.', mtError, [mbOK], 0); MessageDlg('Invalid worksheet name.', mtError, [mbOK], 0);
end; end;

View File

@ -512,6 +512,7 @@ type
FRows, FCols: TIndexedAVLTree; // This lists contain only rows or cols with styles different from default FRows, FCols: TIndexedAVLTree; // This lists contain only rows or cols with styles different from default
FActiveCellRow: Cardinal; FActiveCellRow: Cardinal;
FActiveCellCol: Cardinal; FActiveCellCol: Cardinal;
FSelection: TsCellRangeArray;
FLeftPaneWidth: Integer; FLeftPaneWidth: Integer;
FTopPaneHeight: Integer; FTopPaneHeight: Integer;
FOptions: TsSheetOptions; FOptions: TsSheetOptions;
@ -794,8 +795,13 @@ type
ARowFrom, AColFrom, ARowTo, AColTo: Cardinal); overload; ARowFrom, AColFrom, ARowTo, AColTo: Cardinal); overload;
procedure Sort(ASortParams: TsSortParams; ARange: String); overload; procedure Sort(ASortParams: TsSortParams; ARange: String); overload;
// Selected cell // Selected cell and ranges
procedure SelectCell(ARow, ACol: Cardinal); procedure SelectCell(ARow, ACol: Cardinal);
procedure ClearSelection;
function GetSelection: TsCellRangeArray;
function GetSelectionAsString: String;
function GetSelectionCount: Integer;
procedure SetSelection(const ASelection: TsCellRangeArray);
{ Properties } { Properties }
@ -907,11 +913,13 @@ type
FWriting: Boolean; FWriting: Boolean;
FCalculationLock: Integer; FCalculationLock: Integer;
FOptions: TsWorkbookOptions; FOptions: TsWorkbookOptions;
FActiveWorksheet: TsWorksheet;
FOnWriteCellData: TsWorkbookWriteCellDataEvent; FOnWriteCellData: TsWorkbookWriteCellDataEvent;
FOnReadCellData: TsWorkbookReadCellDataEvent; FOnReadCellData: TsWorkbookReadCellDataEvent;
FOnChangeWorksheet: TsWorksheetEvent; FOnChangeWorksheet: TsWorksheetEvent;
FOnAddWorksheet: TsWorksheetEvent; FOnAddWorksheet: TsWorksheetEvent;
FOnRemoveWorksheet: TsRemoveWorksheetEvent; FOnRemoveWorksheet: TsRemoveWorksheetEvent;
FOnSelectWorksheet: TsWorksheetEvent;
FFileName: String; FFileName: String;
FLog: TStringList; FLog: TStringList;
@ -964,6 +972,7 @@ type
function GetWorksheetIndex(AWorksheet: TsWorksheet): Integer; function GetWorksheetIndex(AWorksheet: TsWorksheet): Integer;
procedure RemoveAllWorksheets; procedure RemoveAllWorksheets;
procedure RemoveWorksheet(AWorksheet: TsWorksheet); procedure RemoveWorksheet(AWorksheet: TsWorksheet);
procedure SelectWorksheet(AWorksheet: TsWorksheet);
function ValidWorksheetName(var AName: String; function ValidWorksheetName(var AName: String;
ReplaceDuplicateName: Boolean = false): Boolean; ReplaceDuplicateName: Boolean = false): Boolean;
@ -1005,6 +1014,8 @@ type
procedure AddErrorMsg(const AMsg: String; const Args: array of const); overload; procedure AddErrorMsg(const AMsg: String; const Args: array of const); overload;
procedure ClearErrorList; procedure ClearErrorList;
{@@ Identifies the "active" worksheet (only for visual controls)}
property ActiveWorksheet: TsWorksheet read FActiveWorksheet;
{@@ This property is only used for formats which don't support unicode {@@ This property is only used for formats which don't support unicode
and support a single encoding for the whole document, like Excel 2 to 5 } and support a single encoding for the whole document, like Excel 2 to 5 }
property Encoding: TsEncoding read FEncoding write FEncoding; property Encoding: TsEncoding read FEncoding write FEncoding;
@ -1023,6 +1034,8 @@ type
property OnChangeWorksheet: TsWorksheetEvent read FOnChangeWorksheet write FOnChangeWorksheet; property OnChangeWorksheet: TsWorksheetEvent read FOnChangeWorksheet write FOnChangeWorksheet;
{@@ This event fires when a worksheet is deleted } {@@ This event fires when a worksheet is deleted }
property OnRemoveWorksheet: TsRemoveWorksheetEvent read FOnRemoveWorksheet write FOnRemoveWorksheet; property OnRemoveWorksheet: TsRemoveWorksheetEvent read FOnRemoveWorksheet write FOnRemoveWorksheet;
{@@ This event fires when a worksheet is made "active"}
property OnSelectWorksheet: TsWorksheetEvent read FOnSelectWorksheet write FOnSelectWorksheet;
{@@ This event allows to provide external cell data for writing to file, {@@ This event allows to provide external cell data for writing to file,
standard cells are ignored. Intended for converting large database files standard cells are ignored. Intended for converting large database files
to a spreadsheet format. Requires Option boVirtualMode to be set. } to a spreadsheet format. Requires Option boVirtualMode to be set. }
@ -3532,6 +3545,70 @@ begin
end; end;
end; end;
{@@ ----------------------------------------------------------------------------
Clears the list of seleccted cell ranges
Only needed by the visual controls.
-------------------------------------------------------------------------------}
procedure TsWorksheet.ClearSelection;
begin
SetLength(FSelection, 0);
end;
{@@ ----------------------------------------------------------------------------
Returns the list of selected cell ranges
-------------------------------------------------------------------------------}
function TsWorksheet.GetSelection: TsCellRangeArray;
var
i: Integer;
begin
SetLength(Result, Length(FSelection));
for i:=0 to High(FSelection) do
Result[i] := FSelection[i];
end;
{@@ ----------------------------------------------------------------------------
Returns all selection ranges as an Excel string
-------------------------------------------------------------------------------}
function TsWorksheet.GetSelectionAsString: String;
const
RELATIVE = [rfRelRow, rfRelCol, rfRelRow2, rfRelCol2];
var
i: Integer;
L: TStringList;
begin
L := TStringList.Create;
try
for i:=0 to Length(FSelection)-1 do
with FSelection[i] do
L.Add(GetCellRangeString(Row1, Col1, Row2, Col2, RELATIVE, true));
L.Delimiter := DefaultFormatSettings.ListSeparator;
L.StrictDelimiter := true;
Result := L.DelimitedText;
finally
L.Free;
end;
end;
{@@ ----------------------------------------------------------------------------
Returns the number of selected cell ranges
-------------------------------------------------------------------------------}
function TsWorksheet.GetSelectionCount: Integer;
begin
Result := Length(FSelection);
end;
{@@ ----------------------------------------------------------------------------
Marks an array of cell ranges as "selected". Only needed for visual controls
-------------------------------------------------------------------------------}
procedure TsWorksheet.SetSelection(const ASelection: TsCellRangeArray);
var
i: Integer;
begin
SetLength(FSelection, Length(ASelection));
for i:=0 to High(FSelection) do
FSelection[i] := ASelection[i];
end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Helper method to update internal caching variables Helper method to update internal caching variables
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
@ -6574,6 +6651,19 @@ begin
end; end;
end; end;
{@@ ----------------------------------------------------------------------------
Makes the specified worksheet "active". Only needed for visual controls.
The active worksheet is displayed in a TsWorksheetGrid and in the selected
tab of a TsWorkbookTabControl.
-------------------------------------------------------------------------------}
procedure TsWorkbook.SelectWorksheet(AWorksheet: TsWorksheet);
begin
if (AWorksheet <> nil) and (FWorksheets.IndexOf(AWorksheet) = -1) then
raise Exception.Create('[TsWorkbook.SelectSheet] Worksheet does not belong to the workbook');
FActiveWorksheet := AWorksheet;
if Assigned(FOnSelectWorksheet) then FOnSelectWorksheet(self, AWorksheet);
end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Checks whether the passed string is a valid worksheet name according to Excel Checks whether the passed string is a valid worksheet name according to Excel
(ODS seems to be a bit less restrictive, but if we follow Excel's convention (ODS seems to be a bit less restrictive, but if we follow Excel's convention

View File

@ -38,6 +38,7 @@ type
procedure WorksheetAddedHandler(Sender: TObject; ASheet: TsWorksheet); procedure WorksheetAddedHandler(Sender: TObject; ASheet: TsWorksheet);
procedure WorksheetChangedHandler(Sender: TObject; ASheet: TsWorksheet); procedure WorksheetChangedHandler(Sender: TObject; ASheet: TsWorksheet);
procedure WorksheetRemovedHandler(Sender: TObject; ASheetIndex: Integer); procedure WorksheetRemovedHandler(Sender: TObject; ASheetIndex: Integer);
procedure WorksheetSelectedHandler(Sender: TObject; AWorksheet: TsWorksheet);
protected protected
procedure DoShowError(const AErrorMsg: String); procedure DoShowError(const AErrorMsg: String);
@ -67,7 +68,7 @@ type
public public
property Workbook: TsWorkbook read FWorkbook; property Workbook: TsWorkbook read FWorkbook;
property SelectedWorksheet: TsWorksheet read FWorksheet; property Worksheet: TsWorksheet read FWorksheet;
published published
property AutoDetectFormat: Boolean read FAutoDetectFormat write FAutoDetectFormat; property AutoDetectFormat: Boolean read FAutoDetectFormat write FAutoDetectFormat;
@ -165,10 +166,10 @@ type
protected protected
procedure DoUpdate; virtual; procedure DoUpdate; virtual;
procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure UpdateCellValue(ACell: PCell); virtual; procedure UpdateCellValue(ACell: PCell; AStrings: TStrings); virtual;
procedure UpdateCellProperties(ACell: PCell); virtual; procedure UpdateCellProperties(ACell: PCell; AStrings: TStrings); virtual;
procedure UpdateWorkbook(AWorkbook: TsWorkbook); virtual; procedure UpdateWorkbook(AWorkbook: TsWorkbook; AStrings: TStrings); virtual;
procedure UpdateWorksheet(ASheet: TsWorksheet); virtual; procedure UpdateWorksheet(ASheet: TsWorksheet; AStrings: TStrings); virtual;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
@ -292,7 +293,7 @@ begin
FWorksheet := FWorkbook.AddWorksheet('Sheet1'); FWorksheet := FWorkbook.AddWorksheet('Sheet1');
SelectWorksheet(FWorksheet); SelectWorksheet(FWorksheet);
// notify dependent controls // notify listeners
NotifyListeners([lniWorkbook, lniWorksheet, lniSelection]); NotifyListeners([lniWorkbook, lniWorksheet, lniSelection]);
end; end;
@ -318,6 +319,7 @@ begin
FWorkbook.OnAddWorksheet := @WorksheetAddedHandler; FWorkbook.OnAddWorksheet := @WorksheetAddedHandler;
FWorkbook.OnChangeWorksheet := @WorksheetChangedHandler; FWorkbook.OnChangeWorksheet := @WorksheetChangedHandler;
FWorkbook.OnRemoveWorksheet := @WorksheetRemovedHandler; FWorkbook.OnRemoveWorksheet := @WorksheetRemovedHandler;
FWorkbook.OnSelectWorksheet := @WorksheetSelectedHandler;
// Pass options to workbook // Pass options to workbook
SetOptions(FOptions); SetOptions(FOptions);
end; end;
@ -521,7 +523,7 @@ end;
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsWorkbookSource.SelectCell(ASheetRow, ASheetCol: Cardinal); procedure TsWorkbookSource.SelectCell(ASheetRow, ASheetCol: Cardinal);
begin begin
if SelectedWorksheet <> nil then if FWorksheet <> nil then
FWorksheet.SelectCell(ASheetRow, ASheetCol); FWorksheet.SelectCell(ASheetRow, ASheetCol);
NotifyListeners([lniSelection]); NotifyListeners([lniSelection]);
end; end;
@ -534,6 +536,10 @@ end;
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsWorkbookSource.SelectWorksheet(AWorkSheet: TsWorksheet); procedure TsWorkbookSource.SelectWorksheet(AWorkSheet: TsWorksheet);
begin begin
FWorksheet := AWorksheet;
if (FWorkbook <> nil) then
FWorkbook.SelectWorksheet(AWorksheet);
{
if AWorksheet = nil then if AWorksheet = nil then
exit; exit;
FWorksheet := AWorkSheet; FWorksheet := AWorkSheet;
@ -541,6 +547,7 @@ begin
FWorksheet.OnSelectCell := @CellSelectedHandler; FWorksheet.OnSelectCell := @CellSelectedHandler;
NotifyListeners([lniWorksheet]); NotifyListeners([lniWorksheet]);
SelectCell(FWorksheet.ActiveCellRow, FWorksheet.ActiveCellCol); SelectCell(FWorksheet.ActiveCellRow, FWorksheet.ActiveCellCol);
}
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
@ -633,6 +640,23 @@ begin
SelectWorksheet(sheet); SelectWorksheet(sheet);
end; end;
{@@ ----------------------------------------------------------------------------
Event handler called whenever a the workbook makes a worksheet "active".
-------------------------------------------------------------------------------}
procedure TsWorkbookSource.WorksheetSelectedHandler(Sender: TObject;
AWorksheet: TsWorksheet);
begin
FWorksheet := AWorksheet;
if FWorksheet <> nil then
begin
FWorksheet.OnChangeCell := @CellChangedHandler;
FWorksheet.OnSelectCell := @CellSelectedHandler;
NotifyListeners([lniWorksheet]);
SelectCell(FWorksheet.ActiveCellRow, FWorksheet.ActiveCellCol);
end else
NotifyListeners([lniWorksheet]);
end;
{------------------------------------------------------------------------------} {------------------------------------------------------------------------------}
{ TsWorkbookTabControl } { TsWorkbookTabControl }
@ -663,6 +687,16 @@ end;
Creates a (string) list containing the names of the workbook's sheet names Creates a (string) list containing the names of the workbook's sheet names
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsWorkbookTabControl.GetSheetList(AList: TStrings); procedure TsWorkbookTabControl.GetSheetList(AList: TStrings);
var
i: Integer;
begin
AList.Clear;
if Workbook <> nil then
for i:=0 to Workbook.GetWorksheetCount-1 do
AList.Add(Workbook.GetWorksheetByIndex(i).Name);
end;
{
procedure TsWorkbookTabControl.GetSheetList(AList: TStrings);
var var
i: Integer; i: Integer;
oldTabIndex: Integer; oldTabIndex: Integer;
@ -680,7 +714,7 @@ begin
TabIndex := oldTabIndex; TabIndex := oldTabIndex;
end; end;
end; end;
}
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Getter method for property "Workbook" Getter method for property "Workbook"
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
@ -698,7 +732,7 @@ end;
function TsWorkbookTabControl.GetWorksheet: TsWorksheet; function TsWorkbookTabControl.GetWorksheet: TsWorksheet;
begin begin
if FWorkbookSource <> nil then if FWorkbookSource <> nil then
Result := FWorkbookSource.SelectedWorksheet Result := FWorkbookSource.Worksheet
else else
Result := nil; Result := nil;
end; end;
@ -714,9 +748,39 @@ procedure TsWorkbookTabControl.ListenerNotification(
AChangedItems: TsNotificationItems; AData: Pointer = nil); AChangedItems: TsNotificationItems; AData: Pointer = nil);
var var
i: Integer; i: Integer;
oldTabIndex: Integer;
list: TStringList;
begin begin
Unused(AData); Unused(AData);
// Workbook changed
if (lniWorkbook in AChangedItems) then
begin
oldTabIndex := TabIndex;
list := TStringList.Create;
Tabs.BeginUpdate;
try
GetSheetList(list);
Tabs.Assign(list);
if (oldTabIndex = -1) and (Tabs.Count > 0) then
TabIndex := 0
else
if oldTabIndex < Tabs.Count then
TabIndex := oldTabIndex;
finally
list.Free;
Tabs.EndUpdate;
end;
end;
// Worksheet changed
if (lniWorksheet in AChangedItems) and (Worksheet <> nil) then
begin
i := Tabs.IndexOf(Worksheet.Name);
if i <> TabIndex then
TabIndex := i;
end;
{
// Workbook changed // Workbook changed
if (lniWorkbook in AChangedItems) then if (lniWorkbook in AChangedItems) then
GetSheetList(Tabs); GetSheetList(Tabs);
@ -728,6 +792,7 @@ begin
if i <> TabIndex then if i <> TabIndex then
TabIndex := i; TabIndex := i;
end; end;
}
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
@ -840,7 +905,7 @@ end;
function TsCellEdit.GetWorksheet: TsWorksheet; function TsCellEdit.GetWorksheet: TsWorksheet;
begin begin
if FWorkbookSource <> nil then if FWorkbookSource <> nil then
Result := FWorkbookSource.SelectedWorksheet Result := FWorkbookSource.Worksheet
else else
Result := nil; Result := nil;
end; end;
@ -963,7 +1028,7 @@ end;
function TsCellIndicator.GetWorksheet: TsWorksheet; function TsCellIndicator.GetWorksheet: TsWorksheet;
begin begin
if FWorkbookSource <> nil then if FWorkbookSource <> nil then
Result := FWorkbookSource.SelectedWorksheet Result := FWorkbookSource.Worksheet
else else
Result := nil; Result := nil;
end; end;
@ -1038,6 +1103,38 @@ end;
setting (workbook, worksheet, cell values, cell properties). setting (workbook, worksheet, cell values, cell properties).
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsSpreadsheetInspector.DoUpdate; procedure TsSpreadsheetInspector.DoUpdate;
var
cell: PCell;
sheet: TsWorksheet;
book: TsWorkbook;
list: TStringList;
begin
cell := nil;
sheet := nil;
book := nil;
if FWorkbookSource <> nil then
begin
book := FWorkbookSource.Workbook;
sheet := FWorkbookSource.Worksheet;
if sheet <> nil then
cell := sheet.FindCell(sheet.ActiveCellRow, sheet.ActiveCellCol);
end;
list := TStringList.Create;
try
case FMode of
imCellValue : UpdateCellValue(cell, list);
imCellProperties : UpdateCellProperties(cell, list);
imWorksheet : UpdateWorksheet(sheet, list);
imWorkbook : UpdateWorkbook(book, list);
end;
Strings.Assign(list);
finally
list.Free;
end;
end;
(*
procedure TsSpreadsheetInspector.DoUpdate;
var var
cell: PCell; cell: PCell;
sheet: TsWorksheet; sheet: TsWorksheet;
@ -1051,7 +1148,7 @@ begin
if FWorkbookSource <> nil then if FWorkbookSource <> nil then
begin begin
book := FWorkbookSource.Workbook; book := FWorkbookSource.Workbook;
sheet := FWorkbookSource.SelectedWorksheet; sheet := FWorkbookSource.Worksheet;
if sheet <> nil then if sheet <> nil then
cell := sheet.FindCell(sheet.ActiveCellRow, sheet.ActiveCellCol); cell := sheet.FindCell(sheet.ActiveCellRow, sheet.ActiveCellCol);
end; end;
@ -1063,6 +1160,7 @@ begin
imWorkbook : UpdateWorkbook(book); imWorkbook : UpdateWorkbook(book);
end; end;
end; end;
*)
function TsSpreadsheetInspector.GetWorkbook: TsWorkbook; function TsSpreadsheetInspector.GetWorkbook: TsWorkbook;
begin begin
@ -1075,7 +1173,7 @@ end;
function TsSpreadsheetInspector.GetWorksheet: TsWorksheet; function TsSpreadsheetInspector.GetWorksheet: TsWorksheet;
begin begin
if FWorkbookSource <> nil then if FWorkbookSource <> nil then
Result := FWorkbookSource.SelectedWorksheet Result := FWorkbookSource.Worksheet
else else
Result := nil; Result := nil;
end; end;
@ -1084,6 +1182,15 @@ procedure TsSpreadsheetInspector.ListenerNotification(
AChangedItems: TsNotificationItems; AData: Pointer = nil); AChangedItems: TsNotificationItems; AData: Pointer = nil);
begin begin
Unused(AData); Unused(AData);
case FMode of
imWorkbook:
if ([lniWorkbook, lniWorksheet]*AChangedItems <> []) then DoUpdate;
imWorksheet:
if ([lniWorksheet, lniSelection]*AChangedItems <> []) then DoUpdate;
imCellValue, imCellProperties:
if ([lniCell, lniSelection]*AChangedItems <> []) then DoUpdate;
end;
{
case FMode of case FMode of
imWorkbook: imWorkbook:
if lniWorkbook in AChangedItems then DoUpdate; if lniWorkbook in AChangedItems then DoUpdate;
@ -1093,6 +1200,7 @@ begin
imCellProperties: imCellProperties:
if ([lniCell, lniSelection]*AChangedItems <> []) then DoUpdate; if ([lniCell, lniSelection]*AChangedItems <> []) then DoUpdate;
end; end;
}
end; end;
procedure TsSpreadsheetInspector.Notification(AComponent: TComponent; procedure TsSpreadsheetInspector.Notification(AComponent: TComponent;
@ -1123,39 +1231,40 @@ begin
ListenerNotification([lniWorkbook, lniWorksheet, lniSelection]); ListenerNotification([lniWorkbook, lniWorksheet, lniSelection]);
end; end;
procedure TsSpreadsheetInspector.UpdateCellProperties(ACell: PCell); procedure TsSpreadsheetInspector.UpdateCellProperties(ACell: PCell;
AStrings: TStrings);
var var
s: String; s: String;
cb: TsCellBorder; cb: TsCellBorder;
r1, r2, c1, c2: Cardinal; r1, r2, c1, c2: Cardinal;
begin begin
if (ACell = nil) or not (uffFont in ACell^.UsedFormattingFields) if (ACell = nil) or not (uffFont in ACell^.UsedFormattingFields)
then Strings.Add('FontIndex=') then AStrings.Add('FontIndex=')
else Strings.Add(Format('FontIndex=%d (%s)', [ else AStrings.Add(Format('FontIndex=%d (%s)', [
ACell^.FontIndex, ACell^.FontIndex,
Workbook.GetFontAsString(ACell^.FontIndex) Workbook.GetFontAsString(ACell^.FontIndex)
])); ]));
if (ACell=nil) or not (uffTextRotation in ACell^.UsedFormattingFields) if (ACell=nil) or not (uffTextRotation in ACell^.UsedFormattingFields)
then Strings.Add('TextRotation=') then AStrings.Add('TextRotation=')
else Strings.Add(Format('TextRotation=%s', [ else AStrings.Add(Format('TextRotation=%s', [
GetEnumName(TypeInfo(TsTextRotation), ord(ACell^.TextRotation)) GetEnumName(TypeInfo(TsTextRotation), ord(ACell^.TextRotation))
])); ]));
if (ACell=nil) or not (uffHorAlign in ACell^.UsedFormattingFields) if (ACell=nil) or not (uffHorAlign in ACell^.UsedFormattingFields)
then Strings.Add('HorAlignment=') then AStrings.Add('HorAlignment=')
else Strings.Add(Format('HorAlignment=%s', [ else AStrings.Add(Format('HorAlignment=%s', [
GetEnumName(TypeInfo(TsHorAlignment), ord(ACell^.HorAlignment)) GetEnumName(TypeInfo(TsHorAlignment), ord(ACell^.HorAlignment))
])); ]));
if (ACell=nil) or not (uffVertAlign in ACell^.UsedFormattingFields) if (ACell=nil) or not (uffVertAlign in ACell^.UsedFormattingFields)
then Strings.Add('VertAlignment=') then AStrings.Add('VertAlignment=')
else Strings.Add(Format('VertAlignment=%s', [ else AStrings.Add(Format('VertAlignment=%s', [
GetEnumName(TypeInfo(TsVertAlignment), ord(ACell^.VertAlignment)) GetEnumName(TypeInfo(TsVertAlignment), ord(ACell^.VertAlignment))
])); ]));
if (ACell=nil) or not (uffBorder in ACell^.UsedFormattingFields) then if (ACell=nil) or not (uffBorder in ACell^.UsedFormattingFields) then
Strings.Add('Borders=') AStrings.Add('Borders=')
else else
begin begin
s := ''; s := '';
@ -1163,84 +1272,85 @@ begin
if cb in ACell^.Border then if cb in ACell^.Border then
s := s + ', ' + GetEnumName(TypeInfo(TsCellBorder), ord(cb)); s := s + ', ' + GetEnumName(TypeInfo(TsCellBorder), ord(cb));
if s <> '' then Delete(s, 1, 2); if s <> '' then Delete(s, 1, 2);
Strings.Add('Borders='+s); AStrings.Add('Borders='+s);
end; end;
for cb in TsCellBorder do for cb in TsCellBorder do
if ACell = nil then if ACell = nil then
Strings.Add(Format('BorderStyles[%s]=', [ AStrings.Add(Format('BorderStyles[%s]=', [
GetEnumName(TypeInfo(TsCellBorder), ord(cb))])) GetEnumName(TypeInfo(TsCellBorder), ord(cb))]))
else else
Strings.Add(Format('BorderStyles[%s]=%s, %s', [ AStrings.Add(Format('BorderStyles[%s]=%s, %s', [
GetEnumName(TypeInfo(TsCellBorder), ord(cb)), GetEnumName(TypeInfo(TsCellBorder), ord(cb)),
GetEnumName(TypeInfo(TsLineStyle), ord(ACell^.BorderStyles[cbEast].LineStyle)), GetEnumName(TypeInfo(TsLineStyle), ord(ACell^.BorderStyles[cbEast].LineStyle)),
Workbook.GetColorName(ACell^.BorderStyles[cbEast].Color)])); Workbook.GetColorName(ACell^.BorderStyles[cbEast].Color)]));
if (ACell = nil) or not (uffBackgroundColor in ACell^.UsedformattingFields) if (ACell = nil) or not (uffBackgroundColor in ACell^.UsedformattingFields)
then Strings.Add('BackgroundColor=') then AStrings.Add('BackgroundColor=')
else Strings.Add(Format('BackgroundColor=%d (%s)', [ else AStrings.Add(Format('BackgroundColor=%d (%s)', [
ACell^.BackgroundColor, ACell^.BackgroundColor,
Workbook.GetColorName(ACell^.BackgroundColor)])); Workbook.GetColorName(ACell^.BackgroundColor)]));
if (ACell = nil) or not (uffNumberFormat in ACell^.UsedFormattingFields) then if (ACell = nil) or not (uffNumberFormat in ACell^.UsedFormattingFields) then
begin begin
Strings.Add('NumberFormat='); AStrings.Add('NumberFormat=');
Strings.Add('NumberFormatStr='); AStrings.Add('NumberFormatStr=');
end else end else
begin begin
Strings.Add(Format('NumberFormat=%s', [ AStrings.Add(Format('NumberFormat=%s', [
GetEnumName(TypeInfo(TsNumberFormat), ord(ACell^.NumberFormat))])); GetEnumName(TypeInfo(TsNumberFormat), ord(ACell^.NumberFormat))]));
Strings.Add('NumberFormatStr=' + ACell^.NumberFormatStr); AStrings.Add('NumberFormatStr=' + ACell^.NumberFormatStr);
end; end;
if (Worksheet = nil) or not Worksheet.IsMerged(ACell) then if (Worksheet = nil) or not Worksheet.IsMerged(ACell) then
Strings.Add('Merged range=') AStrings.Add('Merged range=')
else else
begin begin
Worksheet.FindMergedRange(ACell, r1, c1, r2, c2); Worksheet.FindMergedRange(ACell, r1, c1, r2, c2);
Strings.Add('Merged range=' + GetCellRangeString(r1, c1, r2, c2)); AStrings.Add('Merged range=' + GetCellRangeString(r1, c1, r2, c2));
end; end;
end; end;
procedure TsSpreadsheetInspector.UpdateCellValue(ACell: PCell); procedure TsSpreadsheetInspector.UpdateCellValue(ACell: PCell; AStrings: TStrings);
begin begin
if ACell = nil then if ACell = nil then
begin begin
if Worksheet <> nil then if Worksheet <> nil then
begin begin
Strings.Add(Format('Row=%d', [Worksheet.ActiveCellRow])); AStrings.Add(Format('Row=%d', [Worksheet.ActiveCellRow]));
Strings.Add(Format('Col=%d', [Worksheet.ActiveCellCol])); AStrings.Add(Format('Col=%d', [Worksheet.ActiveCellCol]));
end else end else
begin begin
Strings.Add('Row='); AStrings.Add('Row=');
Strings.Add('Col='); AStrings.Add('Col=');
end; end;
Strings.Add('ContentType=(none)'); AStrings.Add('ContentType=(none)');
end else end else
begin begin
Strings.Add(Format('Row=%d', [ACell^.Row])); AStrings.Add(Format('Row=%d', [ACell^.Row]));
Strings.Add(Format('Col=%d', [ACell^.Col])); AStrings.Add(Format('Col=%d', [ACell^.Col]));
Strings.Add(Format('ContentType=%s', [ AStrings.Add(Format('ContentType=%s', [
GetEnumName(TypeInfo(TCellContentType), ord(ACell^.ContentType)) GetEnumName(TypeInfo(TCellContentType), ord(ACell^.ContentType))
])); ]));
Strings.Add(Format('NumberValue=%g', [ACell^.NumberValue])); AStrings.Add(Format('NumberValue=%g', [ACell^.NumberValue]));
Strings.Add(Format('DateTimeValue=%g', [ACell^.DateTimeValue])); AStrings.Add(Format('DateTimeValue=%g', [ACell^.DateTimeValue]));
Strings.Add(Format('UTF8StringValue=%s', [ACell^.UTF8StringValue])); AStrings.Add(Format('UTF8StringValue=%s', [ACell^.UTF8StringValue]));
Strings.Add(Format('BoolValue=%s', [BoolToStr(ACell^.BoolValue)])); AStrings.Add(Format('BoolValue=%s', [BoolToStr(ACell^.BoolValue)]));
Strings.Add(Format('ErrorValue=%s', [ AStrings.Add(Format('ErrorValue=%s', [
GetEnumName(TypeInfo(TsErrorValue), ord(ACell^.ErrorValue)) GetEnumName(TypeInfo(TsErrorValue), ord(ACell^.ErrorValue))
])); ]));
Strings.Add(Format('FormulaValue=%s', [Worksheet.ReadFormulaAsString(ACell, true)])); //^.FormulaValue])); AStrings.Add(Format('FormulaValue=%s', [Worksheet.ReadFormulaAsString(ACell, true)])); //^.FormulaValue]));
if ACell^.SharedFormulaBase = nil then if ACell^.SharedFormulaBase = nil then
Strings.Add('SharedFormulaBase=') AStrings.Add('SharedFormulaBase=')
else else
Strings.Add(Format('SharedFormulaBase=%s', [GetCellString( AStrings.Add(Format('SharedFormulaBase=%s', [GetCellString(
ACell^.SharedFormulaBase^.Row, ACell^.SharedFormulaBase^.Col) ACell^.SharedFormulaBase^.Row, ACell^.SharedFormulaBase^.Col)
])); ]));
end; end;
end; end;
procedure TsSpreadsheetInspector.UpdateWorkbook(AWorkbook: TsWorkbook); procedure TsSpreadsheetInspector.UpdateWorkbook(AWorkbook: TsWorkbook;
AStrings: TStrings);
var var
bo: TsWorkbookOption; bo: TsWorkbookOption;
s: String; s: String;
@ -1248,75 +1358,87 @@ var
begin begin
if AWorkbook = nil then if AWorkbook = nil then
begin begin
Strings.Add('FileName='); AStrings.Add('FileName=');
Strings.Add('FileFormat='); AStrings.Add('FileFormat=');
Strings.Add('Options='); AStrings.Add('Options=');
Strings.Add('FormatSettings='); AStrings.Add('ActiveWorksheet=');
AStrings.Add('FormatSettings=');
end else end else
begin begin
Strings.Add(Format('FileName=%s', [AWorkbook.FileName])); AStrings.Add(Format('FileName=%s', [AWorkbook.FileName]));
Strings.Add(Format('FileFormat=%s', [ AStrings.Add(Format('FileFormat=%s', [
GetEnumName(TypeInfo(TsSpreadsheetFormat), ord(AWorkbook.FileFormat)) GetEnumName(TypeInfo(TsSpreadsheetFormat), ord(AWorkbook.FileFormat))
])); ]));
if AWorkbook.ActiveWorksheet <> nil then
AStrings.Add('ActiveWorksheet=' + AWorkbook.ActiveWorksheet.Name)
else
AStrings.Add('ActiveWorksheet=');
s := ''; s := '';
for bo in TsWorkbookOption do for bo in TsWorkbookOption do
if bo in AWorkbook.Options then if bo in AWorkbook.Options then
s := s + ', ' + GetEnumName(TypeInfo(TsWorkbookOption), ord(bo)); s := s + ', ' + GetEnumName(TypeInfo(TsWorkbookOption), ord(bo));
if s <> '' then Delete(s, 1, 2); if s <> '' then Delete(s, 1, 2);
Strings.Add('Options='+s); AStrings.Add('Options='+s);
Strings.Add('FormatSettings='); AStrings.Add('FormatSettings=');
Strings.Add(' ThousandSeparator='+AWorkbook.FormatSettings.ThousandSeparator); AStrings.Add(' ThousandSeparator='+AWorkbook.FormatSettings.ThousandSeparator);
Strings.Add(' DecimalSeparator='+AWorkbook.FormatSettings.DecimalSeparator); AStrings.Add(' DecimalSeparator='+AWorkbook.FormatSettings.DecimalSeparator);
Strings.Add(' ListSeparator='+AWorkbook.FormatSettings.ListSeparator); AStrings.Add(' ListSeparator='+AWorkbook.FormatSettings.ListSeparator);
Strings.Add(' DateSeparator='+AWorkbook.FormatSettings.DateSeparator); AStrings.Add(' DateSeparator='+AWorkbook.FormatSettings.DateSeparator);
Strings.Add(' TimeSeparator='+AWorkbook.FormatSettings.TimeSeparator); AStrings.Add(' TimeSeparator='+AWorkbook.FormatSettings.TimeSeparator);
Strings.Add(' ShortDateFormat='+AWorkbook.FormatSettings.ShortDateFormat); AStrings.Add(' ShortDateFormat='+AWorkbook.FormatSettings.ShortDateFormat);
Strings.Add(' LongDateFormat='+AWorkbook.FormatSettings.LongDateFormat); AStrings.Add(' LongDateFormat='+AWorkbook.FormatSettings.LongDateFormat);
Strings.Add(' ShortTimeFormat='+AWorkbook.FormatSettings.ShortTimeFormat); AStrings.Add(' ShortTimeFormat='+AWorkbook.FormatSettings.ShortTimeFormat);
Strings.Add(' LongTimeFormat='+AWorkbook.FormatSettings.LongTimeFormat); AStrings.Add(' LongTimeFormat='+AWorkbook.FormatSettings.LongTimeFormat);
Strings.Add(' TimeAMString='+AWorkbook.FormatSettings.TimeAMString); AStrings.Add(' TimeAMString='+AWorkbook.FormatSettings.TimeAMString);
Strings.Add(' TimePMString='+AWorkbook.FormatSettings.TimePMString); AStrings.Add(' TimePMString='+AWorkbook.FormatSettings.TimePMString);
s := AWorkbook.FormatSettings.ShortMonthNames[1]; s := AWorkbook.FormatSettings.ShortMonthNames[1];
for i:=2 to 12 do for i:=2 to 12 do
s := s + ', ' + AWorkbook.FormatSettings.ShortMonthNames[i]; s := s + ', ' + AWorkbook.FormatSettings.ShortMonthNames[i];
Strings.Add(' ShortMonthNames='+s); AStrings.Add(' ShortMonthNames='+s);
s := AWorkbook.FormatSettings.LongMonthnames[1]; s := AWorkbook.FormatSettings.LongMonthnames[1];
for i:=2 to 12 do for i:=2 to 12 do
s := s +', ' + AWorkbook.FormatSettings.LongMonthNames[i]; s := s +', ' + AWorkbook.FormatSettings.LongMonthNames[i];
Strings.Add(' LongMontNames='+s); AStrings.Add(' LongMontNames='+s);
s := AWorkbook.FormatSettings.ShortDayNames[1]; s := AWorkbook.FormatSettings.ShortDayNames[1];
for i:=2 to 7 do for i:=2 to 7 do
s := s + ', ' + AWorkbook.FormatSettings.ShortDayNames[i]; s := s + ', ' + AWorkbook.FormatSettings.ShortDayNames[i];
Strings.Add(' ShortMonthNames='+s); AStrings.Add(' ShortMonthNames='+s);
s := AWorkbook.FormatSettings.LongDayNames[1]; s := AWorkbook.FormatSettings.LongDayNames[1];
for i:=2 to 7 do for i:=2 to 7 do
s := s +', ' + AWorkbook.FormatSettings.LongDayNames[i]; s := s +', ' + AWorkbook.FormatSettings.LongDayNames[i];
Strings.Add(' LongMontNames='+s); AStrings.Add(' LongMontNames='+s);
Strings.Add(' CurrencyString='+AWorkbook.FormatSettings.CurrencyString); AStrings.Add(' CurrencyString='+AWorkbook.FormatSettings.CurrencyString);
Strings.Add(' PosCurrencyFormat='+IntToStr(AWorkbook.FormatSettings.CurrencyFormat)); AStrings.Add(' PosCurrencyFormat='+IntToStr(AWorkbook.FormatSettings.CurrencyFormat));
Strings.Add(' NegCurrencyFormat='+IntToStr(AWorkbook.FormatSettings.NegCurrFormat)); AStrings.Add(' NegCurrencyFormat='+IntToStr(AWorkbook.FormatSettings.NegCurrFormat));
Strings.Add(' TwoDigitYearCenturyWindow='+IntToStr(AWorkbook.FormatSettings.TwoDigitYearCenturyWindow)); AStrings.Add(' TwoDigitYearCenturyWindow='+IntToStr(AWorkbook.FormatSettings.TwoDigitYearCenturyWindow));
end; end;
end; end;
procedure TsSpreadsheetInspector.UpdateWorksheet(ASheet: TsWorksheet); procedure TsSpreadsheetInspector.UpdateWorksheet(ASheet: TsWorksheet;
AStrings: TStrings);
begin begin
if ASheet = nil then if ASheet = nil then
begin begin
Strings.Add('First row='); AStrings.Add('Name=');
Strings.Add('Last row='); AStrings.Add('First row=');
Strings.Add('First column='); AStrings.Add('Last row=');
Strings.Add('Last column='); AStrings.Add('First column=');
AStrings.Add('Last column=');
AStrings.Add('Active cell=');
AStrings.Add('Selection=');
end else end else
begin begin
Strings.Add(Format('First row=%d', [Integer(ASheet.GetFirstRowIndex)])); AStrings.Add(Format('Name=%s', [ASheet.Name]));
Strings.Add(Format('Last row=%d', [ASheet.GetLastRowIndex])); AStrings.Add(Format('First row=%d', [Integer(ASheet.GetFirstRowIndex)]));
Strings.Add(Format('First column=%d', [Integer(ASheet.GetFirstColIndex)])); AStrings.Add(Format('Last row=%d', [ASheet.GetLastRowIndex]));
Strings.Add(Format('Last column=%d', [ASheet.GetLastColIndex])); AStrings.Add(Format('First column=%d', [Integer(ASheet.GetFirstColIndex)]));
AStrings.Add(Format('Last column=%d', [ASheet.GetLastColIndex]));
AStrings.Add(Format('Active cell=%s', [GetCellString(ASheet.ActiveCellRow, ASheet.ActiveCellCol)]));
AStrings.Add(Format('Selection=%s', [ASheet.GetSelectionAsString]));
end; end;
end; end;
end. end.

View File

@ -17,6 +17,8 @@ unit fpspreadsheetgrid;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
{.$DEFINE ENABLE_MULTI_SELECT} // requires Laz trunk younger than r...??? (containing grid multisel patch)
interface interface
uses uses
@ -325,6 +327,12 @@ type
by the rectangle is activated. } by the rectangle is activated. }
property Wordwraps[ARect: TGridRect]: Boolean property Wordwraps[ARect: TGridRect]: Boolean
read GetWordwraps write SetWordwraps; read GetWordwraps write SetWordwraps;
// inherited
{$IFDEF ENABLE_MULTI_SELECT}
{@@ Allow multiple selections}
property RangeSelectMode default rsmMulti;
{$ENDIF}
end; end;
{ TsWorksheetGrid } { TsWorksheetGrid }
@ -760,6 +768,9 @@ begin
FInitRowCount := 100; FInitRowCount := 100;
FCellFont := TFont.Create; FCellFont := TFont.Create;
FOwnsWorkbook := true; FOwnsWorkbook := true;
{$IFDEF ENABLE_MULTI_SELECT}
RangeSelectMode := rsmMulti;
{$ENDIF}
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
@ -3212,9 +3223,45 @@ end;
old thick selection border. old thick selection border.
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsCustomWorksheetGrid.MoveSelection; procedure TsCustomWorksheetGrid.MoveSelection;
var
sel: TsCellRangeArray;
{$IFDEF ENABLE_MULTI_SELECT}
i: Integer;
{$ENDIF}
begin begin
if (WorkbookSource <> nil) then if Worksheet <> nil then
WorkbookSource.SelectCell(GetWorksheetRow(Row), GetWorksheetCol(Col)); begin
{$IFDEF ENABLE_MULTI_SELECT}
if HasMultiSelection then
begin
SetLength(sel, SelectedRangeCount);
for i:=0 to High(sel) do
with SelectedRange[i] do
begin
sel[i].Row1 := GetWorksheetRow(Top);
sel[i].Col1 := GetWorksheetCol(Left);
sel[i].Row2 := GetWorksheetRow(Bottom);
sel[i].Col2 := GetWorksheetCol(Right);
end;
end else
begin
SetLength(sel, 1);
sel[0].Row1 := GetWorksheetRow(Selection.Top);
sel[0].Col1 := GetWorksheetCol(Selection.Left);
sel[0].Row2 := GetWorksheetRow(Selection.Bottom);
sel[0].Col2 := GetWorksheetRow(Selection.Right);
end;
{$ELSE}
SetLength(sel, 1);
sel[0].Row1 := GetWorksheetRow(Selection.Top);
sel[0].Col1 := GetWorksheetCol(Selection.Left);
sel[0].Row2 := GetWorksheetRow(Selection.Bottom);
sel[0].Col2 := GetWorksheetRow(Selection.Right);
{$ENDIF}
Worksheet.SetSelection(sel);
Worksheet.SelectCell(GetWorksheetRow(Row), GetWorksheetCol(Col));
end;
//Refresh; //Refresh;
inherited; inherited;
Refresh; Refresh;
@ -3743,7 +3790,7 @@ end;
function TsCustomWorksheetGrid.GetWorksheet: TsWorksheet; function TsCustomWorksheetGrid.GetWorksheet: TsWorksheet;
begin begin
if FWorkbookSource <> nil then if FWorkbookSource <> nil then
Result := FWorkbooksource.SelectedWorksheet Result := FWorkbooksource.Worksheet
else else
Result := FOwnedWorksheet; Result := FOwnedWorksheet;
end; end;

View File

@ -83,7 +83,8 @@ function ParseCellColString(const AStr: string;
function GetColString(AColIndex: Integer): String; function GetColString(AColIndex: Integer): String;
function GetCellString(ARow,ACol: Cardinal; AFlags: TsRelFlags = [rfRelRow, rfRelCol]): String; function GetCellString(ARow,ACol: Cardinal; AFlags: TsRelFlags = [rfRelRow, rfRelCol]): String;
function GetCellRangeString(ARow1, ACol1, ARow2, ACol2: Cardinal; function GetCellRangeString(ARow1, ACol1, ARow2, ACol2: Cardinal;
AFlags: TsRelFlags = [rfRelRow, rfRelCol, rfRelRow2, rfRelCol2]): String; AFlags: TsRelFlags = [rfRelRow, rfRelCol, rfRelRow2, rfRelCol2];
Compact: Boolean = false): String;
function GetErrorValueStr(AErrorValue: TsErrorValue): String; function GetErrorValueStr(AErrorValue: TsErrorValue): String;
@ -737,8 +738,12 @@ end;
--> $A1:$B3 --> $A1:$B3
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
function GetCellRangeString(ARow1, ACol1, ARow2, ACol2: Cardinal; function GetCellRangeString(ARow1, ACol1, ARow2, ACol2: Cardinal;
AFlags: TsRelFlags = [rfRelRow, rfRelCol, rfRelRow2, rfRelCol2]): String; AFlags: TsRelFlags = [rfRelRow, rfRelCol, rfRelRow2, rfRelCol2];
Compact: Boolean = false): String;
begin begin
if Compact and (ARow1 = ARow2) and (ACol1 = ACol2) then
Result := GetCellString(ARow1, ACol1, AFlags)
else
Result := Format('%s%s%s%d:%s%s%s%d', [ Result := Format('%s%s%s%d:%s%s%s%d', [
RELCHAR[rfRelCol in AFlags], GetColString(ACol1), RELCHAR[rfRelCol in AFlags], GetColString(ACol1),
RELCHAR[rfRelRow in AFlags], ARow1 + 1, RELCHAR[rfRelRow in AFlags], ARow1 + 1,