You are viewing limited content. For full access, please sign in.

Question

Question

How to run Word's Macro?

asked on March 31, 2020

Hi all,

 

I created a Word's Template with a simple cell and a macro to change the background-color.

If the cell = '-1' then the cell's background-color is yellow (by default no color).

From the Microsoft Office Word I can run the macro easily but idk how to run this macro in the Laserfiche Workflow during the merge.

 

I also tried to use Rich Text but the background-color is only on the text

But this is not what I want, I want all the cell in yellow.

If I can use Rich Text it's ok but I have a preference for use the macro.

 

Thanks in advance.

Regards

 

0 0

Answer

SELECTED ANSWER
replied on April 5, 2020 Show version history

From the original post, it sounded like you wished to highlight either a single cell or any cell with a value of -1.  In our email exchange, I found that you actually want to highlight any row where the first cell/column has a value of -1.  You also expressed that you wanted to get all cells in the row no matter how many cells.  So here is what I think will server your purposes.

 

Start by downloading and installing Open XML SDK 2.5 for Microsoft Office (Note: it installs into Program Files (x86), but will still work with Workflow x64)

 Next, add a SDK Script Activity to your workflow and set the Script's Default Entry to the laserfiche entry with the work document,

Then open the code block for editing.  First you need to add the references for Laserfiche.DocumentServices and the OpenXML SDK.  In the Project Explorer pane, right click "References" and click "Add Reference..."

In the resulting Dialog window, in the search bar, type "open" and then after selecting "DocumentFormat.OpenXml", click "OK".

Next check the version of "Laserfiche.RepositoryAccess" by right clicking it and selecting "Details".

Once the details are shown, it will include the .NET version followed by an Underscore and then the LF RA version.  When selecting DocumentServices, select the one that matches the RA.

Now right click "References" and click "Add Reference..." again.  In the resulting Dialog window, in the search bar, type "laserfiche.doc" and then after selecting the DocumentServices version that matches the RA, click "OK".

Now that the references are added, add some import statements to make the reference files readily available in the code.  At the top of the code window, will be a list of Import statements.  Add the following 3 statements

Imports Laserfiche.DocumentServices
Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging

