delphims-worddelphi-12-athens

Trying to replace text in multiple docx,doc documents


I am trying to replace text that I have in a TStringGrid (two columns - one for text to be replaced, and one for new text to replace the old text).

The program compilation finishes without any errors. When the program executes and the user for example selects 5 files to replace text, I receive an error 5 times with this message:

Invalid number of parameters

Can anyone help, please!?

The procedure that makes the replacement is the following:

procedure TFrmmain.ReplaceWordsInDocs;
var
  WordApp: OLEVariant;
  WordDoc: OLEVariant;
  OpenDialog: TOpenDialog;
  Row: Integer;
  FileName: string;
  i: Integer;
  EmptyParam: OleVariant;
begin
  EmptyParam := Unassigned; // Initialize EmptyParam to Unassigned

  // Create the Word application
  WordApp := CreateOleObject('Word.Application');
  try
    WordApp.Visible := False; // Hide the Word application

    // Let the user select multiple files
    OpenDialog := TOpenDialog.Create(nil);
    try
      OpenDialog.Filter := 'Word Documents (*.docx;*.doc)|*.docx;*.doc';
      OpenDialog.Options := [ofAllowMultiSelect];
      if OpenDialog.Execute then
      begin
        // Loop through the selected files
        for i := 0 to OpenDialog.Files.Count - 1 do
        begin
          FileName := OpenDialog.Files[i];

          try
            // Open the document
            WordDoc := WordApp.Documents.Open(FileName);
            try
              // Loop through each row in the StringGrid (starting from Row 1, assuming Row 0 is headers)
              for Row := 1 to StringGrid1.RowCount - 1 do
              begin
                if Trim(StringGrid1.Cells[1, Row]) <> '' then
                begin
                  // Perform the Find and Replace using Word's Content.Find.Execute
                  try
                    WordDoc.Content.Find.Execute(
                      StringGrid1.Cells[1, Row],       // Find text from column 1 (FindText)
                      True,                            // MatchCase (True for case-sensitive search)
                      False,                           // MatchWholeWord (False for partial matches)
                      False,                           // MatchWildcards (False for simple text match)
                      False,                           // MatchSoundsLike (False for exact matches)
                      False,                           // MatchAllWordForms (False for strict form match)
                      StringGrid1.Cells[2, Row],       // Replace text from column 2 (ReplaceWith)
                      wdReplaceAll,                    // Replace (2 for replacing all)
                      False,                           // Forward (False to search backward)
                      EmptyParam,                      // Wrap (EmptyParam to use the default value)
                      False,                           // Format (False for no specific format)
                      EmptyParam,                      // ReplaceWithStyle (EmptyParam for default)
                      EmptyParam,                      // MatchKashida
                      EmptyParam,                      // MatchDiacritics
                      EmptyParam,                      // MatchAlefHamza
                      EmptyParam                       // MatchControl
                    );
                  except
                    on E: Exception do
                      ShowMessage('Error replacing text in document ' + FileName + ': ' + E.Message);
                  end;
                end;
              end;
              // Save the document after replacements
              WordDoc.Save;
            finally
              WordDoc.Close(False); // Close the document without saving further
            end;
          except
            on E: Exception do
              ShowMessage('Error processing file ' + FileName + ': ' + E.Message);
          end;
        end;
      end;
    finally
      OpenDialog.Free;
    end;
  finally
    WordApp.Quit;  // Quit Word application
    WordApp := Unassigned; // Free the Word application object
  end;
end;

Solution

  • Word's Find.Execute() method takes 15 parameters, but you are passing 16 values to it, hence the "Invalid number of parameters" error. Since you are accessing Word via its COM object and calling Find.Execute() via dynamic dispatch, this kind of mistake cannot be validated at compile-time, only raise an error at runtime.