WPCubed Product Support

WP_Reporter

Hello

When I develop a program for the end user, they do not have access to the WP_Tools and WP_Reporter code to create a table as is done in the WP_Reporter calc demo. If the end user is to create a table that performs calculations, they need to be able to assign paragraph names and commands after the table has been created.

The code at the bottom of this post is executed from a button.OnClick event and will assign a paragraph name and command to individual cells. I can confirm that the changes to the cells are made by displaying the paragraph name and formula by setting WPRichText1.ViewOptions := [wpShowParCalcNames,wpShowParCalcCommands]

Problems:
There are two issues that are present after assigning paragraph names and commands to the cells of a table to reproduce the WP_Reporter invoice demo.

a) The text in the cells to which commands have been assigned can be manually changed. This should not occure and does not in the WP_Reporter invoice demo cells.

b) If WPRichText1.RecalcText(true,true); is executed from a separate button.OnClick event, the recalculation is not performed.

Suggestions as to what I am missing?

TIA

John

Code to assign cell name and command is below

procedure TformWordProcessor.WPToolButtonDefineParagraphClick(Sender: TObject);
var
  tempPar: TParagraph;
begin
  if WPRichText1.CheckHasBody = True then
    begin
      WPRichText1.BeginUpdate;  // Temporarily disable protection!

      LMDInputDlg1.Width := 400;
      LMDInputDlg1.CaptionTitle := 'Input Paragraph Name';
      LMDInputDlg1.DefaultValue := '';

      if LMDInputDlg1.Execute = True then
        begin
          if LMDInputDlg1.Value <> '' then
            begin
              WPRichText1.ActivePar.WPATName := LMDInputDlg1.Value;
              WPRichText1.ActivePar.WPATName := LMDInputDlg1.Value;

              tempPar := WPRichText1.ActivePar;

              LMDInputDlg1.CaptionTitle := 'Input Paragraph Command';
              LMDInputDlg1.DefaultValue := '';

              if LMDInputDlg1.Execute = True then
                begin
                  if LMDInputDlg1.Value <> '' then
                    begin
                      tempPar.ASetStringProp(WPAT_PAR_COMMAND, LMDInputDlg1.Value);
                    end;
                end;

              tempPar.ASet(WPAT_ParProtected,1);
            end;
        end;

      WPRichText1.EndUpdate;  // Enable protection!
      WPRichText1.Modified := True;
    end;

end;
#1 ♥ 0
14k Views 2 users read 7 min
support

Hi,

You need to activate the paragraph protection in the TWPRichText property ProtectedProp.

b) this depends on the setup - the WPFormulaInterface and WPEvalEngine must have been set up.

#2 ♥ 0

Thanks for the reply.

I have the calculations and protection issues resolved.

Using the "create name table" code as a template I have been able to create a number of table templates to automate the table creation process for the end user. Using the WPAT_PAR_Command and WPAT_PAR_Name parameters I have been able to import summary values in a cell from table A to a cell in table B via the recalc process as long as there is no overlap in cell names.

Question 1: Is there a mechanism to via code to determine the number of tables that are present on a given document? This number would be helpful in assigning unique par names of newly created table cells.

Question 2: When text is calculated, the results are expressed as floating point numbers. Is there a mechanism to convert the displayed text in a table cell or a WPTextObj to a currency?

TIA

John

#3 ♥ 0
support

Question 1: Is there a mechanism to via code to determine the number of tables that are present on a given document? This number would be helpful in assigning unique par names of newly created table cells.

Please use a
par := FirstPar;
while par <>nil do ...
loop for this. You can check par.ParagraphType for wpIsTable.

Question 2: When text is calculated, the results are expressed as floating point numbers. Is there a mechanism to convert the displayed text in a table cell or a WPTextObj to a currency?

Please check out the events OnCalcFormula and BeforeCalcFormula of TWPFormulaInterface

and

function TWPFormulaInterface.CalcFormula(RTFData: TWPRTFDataCollectionBase; // Owner collection
par: TParagraph; // current paragraph or parent paragraph of field
posinpar: Integer; // -1 for a paragraph formula, otherwise position of the object
const formula: string;
format: Integer; var value: Double; var strvalue: string): Boolean;

in unit WPTblCalc.

#4 ♥ 0

Thanks for the reply

As per your suggestion, the procedure below iterates through the paragraphs to obtain the table count. I also need to capture the table name associated with each paragraph that is of type wplsTable so it can be displayed to the end user. I have been unsuccessful in this endeavor. The line below with two asterisks seems like the logical solution, but it does not compile.

Suggestions??

TIA

John

procedure TformWordProcessor.ParagraphCount;
var
  tempCurrentPar: TParagraph;
  tempNewString: String;
  tempMenuItems: TStringList;
begin
  tempMenuItems := TStringList.Create;
  tempCurrentPar := WPRichText1.FirstPar;
  tempTableCount := 0;
  while tempCurrentPar <> nil do
    begin
      if tempCurrentPar.ParagraphType = wpIsTable then
        begin
          tempTableCount := tempTableCount + 1;