Finally the references are added and it is time to update the code.  Between the line of code that has "Protected Overrides Sub Execute()" and the line that has "End Sub", paste the following code:

            'Write your code here. The BoundEntryInfo property will access the entry, RASession will get the Repository Access session
            Dim sTempPath As String = "C:\Temp"
            Dim sExpDocName As String = Nothing
            Try
                ' Open LF Doc for Export
                Using DocInfo As DocumentInfo = TryCast(BoundEntryInfo, DocumentInfo)
                    ' Ensure LF Doc is not Nothing
                    If DocInfo IsNot Nothing Then
                        ' Set Word Doc Name
                        sExpDocName = DocInfo.Name & ".docx"
                        ' Create Exporter
                        Dim de As DocumentExporter = New DocumentExporter()
                        ' Export LF Doc To Temp File
                        de.ExportElecDoc(DocInfo, System.IO.Path.Combine(sTempPath, sExpDocName))
                        ' Open Temp .docx file
                        Using wordDoc As WordprocessingDocument = WordprocessingDocument.Open(System.IO.Path.Combine(sTempPath, sExpDocName), True)
                            ' Get an enumerator of all Tables in Document
                            Dim enumTables As IEnumerable(Of Wordprocessing.Table) = wordDoc.MainDocumentPart.Document.Body.Elements(Of Wordprocessing.Table)
                            ' Process each Table in document
                            For Each tbl As Wordprocessing.Table In enumTables
                                ' Get an enumerator of all Rows in Table
                                Dim enumRows As IEnumerable(Of Wordprocessing.TableRow) = tbl.Elements(Of Wordprocessing.TableRow)
                                ' Process each Row in Table
                                For Each tblRow As Wordprocessing.TableRow In enumRows
                                    ' Get First Cell in Row
                                    Dim FirstCell As Wordprocessing.TableCell = tblRow.GetFirstChild(Of Wordprocessing.TableCell)
                                    ' Get an enumerator of all Cells in Row
                                    Dim enumCells As IEnumerable(Of Wordprocessing.TableCell) = tblRow.Elements(Of Wordprocessing.TableCell)
                                    ' Process each Cell in Row
                                    For Each tblCell As Wordprocessing.TableCell In enumCells
                                        ' Get Shading Property from Cell
                                        Dim tblCellShading As Wordprocessing.Shading = tblCell.TableCellProperties.Shading
                                        ' Evaluate Shading Property
                                        If tblCellShading Is Nothing Then
                                            ' Check First Cell for processing
                                            If FirstCell.InnerText = "-1" Then
                                                ' Create new Shading Property
                                                Dim NewShading As Wordprocessing.Shading = New Wordprocessing.Shading()
                                                ' Set Shading Property settings
                                                NewShading.Color = "auto"
                                                NewShading.Fill = "FFFF00" ' Yellow
                                                NewShading.Val = Wordprocessing.ShadingPatternValues.Clear
                                                ' Add Shading Property
                                                tblCell.TableCellProperties.AppendChild(Of Wordprocessing.Shading)(NewShading)
                                            End If
                                        Else
                                            ' Check First Cell for processing
                                            If FirstCell.InnerText = "-1" Then
                                                ' Only modify if Shading is not Yellow
                                                If tblCellShading.Fill <> "FFFF00" Then ' Yellow then
                                                    '  Remove Existing Shading
                                                    tblCellShading.Remove()
                                                    ' Create new Shading Property
                                                    Dim NewShading As Wordprocessing.Shading = New Wordprocessing.Shading()
                                                    ' Set Shading Property settings
                                                    NewShading.Color = "auto"
                                                    NewShading.Fill = "FFFF00" ' Yellow
                                                    NewShading.Val = Wordprocessing.ShadingPatternValues.Clear
                                                    ' Add Shading Property
                                                    tblCell.TableCellProperties.AppendChild(Of Wordprocessing.Shading)(NewShading)
                                                End If
                                            Else
                                                '  Remove Existing Shading
                                                tblCellShading.Remove()
                                            End If
                                        End If
                                    Next
                                Next
                            Next
                        ' Close and Save Temp .docx file
                        End Using
                    End If
                ' Close LF Doc For Export
                End Using
                'Check for Temp Doc
                Dim fiWordDoc As System.IO.FileInfo = New System.IO.FileInfo(System.IO.Path.Combine(sTempPath, sExpDocName))
                If fiWordDoc.Exists Then
                    ' Open LF Doc for Import
                    Using UpdateDocInfo As DocumentInfo = TryCast(BoundEntryInfo, DocumentInfo)
                        ' Ensure LF Doc is not Nothing
                        If UpdateDocInfo IsNot Nothing Then
                            ' Create Importer
                            Dim di As DocumentImporter = New DocumentImporter()
                            ' Set Importer to import into LF Doc
                            di.Document = UpdateDocInfo
                            ' Import Temp .docx file into LF Doc
                            di.ImportEdoc("application/vnd.openxmlformats-officedocument.wordprocessingml.document", System.IO.Path.Combine(sTempPath, sExpDocName))
                            ' Set LF Doc File Extension
                            UpdateDocInfo.Extension = "docx"
                            ' Save the Changes to the LF Doc
                            UpdateDocInfo.Save()
                        End If
                    ' Close LF Doc For Import
                    End Using
                End If
            Catch ex As Exception
                WorkflowApi.TrackError(ex.Message)
            End Try
            ' Cleanup Temp .docx file
            Dim fi As System.IO.FileInfo = New System.IO.FileInfo(System.IO.Path.Combine(sTempPath, sExpDocName))
            If fi.Exists Then
                fi.Delete()
            End If

There is only 1 line of code to change and it is the first Dim Statement.

In the "sTempPath", set "C:\Temp" to a folder where the Workflow Service user can create, modify, and delete the temp word document.

The resulting Word doc will highlight each row that has a -1 in the first cell.

1 0

Replies

replied on April 1, 2020

Running Office applications from a service process like Workflow is not supported by Microsoft, so you can't launch Word to run the macro.

1 0
replied on April 1, 2020

Thanks Brian,

 

Do you have another way to auto edit the cell's background-color if the value = '-1' from the Workflow?

0 0
replied on April 1, 2020

Microsoft has the OpenXML libraries to assist with modfying Office documents programmatically. They aren't a lot of fun to work with and you've going to have to read a bunch of documentation, but I'm not sure what the alternatives are.

0 0
replied on April 1, 2020

If it is good enough to set the background color based on cell value when the document is opened, you can use VBA.  Something like this (you will have to adjust to select the correct cell) should work.

Private Sub Document_Open()
  On Error GoTo CleanFail

  If ActiveDocument.Range.Cells.Count > 0 Then
    Dim objCell As Word.Cell
    Set objCell = ActiveDocument.Range.Cells.Item(1)
    Dim sCellVal As String
    ' Strip off CR/LF if present
    sCellVal = IIf(InStr(objCell.Range.Text, Chr(13)) > 0, Left(objCell.Range.Text, InStr(objCell.Range.Text, Chr(13)) - 1), objCell.Range.Text)
    If sCellVal = "-1" Then
      objCell.Shading.BackgroundPatternColor = wdColorYellow
    Else
      objCell.Shading.BackgroundPatternColor = wdColorWhite
    End If
  End If

CleanExit:
    'cleanup code goes here. runs regardless of error state.
    Exit Sub

