📄 uxlsreferences.pas
字号:
function TReferences.GetSheetName(const SheetRef: word; const Globals: TObject): widestring;
var
idx: integer;
Sh1: string;
Ld: integer;
begin
if (SheetRef>=FExternRefs.Count) then raise
Exception.CreateFmt(ErrIndexOutBounds, [SheetRef,'Sheet Reference',0,FExternRefs.Count]);
idx:=FExternRefs[SheetRef].SupBookRecord;
Sh1:=FSupBooks[idx].SheetName(FExternRefs[SheetRef].FirstSheet, Globals);
if FExternRefs[SheetRef].FirstSheet<>FExternRefs[SheetRef].LastSheet then
Sh1:=Sh1+fmRangeSep+FSupBooks[idx].SheetName(FExternRefs[SheetRef].LastSheet, Globals);
if idx = LocalSupBook then Result:='' else
begin
Result:= FSupBooks[idx].BookName;
if Sh1<>'' then
begin
Ld:= LastDelimiter('\:',Result);
if Ld>0 then Insert(fmWorkbookOpen, Result, Ld+1) else Result:=fmWorkbookOpen+Result;
Result:=Result+fmWorkbookClose;
end;
end;
Result:=Result+Sh1;
if Result<>'' then Result:=''''+Result+''''+fmExternalRef;
end;
procedure TReferences.InsertSheets(const BeforeSheet, SheetCount: integer);
begin
FExternRefs.InsertSheets(BeforeSheet, SheetCount, LocalSupBook);
if LocalSupBook>=0 then FSupBooks[LocalSupBook].InsertSheets(SheetCount);
end;
procedure TReferences.SaveToStream(const DataStream: TStream);
begin
FSupBooks.SaveToStream(DataStream, false);
FExternRefs.SaveToStream(DataStream);
end;
function TReferences.SetSheet(const Sheet: word): integer;
var
i:integer;
begin
for i:=0 to FExternRefs.Count-1 do
if (FExternRefs[i].SupBookRecord = LocalSupBook) and
(FExternRefs[i].FirstSheet = FExternRefs[i].LastSheet) and
(FExternRefs[i].FirstSheet = Sheet) then
begin
Result:=i;
exit;
end;
//Ref doesnt exits...
FExternRefs.Add(TExternRef.Create(LocalSupBook, Sheet, Sheet));
Result:=FExternRefs.Count-1;
end;
function TReferences.TotalSize: int64;
begin
Result:= FSupBooks.TotalSize+ FExternRefs.TotalSize;
end;
{ TExternRef }
constructor TExternRef.Create(const aSupBookRecord, aFirstSheet, aLastSheet: word);
begin
inherited Create;
SupBookRecord:=aSupBookRecord;
FirstSheet:=aFirstSheet;
LastSheet:=aLastSheet;
end;
procedure TExternRef.SaveToStream(const DataStream: TStream);
begin
DataStream.Write(SupBookRecord, SizeOf(SupBookRecord));
DataStream.Write(FirstSheet, SizeOf(FirstSheet));
DataStream.Write(LastSheet, SizeOf(LastSheet));
end;
{ TSupBookRecord }
function DecodeFileName(const s: widestring): widestring;
var
i: integer;
begin
Result:=''; i:=1;
while i <= Length(s) do
begin
if s[i]=#1 then
begin
inc(i);
if s[i]='@' then
begin
Result := Result + '\\';
end else
begin
Result := Result + s[i] +':\';
end
end else
if s[i]=#2 then
begin
Result := Result + '\';
end else
if s[i]=#3 then
begin
Result := Result + '\';
end else
if s[i]=#4 then
begin
Result := Result + '..\';
end
else
Result := Result + s[i];
inc(i);
end;
end;
procedure TSupBookRecord.AddExternName(const ExternNameRecord: TExternNameRecord);
begin
FExternNameList.Add(ExternNameRecord);
end;
function TSupBookRecord.BookName: widestring;
var
Xs: TExcelString;
MySelf: TBaseRecord;
MyPos: integer;
begin
if IsLocal or IsAddIn then begin; Result:= ''; exit; end;
MySelf:=Self;
MyPos:=2;
Xs:=TExcelString.Create(2, MySelf, MyPos);
try
Result:=Xs.Value;
if Length(Result)>0 then
begin
if Result[1]=#0 then Result:='' else
if Result[1]=#1 then Result:=DecodeFileName(copy(Result,2,Length(Result))) else
if Result[1]=#2 then Result:='';
end;
finally
FreeAndNil(Xs);
end; //finally
end;
constructor TSupBookRecord.Create(const aId: word; const aData: PArrayOfByte; const aDataSize: integer);
begin
inherited;
FExternNameList:=TExternNameRecordList.Create;
end;
constructor TSupBookRecord.CreateEmpty(const SheetCount: integer);
var
MyData: PArrayOfByte;
begin
GetMem(MyData, 4);
MyData[0]:=lo(SheetCount);
MyData[1]:=hi(SheetCount);
MyData[2]:=$01;
MyData[3]:=$04;
Create(xlr_SUPBOOK, myData, 4);
end;
destructor TSupBookRecord.Destroy;
begin
FreeAndNil(FExternNameList);
inherited;
end;
function TSupBookRecord.DoCopyTo: TBaseRecord;
begin
Result:=inherited DoCopyTo;
FreeAndNil((Result as TSupBookRecord).FExternNameList);
(Result as TSupBookRecord).FExternNameList:= TExternNameRecordList.Create;
(Result as TSupBookRecord).FExternNameList.CopyFrom(FExternNameList);
end;
procedure TSupBookRecord.InsertSheets(const SheetCount: integer);
begin
if not IsLocal then raise Exception.Create(ErrExcelInvalid);
IncWord(Data, 0, SheetCount, MaxSheets);
end;
function TSupBookRecord.IsLocal: boolean;
begin
IsLocal:= (DataSize = 4)and (GetWord (Data, 2)= $0401);
end;
function TSupBookRecord.IsAddIn: boolean;
begin
Result:= (DataSize = 4)and (GetWord (Data, 2)= $3A01);
end;
procedure TSupBookRecord.SaveToStream(const Workbook: TStream; const NeedsRecalc: boolean);
begin
inherited;
FExternNameList.SaveToStream(Workbook, NeedsRecalc);
end;
function TSupBookRecord.SheetName(const SheetIndex: integer; const Globals: TObject): widestring;
var
n: integer;
i, tpos: integer;
Xs: TExcelString;
MySelf: TBaseRecord;
begin
n:=GetWord(Data, 0);
if (SheetIndex<0) or (SheetIndex>=n) then //this might happen... on range references to another workbook
begin
Result:='';
exit;
end;
if GetWord(Data,2)= $0401 then //current sheet
begin
Result:=(Globals as TWorkbookGlobals).SheetName[SheetIndex];
exit;
end;
//A little slow... but it shouldn't be called much.
//I don't think it justifies a cache.
MySelf:=Self;
tPos:=2;
for i:=0 to SheetIndex do //0 stands for the first unicode string, the book name.
begin
Xs:=TExcelString.Create(2, MySelf, tPos);
try
finally
FreeAndNil(Xs);
end; //finally
end;
Xs:=TExcelString.Create(2, MySelf, tPos);
try
Result:=Xs.Value;
finally
FreeAndNil(Xs);
end; //finally
end;
function TSupBookRecord.TotalSize: integer;
begin
Result:=inherited TotalSize+ FExternNameList.TotalSize;
end;
function TSupBookRecord.TotalSizeNoHeaders: integer;
var
i:integer;
begin
Result:=inherited TotalSizeNoHeaders;
for i:=0 to FExternNameList.Count-1 do Result:=Result+ (FExternNameList[i] as TBaseRecord).TotalSizeNoHeaders;
end;
{ TSupBookRecordList }
function TSupBookRecordList.TotalSize: int64;
var
i: integer;
begin
Result:=0;
for i:=0 to Count-1 do Result:=Result+Items[i].TotalSize;
end;
{ TExternNameRecord }
function TExternNameRecord.Name: Widestring;
var
s: string;
begin
if (Data[7] and 1)=1 then
begin
SetLength(Result, NameLength);
Move(Data[8], Result[1], NameLength*2);
end else
begin
SetLength(s, NameLength);
Move(Data[8], s[1], NameLength);
Result:=s;
end;
end;
function TExternNameRecord.NameLength: byte;
begin
Result:= Data[6];
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -