Ask Your Question

Writer v4.1 macro to adjust column widths in tables

asked 2013-10-26 12:42:25 +0200

Yimin Rong gravatar image

updated 2015-08-28 19:50:39 +0200

Alex Kemp gravatar image

I am working on some LibreOffice macros that work on tables, in particular to set the width and height of each column and row to 0.85 cm (0.335 in).

In MS Office, this is easy, just select the table and in the macro have:

Selection.Rows.Height = CentimetersToPoints(0.85)
Selection.Columns.PreferredWidth = CentimetersToPoints(0.85)

There isn't anything like this in LibreOffice 4.1. It appears each column must be adjusted individually. I'm thinking two ways to do this:

  1. Iterate through all the columns and adjust each column

  2. Adjust the first column to some carefully calculated wide width, then Distribute Columns Evenly

Just to get an idea of the code, I tried using the macro recorder and went through Table | Table Properties and played around until the table looked okay, but most of what I did was not recorded in the macro.

Has anyone done something like this?

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted

answered 2015-02-27 06:30:37 +0200

alphapapa gravatar image

updated 2015-02-27 06:56:47 +0200

I am attempting to set the width of all the cells in a table to a certain value by setting the position of each row's separators using the TableColumnRelativeSum to calculate the appropriate relative Position. It's necessary to use the relative values because, as the TableColumnSeparator docs explain:

The real width of a table depends on the environment (page style and number of text columns at the table's position, alignment, and left and right margins). For that reason, the table column separator does not contain metric values for the column widths. The values are relative to the value of the property TextTable::TableColumnRelativeSum.

So here's my attempt. It calculates the correct relative column separator positions for my table (using inches and a specific table width and column width), row by row. When I step through the macro, I can see the variables changing to the correct values, including the Position of each separator in each row.

The problem is, the changes are never reflected in the document. I tried setting the TableColumnSeparators and even each row, but it doesn't do anything.

I found a forum post discussing how to do it in Java, but that doesn't help me much, I'm afraid. It looks like in a simple table (one where all the rows have cells of equal width, so it's uniform), you can set the TableColumnSeparators on the whole table at once, but it's not possible to set them for a row. I guess this is a bug or missing functionality in Writer.

I don't know where to go from here. :(

Sub Main

tableName = "Table5"
tables = ThisComponent.TextTables
table = tables.getByName(tableName)

tableWidthRelative = table.TableColumnRelativeSum
tableWidthIn = 5.5

columnWidthIn = 0.89
columnWidthRelative = columnWidthIn / tableWidthIn * tableWidthRelative

rows = table.getRows()
for i = 0 to (rows.Count() - 1)
    row = rows.getByIndex(i)

    seps = row.TableColumnSeparators

    ' TableColumnSeparators is a Sequence, which 
      does not support the Count method.  You must use
      UBound() to get its length. '
    numSeps = UBound(seps)

    for s = 0 to numSeps
        sep = seps(s)
        sep.Position = columnWidthRelative * (s+1)

    ' Now nothing happens.  The changes are never reflected
      in the document.  Here I try setting the separators back,
      and setting each row back, but it does not do anything.
      I even try setting the table back, but nope. '
    row.TableColumnSeparators = seps

    table.Rows(i) = row

tables.getByName(tableName) = table

end sub
edit flag offensive delete link more

answered 2013-11-08 17:06:25 +0200

Yimin Rong gravatar image

updated 2013-11-08 17:07:23 +0200

Provided by Russell Harper [RH] in another forum:

Here is as far as I [RH] could get:

sub Testing

    dim tables as object
    dim table as object
    dim columns as object
    dim column as object
    dim index as integer

    tables = ThisComponent.TextTables

    if tables.Count > 0 then

        table = tables.getByIndex(0)
        columns = table.columns
        table.Width = 850 * columns.Count '850 == 0.85 cm

        for index = 0 to columns.Count - 1
            column = columns.getByIndex(index)
            'column is always NULL
            'column.Width = 850

    end if

end sub

Major problems noted:

  1. no way to retrieve the actual table you want to modify via ThisComponent.CurrentSelection, so instead hardcoded to the table at index 0

  2. the function that distributes columns evenly doesn't seem to be available

  3. columns.getByIndex always returns NULL!, and there's no documentation on how to use the column enumeration class within Basic

Based on this investigation, would advise against trying to do anything productive with LibreOffice 4.1 Writer Basic macros.

edit flag offensive delete link more
Login/Signup to Answer

Question Tools

1 follower


Asked: 2013-10-26 12:42:25 +0200

Seen: 1,822 times

Last updated: Feb 27 '15