CleanFail:
    'handle runtime error(s) here.
    'Raise Err.Number '"rethrow" / "bubble up"
    Resume CleanExit
    Resume
End Sub

 

0 0
replied on April 1, 2020

Hi Bert Warren,

 

Thanks for your help.

I already have my own VBA and it works but this means I should :

1°) save the file to doc (using the 1st workflow),

2°) open the doc file to run VBA then save the new version,

3°) use another workflow to transform it to PDF.

 

Added more 3 steps ; I don't like this solution.

0 0
replied on April 1, 2020 Show version history

Since I did not know what you were doing with the document after filling it out with Workflow, my first question was if using the OnOpen event was good enough.  For your case, it is not, and you should look into using the OpenOffice DLL in a SDK Script Activity.  The thing to remember is that the OpenOffice for Windows is x86, so you will need a x86 Workflow instance to build this on.  If you do not want to put up a x86 workflow instance to do this, you could create a x86 console app that edits the word document and then sets a field value to tell workflow it is done.  From your workflow, use a script activity to call the console app and then wait for the field value to change.

2 0
replied on April 2, 2020

Hi Bert, thank you for your suggestion.

 

I don't have any idea how to use OpenOffice DLL in SDK Script Activity.

I will see what I can find on the net.

 

Thanks for  your help.

Regards

0 0
replied on April 2, 2020 Show version history

I have a solution, but I need a copy of your master Word document so that I can make sure I get the correct Cell highlighted.  If you email me the word file, I will get you a working solution.

1 0
replied on April 3, 2020

Hi Bert,

 

I sent you an email with the doc file.
Regards

0 0
SELECTED ANSWER
replied on April 5, 2020 Show version history

From the original post, it sounded like you wished to highlight either a single cell or any cell with a value of -1.  In our email exchange, I found that you actually want to highlight any row where the first cell/column has a value of -1.  You also expressed that you wanted to get all cells in the row no matter how many cells.  So here is what I think will server your purposes.

 

Start by downloading and installing Open XML SDK 2.5 for Microsoft Office (Note: it installs into Program Files (x86), but will still work with Workflow x64)

 Next, add a SDK Script Activity to your workflow and set the Script's Default Entry to the laserfiche entry with the work document,

Then open the code block for editing.  First you need to add the references for Laserfiche.DocumentServices and the OpenXML SDK.  In the Project Explorer pane, right click "References" and click "Add Reference..."

In the resulting Dialog window, in the search bar, type "open" and then after selecting "DocumentFormat.OpenXml", click "OK".

Next check the version of "Laserfiche.RepositoryAccess" by right clicking it and selecting "Details".

Once the details are shown, it will include the .NET version followed by an Underscore and then the LF RA version.  When selecting DocumentServices, select the one that matches the RA.

Now right click "References" and click "Add Reference..." again.  In the resulting Dialog window, in the search bar, type "laserfiche.doc" and then after selecting the DocumentServices version that matches the RA, click "OK".

Now that the references are added, add some import statements to make the reference files readily available in the code.  At the top of the code window, will be a list of Import statements.  Add the following 3 statements

Imports Laserfiche.DocumentServices
Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging

