❗重大更新:设计方式由namspace转变成unit
This commit is contained in:
@@ -4,8 +4,8 @@ public
|
||||
function Init();virtual;
|
||||
function InitZip(zip: ZipFile);
|
||||
function Open(alias: string; file: string; password: string): tableArray;
|
||||
function Save(): tableArray;
|
||||
function SaveAs(alias: string; file: string): tableArray;
|
||||
function Save(): array of info; // array(err, errmsg)
|
||||
function SaveAs(alias: string; file: string): array of info;
|
||||
function Zip(): ZipFile;
|
||||
|
||||
protected
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
type Collection = class
|
||||
public
|
||||
function Create();
|
||||
function Operator[](index: stringORinteger): tslobj;
|
||||
function SetIgnoreCase(value: boolean);
|
||||
function SetActivation(value: tslobj);
|
||||
function GetActivation(): tslobj;
|
||||
function CalNewName(prefix: string): string;
|
||||
function AddCollection(obj: tslobj; name: string);
|
||||
function RemoveCollection(index: stringORinteger);
|
||||
function GetCount(): integer;
|
||||
|
||||
private
|
||||
function CompareFunction(index: stringORinteger; data: tslobj): boolean;
|
||||
|
||||
private
|
||||
ignorecase_: boolean; // 忽略大小写
|
||||
container_: anycontainer; // 容器对象
|
||||
[weakref]activation_: tslobj; // 激活的对象
|
||||
[weakref]fp_; // 函数指针 -- 用来比较
|
||||
end;
|
||||
|
||||
type LinkList = class
|
||||
public
|
||||
function Create();
|
||||
function Add(data: tslobj);
|
||||
function Remove(index: stringORinteger; fp: functionPointer);
|
||||
function Size();
|
||||
function Get(index: stringORinteger; fp: functionPointer);
|
||||
|
||||
private
|
||||
function Find(index: stringORinteger; fp: functionPointer);
|
||||
|
||||
private
|
||||
count_: integer;
|
||||
head_: Node;
|
||||
tail_: Node;
|
||||
|
||||
end;
|
||||
|
||||
// ============== 实现 ================= //
|
||||
function Collection.Create();
|
||||
begin
|
||||
container_ := new LinkList();
|
||||
ignorecase_ := false;
|
||||
fp_ := thisFunction(CompareFunction);
|
||||
end;
|
||||
|
||||
function Operator Collection.[](index: stringORinteger): tslobj;
|
||||
begin
|
||||
ret := container_.Get(index, fp_);
|
||||
return ret ? ret.obj : nil;
|
||||
end;
|
||||
|
||||
function Collection.SetIgnoreCase(value: boolean);
|
||||
begin
|
||||
ignorecase_ := value;
|
||||
end;
|
||||
|
||||
function Collection.SetActivation(value: tslobj);
|
||||
begin
|
||||
activation_ := self[value];
|
||||
end;
|
||||
|
||||
function Collection.GetActivation(): tslobj;
|
||||
begin
|
||||
return activation_;
|
||||
end;
|
||||
|
||||
function Collection.CalNewName(prefix: string): string;
|
||||
begin
|
||||
len := {self.}GetCount() + 1;
|
||||
name := prefix $ len;
|
||||
while container_.Get(name, fp_) do
|
||||
name := prefix $ ++len;
|
||||
return name;
|
||||
end;
|
||||
|
||||
function Collection.AddCollection(obj: tslobj; name: string);
|
||||
begin
|
||||
data := new Data();
|
||||
data.obj := obj;
|
||||
data.name := name;
|
||||
data.index := {self.}GetCount() + 1;
|
||||
container_.Add(data);
|
||||
end;
|
||||
|
||||
function Collection.RemoveCollection(index: stringORinteger);
|
||||
begin
|
||||
container_.Remove(index, fp_);
|
||||
end;
|
||||
|
||||
function Collection.GetCount(): integer;
|
||||
begin
|
||||
return container_.Size();
|
||||
end;
|
||||
|
||||
function Collection.CompareFunction(index: stringORinteger; data: tslobj): boolean;
|
||||
begin
|
||||
return (ifNumber(index) and data.index = index) or
|
||||
(ifString(index) and (data.name = index or (ignorecase_ and lowercase(data.name) = lowercase(index))));
|
||||
end;
|
||||
|
||||
// 集合中需要记录的数据
|
||||
type Data = class
|
||||
obj: tslobj;
|
||||
name: string;
|
||||
index: integer;
|
||||
end;
|
||||
|
||||
function LinkList.Create();
|
||||
begin
|
||||
head_ := new Node(nil);
|
||||
tail_ := head_;
|
||||
count_ := 0;
|
||||
end;
|
||||
|
||||
function LinkList.Add(data: tslobj);
|
||||
begin
|
||||
node := new Node(data);
|
||||
tail_.next := node;
|
||||
node.prev := tail_;
|
||||
tail_ := node;
|
||||
count_ ++;
|
||||
end;
|
||||
|
||||
function LinkList.Remove(index: stringORinteger; fp: functionPointer);
|
||||
begin
|
||||
node := Find(index, fp);
|
||||
if ifnil(node) then return;
|
||||
if node = tail_ then
|
||||
begin
|
||||
tail_ := node.prev;
|
||||
node.prev.next := nil;
|
||||
end
|
||||
else begin
|
||||
node.prev.next := node.next;
|
||||
node.next.prev := node.prev;
|
||||
node := nil;
|
||||
end
|
||||
count_--;
|
||||
end;
|
||||
|
||||
function LinkList.Size();
|
||||
begin
|
||||
return count_;
|
||||
end;
|
||||
|
||||
function LinkList.Find(index: stringORinteger; fp: functionPointer);
|
||||
begin
|
||||
node := head_.next;
|
||||
while (node) do
|
||||
begin
|
||||
if (fp and fp.do(index, node.data)) or node.data = index then
|
||||
return node;
|
||||
node := node.next;
|
||||
end
|
||||
return nil;
|
||||
end;
|
||||
|
||||
function LinkList.Get(index: stringORinteger; fp: functionPointer);
|
||||
begin
|
||||
node := Find(index, fp);
|
||||
return ifnil(node) ? nil : node.data;
|
||||
end;
|
||||
|
||||
|
||||
type Node = class
|
||||
public
|
||||
function Create(value: tslobj);
|
||||
begin
|
||||
data := value;
|
||||
prev := nil;
|
||||
next := nil;
|
||||
end;
|
||||
|
||||
data: tslobj;
|
||||
[weakref]prev: Node;
|
||||
next: Node;
|
||||
|
||||
end;
|
||||
@@ -0,0 +1,41 @@
|
||||
type VBABase = class
|
||||
public
|
||||
function Create(Par: tslobj; App: Application; Cre: integer);
|
||||
|
||||
public
|
||||
property Application read ReadApplication;
|
||||
property Parent read ReadParent;
|
||||
property Creator read ReadCreator;
|
||||
function ReadApplication();
|
||||
function ReadParent();
|
||||
function ReadCreator();
|
||||
private
|
||||
[weakref]parent_: tslobj;
|
||||
[weakref]application_: Application;
|
||||
creator_: integer;
|
||||
|
||||
End;
|
||||
|
||||
// ============== 实现 ================= //
|
||||
function VBABase.Create(Par: tslobj; App: Application; Cre: integer);
|
||||
begin
|
||||
parent_ := Par;
|
||||
application_ := App;
|
||||
creator_ := Cre;
|
||||
end;
|
||||
|
||||
// properties
|
||||
function VBABase.ReadApplication();
|
||||
begin
|
||||
return application_;
|
||||
end;
|
||||
|
||||
function VBABase.ReadParent();
|
||||
begin
|
||||
return parent_;
|
||||
end;
|
||||
|
||||
function VBABase.ReadCreator();
|
||||
begin
|
||||
return creator_;
|
||||
end;
|
||||
@@ -0,0 +1,64 @@
|
||||
type XlsxSheetData = class
|
||||
public
|
||||
function Create(sheet_data: SheetData);
|
||||
function Operator[](index: integer): XlsxSheetDataRow;
|
||||
function Cell(r: integer; c: integer): C;
|
||||
function Rows(index: integer): XlsxSheetDataRow;
|
||||
function Serialize();
|
||||
|
||||
private
|
||||
rows_: array of XlsxSheetDataRow;
|
||||
sheet_data_: SheetData;
|
||||
end;
|
||||
|
||||
function XlsxSheetData.Create(sheet_data: SheetData);
|
||||
begin
|
||||
rows_ := array();
|
||||
sheet_data_ := sheet_data;
|
||||
rows := sheet_data.Rows();
|
||||
for i:=0 to length(rows)-1 do
|
||||
begin
|
||||
r := strToInt(rows[i].R);
|
||||
rows_[r] := new XlsxSheetDataRow(rows[i]);
|
||||
end
|
||||
// println("rows = {}", rows_);
|
||||
end;
|
||||
|
||||
function Operator XlsxSheetData.[](index: integer): XlsxSheetDataRow;
|
||||
begin
|
||||
if ifnil(rows_[index]) and tslassigning then
|
||||
begin
|
||||
row := new Row(sheet_data_, "", "row");
|
||||
rows_[index] := new XlsxSheetDataRow(row);
|
||||
pos := -1;
|
||||
for k,_ in rows_ do // TODO:此处弊端是要遍历所有k,可考虑维护一个新array,用二分
|
||||
if pos < k and k < index then pos := k;
|
||||
pos = -1 ? sheet_data_.AppendChild(row) : sheet_data_.InsertAfter(row, rows_[pos].Data());
|
||||
end
|
||||
return rows_[index];
|
||||
end;
|
||||
|
||||
function XlsxSheetData.Rows(index: integer): XlsxSheetDataRow;
|
||||
begin
|
||||
return self[index];
|
||||
end;
|
||||
|
||||
function XlsxSheetData.Cell(r: integer; c: integer): C;
|
||||
begin
|
||||
bk := tslassigning;
|
||||
tslassigning := 1;
|
||||
c := self[r][c];
|
||||
tslassigning := bk;
|
||||
return c;
|
||||
end;
|
||||
|
||||
function XlsxSheetData.Serialize();
|
||||
begin
|
||||
for k,row in rows_ do
|
||||
begin
|
||||
r := row.Data();
|
||||
r.R := k;
|
||||
row.Serialize();
|
||||
end
|
||||
// sheet_data_.Serialize();
|
||||
end;
|
||||
@@ -0,0 +1,63 @@
|
||||
type XlsxSheetDataRow = class
|
||||
public
|
||||
function Create(row: Row);
|
||||
function Operator[](index: integer): XlsxSheetDataCol;
|
||||
function Cols(index: integer): XlsxSheetDataCol;
|
||||
function Data(): Row;
|
||||
function Serialize();
|
||||
|
||||
public
|
||||
row_: Row;
|
||||
cols_: array of XlsxSheetDataCol;
|
||||
end;
|
||||
|
||||
|
||||
function XlsxSheetDataRow.Create(row: Row);
|
||||
begin
|
||||
row_ := row;
|
||||
cols_ := array();
|
||||
cs := row.Cs();
|
||||
for i:=0 to length(cs)-1 do
|
||||
begin
|
||||
r := cs[i].R;
|
||||
cell_name := SplitCellName(r);
|
||||
index := ColumnNameToNumber(cell_name[1])[1];
|
||||
cols_[index] := cs[i];
|
||||
end
|
||||
// println("cols_ = {}", cols_);
|
||||
end;
|
||||
|
||||
function Operator XlsxSheetDataRow.[](index: integer): XlsxSheetDataCol;
|
||||
begin
|
||||
if ifnil(cols_[index]) and tslassigning then
|
||||
begin
|
||||
col := new C(row_, "", "c");
|
||||
cols_[index] := col;
|
||||
pos := -1;
|
||||
for k,_ in cols_ do
|
||||
if pos < k and k < index then pos := k;
|
||||
pos = -1 ? row_.AppendChild(col) : row_.InsertAfter(col, cols_[pos]);
|
||||
end
|
||||
return cols_[index];
|
||||
end;
|
||||
|
||||
function XlsxSheetDataRow.Cols(index: integer): XlsxSheetDataCol;
|
||||
begin
|
||||
return self[index];
|
||||
end;
|
||||
|
||||
function XlsxSheetDataRow.Data(): Row;
|
||||
begin
|
||||
return row_;
|
||||
end;
|
||||
|
||||
function XlsxSheetDataRow.Serialize();
|
||||
begin
|
||||
for k,c in cols_ do
|
||||
begin
|
||||
c.R := CoordinatesToCellName(k, row_.R)[1];
|
||||
c.Serialize();
|
||||
// println("c.R = {}, row.R = {}", c.R, row_.R);
|
||||
end
|
||||
row_.Serialize();
|
||||
end;
|
||||
Reference in New Issue
Block a user