**          tempMenuItems.Add('Table #' + IntToStr(tempTableCount) + '    ' + 'Table Name = ' +  tempCurrentPar.CurrAttr.TableName);
        end;

      tempCurrentPar := tempCurrentPar.NextPar;
    end;

  ShowMenuDlg('Table Information', 'Available Tables', tempNewString, tempMenuItems);
  tempMenuItems.Free;
end;
#5 ♥ 0
support

CurrAttr is an interface to change the current wring mode. If you have a TParagraph reference you can access the properties directly, such as Name.

tempCurrentPar.Name

or

tempCurrentPar.CurrAttr.WPATCaption

#6 ♥ 0

Support:

In response to my question 2 above

When text is calculated, the results are expressed as floating point numbers. Is there a mechanism to convert the displayed text in a table cell or a WPTextObj to a currency?

Your reply was

Please check out the events OnCalcFormula and BeforeCalcFormula of TWPFormulaInterface

The HTML help file does list both functions, but I can find no example of the implementation of either function in any of the demos or the WP7manual. Could you please provide an example of how to implement the currency text formatting of table cells with numeric values such as are shown in the CalcTU demo?

I greatly appreciate your efforts.

John

#7 ♥ 0
support

To write the value as currency use this event handler.

function TWPTableCalc.DoConvertValueToText(Sender: TObject; var text: string;  Format: Integer; Value: Double): Boolean;begin  text := FloatToStrF(Value, ffCurrency,10,2);  Result := true;end;

It had been assigned to event ConvertValueToText.

Please note that the EvalEngine is using the standard Delphi Round() method which is not necessarily correct for currencies, the same is true for FloatToStrF.

I mentioned the unit WPTblCalc - there you find the method CalcFormula which is basically the reference (or default) implementation.

function TWPFormulaInterface.CalcFormula(RTFData: TWPRTFDataCollectionBase; // Owner collection
  par: TParagraph; // current paragraph or parent paragraph of field
  posinpar: Integer; // -1 for a paragraph formula, otherwise position of the object
  const formula: string;
  format: Integer; var value: Double; var strvalue: string): Boolean;
var Abort : Boolean;
begin
  Result := FALSE;
  strvalue := '';
  if Trim(formula)='' then exit; // 4.4.2014
  FCurrentMemo := RTFData as TWPRTFDataCollection;
  FCurrentPar := par;
  FCurrentPosInPar := posinpar;
  FCurrentFormula := formula;
  Abort := FALSE;
  if assigned(FBeforeCalcFormula) then FBeforeCalcFormula(Self, formula, Abort);
  if not Abort then
  try
    if assigned(FEvalEngine) then
    begin
      value := 0;
      try
        FEvalEngine._InternOnReadVariable := ReadVariable;
        FEvalEngine.aRTFEngineObject := RTFData;
        RTFData.GetCellValueError := false;
        if assigned(FOnCalcFormula) then strvalue := FOnCalcFormula(Self, formula)
        else strvalue := FEvalEngine.EvaluateAsString(formula);
        if strvalue <> '' then try value := StrToFloat(strvalue); except end;
        if RTFData.GetCellValueError then
        begin
             Result := true;  // use result !
             value := 0;
             strvalue := '[ERR]';
        end
        else Result := WriteValueToText(strvalue, format, value);
      finally
        FEvalEngine._InternOnReadVariable := nil;
        FEvalEngine.aRTFEngineObject := nil;
      end;
    end
    else if assigned(FOnCalcFormula) then
    begin
      strvalue := FOnCalcFormula(Self, formula);
      if strvalue <> '' then try value := StrToFloat(strvalue); except end;
      Result := WriteValueToText(strvalue, format, value);
    end;
  finally
    FCurrentMemo := nil;
    FCurrentPar := nil;
    FCurrentPosInPar := 0;
    FCurrentFormula := '';
  end;
end;

I highly recommend to check out such units since the source is part of the documentation. In Delphi you can press ALT and click on a type, unit or procedure and it takes you there - you get an interactive manual.

#8 ♥ 0

Support

I did look at the function TWPFormulaInterface.CalcFormula and saw that it called TWPFormulaInterface.WriteValueToText. In point of fact, I could substitute text := FloatToStrF(Value, ffCurrency,10,2); for text := FloatToStrF(value, ffFixed, 10, 2); on line 241 and get the result that I needed. I also saw that if IWPFormulaInterface.ConvertValueToText was assigned a function then that function would be implemented.

Once I saw your implementation of DoConvertValueToText, I understood that I could declared the public function DoConvertValueToText and assign IWPFormulaInterface.ConvertValueToText := DoConvertValueToText in the OnCreate event of the form. I was then good to go.

Thanks for your efforts

John

#9 ♥ 0
This category is archived. No new posts are possible.