Finally the references are added and it is time to update the code.  Between the line of code that has "Protected Overrides Sub Execute()" and the line that has "End Sub", paste the following code:

            'Write your code here. The BoundEntryInfo property will access the entry, RASession will get the Repository Access session
            Dim sTempPath As String = "C:\Temp"
            Dim sExpDocName As String = Nothing
            Try
                ' Open LF Doc for Export
                Using DocInfo As DocumentInfo = TryCast(BoundEntryInfo, DocumentInfo)
                    ' Ensure LF Doc is not Nothing
                    If DocInfo IsNot Nothing Then
                        ' Set Word Doc Name
                        sExpDocName = DocInfo.Name & ".docx"
                        ' Create Exporter
                        Dim de As DocumentExporter = New DocumentExporter()
                        ' Export LF Doc To Temp File
                        de.ExportElecDoc(DocInfo, System.IO.Path.Combine(sTempPath, sExpDocName))
                        ' Open Temp .docx file
                        Using wordDoc As WordprocessingDocument = WordprocessingDocument.Open(System.IO.Path.Combine(sTempPath, sExpDocName), True)
                            ' Get an enumerator of all Tables in Document
                            Dim enumTables As IEnumerable(Of Wordprocessing.Table) = wordDoc.MainDocumentPart.Document.Body.Elements(Of Wordprocessing.Table)
                            ' Process each Table in document
                            For Each tbl As Wordprocessing.Table In enumTables
                                ' Get an enumerator of all Rows in Table
                                Dim enumRows As IEnumerable(Of Wordprocessing.TableRow) = tbl.Elements(Of Wordprocessing.TableRow)
                                ' Process each Row in Table
                                For Each tblRow As Wordprocessing.TableRow In enumRows
                                    ' Get First Cell in Row
                                    Dim FirstCell As Wordprocessing.TableCell = tblRow.GetFirstChild(Of Wordprocessing.TableCell)
                                    ' Get an enumerator of all Cells in Row
                                    Dim enumCells As IEnumerable(Of Wordprocessing.TableCell) = tblRow.Elements(Of Wordprocessing.TableCell)
                                    ' Process each Cell in Row
                                    For Each tblCell As Wordprocessing.TableCell In enumCells
                                        ' Get Shading Property from Cell
                                        Dim tblCellShading As Wordprocessing.Shading = tblCell.TableCellProperties.Shading
                                        ' Evaluate Shading Property
                                        If tblCellShading Is Nothing Then
                                            ' Check First Cell for processing
                                            If FirstCell.InnerText = "-1" Then
                                                ' Create new Shading Property
                                                Dim NewShading As Wordprocessing.Shading = New Wordprocessing.Shading()
                                                ' Set Shading Property settings
                                                NewShading.Color = "auto"
                                                NewShading.Fill = "FFFF00" ' Yellow
                                                NewShading.Val = Wordprocessing.ShadingPatternValues.Clear
                                                ' Add Shading Property
                                                tblCell.TableCellProperties.AppendChild(Of Wordprocessing.Shading)(NewShading)
                                            End If
                                        Else
                                            ' Check First Cell for processing
                                            If FirstCell.InnerText = "-1" Then
                                                ' Only modify if Shading is not Yellow
                                                If tblCellShading.Fill <> "FFFF00" Then ' Yellow then
                                                    '  Remove Existing Shading
                                                    tblCellShading.Remove()
                                                    ' Create new Shading Property
                                                    Dim NewShading As Wordprocessing.Shading = New Wordprocessing.Shading()
                                                    ' Set Shading Property settings
                                                    NewShading.Color = "auto"
                                                    NewShading.Fill = "FFFF00" ' Yellow
                                                    NewShading.Val = Wordprocessing.ShadingPatternValues.Clear
                                                    ' Add Shading Property
                                                    tblCell.TableCellProperties.AppendChild(Of Wordprocessing.Shading)(NewShading)
                                                End If
                                            Else
                                                '  Remove Existing Shading
                                                tblCellShading.Remove()
                                            End If
                                        End If
                                    Next
                                Next
                            Next
                        ' Close and Save Temp .docx file
                        End Using
                    End If
                ' Close LF Doc For Export
                End Using
                'Check for Temp Doc
                Dim fiWordDoc As System.IO.FileInfo = New System.IO.FileInfo(System.IO.Path.Combine(sTempPath, sExpDocName))
                If fiWordDoc.Exists Then
                    ' Open LF Doc for Import
                    Using UpdateDocInfo As DocumentInfo = TryCast(BoundEntryInfo, DocumentInfo)
                        ' Ensure LF Doc is not Nothing
                        If UpdateDocInfo IsNot Nothing Then
                            ' Create Importer
                            Dim di As DocumentImporter = New DocumentImporter()
                            ' Set Importer to import into LF Doc
                            di.Document = UpdateDocInfo
                            ' Import Temp .docx file into LF Doc
                            di.ImportEdoc("application/vnd.openxmlformats-officedocument.wordprocessingml.document", System.IO.Path.Combine(sTempPath, sExpDocName))
                            ' Set LF Doc File Extension
                            UpdateDocInfo.Extension = "docx"
                            ' Save the Changes to the LF Doc
                            UpdateDocInfo.Save()
                        End If
                    ' Close LF Doc For Import
                    End Using
                End If
            Catch ex As Exception
                WorkflowApi.TrackError(ex.Message)
            End Try
            ' Cleanup Temp .docx file
            Dim fi As System.IO.FileInfo = New System.IO.FileInfo(System.IO.Path.Combine(sTempPath, sExpDocName))
            If fi.Exists Then
                fi.Delete()
            End If

There is only 1 line of code to change and it is the first Dim Statement.

In the "sTempPath", set "C:\Temp" to a folder where the Workflow Service user can create, modify, and delete the temp word document.

The resulting Word doc will highlight each row that has a -1 in the first cell.

1 0
replied on April 6, 2020 Show version history

Hi Bert,

 

I changed your code by the new one but I have some errors.

Expression is not a method,

Expected expression,

Method arguments must be enclosed in parentheses

 

It's ok ! I found why. 'Set Word Doc name

I removed 'As String' and now everything is ok.

 

Maybe you should update your script.

 

Thank you so much !!

1 0
replied on April 6, 2020

Yes.  I had copied the line and forgot to remove the "As String"...

Fixed the code above, thanks for pointing it out.

0 0
You are not allowed to follow up in this post.

Sign in to reply to this post.