init `word_templat`

This commit is contained in:
csh 2023-05-16 16:49:34 +08:00
parent 823aa12a98
commit 4dc02530ba
30 changed files with 353 additions and 83 deletions

View File

@ -9933,7 +9933,7 @@ type TProtect=class(NodeInfo)
Function GetAttrs(); override;
Begin
HandleAttrs();
return array(("Sheet", "sheet", Sheet, ""),("EditObjects", "objects", EditObjects, ""),("EditScenarios", "scenarios", EditScenarios, ""),("FormatCells", "formatCells", FormatCells, ""),("FormatColumns", "formatColumns", FormatColumns, ""),("FormatRows", "formatRows", FormatRows, ""),("InsertColumns", "insertColumns", InsertColumns, ""),("InsertRows", "insertRows", InsertRows, ""),("InsertHyperlinks", "insertHyperlinks", InsertHyperlinks, ""),("DeleteColumns", "deleteColumns", DeleteColumns, ""),("DeleteRows", "deleteRows", DeleteRows, ""),("SelectLockedCells", "selectLockedCells", SelectLockedCells, ""),("Sort", "sort", Sort, ""),("AutoFilter", "autoFilter", AutoFilter, ""),("PivotTables", "pivotTables", PivotTables, ""),("SelectUnLockedCells", "selectUnlockedCells", SelectUnLockedCells, "")) union ExtAttr;
return array(("Password", "password", Password, ""),("AlgorithmName", "algorithmName", AlgorithmName, ""),("HashValue", "hashValue", HashValue, ""),("SaltValue", "saltValue", SaltValue, ""),("SpinCount", "spinCount", SpinCount, ""),("Sheet", "sheet", Sheet, ""),("EditObjects", "objects", EditObjects, ""),("EditScenarios", "scenarios", EditScenarios, ""),("FormatCells", "formatCells", FormatCells, ""),("FormatColumns", "formatColumns", FormatColumns, ""),("FormatRows", "formatRows", FormatRows, ""),("InsertColumns", "insertColumns", InsertColumns, ""),("InsertRows", "insertRows", InsertRows, ""),("InsertHyperlinks", "insertHyperlinks", InsertHyperlinks, ""),("DeleteColumns", "deleteColumns", DeleteColumns, ""),("DeleteRows", "deleteRows", DeleteRows, ""),("SelectLockedCells", "selectLockedCells", SelectLockedCells, ""),("Sort", "sort", Sort, ""),("AutoFilter", "autoFilter", AutoFilter, ""),("PivotTables", "pivotTables", PivotTables, ""),("SelectUnLockedCells", "selectUnlockedCells", SelectUnLockedCells, "")) union ExtAttr;
End;
Function GetChildren(); override;
@ -9943,6 +9943,11 @@ type TProtect=class(NodeInfo)
End;
//Attributes
Password;
AlgorithmName;
HashValue;
SaltValue;
SpinCount;
Sheet;
EditObjects;
EditScenarios;
@ -11323,20 +11328,22 @@ Type TPicture = Class(DocObject, TPictureImpl)
ETU := 360045;//1cm单位
maxX := 17.0;//水平方向17cm
maxY := 23.0;//垂直方向23cm
imageW := image.Width() / 28.346 * ETU;
imageH := image.Height() / 28.346 * ETU;
if Width <= 0 and Height <= 0 then Begin //图像缺省大小
widthVal := image.Width();
heightVal := image.Height();
widthVal := imageW;
heightVal := imageH;
End
else Begin //用户设置了图片尺寸
widthVal := ETU * Width;
heightVal := ETU * Height;
if Width <= 0 and image.Height() and image.Width() then Begin //按照图片比例自动缩放
scaling_factor := image.Width() / image.Height();
if Width <= 0 and imageH and imageW then Begin //按照图片比例自动缩放
scaling_factor := imageW / imageH;
widthVal := round(heightVal * scaling_factor);
End;
if Height <= 0 and image.Height() and image.Width() then Begin //按照图片比例自动缩放
scaling_factor := image.Width() / image.Height();
if Height <= 0 and imageH and imageW then Begin //按照图片比例自动缩放
scaling_factor := imageW / imageH;
heightVal := round(widthVal / scaling_factor);
End;
End;
@ -11361,7 +11368,7 @@ Type TPicture = Class(DocObject, TPictureImpl)
heightVal *= ratio;
widthVal *= ratio;
End;
//println('w={}-{},maxx={}, h={}-{},maxh={},ratio={}',integer(image.Width()),integer(widthVal),15 * ETU, integer(image.Height()),integer(heightVal),23 * ETU,ratio);
//println('w={}-{},maxx={}, h={}-{},maxh={},ratio={}',integer(imageW),integer(widthVal),15 * ETU, integer(imageH),integer(heightVal),23 * ETU,ratio);
return array(integer(widthVal), integer(heightVal));
End;
@ -12946,6 +12953,7 @@ Type TDocumentBody = Class(DocObject)
Function InsertTable(tbl, posOpt);
Begin
addPart(posOpt, tbl);
TOfficeApi().Set('CurrentTable', tbl.node_);
tblBorders := class(TSXml).GetNode(tbl.node_, 'w:tblPr/w:tblBorders');
tblCellMar := class(TSXml).GetNode(tbl.node_, 'w:tblPr/w:tblCellMar');
if ifObj(tblBorders) or ifObj(tblCellMar) then Begin
@ -13107,6 +13115,7 @@ Type TDocumentBody = Class(DocObject)
p := new TPicture(picture.node_);
_set_lastParagraph_(posOpt, picture.node_);
TOfficeApi().Set('CurrentShape', picture.node_);
return p;
End;
@ -13268,8 +13277,9 @@ Type TDocumentBody = Class(DocObject)
begParagraphIndex := -1;
begPos := 0;
begTxtLen := 0;
for i:=0 to length(tArr)-1 do Begin
while i < length(tArr) do Begin
txt := '';
iStep := 1;
if ifObj(tArr[i]['rNode']) then Begin
run := new TRun(tArr[i]['rNode']);
txt := run.Text();
@ -13342,7 +13352,8 @@ Type TDocumentBody = Class(DocObject)
flag := '[TSL]';
'[TSL][/TSL':
if c = ']' then Begin
curParagraphNode := tslArr[0]['pNode'];
tslBegParagraphNode := tslArr[0]['pNode'];
tslEndParagraphNode := tArr[i]['pNode'];
ind := length(tslArr) - 1;
if tslArr[ind]['pIndex'] <> tArr[i]['pIndex'] or tslArr[ind]['rIndex'] <> tArr[i]['rIndex'] then Begin
ind ++;
@ -13359,7 +13370,7 @@ Type TDocumentBody = Class(DocObject)
oldNode := prevRun;
tArr[i]['rNode'] := run._duplicate_r(oldNode);
run._adjust_r(tArr[i]['rNode'], wz, txtLen);
i--;
iStep := 0;
End;
curRunNode := tslArr[0]['rNode'];
curRun := new TRun(curRunNode);
@ -13382,84 +13393,68 @@ Type TDocumentBody = Class(DocObject)
code := leftstr(code, lengthW(code) - 5 - endPos);
CodePage := TOfficeApi().Get('CodePage');
TOfficeApi().Set('Docx', docx);
TOfficeApi().Set('CurrentParagraph', curParagraphNode);
TOfficeApi().Set('CurrentParagraph', tslBegParagraphNode);
TOfficeApi().Set('CurrentPosition', tslBegParagraphNode);
TOfficeApi().Set('CurrentRun', curRunNode);
TOfficeApi().Set('CodePage', 'gbk');
try
tslFuncCount ++;
println('run code=[{}]', code);
if code <> '' then
str := eval(&code);
eval(&code);
except
println('run code={},err={}', code, ExceptObject.ErrInfo);
errArr[ length(errArr) ] := array('code':code, 'err':ExceptObject.ErrInfo);
str := '';
End;
tNode := curRun.node_.FirstChildElement('w:t');
if not ifObj(tNode) then Begin //没有在外部插入文字
if not ifstring(str) or str = '' then Begin //删除w:r
curParagraphNode.DeleteChild(curRunNode);
hasrNode := curParagraphNode.FirstChildElement('w:r');
if not ifObj(hasrNode) then Begin//删除空段落
curParagraphNode.Parent().DeleteChild(curParagraphNode);
curParagraphNode := nil;
End;
End
else Begin
str := AnsiToUTF8(str);
lines := str2array(str, '\r\n');
lineCnt := length(lines);
if lineCnt = 1 then Begin //单行
curRun.SetText(str, true);
tslBegParagraphNode.DeleteChild(curRunNode);
//兼容WordTemplate函数不删除空段落TSL脚本段落
//hasrNode := tslBegParagraphNode.FirstChildElement('w:r');
//if not ifObj(hasrNode) then Begin//删除空段落
// tslBegParagraphNode.Parent().DeleteChild(tslBegParagraphNode);
// tslBegParagraphNode := nil;
//End;
End;
//段落炸裂
curPosotion := TOfficeApi().Get('CurrentPosition');
if i+iStep < length(tArr) and tArr[i+iStep]['pNode'] = tslEndParagraphNode and tslBegParagraphNode <> curPosotion then Begin
data := tslEndParagraphNode.Marshal();
NewParagraphNode := tslEndParagraphNode.Parent().InsertAfterChild(curPosotion, data[0]);//复制段落
rmvArr := array();
cnt := 0;
curLine := 0;
prevRNode := tArr[i+iStep]['rNode'].PrevElement('w:r');
while ifObj(prevRNode) do Begin
curLine ++;
prevRNode := prevRNode.PrevElement('w:r');
End;
rmvN := 0;
nextRNode := tArr[i+iStep]['rNode'];
while ifObj(nextRNode) do Begin
rmvArr[rmvN++] := nextRNode;
nextRNode := nextRNode.NextElement('w:r');
End;
rNode := NewParagraphNode.FirstChildElement('w:r');
nI := 0;
rIndex := 0;
while ifObj(rNode) do Begin
cnt ++;
if cnt <= curLine then Begin
rmvArr[rmvN++] := rNode;
End
else Begin //多行
curRun.SetText(lines[0], true);
nextRun := curRun.node_.NextElement('w:r');
if ifObj(nextRun) then Begin //段落炸裂
curLine := 0;
prevRNode := curRunNode;
while ifObj(prevRNode) do Begin
curLine ++;
prevRNode := prevRNode.PrevElement('w:r');
End;
data := curParagraphNode.Marshal();
LastParagraphNode := curParagraphNode.Parent().InsertAfterChild(curParagraphNode, data[0]);//复制段落
rmvArr := array();
cnt := 0;
rNode := LastParagraphNode.FirstChildElement('w:r');
while ifObj(rNode) do Begin
cnt ++;
if cnt < curLine then
rmvArr[rmvN++] := rNode;
else if cnt = curLine then Begin
rNode.ClearText();
rNode.SetText(lines[lineCnt-1], true);
lineCnt--;
End;
rNode := rNode.NextElement('w:r');
End;
cnt := 0;
rNode := curParagraphNode.FirstChildElement('w:r');
while ifObj(rNode) do Begin
cnt ++;
if cnt > curLine then
rmvArr[rmvN++] := rNode;
rNode := rNode.NextElement('w:r');
End;
//删除重复的run
for rmvN := 0 to rmvN < length(rmvArr)-1 do begin
rmvArr[rmvN].Parent().DeleteChild(rmvArr[rmvN]);
End;
End;//段落炸裂
curParagraph := new TParagraph(curParagraphNode);
prev := curParagraph;
for nP:=1 to lineCnt - 1 do Begin //新段落
if lines[nP]='' then continue;
p := new TParagraph();
p.Run.SetText(lines[nP], true);
prev := docx.AddParagraph(p, prev.Node());
docx.CopyFormat(curParagraph, prev);//格式刷
End;
else Begin
tArr[i+iStep+nI]['pNode'] := NewParagraphNode;
tArr[i+iStep+nI]['rNode'] := rNode;
tArr[i+iStep+nI]['rIndex'] := rIndex++;
nr := new TRun(tArr[i+iStep+nI]['rNode']);
nI ++;
End;
rNode := rNode.NextElement('w:r');
End;
//删除重复的run
for rmvN := 0 to length(rmvArr)-1 do begin
rmvArr[rmvN].Parent().DeleteChild(rmvArr[rmvN]);
End;
End;
TOfficeApi().Set('CodePage', CodePage);
@ -13467,7 +13462,7 @@ Type TDocumentBody = Class(DocObject)
flag := '';
code := nil;
tslArr := array();
continue;
break;
End
else
flag := '[TSL]';
@ -13492,6 +13487,7 @@ Type TDocumentBody = Class(DocObject)
if tslArr[ind]['pIndex'] <> tArr[i]['pIndex'] or tslArr[ind]['rIndex'] <> tArr[i]['rIndex'] then
tslArr[ind + 1] := tArr[i];
End;
i += iStep;
End;
return array(length(errArr), tslFuncCount, errArr);
End;
@ -13625,6 +13621,7 @@ Type TDocumentBody = Class(DocObject)
else Begin
raise 'Invalid input param.';
End;
TOfficeApi().Set('CurrentPosition', o.node_);
End;
Function findNode(posOpt, b);
@ -14131,25 +14128,28 @@ Type TTable = Class(DocObject, TTableImpl)
///设置表格数据
///data: table数据表
///[IncludeHeader: bool] 是否包括表头默认FALSE
///[IncludeIndex: bool] 是否自动添加索引号默认FALSE
Function SetData(docx, data, IncludeHeader, IncludeIndex);
///[includeHeader: bool] 是否包括表头默认FALSE
///[includeIndex: bool] 是否自动添加索引号默认FALSE
Function SetData(docx, data, includeHeader, includeIndex);
Begin
if not IsTable(data) then
raise "Invalid Data.";
[rowcount,colcount] := mSize(data);//一维数组
if colcount = 0 then
data := array(data);
fields := FieldNames(data);
if IsTable(fields) then Begin
r := nils(length(data),length(fields));
r[:,:] := data;
data := r;
End;
if IncludeIndex then Begin
if includeIndex then Begin
n := length(data)-1;
r := array(0->n);
data := `r | data;
End;
if IncludeHeader and IsTable(fields) then Begin
if IncludeIndex then
if includeHeader and IsTable(fields) then Begin
if includeIndex then
fields := array("Index") union fields;
data := array(fields) union data;
End;

View File

@ -271,6 +271,7 @@ Type TSDocxFile = Class
p := AddParagraph(p, getPosNode(posOpt), nil);
chart.pNode := p.node_;
p.Node().InsertEndChild(o.GetInnerXml());
TOfficeApi().Set('CurrentShape', p.node_);
return chart;
End;

View File

@ -73,6 +73,11 @@ Type TOffice = Class
hash_['Paragraph-Node-' + name] := hash_['CurrentParagraph'];
End;
Function GetCurrentPosition()
Begin
return hash_['CurrentPosition'];
End;
///获取当前TSL代码段所在段落
///返回TParagraph对象
Function GetCurrentParagraph();

View File

@ -0,0 +1,3 @@
Function _ExcelChartCopyPic(excelFileName, excelSheetName, picType);
Begin
End;

View File

@ -0,0 +1,3 @@
Function _WordAddOleObjectFromFile(fileName, width, height);
Begin
End;

View File

@ -0,0 +1,5 @@
Function _WordBr();
Begin
TOfficeApi().GetDocument().AddLineBreak(TOfficeApi().Get('CurrentPosition'));
End;

View File

@ -0,0 +1,34 @@
Function _WordCopyFromExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol);
Begin
excel := new TSExcelFile();
[err, msg] := excel.OpenFile('', excelFileName);
if err then return false;
total_row := excel.TotalRows(excelSheetName);
total_col := excel.TotalCols(excelSheetName);
if not total_row or not total_col then return false;
if ifnil(startRow) then
startRow := 1;
if ifnil(startCol) then
startCol := 1;
if ifnil(endRow) then
endRow := total_row;
if ifnil(endCol) then
endCol := total_col;
data := excel.GetTable(excelSheetName,
CoordinatesToCellName(startCol, startRow),
CoordinatesToCellName(endCol, endRow),
false,
false,
false);
if length(data) = 0 then return false;
//println('data={}',data);
docx := TOfficeApi().GetDocument();
tbl := docx.CreateTable(data, false, false);
tbl.Format.Borders.Top.Val := 'dashed';
tbl.Format.Borders.Left.Val := 'dashed';
tbl.Format.Borders.Bottom.Val := 'dashed';
tbl.Format.Borders.Right.Val := 'dashed';
tbl.Format.Borders.InsideH.Val := 'dashed';
tbl.Format.Borders.InsideV.Val := 'dashed';
tbl := docx.InsertTable(tbl, TOfficeApi().GetCurrentPosition());
End;

View File

@ -0,0 +1,3 @@
Function _WordCopyPicFormatExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol, picType);
Begin
End;

View File

@ -0,0 +1,4 @@
Function _WordGetCurrentDocument();
Begin
return TOfficeApi().GetDocument();
End;

View File

@ -0,0 +1,4 @@
Function _WordGetCurrentRange();
Begin
return TOfficeApi().GetCurrentPosition();
End;

View File

@ -0,0 +1,10 @@
Function _WordGetFont(prop, value);
Begin
crun := TOfficeApi().GetCurrentRun();
node := crun.Node().FirstChildElement('w:rPr');
rPr := TOfficeObj('TwrPr');
rPr.InitRootNode(node);
value := rPr.Value(prop);
if not ifnil(value) then return true;
return false;
End;

View File

@ -0,0 +1,4 @@
Function _WordGetLastRange();
Begin
return TOfficeApi().GetCurrentPosition();
End;

View File

@ -0,0 +1,16 @@
Function _WordGetLastShape();
Begin
node := TOfficeApi().Get('CurrentShape');
if not ifObj(node) then return nil;
uri := 'w:r/w:drawing/wp:inline/a:graphic/a:graphicData/c:chart';
cNode := class(TSXml).GetNode(node, uri);
if ifObj(cNode) then Begin
chart := TOfficeObj('TChart');
chart.Init(TOfficeApi().GetDocument(), node, cNode);
return chart;
End;
pic := TOfficeObj('TPicture');
pic.Init(node);
return pic;
End;

View File

@ -0,0 +1,4 @@
Function _WordGetLastTable();
Begin
return TOfficeApi().Get('LastTable');
End;

View File

@ -0,0 +1,12 @@
Function _WordGetLastTableCellProp(row, col, name, value);
Begin
table := TOfficeApi().Get('LastTable');
if ifnil(table) then return false;
table_cell := table.Cell(row, col);
ctr := _wordCompTable();
name_ := ctr[lowercase(name)];
if ifnil(name_) then name_ := name;
str := 'return table_cell.Format.' $ name_ $ '"' $ value $ '"';
value := eval(&str);
return true;
End;

View File

@ -0,0 +1,11 @@
Function _WordGetLastTableProp(name, value);
Begin
table := TOfficeApi().Get('LastTable');
if ifnil(table) then return false;
ctr := _wordCompTable();
name_ := ctr[lowercase(name)];
if ifnil(name_) then name_ := name;
str := 'return table.Format.' $ name_ $ '"' $ value $ '"';
value := eval(&str);
return true;
End;

View File

@ -0,0 +1,3 @@
Function _WordGetRangeProp(name, value);
Begin
End;

View File

@ -0,0 +1,11 @@
Function _WordLastTableMerge(row1, col1, row2, col2);
Begin
table := TOfficeApi().Get('LastTable');
if ifnil(table) then return false;
[err1, beg_cell] := CoordinatesToCellName(col1, row1);
[err2, end_cell] := CoordinatesToCellName(col2, row2);
if err1 or err2 then return false;
table.Merge(beg_cell, end_cell, false);
TOfficeApi().Set('LastTable', table);
return true;
End;

View File

@ -0,0 +1,3 @@
Function _WordLastTableSplit(row, col, rCnt, cCnt);
Begin
End;

View File

@ -0,0 +1,4 @@
Function _WordSetCurrnetRange(range);
Begin
TOfficeApi().Set('CurrentPosition', range);
End;

View File

@ -0,0 +1,8 @@
Function _WordSetFont(prop, value);
Begin
run := TOfficeApi().GetCurrentRun();
str := 'run.font.' $ prop $ ' := ' $ '"' $ value $ '"';
eval(&str);
run.Apply();
return true;
End;

View File

@ -0,0 +1,17 @@
Function _WordSetLastTableCellProp(row, col, name, value);
Begin
table := TOfficeApi().Get('LastTable');
if ifnil(table) then return false;
table_cell := table.Cell(row, col);
ctr := _wordCompTable();
name_ := ctr[lowercase(name)];
if ifnil(name_) then name_ := name;
str := 'table_cell.Format.' $ name_ $ ' := ';
if ifstring(value) then
str += '"' $ value $ '"';
else
str = str $ value;
eval(&str);
TOfficeApi().Set('LastTable', table);
return true;
End;

View File

@ -0,0 +1,18 @@
Function _WordSetLastTableProp(name, value);
Begin
table := TOfficeApi().Get('LastTable');
if ifnil(table) then return false;
ctr := _wordCompTable();
name_ := ctr[lowercase(name)];
if ifnil(name_) then name_ := name;
str := 'table.Format.' $ name_ $ ' := ';
if ifstring(value) then
str += '"' $ value $ '"';
else
str = str $ value;
println("str = {}", str);
eval(&str);
TOfficeApi().Set('LastTable', table);
return true;
End;

View File

@ -0,0 +1,5 @@
Function _WordSetRangeProp(name, value);
Begin
cur := TOfficeApi().GetCurrentPosition();
if ifnil(cur) then return nil;
End;

View File

@ -0,0 +1,10 @@
Function _WordTemplate(alias, fileName);
Begin
docx := new TSDocxFile();
[err, msg] := docx.OpenFile(alias, fileName);
if err then return false;
docx.ExecInnerTSL();
[err, msg] := docx.Save();
if err then return false;
return true;
End;

View File

@ -0,0 +1,17 @@
Function _WordWrite();
Begin
docx := TOfficeApi().GetDocument();
curParagraph := TOfficeApi().GetCurrentParagraph();
curRun := TOfficeApi().GetCurrentRun();
for i:=1 to PARAMCOUNT do Begin
argv := params[i];
if ifstring( argv ) then
curRun.AddText( argv );
else if ifnumber(argv) then
curRun.AddText('' $ argv);
else if ifarray(argv) then Begin
tbl := docx.CreateTable(argv, false, false);
tbl := docx.InsertTable(tbl, TOfficeApi().GetCurrentPosition());
End
End
End;

View File

@ -0,0 +1,11 @@
Function _WordWritePicFromFile(fileName);
Begin
file_size := fileSize('', fileName);
flag := readfile(rwbinary(), '', fileName, 0, file_size, data);
if not flag then return false;
picture := TOfficeObj('TPicture');
picture.Image := data;
docx := TOfficeApi().GetDocument();
docx.AddPicture(picture, TOfficeApi().GetCurrentPosition());
return true;
End;

View File

@ -0,0 +1,8 @@
Function _WordWriteTable(table, writeIntIndex, writeIntTitle, incIntIndex);
Begin
docx := TOfficeApi().GetDocument();
tbl := docx.CreateTable(table, true, writeIntIndex);
table := docx.InsertTable(tbl, TOfficeApi().GetCurrentPosition());
TOfficeApi().Set('LastTable', table);
return true;
End;

View File

@ -0,0 +1,10 @@
Function _wordCompTable();
Begin
return array(
'alignment': 'Alignment',
'shadingcolor': 'Shading.Color',
'style': 'StyleID',
'verticalalignment': 'Valign',
'width': 'Width',
);
End;

View File

@ -0,0 +1,26 @@
_WordTemplate(alias, fileName);
_WordCopyFromExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol);
_WordCopyPicFromExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol, picType);
_ExcelChartCopyPic(excelFileName, excelSheetName, picType);
_WordGetCurrentDocument();
_WordGetCurrentRange();
_WordSetCurrnetRange(range);
_WordGetLastRange();
_WordGetLastTable();
_WordGetLastShape();
_WordWrite();
_WordBr();
_WordWriteTable(table, writeIntIndex, writeIntTile, incIntIndex);
_WordWritePicFromFile(fileName);
_WordSetFont(prop, value);
_WordGetFont(prop, value);
_WordAddOleObjectFromFile(fileName, width, height);
_WordLastTableSplit(row, col, rCnt, cCnt);
_WordLastTableMerge(row1, col1, row2, col2);
_WordSetRangeProp(name, value);
_WordGetRangeProp(name, value);
_WordSetLastTableProp(name, value);
_WordGetLastTableProp(name, value);
_WordSetLastTableCellProp(row, col, name, value);
_WordGetLastTableCellProp(row, col, name, value);