1. What I’m Trying To Do
I have a folder with 84 Word documents (.docx). Every document contains a table of identical layout (some of the documents span across 2 pages). However, the column widths are not always the same.
I want to make all the table column widths identical at 2 inches, so I can subsequently save all the files as PDF, and prepare them for use in another process which I will not elaborate on.
2. My Current Approach
I’ve got a Word VBA macro that runs a script (below) over all .docx files in a folder, based on a user-prompted file path. This part works — there’s no problem.
The problem
However, when my script attempts to set all the columns in the document’s tables to the same width, this doesn’t work. It only works, in the example document shown here, on the first 3 columns.
Illustrating the problem with screenshots
Figure 1 (above): This is what the original table looks like in the Word document.
Figure 2 (above): This is what the table looks like after running my macro. In this example, I ran the macro to set all column widths to 1.5 (InchesToPoints(1.5)
). You can see that only the first 3 columns are adjusted, but columns 4-7 are unmodified.
Figure 3 (above): This is what I expected the table to look like after running my macro to set all columns to 1.5 inches in width.
Here’s a link to the original document: https://www.dropbox.com/s/cm0fqr6o7xgavpv/1-Accounting-Standards.docx?dl=0
Testing on another file
I tested the macro on another file I created, where I inserted 3 tables.
Figure 4 (above): I created a new file with 3 tables, all with different column widths.
Figure 5 (above): Running the macro with this test file in the same folder as the example document previously, shows that the macro works, and adjusts the columns in all tables to the specified width.
3. My Question
What’s going on here? Why isn’t SetTableWidths
working as expected?
I’m guessing that it’s maybe because the original table in the original word document contains merged cells, otherwise why would the script not work on columns 4-7?
Any help would be greatly appreciated.
4. Word VBA Macro
Sub RunMacroOnAllFilesInFolder()
Dim flpath As String, fl As String
flpath = InputBox("Please enter the path to the folder you want to run the macro on.")
If flpath = "" Then Exit Sub
If Right(flpath, 1) <> Application.PathSeparator Then flpath = flpath & Application.PathSeparator
fl = Dir(flpath & "*.docx")
Application.ScreenUpdating = False
Do Until fl = ""
MyMacro flpath, fl
fl = Dir
Loop
End Sub
Sub MyMacro(flpath As String, fl As String)
Dim doc As Document
Set doc = Documents.Open(flpath & fl)
'Your code below
SetTableWidths doc
DeleteAllHeadersFooters doc
'your code above
doc.Save
doc.Close SaveChanges:=wdSaveChanges
End Sub
Sub SetTableWidths(doc As Document)
Dim t As Table
For Each t In doc.Tables
t.Columns.Width = InchesToPoints(2)
Next t
End Sub
Sub DeleteAllHeadersFooters(doc As Document)
Dim sec As Section
Dim hd_ft As HeaderFooter
For Each sec In ActiveDocument.Sections
For Each hd_ft In sec.Headers
hd_ft.Range.Delete
Next
For Each hd_ft In sec.Footers
hd_ft.Range.Delete
Next
Next sec
End Sub
5. Credit & Disclaimers
I didn’t write the VBA macros. I got them online at these two places:
- https://wordribbon.tips.net/T011693_Setting_Consistent_Column_Widths_in_Multiple_Tables
- https://www.quora.com/How-do-I-automatically-run-a-macro-on-all-Word-files-docx-in-a-folder
- http://vba.relief.jp/word-macro-delete-all-headers-and-footers-active-document/
The example documents shown here are property of the Singapore government: http://www.skillsfuture.sg/skills-framework
Таблица в документе Word создана.
Содержит 17 колонок
Первая должна быть шириной 150 пт
Остальные 24 пт
Как задать ширину колонок в таблице из Excel?
Цепляю весь паровоз сюда до момента , когда нужно начать управление шириной колонок
Visual Basic | ||
|
Добавлено через 17 минут
Чтобы выделить колонку нашел такой способ
Visual Basic | ||
|
Модераторы: Ramzes, Sebas
- vatnick
- Начинающий
-
- Сообщения: 6
- Зарегистрирован: 23.03.2010 (Вт) 22:44
Проблема с шириной столбца таблицы Word
Добрый вечер. Недавно столкнулся с проблемой назначения ширины столбца в таблице word .
Я работаю в Visual Basic 2008 express edition, использую Microsoft Word 11.0 Object Library для соединения с Word. Создаю документ, таблицу, начинаю назначать ширину столбцам. Все, вроде, нормально, но как только подходит момент обработать очередной столбец (сузить до 3 мм = 8,5 point) программа тут же выдает ошибку («COMException was unhandled. Значение лежит вне допустимого диапазона.»). Причем, как я уже проанализировал, «допустимый диапазон» начинается с 11 пунктов (3.88 мм), но почему? Почему? Если я тупо захожу в Word, кликая мышкой, и создав таблицу, могу задать ширину столбца или любой ячейки равной, даже 0,1 мм . Помогите пожалуйста. Может решение лежит под носом, а я его не вижу? Или какие-нибудь есть скрытые нюансы ? Заранее спасибо.
Вот фрагмент кода:
«
- Код: Выделить всё
Private Sub CreateTable(ByVal w As Microsoft.Office.Interop.Word.Document, ByVal r As Microsoft.Office.Interop.Word.Range)
Dim strok As Short = 21 ' Количество строк в таблице
Dim stolb As Short = 18 ' Количество столбцов в таблице
Dim m As Single = 2.834645669213 ' Количество поинтов в миллиметре
w.Tables.Add(w.Paragraphs.Item(w.Paragraphs.Count).Range, strok, stolb) ' Добавляем таблицу в документ
Dim iMax As Integer = w.Tables.Count ' Номер последней таблицы
w.Tables.Item(iMax).LeftPadding = 0
w.Tables.Item(iMax).RightPadding = 0
w.Tables.Item(iMax).TopPadding = 0
w.Tables.Item(iMax).BottomPadding = 0
w.Tables.Item(iMax).Columns(1).Cells.Width = 5 * m ' Начинаем задавать ширину столбцам
w.Tables.Item(iMax).Columns(2).Cells.Width = 7 * m
w.Tables.Item(iMax).Columns(3).Cells.Width = 7 * m
w.Tables.Item(iMax).Columns(4).Cells.Width = 10 * m
w.Tables.Item(iMax).Columns(5).Cells.Width = 3 * m ' <--- Вот эта строка, тут все обрывается :(
w.Tables.Item(iMax).Columns(6).Cells.Width = 23 * m
w.Tables.Item(iMax).Columns(7).Cells.Width = 15 * m
w.Tables.Item(iMax).Columns(8).Cells.Width = 10 * m
w.Tables.Item(iMax).Columns(9).Cells.Width = 25 * m
w.Tables.Item(iMax).Columns(10).Cells.Width = 5 * m
w.Tables.Item(iMax).Columns(11).Cells.Width = 20 * m
w.Tables.Item(iMax).Columns(12).Cells.Width = 20 * m
w.Tables.Item(iMax).Columns(13).Cells.Width = 5 * m
w.Tables.Item(iMax).Columns(14).Cells.Width = 5 * m
w.Tables.Item(iMax).Columns(15).Cells.Width = 5 * m
w.Tables.Item(iMax).Columns(16).Cells.Width = 10 * m
w.Tables.Item(iMax).Columns(17).Cells.Width = 5 * m
w.Tables.Item(iMax).Columns(18).Cells.Width = 20 * m
w.Range.InsertParagraphAfter()
End Sub
«
- viter.alex
- Бывалый
- Сообщения: 221
- Зарегистрирован: 27.07.2008 (Вс) 20:17
- Откуда: Montreal
-
- Сайт
- ICQ
Re: Проблема с шириной столбца таблицы Word
viter.alex » 24.03.2010 (Ср) 14:43
Перед установкой ширины столбца, нужно задать правило, по которому она вычисляется:
- Код: Выделить всё
w.Tables.Item(iMax).Columns.PreferredWidthType=wdPreferredWidthPoints
Миллиметры в поинты переводятся функцией MillimetersToPoints. Её можно вызвать так:
- Код: Выделить всё
w.Application.MillimetersToPoints()
Лучше день потерять — потом за пять минут долететь!
- vatnick
- Начинающий
- Сообщения: 6
- Зарегистрирован: 23.03.2010 (Вт) 22:44
Re: Проблема с шириной столбца таблицы Word
vatnick » 25.03.2010 (Чт) 21:54
Спасибо за советы. Сделал все как сказали, но ошибка осталась. . Что после такого кода
- Код: Выделить всё
w.Tables.Item(iMax).Columns.PreferredWidthType = Microsoft.Office.Interop.Word.WdPreferredWidthType.wdPreferredWidthPoints
w.Tables.Item(iMax).Columns(5).Cells.Width = w.Application.MillimetersToPoints(3)
что без него — к сожалению одно и тоже.
Мне уже кажется, что эту ошибку не убрать вообще, потому что это ограничение связано с возможностями Microsoft Word 11.0 Object Library.
Неужели придется менять намеченный план ?
Последний раз редактировалось vatnick 25.03.2010 (Чт) 22:00, всего редактировалось 1 раз.
- Emzari
- Продвинутый пользователь
- Сообщения: 129
- Зарегистрирован: 06.09.2002 (Пт) 9:08
- Откуда: Georgia
Re: Проблема с шириной столбца таблицы Word
Emzari » 25.03.2010 (Чт) 21:59
а собственно зачем тебе требуется столбец в 3 мм ширину в него вед нормально текст не поместится
- vatnick
- Начинающий
- Сообщения: 6
- Зарегистрирован: 23.03.2010 (Вт) 22:44
Re: Проблема с шириной столбца таблицы Word
vatnick » 25.03.2010 (Чт) 22:25
Дело тут в том, что я создаю форматку для текстового конструкторского документа, у которого ширина столбцов и строк определена нормативными документами. Вы мне скажете, что там и нет такого столбца шириной в 3 мм. Да нет, но тут вступает в силу специфика создания таблицы в Word. Там же нельзя создать таблицу у которой, допустим, в первой строке 2 ячейки, во второй строке 3 ячейки (типа как кирпичная стена), а общее количество столбцов не равно 5. Т.е., создавая таблицу, вначале нужно задать общее количество столбцов и строк, далее назначить для них ширины и высоты, а потом объединять нужные ячейки. Отсюда и проблема. Сам столбец в 3 мм. использоваться не будет, будут использоваться его левые и правые стороны.
- viter.alex
- Бывалый
- Сообщения: 221
- Зарегистрирован: 27.07.2008 (Вс) 20:17
- Откуда: Montreal
-
- Сайт
- ICQ
Re: Проблема с шириной столбца таблицы Word
viter.alex » 25.03.2010 (Чт) 23:44
Я понял! У ячеек этого столбца нужно убрать правые и левые границы. Ширина столбца не может быть меньше, чем сумма правого и левого отступа для текста. Т.е.
- Код: Выделить всё
For Each oCell As Word.Cell In w.Tables.Item(iMax).Columns(5).Cells
oCell.RightPadding = 0
oCell.LeftPadding = 0
Next
А уже потом задавать ширину столбца.
И почему это нельзя сделать «кирпичную стену»? Разбиение ячеек ещё никто не отменял
Лучше день потерять — потом за пять минут долететь!
- vatnick
- Начинающий
- Сообщения: 6
- Зарегистрирован: 23.03.2010 (Вт) 22:44
Re: Проблема с шириной столбца таблицы Word
vatnick » 26.03.2010 (Пт) 0:06
Не выходит опять все таже ошибка. А у Вас, что заработало?
- vatnick
- Начинающий
- Сообщения: 6
- Зарегистрирован: 23.03.2010 (Вт) 22:44
Re: Проблема с шириной столбца таблицы Word
vatnick » 26.03.2010 (Пт) 0:37
Кирпичную стену создать можно, но после разбиения, когда нужно будет задать для них нужные ширину и высоту начнется «непонятный геморой»
- viter.alex
- Бывалый
-
- Сообщения: 221
- Зарегистрирован: 27.07.2008 (Вс) 20:17
- Откуда: Montreal
-
- Сайт
- ICQ
Re: Проблема с шириной столбца таблицы Word
viter.alex » 26.03.2010 (Пт) 9:24
Конечно, заработало. Я бы не говорил, если бы не работало:
- Код: Выделить всё
Imports Microsoft.Office.Interop.Word
Imports Microsoft.Office.Interop
Module Module1Sub Main()
Dim wdApp As New Word.Application
Dim wdDoc As Word.Document
Dim Tbl As Word.Table
wdDoc = wdApp.Documents.Add()
Tbl = wdDoc.Tables.Add(wdDoc.Application.Selection.Range, 5, 5)
For Each ocell As Word.Cell In Tbl.Columns(3).Cells
ocell.RightPadding = 0
ocell.LeftPadding = 0
Next
With Tbl.Columns(3)
.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPoints
.PreferredWidth = wdApp.MillimetersToPoints(3)
End With
wdApp.Visible = True
wdDoc = Nothing : wdApp = Nothing
End SubEnd Module
И вот результат:
Лучше день потерять — потом за пять минут долететь!
- vatnick
- Начинающий
- Сообщения: 6
- Зарегистрирован: 23.03.2010 (Вт) 22:44
Re: Проблема с шириной столбца таблицы Word
vatnick » 26.03.2010 (Пт) 23:16
Спасибо огромное за подробное объяснение. Теперь можно сказать, что проблема с шириной столбца таблицы Word окончательно и бесповоротно РЕШЕНА. Я понял, моя ошибка заключалась в том, что я задавал ширину столбца неправильно.
Я делал так:
«w.Tables.Item(iMax).Columns(5).Cells.Width = 3 * m»,
а надо было так:
«w.Tables.Item(iMax).Columns(5).PreferredWidth= 3 * m»
Еще раз спасибо. Всем удачи!!!
Вернуться в Visual Basic .NET
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1
Создание таблиц в документе Word из кода VBA Excel. Метод Tables.Add, его синтаксис и параметры. Объекты Table, Column, Row, Cell. Границы таблиц и стили.
Работа с Word из кода VBA Excel
Часть 4. Создание таблиц в документе Word
[Часть 1] [Часть 2] [Часть 3] [Часть 4] [Часть 5] [Часть 6]
Таблицы в VBA Word принадлежат коллекции Tables, которая предусмотрена для объектов Document, Selection и Range. Новая таблица создается с помощью метода Tables.Add.
Синтаксис метода Tables.Add
Expression.Add (Range, Rows, Columns, DefaultTableBehavior, AutoFitBehavior) |
Expression – выражение, возвращающее коллекцию Tables.
Параметры метода Tables.Add
- Range – диапазон, в котором будет создана таблица (обязательный параметр).
- Rows – количество строк в создаваемой таблице (обязательный параметр).
- Columns – количество столбцов в создаваемой таблице (обязательный параметр).
- DefaultTableBehavior – включает и отключает автоподбор ширины ячеек в соответствии с их содержимым (необязательный параметр).
- AutoFitBehavior – определяет правила автоподбора размера таблицы в документе Word (необязательный параметр).
Создание таблицы в документе
Создание таблицы из 3 строк и 4 столбцов в документе myDocument без содержимого и присвоение ссылки на нее переменной myTable:
With myDocument Set myTable = .Tables.Add(.Range(Start:=0, End:=0), 3, 4) End With |
Создание таблицы из 5 строк и 4 столбцов в документе Word с содержимым:
With myDocument myInt = .Range.Characters.Count — 1 Set myTable = .Tables.Add(.Range(Start:=myInt, End:=myInt), 5, 4) End With |
Для указания точки вставки таблицы присваиваем числовой переменной количество символов в документе минус один. Вычитаем единицу, чтобы исключить из подсчета последний знак завершения абзаца (¶), так как точка вставки не может располагаться за ним.
Последний знак завершения абзаца всегда присутствует в документе Word, в том числе и в новом без содержимого, поэтому такой код подойдет и для пустого документа.
При создании, каждой новой таблице в документе присваивается индекс, по которому к ней можно обращаться:
myDocument.Tables(индекс) |
Нумерация индексов начинается с единицы.
Отображение границ таблицы
Новая таблица в документе Word из кода VBA Excel создается без границ. Отобразить их можно несколькими способами:
Вариант 1
Присвоение таблице стиля, отображающего все границы:
myTable.Style = «Сетка таблицы» |
Вариант 2
Отображение внешних и внутренних границ в таблице:
With myTable .Borders.OutsideLineStyle = wdLineStyleSingle .Borders.InsideLineStyle = wdLineStyleSingle End With |
Вариант 3
Отображение всех границ в таблице по отдельности:
With myTable .Borders(wdBorderHorizontal) = True .Borders(wdBorderVertical) = True .Borders(wdBorderTop) = True .Borders(wdBorderLeft) = True .Borders(wdBorderRight) = True .Borders(wdBorderBottom) = True End With |
Присвоение таблицам стилей
Вариант 1
myTable.Style = «Таблица простая 5» |
Чтобы узнать название нужного стиля, в списке стилей конструктора таблиц наведите на него указатель мыши. Название отобразится в подсказке. Кроме того, можно записать макрос с присвоением таблице стиля и взять название из него.
Вариант 2
myTable.AutoFormat wdTableFormatClassic1 |
Выбирайте нужную константу с помощью листа подсказок свойств и методов – Auto List Members.
Обращение к ячейкам таблицы
Обращение к ячейкам второй таблицы myTable2 в документе myDocument по индексам строк и столбцов:
myTable2.Cell(nRow, nColumn) myDocument.Tables(2).Cell(nRow, nColumn) |
- nRow – номер строки;
- nColumn – номер столбца.
Обращение к ячейкам таблицы myTable в документе Word с помощью свойства Cell объектов Row и Column и запись в них текста:
myTable.Rows(2).Cells(2).Range = _ «Содержимое ячейки во 2 строке 2 столбца» myTable.Columns(3).Cells(1).Range = _ «Содержимое ячейки в 1 строке 3 столбца» |
В таблице myTable должно быть как минимум 2 строки и 3 столбца.
Примеры создания таблиц Word
Пример 1
Создание таблицы в новом документе Word со сплошными наружными границами и пунктирными внутри:
Sub Primer1() Dim myWord As New Word.Application, _ myDocument As Word.Document, myTable As Word.Table Set myDocument = myWord.Documents.Add myWord.Visible = True With myDocument Set myTable = .Tables.Add(.Range(0, 0), 5, 4) End With With myTable .Borders.OutsideLineStyle = wdLineStyleSingle .Borders.InsideLineStyle = wdLineStyleDot End With End Sub |
В выражении myDocument.Range(Start:=0, End:=0)
ключевые слова Start и End можно не указывать – myDocument.Range(0, 0)
.
Пример 2
Создание таблицы под ранее вставленным заголовком, заполнение ячеек таблицы и применение автосуммы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
Sub Primer2() On Error GoTo Instr Dim myWord As New Word.Application, _ myDocument As Word.Document, _ myTable As Word.Table, myInt As Integer Set myDocument = myWord.Documents.Add myWord.Visible = True With myDocument ‘Вставляем заголовок таблицы .Range.InsertAfter «Продажи фруктов в 2019 году» & vbCr myInt = .Range.Characters.Count — 1 ‘Присваиваем заголовку стиль .Range(0, myInt).Style = «Заголовок 1» ‘Создаем таблицу Set myTable = .Tables.Add(.Range(myInt, myInt), 4, 4) End With With myTable ‘Отображаем сетку таблицы .Borders.OutsideLineStyle = wdLineStyleSingle .Borders.InsideLineStyle = wdLineStyleSingle ‘Форматируем первую и четвертую строки .Rows(1).Range.Bold = True .Rows(4).Range.Bold = True ‘Заполняем первый столбец .Columns(1).Cells(1).Range = «Наименование» .Columns(1).Cells(2).Range = «1 квартал» .Columns(1).Cells(3).Range = «2 квартал» .Columns(1).Cells(4).Range = «Итого» ‘Заполняем второй столбец .Columns(2).Cells(1).Range = «Бананы» .Columns(2).Cells(2).Range = «550» .Columns(2).Cells(3).Range = «490» .Columns(2).Cells(4).AutoSum ‘Заполняем третий столбец .Columns(3).Cells(1).Range = «Лимоны» .Columns(3).Cells(2).Range = «280» .Columns(3).Cells(3).Range = «310» .Columns(3).Cells(4).AutoSum ‘Заполняем четвертый столбец .Columns(4).Cells(1).Range = «Яблоки» .Columns(4).Cells(2).Range = «630» .Columns(4).Cells(3).Range = «620» .Columns(4).Cells(4).AutoSum End With ‘Освобождаем переменные Set myDocument = Nothing Set myWord = Nothing ‘Завершаем процедуру Exit Sub ‘Обработка ошибок Instr: If Err.Description <> «» Then MsgBox «Произошла ошибка: « & Err.Description End If If Not myWord Is Nothing Then myWord.Quit Set myDocument = Nothing Set myWord = Nothing End If End Sub |
Метод AutoSum суммирует значения в ячейках одного столбца над ячейкой с суммой. При использовании его для сложения значений ячеек в одной строке, результат может быть непредсказуемым.
Чтобы просуммировать значения в строке слева от ячейки с суммой, используйте метод Formula объекта Cell:
myTable.Cell(2, 4).Formula («=SUM(LEFT)») |
Другие значения метода Formula, применяемые для суммирования значений ячеек:
- «=SUM(ABOVE)» – сумма значений над ячейкой (аналог метода AutoSum);
- «=SUM(BELOW)» – сумма значений под ячейкой;
- «=SUM(RIGHT)» – сумма значений справа от ячейки.
nested table in WordI have a template which is essentially a 4-row column in Work. Each cell marked with a bookmark. I’ve copied a table from Excel to Word into one of these bookmarks (inside on of the cells). Now I’m trying to format this ‘nested table’ to make it fit according to my desired column widths (for certain columns) but I’m really struggling with the syntax. Additionally, in the table, the first row contains some merged cells (Some are merged to the cell in the adjacent column and some in the row below).
The code I was trying:
With wd.Tables(2)
.Columns(2).Width = 20
End With
But I keep getting «Run-time error ‘5941’: The requested member of the collection does not exist.» Does this mean I am not indexing it properly?
Tabels(2)
is meant to refer to the ‘nested table’ within the larger single column of 4 rows cells.
How do index it properly/find its index?
And how would I change the widths when I have merged cells?
Would I need to:
divide them first>adjust width>re-merge?
Also, I’m doing this in VBA Word, if I reference ‘Microsoft Word xx.0 Object Library’ in excel VBA can I do this in excel?
asked Feb 14, 2017 at 9:51
JoshDJoshD
331 silver badge9 bronze badges
8
I have recreated a nested table like the one in the screen shot; i.e. 1 column with 4 rows, then a nested 14 column/10 row table in row 3.
The following code works just fine for me:
Sub AccessNestedTable()
Dim tbl As Table, tbl2 As Table
Dim wd As Document
Set wd = ActiveDocument
Set tbl = wd.Tables(1)
Set tbl2 = tbl.Tables(1)
With tbl2
.Columns.Width = 20
End With
End Sub
answered Feb 15, 2017 at 11:49
LocEngineerLocEngineer
2,8271 gold badge16 silver badges28 bronze badges
0