so I am having this problem. I want to create a table in Word using VBA , but every time I do it creates a table with this weird grey border; I want it to look like a normal table. Here is my code I am using
Sub MakeATable()
Dim actdoc As Document
Dim newtbl As Table
Set actdoc = ActiveDocument
Set myrange = actdoc.Range(0, 0)
Set newtbl = actdoc.Tables.Add(myrange, 10, 2, wdWord9Behavior)
End Sub
I tired adding in the following to get the table to be a normal style but adding it did not work either
newtbl.Style = Normal
What is so weird is that I get no problem at all with the following code
Sub MakeATable()
Dim actdoc As Document
Dim newtbl As Table
Set actdoc = ActiveDocument
Set myrange = actdoc.Range(0, 0)
actdoc.Tables.Add Range:=myrange, NumRows:=10, NumColumns:=2, DefaultTableBehavior:=wdWord9TableBehavior
Can anyone please help me or at least explain what is going on?
Thank you
In your first listing, replace
wdWord9Behavior
with
wdWord9TableBehavior
Related
I want to access tables from a word document and I got a method that uses its index. But for my project, it arises confusion so I want to use their names as we can do in excel using this.
Set tbl = oExcelWorksheet.ListObjects("Table2").Range
But in word to access a table I only found this command
Set oTable = ActiveDocument.Tables("1")
Is there any other command in word VBA through which I can use the table name to access the table and not the index.
As #Timothy correctly pointed out in the comments, tables in word don't have names.
One way around is to bookmark the first cell (or any other cell) of each table with the name you want to give the table
Then you can use this bookmark to locate your table. For example you can use this function (I used suggestion from here) [Please see Edit1 below]
Function GetTable(sTableName As String) As Table
Dim sCell_1_Range As Range
With ThisDocument
On Error Resume Next
Set sCell_1_Range = .Bookmarks(sTableName).Range
If Err.Number > 0 Then Exit Function ' table not found
On Error GoTo 0
Set GetTable = .Tables(.Range(0, sCell_1_Range.End).Tables.Count)
End With
End Function
and use it like this
Sub TestTableWithName()
Dim myTable As Table
Set myTable = GetTable("SecondTable")
If Not myTable Is Nothing Then
myTable.Range.Select
End If
End Sub
Edit1
#freeflow suggested a much better implementation of the function
Function GetTable(sTableName As String) As Table
On Error Resume Next
Set GetTable = ThisDocument.Bookmarks(sTableName).Range.Tables(1)
End Function
Which means - depending on your coding style - you might not even need to use a function. Just remember to use On Error GoTo 0 if you use it directly
what I normally do is give unique title to the table in table properties of the table.
Then use a custom function.
Sub getTableByTitle()
Dim doc As Document
Dim tbl As Table
Set tbl = getTable("Tb1")
End Sub
Public Function getTable(s As String) As Table
Dim tbl As Table
For Each tbl In ActiveDocument.Tables
If tbl.Title = s Then
Set getTable = tbl
Exit Function
End If
Next
End Function
I am a beginner. I have been trying to teach myself VBA and researching this question for two weeks, including reviewing all the relevant answers on this forum. I give up!
I am trying to loop through the rows of a table to select a table row based on the content of one of the row's cells (naming a particular column). I want to use the name of the table column. But something is wrong with my "If ... Then" statement. I get errors with every attempt. Right now I get a compile error "Expected Then or Go To," with the period before Value highlighted. But I have a feeling that if I fixed that error there would be another one right behind it. What am I getting wrong, besides trying to learn this on my own? ;>)
Thanks in advance!
Sub CommandButton1_Click()
Dim tbl As ListObject
Dim x As Long
Set tbl = ActiveSheet.ListObjects("Table1")
For x = 1 To tbl.Range.Rows.Count
If (Range("Table1[Status]")).Value = "Completed"
'I can't seem to find the right statement to put between If and .Value!
Rows(x).Select
End If
Next x
End Sub
Change If (Range("Table1[Status]")).Value = "Completed" to If (Range("Table1[Status]").Value) = "Completed" Then. Your .Value just needed to be put in the brackets. I would also highly suggest looking into the Rubberduck add-in for VBA. It has an Auto Indenter so your code always looks in order.
Sub CommandButton1_Click()
Dim tbl As ListObject
Dim x As Long
Dim myRange As Range
Set tbl = ActiveSheet.ListObjects("Table1")
For x = 1 To tbl.Range.Rows.Count
If tbl.DataBodyRange(x, Range("Table1[Status]").Column) = "Completed" Then
If myRange Is Nothing Then
Set myRange = tbl.ListRows(x).Range
Else
Set myRange = Union(myRange, tbl.ListRows(x).Range)
End If
End If
Next x
myRange.Select
End Sub
I have code that is supposed to update the style of the tables in a Word document and then change the width to 17cm.
Sub ConvertTables()
Dim tbl As Table
For Each tbl In ActiveDocument.Tables
tbl.Style = "K2 Table"
Next
Selection.Tables(1).PreferredWidthType = wdPreferredWidthPoints
Selection.Tables(1).PreferredWidth = CentimetersToPoints(17)
End Sub
When I run the macro, it stops at the second part. Sometimes it will run in the VB viewer but never from running the macro through the Developer.
What is wrong with this piece of VBA?
Try this
Dim tbl As Table
For Each tbl In ActiveDocument.Tables
tbl.Style = "K2 Table"
tbl.PreferredWidthType = wdPreferredWidthPoints
tbl.PreferredWidth = CentimetersToPoints(17)
Next
I'm guessing the second part doesn't work when you don't have a table selected
I have issues with my code dealing with tables, specifically I want the code to ignore them. I do not want this code to apply to tables so I thouht that I'd use "Selection.Information(wdWithInTable) = False" to clear things up. Unfortunately I don't know how to select the paragraph that the script is currently working.
I tried putting Selection.Paragraphs(i).Range.Select in at the **** but that didn't eliminate working with the first row of a table and I don't know why. I'm new to VBA and syntax in general so I'm assuming that's the issue.
Dim prePara As Paragraph
Dim curPara As Paragraph
Dim nextPara As Paragraph
For i = 2 To ActiveDocument.Paragraphs.Count
Set prePara = ActiveDocument.Paragraphs(i - 1)
Set curPara = ActiveDocument.Paragraphs(i)
If curPara.LeftIndent <= prePara.LeftIndent And curPara.Style = "Normal" Or curPara.Style = "List Paragraph" Then
***** 'here is where I tried Selection.Paragraphs(n).Range.Select but it didn't work
If Selection.Information(wdWithInTable) = False Then
If curPara.LeftIndent < prePara.LeftIndent Then
curPara.LeftIndent = prePara.LeftIndent
End If
End If
End If
Next
With this statement:
Selection.Paragraphs(i).Range.Select
you are trying to Select a Selection object.
Try:
ActiveDocument.Paragraphs(i).Range.Select
I'm trying to use Word 2010 to create a template for a programming project test plan. I've created a mockup template showing what I want to do.
What I'd like to be able to do is be able to click on something on the Word ribbon, and have the template generate the next test table and sequence the caption. Once the table is generated, I would fill in the table fields for the test.
Could someone tell me what to look up in the Word help or elsewhere so I can create this template?
I personally would create a macro for this or you can embed it in your template with code to add menu items and add something like the following. (It's very rough but you can use it to generate a table with your layout and numeric ascending numbers), it is not as dynamic as knowing where the previous test left off but should be a start point.)
Dim iCount As Integer
iCount = CInt(InputBox("How many tables?", "Table Count", 1))
For icurtable = 1 To iCount
Dim oTableRange As Paragraph
Dim oTable As Table
Dim oCaption As Paragraph
Set oCaption = ActiveDocument.Paragraphs.Add
Call oCaption.Range.InsertBefore(CStr(icurtable))
Set oTableRange = ActiveDocument.Paragraphs.Add
Set oTable = oTableRange.Range.Tables.Add(oTableRange.Range, 4, 1, True, True)
oTable.Rows.First.Cells(1).Range.InsertBefore ("Setup:")
oTable.Rows(2).Cells(1).Range.InsertBefore ("Test:")
oTable.Rows(3).Cells(1).Range.InsertBefore ("Expected Response:")
oTable.Rows(4).Cells(1).Range.InsertBefore ("Restore")
Call oTableRange.Range.InsertAfter(vbCrLf)
Next
In case someone else comes across this question, I'll provide my solution. I decided to create a table inside of a table so the test case number will be on the left, where people expect to see it.
Using Sacha's answer as a model, and making liberal use of the macro recorder, I came up with this VBA macro that does most of what I want.
Sub InsertTestTable()
'
' InsertTestTable Macro
' This macro inserts a test table into the document.
'
Dim oTable As Table
Dim iTable As Table
Set oTable = ActiveDocument.Tables.Add(Selection.Range, 1, 2, _
wdWord9TableBehavior, wdAutoFitContent)
Selection.TypeText ("1.")
Selection.MoveRight
Set iTable = ActiveDocument.Tables.Add(Selection.Range, 4, 2, _
wdWord9TableBehavior, wdAutoFitContent)
iTable.Rows(1).Cells(1).Range.InsertBefore ("Setup:")
iTable.Rows(2).Cells(1).Range.InsertBefore ("Test:")
iTable.Rows(3).Cells(1).Range.InsertBefore ("Expected Response:")
iTable.Rows(4).Cells(1).Range.InsertBefore ("Restore:")
iTable.Rows(1).Cells(2).Range.Select
End Sub
Now, all I need to do is format the tables the way I want, and figure out how to have the number ascend through the set of tables in the document.