Question

Hi All, I wanted to input a table of data in word document and this table is dynamic in nature (i.e no of rows vary in each bot run ) .I tried MS word package replace text feature but that only provides us with replacing a single text .

  • 3 November 2022
  • 1 reply
  • 490 views

Badge +5

So is there any way to have a placeholder and then replace it with a table ? what is the best way to automate the above requirement?

 

@Tamil Arasu​ , @Ashwin A.K​ ,@Paul Hawkins​ any thoughts here please?

 

Thanks in advance

Mahesh


1 reply

Userlevel 2
Badge +7

@Mahesh Duggirala​ I've had a similar scenario in the past for updating a series of placeholders and tables in MS Word template.

 

The most efficient way at the time was to create a class library (dll) that utilises the functionality of the Microsoft Interop library (https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.interop.word?view=word-pia). You can then call the DLL from your task. There may be an easier native way to do this now in a360, but rough outline I followed is below:

 

I have a couple of methods to either open the word document or hook into the session of an existing one. If its already open you need to pass the name of the open document e.g. myDoc.docx or the whole path if opening fresh e.g. C:\MyDocs\MyDoc.docx

 

private Application _application;

    private Document _document;

    private object _missing = Type.Missing;

    public void SetExistingApplicationInstance(string documentName, bool isVisible)

    {

      _application = (Application)Marshal.GetActiveObject("Word.Application");

      _application.Visible = isVisible;

      _document = _application.Documents[documentName];

 

    }

    public void SetNewApplicationInstance(string documentName, bool isVisible)

    {

      _application = new Application

      {

        Visible = isVisible

      };

      _document = _application.Documents.Open(documentName);

    }

 

Each workbook will have a collection of tables, iirc are stored in the order they appear in the template e.g. first table in your template is table number 1. All you then need to do is pass a reference to the table and the array/table of the row data you wish to insert. This will create a new row before inserting the data, so you dont have to have lots of rows in your existing template table. Basic outline:

 

public void AddRowAndDataToTable(int tableNum, string[] rowData)

    {

 

      var table = _document.Tables[tableNum];

      var rows = table.Rows;

 

      rows.Add(ref _missing);

      var rowNumber = rows.Count;

 

      foreach (var columnNumber in from Column column in table.Columns select column.Index)

      {

        table.Cell(rowNumber, columnNumber).Range.Text = rowData[columnNumber - 1];

//could also apply alignments / emphasis at this point

      }

    }

 

You could change this to accept a whole dataset and do multiple rows at once

 

Final bit would be to save and close

 

public void SaveAndClose()

    {

      _document.Save();

      _document.Close(ref _missing, ref _missing, ref _missing);

      _application.Quit(ref _missing, ref _missing, ref _missing);

      _document = null;

      _application = null;

    }

 

You could obviously add loads more methods for other things as well (find and replace etc.) and then do it all within the same dll session without the need to add the additional MS Word package to your task.

 

I know this requires some C# knowledge and the ability to compile your own DLL, but hope this helps. The interop library isn't the easiest to use, but will be plenty online like stackoverflow to get to grips with its other functionality.

Reply