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.
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)
seps(s) = sep
next
row.TableColumnSeparators = seps
table.Rows(i) = row
next
tables.getByName(tableName) = table
end sub
Edit after JohnSUN’s answer
JohnSUN’s answer was very helpful, and nearly worked, but I ran into issues where some rows would have separators that were somehow conflicting with each other. I tried to use IsVisible
to work around that, but I couldn’t get it to work. It might be possible to hack something up with counting cells in rows and calculating how many separators there are per row, or how many visible ones, or something like that. I corrected the script above so it works now, as much as seems possible.
In the end, the most reliable method to set all the columns’ widths was this Bash script, bound to a global keyboard shortcut. I have it open in Emacs in one window, so I can easily modify it as needed.
#!/bin/bash
delay="--delay 25"
doTimes()
{
times=$1
shift
for i in $(seq $times)
do
eval "$@"
done
sleep 0.1
}
setTo()
{
xdotool key --clearmodifiers $delay Menu type --clearmodifiers $delay "mw"
xdotool search "Column Width" windowfocus
xdotool key --clearmodifiers $delay Tab type --clearmodifiers $delay "$1"
xdotool key --clearmodifiers Return
}
tab()
{
xdotool key --clearmodifiers Tab
}
doTimes 4 "setTo 0.89; tab"
#doTimes 2 "setTo 0.08; tab"
doTimes 1 "setTo 0.16; tab"
doTimes 2 "setTo 0.89; tab"
If only Writer would actually change all of the cells’ widths when you select all of them…