How to use ActiveX to change MS Word Table properties

28 views (last 30 days)
I am trying to edit the properties of a table I create in MS Word via ActiveX control in MATLAB and running into difficulties.
Pretty much everywhere I look, people just point to the Microsoft Word object model for Visual Basic help page (https://learn.microsoft.com/en-us/office/vba/api/overview/Word/object-model) and a few example codes (https://www.mathworks.com/matlabcentral/fileexchange/56283-activex-word-control-base-commands?s_tid=FX_rc2_behav and https://www.mathworks.com/matlabcentral/fileexchange/9112-writetowordfrommatlab). My issue is when I try to follow the pattern setout in these examples for implementing the properties on the VB website, MATLAB says "Undefined function" for nearly all of the properties listed.
Based on the discussion on a few other questions posted (e.g. https://www.mathworks.com/matlabcentral/answers/402024-activex-syntax-for-word-tables-cursor-position-sub-tables-etc#answer_321964) , would expect that they should all work. What am I missing? I am a relative newbie with this stuff, so I am most likely just misunderstanding something fundamental here. As an example, why does the following code not let me change the property for table borders (https://learn.microsoft.com/en-us/office/vba/api/word.table.borders):
actx_word = actxserver('Word.Application');
actx_word.Visible = true;
trace(actx_word.Visible);
% Open existing document:
filePath = 'C:\Example.doc';
word_handle = invoke(actx_word.Documents,'Open',filePath);
nr_rows = 2;
nr_rows = 4;
actx_word.ActiveDocument.Tables.Add(actx_word.Selection.Range,nr_rows,nr_cols,1,1);
% Try to change Border thickness
actx_word.ActiveDocument.Tables.Borders.OutsideLineStyle = 'wdLineStyleDouble';
% populate the table with content
for r=1:nr_rows
for c=1:nr_rows
actx_word.Selection.TypeText(['(',num2str(r),',',num2str(c),')']);
actx_word.Selection.MoveRight;
end
end
The error it throws at the line that tries to change Border thickness:
Undefined function 'Borders' for input arguments of type
'Interface.0002094D_0000_0000_C000_000000000046'.
Error in untitled2 (line 23)
actx_word.ActiveDocument.Tables.Borders.OutsideLineStyle
= 'wdLineStyleDouble';

Accepted Answer

dpb
dpb on 16 Aug 2023
Moved: dpb on 16 Aug 2023
I've only done any extensive COM with Excel so I don't know the Word object model at all, but the biggest thing to remember is that MATLAB doesn't "know nuthink!" about VBA syntax; the VB compiler isn't available and there's a lot going between the VB syntax shown and the actual end result.
In MATLAB with COM, you've got to deal with converting higher level VBA code down to the bare basics of being able to directly interact with each object.
As the doc you link to says, the expression
actx_word.ActiveDocument.Tables.Borders
Returns a Borders collection that represents all the borders for the specified object, and the actual VBA code isn't as you've written it exactly, it is
With myTable.Borders
.InsideLineStyle = wdLineStyleSingle
.OutsideLineStyle = wdLineStyleDouble
End With
That "With...End With" block is important; it tells VBA to generate the code to do the dereferencing of each element in the collection and set each in turn. That's missing in your code; MATLAB has no way to do that automagically.
You'll need to save a handle to the borders collection and then iterate over it selecting each in turn and then set each.
If you'll set a breakpoint in your code and stop at each step, you can poke around at each object in turn and intellisense will show you methods and properties that are accessible from each. That is a big help in figuring out how to write COM code that will work; without that it's a real joy. (not!).
  2 Comments
chris
chris on 17 Aug 2023
This is a HUGE help, thanks!
What I ended up doing was opening the document then typing actx_word.get then actx_word.ActiveDocument.get and so on until I found the properties I was looking for. It still seems like you can only do about 10% of what you should be able to do though. (Perhaps I am still missing something?) For instance, I can't set the border of the table or cell to have lines on the horizontal, but not on the vertical.
dpb
dpb on 17 Aug 2023
Anything CAN be done that can be done with VBA, but writing the code directly at the ActiveX/COM interface level is a whole different animal than writing VBA. If it's important-enough and you spend enough time to become intimately familiar with the Word object model and then experiment enough at writing the equivalent you'll begin to learn how to make the translation. But, it's a pretty deep dive to get there.
I've never done it in Word, I presume one has similar developer tools with it as in Excel--one other very useful tool is to record a macro that does what you want and then save that VBA code as a template. It will have a lot of the higher-level constructs in it, but it will identify the named constants that aren't available to MATLAB and give you an outline of what needs to be done to create the desired result.
Again, to do what you were trying to do with the borders will take assigning that borders collection to a variable, then returning the count of the number in the collection and iterating over it. In Excel, a cell has 6 iirc, not just 4 (the diagonals across the cell as well as the outlines) and, iirc, they aren't numbered sequentially by constant although the collection is an array from 1:N. What I'm getting at is that things aren't nearly as simple as VBA makes it appear; it takes a lot of the burden off the coder just like MATLAB does when writing m-file code as compared to writing the same code in Fortran or C.

Sign in to comment.

More Answers (0)

Products


Release

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!