fpspreadsheet: Add, with r/w support, conditional date formats cfcLastYear, cfcThisYear, cfcNextYear.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7588 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
aebb067738
commit
9d7457ccd4
@ -27,6 +27,7 @@ type
|
||||
cfcYesterday, cfcToday, cfcTomorrow, cfcLast7Days,
|
||||
cfcLastWeek, cfcThisWeek, cfcNextWeek,
|
||||
cfcLastMonth, cfcThisMonth, cfcNextMonth,
|
||||
cfcLastYear, cfcThisYear, cfcNextYear,
|
||||
cfcExpression
|
||||
);
|
||||
|
||||
|
@ -409,6 +409,7 @@ const
|
||||
'', '', '', '', // cfcYesterday .. cfcLast7Days
|
||||
'', '', '', // cfcLastWeek .. cfcNextWeek
|
||||
'', '', '', // cfcLastMonth .. cfcNextMonth
|
||||
'', '', '', // cfcLastYear .. cfcNextYear
|
||||
'is-true-formula(%s)' // cfcExpression
|
||||
);
|
||||
|
||||
@ -428,8 +429,9 @@ const
|
||||
'yesterday', 'today', 'tomorrow', 'last-7-days', // cfcYesterday .. cfcLast7Days
|
||||
'last-week', 'this-week', 'next-week', // cfcLastWeek .. cfcNextWeek
|
||||
'last-month', 'this-month', 'next-month', // cfcLastMonth .. cfcNextMonth
|
||||
'last-year', 'this-year', 'next-year', // cfcLastYear .. cfcNextYear
|
||||
'formula-is(%s)' // cfcExprssion
|
||||
); // ???????????????????
|
||||
);
|
||||
|
||||
CF_VALUE_KIND: array[TsCFValueKind] of string = (
|
||||
'', // vkNone
|
||||
@ -4185,7 +4187,7 @@ begin
|
||||
exit;
|
||||
|
||||
// condition for comparison
|
||||
for c in [cfcYesterday..cfcNextMonth] do
|
||||
for c in [cfcYesterday..cfcNextYear] do
|
||||
if CF_CALCEXT_OP[c] = s then
|
||||
begin
|
||||
condition := c;
|
||||
@ -6561,7 +6563,7 @@ begin
|
||||
value1Str := CFOperandToStr(cf_cellRule.Operand1, sheet);
|
||||
value2Str := CFOperandToStr(cf_cellRule.Operand2, sheet);
|
||||
opStr := Format(CF_CALCEXT_OP[cf_cellRule.Condition], [value1Str, value2str]);
|
||||
isDateFmt := cf_cellRule.Condition in [cfcYesterday..cfcNextMonth];
|
||||
isDateFmt := cf_cellRule.Condition in [cfcYesterday..cfcNextYear];
|
||||
if opStr <> '' then
|
||||
begin
|
||||
if isDateFmt then
|
||||
|
@ -253,7 +253,10 @@ const
|
||||
'@AND(MONTH(RC)=MONTH(EDATE(TODAY(),0-1)),YEAR(RC)=YEAR(EDATE(TODAY(),0-1)))', // cfcLastMonth
|
||||
'@AND(MONTH(RC)=MONTH(TODAY()),YEAR(RC)=YEAR(TODAY()))', // cfcThisMonth
|
||||
'@AND(MONTH(RC)=MONTH(EDATE(TODAY(),0+1)),YEAR(RC)=YEAR(EDATE(TODAY(),0+1)))', // cfcNextMonth
|
||||
'@' // cfcExpression
|
||||
'@YEAR(RC)=YEAR(TODAY())-1', // cfcLastYear
|
||||
'@YEAR(RC)=YEAR(TODAY())', // cfcThisYear
|
||||
'@YEAR(RC)=YEAR(TODAY())+1', // cfcNextYear
|
||||
'@' // cfcExpression
|
||||
);
|
||||
// The leading '@' indicates that the formula will be used in <Value1> node
|
||||
// Parameter 0 is Operand1, parameter 1 is Operand2 and parameter 2 is Range
|
||||
@ -429,7 +432,7 @@ begin
|
||||
end else
|
||||
begin
|
||||
expr := '@' + UTF8TextToXMLText(AExpr);
|
||||
for c in [cfcContainsErrors..cfcNextMonth] do
|
||||
for c in [cfcContainsErrors..cfcNextYear] do
|
||||
if CF_CONDITIONS[c] = expr then
|
||||
begin
|
||||
ACondition := c;
|
||||
|
@ -442,6 +442,7 @@ const
|
||||
'timePeriod', // cfcLast7Days
|
||||
'timePeriod', 'timePeriod', 'timePeriod',// cfcLastWeek, cfcThisWeek, cfcNextWeek
|
||||
'timePeriod', 'timePeriod', 'timePeriod',// cfcLastMonth, cfcThisMonth, cfcNextMonth
|
||||
'expression', 'expression', 'expression',// cfcLastYear, cfcThisYear, cfcNextYear // implemented as expression
|
||||
'expression' // cfcExpression
|
||||
);
|
||||
|
||||
@ -456,9 +457,16 @@ const
|
||||
'yesterday', 'today', 'tomorrow', 'last7Days', // cfcYesterday, cfcToday, cfcTomorrow, cfcLast7Days
|
||||
'lastWeek', 'thisWeek', 'nextWeek', // cfcLastWeek, cfcThisWeek, cfcNextWeek
|
||||
'lastMonth', 'thisMonth', 'nextMonth', // cfcLastMonth, cfcThisMonth, cfcNextMonth
|
||||
'', '', '', // cfcLastYear, cfcThisYear, cfcNextYear
|
||||
'' // cfcExpression
|
||||
);
|
||||
|
||||
CF_YEAR_FORMULAS: array[cfcLastYear..cfcNextYear] of string = (
|
||||
'YEAR(%0:s)=YEAR(TODAY())-1', // cfcLastYear
|
||||
'YEAR(%0:s)=YEAR(TODAY())', // cfcThisYear
|
||||
'YEAR(%0:s)=YEAR(TODAY())+1' // cfcNextYear
|
||||
);
|
||||
|
||||
CF_ICON_SET: array[TsCFIconSet] of string = (
|
||||
'3Arrows', '3ArrowsGray','3Flags', // is3Arrows, is3ArrowsGray, is3Flags
|
||||
'3TrafficLights2', // REPLACEMENT FOR is3TrafficLights1 which requires x14
|
||||
@ -1549,6 +1557,7 @@ begin
|
||||
|
||||
sheet := TsWorksheet(AWorksheet);
|
||||
s := GetAttrValue(ANode, 'timePeriod');
|
||||
|
||||
for cond in [cfcYesterday..cfcNextMonth] do
|
||||
if CF_OPERATOR_NAMES[cond] = s then
|
||||
begin
|
||||
@ -1562,9 +1571,12 @@ procedure TsSpreadOOXMLReader.ReadCFExpression(ANode: TDOMNode;
|
||||
var
|
||||
sheet: TsWorksheet;
|
||||
nodeName: String;
|
||||
s: String;
|
||||
s, s1: String;
|
||||
c: TsCFCondition;
|
||||
firstCellInRange: String;
|
||||
begin
|
||||
sheet := TsWorksheet(AWorksheet);
|
||||
firstCellInRange := GetCellString(ARange.Row1, ARange.Col1);
|
||||
|
||||
ANode := ANode.FirstChild;
|
||||
while ANode <> nil do
|
||||
@ -1573,6 +1585,16 @@ begin
|
||||
if nodeName = 'formula' then
|
||||
begin
|
||||
s := GetNodeValue(ANode);
|
||||
|
||||
for c in [cfcLastYear..cfcNextYear] do
|
||||
begin
|
||||
s1 := Format(CF_YEAR_FORMULAS[c], [firstCellInRange]);
|
||||
if s1 = s then begin
|
||||
sheet.WriteConditionalCellFormat(ARange, c, AFormatIndex);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
sheet.WriteConditionalCellFormat(ARange, cfcExpression, s, AFormatIndex);
|
||||
exit;
|
||||
end;
|
||||
@ -4096,19 +4118,19 @@ procedure TsSpreadOOXMLWriter.WriteCFCellRule(AStream: TStream;
|
||||
ARule: TsCFCellRule; ARange: TsCellRange; APriority: Integer);
|
||||
const
|
||||
FORMULA: array[cfcBeginsWith..cfcNextMonth] of String = (
|
||||
'LEFT(%0:s,LEN("%1:s"))="%1:s"', // cfcBeginsWith
|
||||
'RIGHT(%0:s,Len("%1:s"))="%1:s"', // cfcEndsWidth
|
||||
'NOT(ISERROR(SEARCH("%1:s",%0:s)))', // cfcContainsText
|
||||
'LEFT(%0:s,LEN("%1:s"))="%1:s"', // cfcBeginsWith
|
||||
'RIGHT(%0:s,Len("%1:s"))="%1:s"', // cfcEndsWidth
|
||||
'NOT(ISERROR(SEARCH("%1:s",%0:s)))', // cfcContainsText
|
||||
'ISERROR(SEARCH("%1:s",%0:s))', // cfcNotContainsText
|
||||
'ISERROR(%0:s)', // cfcContainsErrors
|
||||
'NOT(ISERROR(%0:s))', // cfcNotContainsErrors
|
||||
'FLOOR(%s,1)=TODAY()-1', // cfcYesterday
|
||||
'FLOOR(%s,1)=TODAY()', // cfcToday
|
||||
'FLOOR(%s,1)=TODAY()+1', // cfcTomorrow
|
||||
'AND(TODAY()-FLOOR(%0:s,1)<=6,FLOOR(%0:s,1)<=TODAY())', // cfcLasst7Days
|
||||
'AND(TODAY()-FLOOR(%0:s,1)<=6,FLOOR(%0:s,1)<=TODAY())', // cfcLast7Days
|
||||
'AND(TODAY()-ROUNDDOWN(%0:s,0)>=(WEEKDAY(TODAY())),TODAY()-ROUNDDOWN(%0:s,0)<(WEEKDAY(TODAY())+7))', // cfcLastWeek
|
||||
'AND(TODAY()-ROUNDDOWN(%0:s,0)<=WEEKDAY(TODAY())-1,ROUNDDOWN(%0:s,0)-TODAY()<=7-WEEKDAY(TODAY()))', // cfcThisWeek
|
||||
'AND(ROUNDDOWN(%0:s,0)-TODAY()>(7-WEEKDAY(TODAY())),ROUNDDOWN(C15,0)-TODAY()<(15-WEEKDAY(TODAY())))', // cfcNextWeek
|
||||
'AND(TODAY()-ROUNDDOWN(%0:s,0)<=WEEKDAY(TODAY())-1,ROUNDDOWN(%0:s,0)-TODAY()<=7-WEEKDAY(TODAY()))', // cfcThisWeek
|
||||
'AND(ROUNDDOWN(%0:s,0)-TODAY()>(7-WEEKDAY(TODAY())),ROUNDDOWN(C15,0)-TODAY()<(15-WEEKDAY(TODAY())))', // cfcNextWeek
|
||||
'AND(MONTH(%0:s)=MONTH(EDATE(TODAY(),0-1)),YEAR(%0:s)=YEAR(EDATE(TODAY(),0-1)))', // cfcLastMonth
|
||||
'AND(MONTH(%0:s)=MONTH(TODAY()),YEAR(%0:s)=YEAR(TODAY()))', // cfcThisMonth
|
||||
'AND(MONTH(%0:s)=MONTH(EDATE(TODAY(),0+1)),YEAR(%0:s)=YEAR(EDATE(TODAY(),0+1)))' // cfcNextMonth
|
||||
@ -4169,19 +4191,28 @@ begin
|
||||
end;
|
||||
cfcDuplicate, cfcUnique:
|
||||
;
|
||||
cfcBeginsWith..cfcNextMonth:
|
||||
cfcBeginsWith..cfcNotContainsErrors:
|
||||
begin
|
||||
firstCellOfRange := GetCellString(ARange.Row1, ARange.Col1);
|
||||
formula1Str :=
|
||||
'<formula>' +
|
||||
Format(FORMULA[ARule.Condition], [firstcellOfRange, ARule.Operand1]) +
|
||||
'</formula>';
|
||||
if ARule.Condition >= cfcYesterday then
|
||||
begin
|
||||
param1Str := ' timePeriod="' + CF_OPERATOR_NAMES[ARule.Condition] + '"';
|
||||
opStr := '';
|
||||
end else
|
||||
param1Str := ' text="' + VarToStr(ARule.Operand1) + '"';
|
||||
param1Str := ' text="' + VarToStr(ARule.Operand1) + '"';
|
||||
end;
|
||||
cfcYesterday..cfcNextMonth:
|
||||
begin
|
||||
firstCellOfrange := GetCellString(ARange.Row1, ARange.Col1);
|
||||
s := Format(FORMULA[ARule.Condition], [firstcellOfRange]);
|
||||
formula1Str := '<formula>' + s + '</formula>';
|
||||
param1Str := Format(' timePeriod="%s"', [CF_OPERATOR_NAMES[ARule.Condition]]);
|
||||
opStr := '';
|
||||
end;
|
||||
cfcLastYear..cfcNextYear:
|
||||
begin
|
||||
firstCellOfRange := GetCellString(ARange.Row1, ARange.Col1);
|
||||
s := Format(CF_YEAR_FORMULAS[ARule.Condition], [firstCellOfRange]);
|
||||
formula1Str := '<formula>' + s + '</formula>';
|
||||
end;
|
||||
cfcExpression:
|
||||
begin
|
||||
|
@ -84,6 +84,9 @@ type
|
||||
procedure TestWriteRead_CF_CellFmt_XLSX_LastMonth;
|
||||
procedure TestWriteRead_CF_CellFmt_XLSX_ThisMonth;
|
||||
procedure TestWriteRead_CF_CellFmt_XLSX_NextMonth;
|
||||
procedure TestWriteRead_CF_CellFmt_XLSX_LastYear;
|
||||
procedure TestWriteRead_CF_CellFmt_XLSX_ThisYear;
|
||||
procedure TestWriteRead_CF_CellFmt_XLSX_NextYear;
|
||||
procedure TestWriteRead_CF_CellFmt_XLSX_Expression;
|
||||
procedure TestWriteRead_CF_CellFmt_XLSX_Background;
|
||||
procedure TestWriteRead_CF_CellFmt_XLSX_Border4;
|
||||
@ -134,6 +137,9 @@ type
|
||||
procedure TestWriteRead_CF_CellFmt_XML_LastMonth;
|
||||
procedure TestWriteRead_CF_CellFmt_XML_ThisMonth;
|
||||
procedure TestWriteRead_CF_CellFmt_XML_NextMonth;
|
||||
procedure TestWriteRead_CF_CellFmt_XML_LastYear;
|
||||
procedure TestWriteRead_CF_CellFmt_XML_ThisYear;
|
||||
procedure TestWriteRead_CF_CellFmt_XML_NextYear;
|
||||
procedure TestWriteRead_CF_CellFmt_XML_Expression;
|
||||
|
||||
procedure TestWriteRead_CF_CellFmt_XML_Background;
|
||||
@ -178,6 +184,9 @@ type
|
||||
procedure TestWriteRead_CF_CellFmt_ODS_LastMonth;
|
||||
procedure TestWriteRead_CF_CellFmt_ODS_ThisMonth;
|
||||
procedure TestWriteRead_CF_CellFmt_ODS_NextMonth;
|
||||
procedure TestWriteRead_CF_CellFmt_ODS_LastYear;
|
||||
procedure TestWriteRead_CF_CellFmt_ODS_ThisYear;
|
||||
procedure TestWriteRead_CF_CellFmt_ODS_NextYear;
|
||||
procedure TestWriteRead_CF_CellFmt_ODS_Expression;
|
||||
procedure TestWriteRead_CF_CellFmt_ODS_Background;
|
||||
procedure TestWriteRead_CF_CellFmt_ODS_Border4;
|
||||
@ -810,6 +819,33 @@ begin
|
||||
TestWriteRead_CF_CellFmt(sfOOXML, cfcNextMonth, fmt);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_CellFmt_XLSX_LastYear;
|
||||
var
|
||||
fmt: TsCellFormat;
|
||||
begin
|
||||
InitFormatRecord(fmt);
|
||||
fmt.SetBackgroundColor(scRed);
|
||||
TestWriteRead_CF_CellFmt(sfOOXML, cfcLastYear, fmt);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_CellFmt_XLSX_ThisYear;
|
||||
var
|
||||
fmt: TsCellFormat;
|
||||
begin
|
||||
InitFormatRecord(fmt);
|
||||
fmt.SetBackgroundColor(scRed);
|
||||
TestWriteRead_CF_CellFmt(sfOOXML, cfcThisYear, fmt);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_CellFmt_XLSX_NextYear;
|
||||
var
|
||||
fmt: TsCellFormat;
|
||||
begin
|
||||
InitFormatRecord(fmt);
|
||||
fmt.SetBackgroundColor(scRed);
|
||||
TestWriteRead_CF_CellFmt(sfOOXML, cfcNextYear, fmt);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_CellFmt_XLSX_Expression;
|
||||
var
|
||||
fmt: TsCellFormat;
|
||||
@ -1119,6 +1155,32 @@ begin
|
||||
TestWriteRead_CF_CellFmt(sfExcelXML, cfcNextMonth, fmt);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_CellFmt_XML_LastYear;
|
||||
var
|
||||
fmt: TsCellFormat;
|
||||
begin
|
||||
InitFormatRecord(fmt);
|
||||
fmt.SetBackgroundColor(scRed);
|
||||
TestWriteRead_CF_CellFmt(sfExcelXML, cfcLastYear, fmt);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_CellFmt_XML_ThisYear;
|
||||
var
|
||||
fmt: TsCellFormat;
|
||||
begin
|
||||
InitFormatRecord(fmt);
|
||||
fmt.SetBackgroundColor(scRed);
|
||||
TestWriteRead_CF_CellFmt(sfExcelXML, cfcThisYear, fmt);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_CellFmt_XML_NextYear;
|
||||
var
|
||||
fmt: TsCellFormat;
|
||||
begin
|
||||
InitFormatRecord(fmt);
|
||||
fmt.SetBackgroundColor(scRed);
|
||||
TestWriteRead_CF_CellFmt(sfExcelXML, cfcNextYear, fmt);
|
||||
end;
|
||||
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_CellFmt_XML_Expression;
|
||||
var
|
||||
fmt: TsCellFormat;
|
||||
@ -1493,6 +1555,33 @@ begin
|
||||
TestWriteRead_CF_CellFmt(sfOpenDocument, cfcNextMonth, fmt);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_CellFmt_ODS_LastYear;
|
||||
var
|
||||
fmt: TsCellFormat;
|
||||
begin
|
||||
InitFormatRecord(fmt);
|
||||
fmt.SetBackgroundColor(scRed);
|
||||
TestWriteRead_CF_CellFmt(sfOpenDocument, cfcLastYear, fmt);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_CellFmt_ODS_ThisYear;
|
||||
var
|
||||
fmt: TsCellFormat;
|
||||
begin
|
||||
InitFormatRecord(fmt);
|
||||
fmt.SetBackgroundColor(scRed);
|
||||
TestWriteRead_CF_CellFmt(sfOpenDocument, cfcThisYear, fmt);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_CellFmt_ODS_NextYear;
|
||||
var
|
||||
fmt: TsCellFormat;
|
||||
begin
|
||||
InitFormatRecord(fmt);
|
||||
fmt.SetBackgroundColor(scRed);
|
||||
TestWriteRead_CF_CellFmt(sfOpenDocument, cfcNextYear, fmt);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_CellFmt_ODS_Expression;
|
||||
var
|
||||
fmt: TsCellFormat;
|
||||
|
Loading…
Reference in New Issue
Block a user