Exporting Table of Contents from Word to Excel - vba

I am looking for a way to get the table of contents (not created but headings available) from word and store the chapter numbers and headings on Excel. Is there a method using Excel VBA to take those headings from word doc to excel? I have searched for this but everybody suggest using paste special however I want it automated since the data from TOC is sorted into a different table in Excel afterwards.
Sub importwordtoexcel()
MsgBox ("This Macro Might Take a While, wait until next Message")
Application.ScreenUpdating = False
Sheets("Temp").Cells.Clear
'Import all tables to a single sheet
Dim wdDoc As Object
Dim wdFileName As Variant
Dim TableNo As Integer 'table number in Word
Dim iRow As Long 'row index in Word
Dim jRow As Long 'row index in Excel
Dim iCol As Integer 'column index in Excel
wdFileName = Application.GetOpenFilename("Word files (*.docx),*.docx", , _
"Browse for file containing table to be imported")
If wdFileName = False Then Exit Sub '(user cancelled import file browser)
Set wdDoc = GetObject(wdFileName) 'open Word file
With wdDoc
If wdDoc.Tables.Count = 0 Then
MsgBox "This document contains no tables", _
vbExclamation, "Import Word Table"
Else
jRow = 0
For TableNo = 1 To wdDoc.Tables.Count
With .Tables(TableNo)
'copy cell contents from Word table cells to Excel cells
For iRow = 1 To .Rows.Count
jRow = jRow + 1
For iCol = 1 To .Columns.Count
On Error Resume Next
Sheets("Temp").Cells(jRow, iCol) = WorksheetFunction.Clean(.Cell(iRow, iCol).Range.Text)
On Error GoTo 0
Next iCol
Next iRow
End With
jRow = jRow + 1
Next TableNo
End If
End With
Set wdDoc = Nothing
'Takes data from temp to RTM_FD
Dim nRow As Long
Dim mRow As Long
Dim Temp As Worksheet
Dim RTM As Worksheet
Set Temp = Sheets("Temp")
Set RTM = Sheets("RTM_FD")
mRow = 16
For nRow = 1 To Temp.Rows.Count
If Temp.Cells(nRow, 1).Value = "Position" Or Temp.Cells(nRow, 1).Value = "" Then
Else
RTM.Cells(mRow, 1).Value = Temp.Cells(nRow, 1)
RTM.Cells(mRow, 2).Value = Temp.Cells(nRow, 4)
RTM.Cells(mRow, 2).Font.Bold = False
RTM.Cells(mRow, 3).Value = Temp.Cells(nRow, 5)
RTM.Cells(mRow, 3).Font.ColorIndex = 32
If Temp.Cells(nRow, 3).Value = "P" Then
RTM.Cells(mRow, 9).Value = "X"
RTM.Cells(mRow, 9).Interior.ColorIndex = 44
ElseIf Temp.Cells(nRow, 3) = "Q" Then
RTM.Cells(mRow, 7).Value = "X"
RTM.Cells(mRow, 7).Interior.ColorIndex = 44
ElseIf Temp.Cells(nRow, 3) = "TA" Then
RTM.Cells(mRow, 8).Value = "X"
RTM.Cells(mRow, 8).Interior.ColorIndex = 44
Else
End If
mRow = mRow + 1
End If
Next nRow
Application.ScreenUpdating = True
MsgBox ("DONE")
Sheets("Temp").Cells.Clear
Dim SaveName As String
SaveName = InputBox("What Do You Want to Save the File As:")
ActiveWorkbook.SaveAs (SaveName)
MsgBox ("Your file is saved as " & SaveName)
MsgBox ("Please Accept Delete Operation")
Sheets("Temp").Delete
ActiveWorkbook.Save
End Sub

One way to get section headings without creating a TOC is by iterating with the selection object, using Selection.Goto. The folowing example prints all the sections headings in a document to the immediate window. I am sure you can adapt the concept to your code.
Sub PrintHeadings()
Dim wrdApp As Word.Application
Dim wrdDoc As Document
Dim Para As Paragraph
Dim oldstart As Variant
Set wrdApp = CreateObject("Word.Application") 'open word
Set wrdDoc = wrdApp.Documents.Open("C:\sample.docx", , True, False, , , , , , , , True) 'open file
wrdDoc.ActiveWindow.ActivePane.View.Type = wdPrintView 'avoids crashing if opens on read view
With wrdDoc.ActiveWindow.Selection
.GoTo What:=wdGoToHeading, which:=wdGoToFirst 'go to first heading
Do
Set Para = .Paragraphs(1) 'get first paragraph
Title = Replace(Para.Range.Text, Chr(13), "") 'gets title and remove trailing newline
Debug.Print Title, "pg. "; .Information(wdActiveEndAdjustedPageNumber) 'prints title and page to console
oldstart = .Start 'stores position
.GoTo What:=wdGoToHeading, which:=wdGoToNext 'go to next heading
If .Start <= oldstart Then Exit Do 'if looped around to first section (i.e. new heading is before old heading) we are done
Loop
End With
wrdDoc.Close
wrdApp.Quit
Set Para = Nothing
Set wrdDoc = Nothing
Set wrdApp = Nothing
End Sub
I use early binding, so you will need to either add a reference to Word object model, or tweak the code to late binding (including finding out the numeric value of the enums).

I worked fine with My Chinese words documents, it may require to change some of the codes for different heading style.
If it won't work for you, I would love to have your words sample file and figure out why.
PS: The key point is to have the correct #OLE_LINK format.
My codes is as follows:
' Get your file and save in Range("A1")
Public Sub SelectAFile()
Dim intChoice As Integer
Dim strPath As String
'only allow the user to select one file
Application.FileDialog(msoFileDialogOpen).AllowMultiSelect = False
'make the file dialog visible to the user
intChoice = Application.FileDialog(msoFileDialogOpen).Show
'determine what choice the user made
If intChoice <> 0 Then
'get the file path selected by the user
strPath = Application.FileDialog( _
msoFileDialogOpen).SelectedItems(1)
'print the file path to sheet 1
Cells(1, 1) = strPath
End If
End Sub
' Main program start here
Sub genWordIndex()
Dim rng As Range
Dim r As Range
Dim PageName As String
Dim TestValue As String
Dim WshShell As Variant
Set WshShell = CreateObject("WScript.Shell")
Set rng = Range("A1") 'Selection
Call CleanOldText(1)
PageName = rng.text
Call ReadIndexFromWords3(PageName)
End Sub
Sub ReadIndexFromWords3(ByVal FileName As String)
'
' This is a common routine for handling open file
'
Dim WA As Object
Dim wdDoc As Word.Document
On Error Resume Next
Set WA = GetObject(, "Word.Application")
If WA Is Nothing Then
Set WA = CreateObject("Word.Application")
Set wdDoc = WA.Documents.Open(FileName)
Else
On Error GoTo notOpen
Set wdDoc = WA.Documents(FileName)
GoTo OpenAlready
notOpen:
Set wdDoc = WA.Documents.Open(FileName)
End If
OpenAlready:
wdDoc.Activate
'
' read index program start here。
'
Dim i As Integer: i = 2
Dim H_start, H_end, H_Caption, H_lvl, H_page As String
Dim H_txt As String
Dim Para As Paragraph
For Each Para In wdDoc.Paragraphs
Para.Range.Select
If Not Para.Range.Style Is Nothing Then
If IsMyHeadingStype(Para.Range.Style) = True Then
H_start = Para.Range.Start
H_end = Para.Range.End
H_txt = Para.Range.text
H_Caption = Para.Range.ListFormat.ListString
H_page = Para.Range.Information(wdActiveEndPageNumber)
Dim myLinkAddress As String
myLinkAddress = FileName & "#OLE_LINK" & i & vbTab & "1," & H_start & "," & H_end & ",2,," & H_txt
Application.ActiveWorkbook.Activate
ActiveSheet.Cells(i, 1).Select
Dim CapLen As Integer:
CapLen = Len(H_Caption) - 1
If CapLen < 0 Then CapLen = 0
ActiveSheet.Cells(i, 1) = Space(CapLen) & H_Caption & " " & H_txt
ActiveCell.Hyperlinks.Add Anchor:=Selection, Address:=myLinkAddress, SubAddress:="" 'TextToDisplay:=H_txt,
ActiveSheet.Cells(i, 2) = H_page
i = i + 1
End If
End If
Next
End Sub
'
' you may have to change your InStyle here
'
Function IsMyHeadingStype(ByVal InStyle As String) As Boolean
Dim rc As Boolean: rc = False
If InStr(InStyle, "標題 1") Or InStr(InStyle, "標題 2") Or InStr(InStyle, "標題 3") Then
rc = True
End If
IsMyHeadingStype = rc
End Function
' sub routine
Sub CleanOldText(ByVal col1 As Integer)
Dim i As Integer
Dim lastR As Integer
lastR = Cells(10000, col1).End(xlUp).Row
For i = 2 To lastR
Cells(i, col1).ClearContents
Cells(i, col1 + 1).ClearContents
Next i
End Sub

Related

vba read the content of a footer out of a word document

I need to get the content out of the footer section of a word document. Especially I need to transfer the content of a table inside the footer section into an excel document. I'd already do this with tables from the body section of a word document. How can I get the content of the footer section into an other worksheet or be added to the existing worksheet with the content of the body of the document?
Sub ImportWordTable()
Dim sPfad As String
Dim appWord As Object
Dim strDatei As String
Dim TableNo As Integer 'table number in Word
Dim iRow As Long 'row index in Word
Dim jRow As Long 'row index in Excel
Dim iCol As Integer 'column index in Excel
sPfad = "C:\Users\tim\Test2\" '<== adjust path
Application.ScreenUpdating = False
Set appWord = CreateObject("Word.Application")
appWord.Visible = True
strDatei = Dir(sPfad & "*.doc*")
Do While strDatei <> ""
appWord.Documents.Open sPfad & strDatei
'Read all tables of the document body
If appWord.ActiveDocument.tables.Count = 0 Then
MsgBox "This document contains no tables", _
vbExclamation, "Import Word Table"
Else
jRow = 0
Sheets.Add after:=Sheets(Worksheets.Count)
ActiveSheet.Name = strDatei & "Label-Text"
For TableNo = 1 To appWord.ActiveDocument.tables.Count
With appWord.ActiveDocument.tables(TableNo)
'copy cell contents from Word table cells to Excel cells
For iRow = 1 To .Rows.Count
jRow = jRow + 1
For iCol = 1 To .Columns.Count
On Error Resume Next
ActiveSheet.Cells(jRow, iCol) = WorksheetFunction.Clean(.cell(iRow, iCol).Range.Text)
On Error GoTo 0
Next iCol
Next iRow
End With
jRow = jRow + 1
Next TableNo
End If
appWord.ActiveDocument.Close savechanges:=False
strDatei = Dir
Loop
appWord.Quit
Set appWord = Nothing
End Sub
To get a table in the footer section of word, use:
appWord.ActiveDocument.Sections(1).Footers(1).Range.Tables.Count
and
With appWord.ActiveDocument.Sections(1).Footers(1).Range.Tables(TableNo)
ps. Footers(1) = Footers(wdHeaderFooterPrimary) but you don't have this constant defined when driving word with late binding.

transfer data from word to excel via vba

I have a form in ms word with some of the fields are content control and some (which are the radio buttons) are ActiveX control. I want to automatically transfer hundred word forms to an excel file. I use the following vba code:
Sub getWordFormData()
Dim wdApp As New Word.Application
Dim myDoc As Word.Document
Dim CCtl As Word.ContentControl
Dim myFolder As String, strFile As String
Dim myWkSht As Worksheet, i As Long, j As Long
myFolder = "C:\Users\alarfajal\Desktop\myform"
Application.ScreenUpdating = False
If myFolder = "" Then Exit Sub
Set myWkSht = ActiveSheet
ActiveSheet.Cells.Clear
Range("A1") = "name"
Range("a1").Font.Bold = True
Range("B1") = "age"
Range("B1").Font.Bold = True
Range("C1") = "gender"
Range("C1").Font.Bold = True
Range("D1") = "checkbox1"
Range("D1").Font.Bold = True
Range("E1") = "checkbox2"
Range("E1").Font.Bold = True
Range("F1") = "singlechoice1"
Range("F1").Font.Bold = True
Range("G1") = "singlechoice2"
Range("G1").Font.Bold = True
i = myWkSht.Cells(myWkSht.Rows.Count, 1).End(xlUp).Row
strFile = Dir(myFolder & "\*.docx", vbNormal)
While strFile <> ""
i = i + 1
Set myDoc = wdApp.Documents.Open(Filename:=myFolder & "\" & strFile, AddToRecentFiles:=False, Visible:=False)
With myDoc
j = 0
For Each CCtl In .ContentControls
j = j + 1
myWkSht.Cells(i, j) = CCtl.Range.Text
Next
myWkSht.Columns.AutoFit
End With
myDoc.Close SaveChanges:=False
strFile = Dir()
Wend
wdApp.Quit
Set myDoc = Nothing: Set wdApp = Nothing: Set myWkSht = Nothing
Application.ScreenUpdating = True
End Sub
all the data (text fields, checkbox) are transferred successfully but, the radio button (which is ActiveX) is not transferred.
This is the word doc:
This is the excel result:
How can I solve this problem?
You can refer to an ActiveX control on a Word document by it's name
myDoc.singlechoice1.Value
It is better to refer to the ContentControls by their tag names.
myDoc.SelectContentControlsByTag("name").Item(1).Range.Text
Refactored Code
Sub getWordFormData()
Dim wdApp As Object, myDoc As Object
Dim myFolder As String, strFile As String
Dim i As Long, j As Long
myFolder = "C:\Users\alarfajal\Desktop\myform"
If Len(Dir(myFolder)) = 0 Then
MsgBox myFolder & vbCrLf & "Not Found", vbInformation, "Cancelled - getWordFormData"
Exit Sub
End If
Application.ScreenUpdating = False
Set wdApp = CreateObject("Word.Application")
With ActiveSheet
.Cells.Clear
With .Range("A1:G1")
.Value = Array("name", "age", "gender", "checkbox1", "checkbox2", "singlechoice1", "singlechoice2")
.Font.Bold = True
End With
strFile = Dir(myFolder & "\*.docx", vbNormal)
i = 1
While strFile <> ""
i = i + 1
Set myDoc = wdApp.Documents.Open(Filename:=myFolder & "\" & strFile, ReadOnly:=True, AddToRecentFiles:=False, Visible:=False)
.Cells(i, 1).Value = myDoc.SelectContentControlsByTag("name").Item(1).Range.Text
.Cells(i, 2).Value = myDoc.SelectContentControlsByTag("age").Item(1).Range.Text
.Cells(i, 3).Value = myDoc.SelectContentControlsByTag("gender").Item(1).Range.Text
.Cells(i, 4).Value = myDoc.SelectContentControlsByTag("checkbox1").Item(1).Checked
.Cells(i, 5).Value = myDoc.SelectContentControlsByTag("checkbox2").Item(1).Checked
.Cells(i, 6).Value = myDoc.singlechoice1.Value
.Cells(i, 7).Value = myDoc.singlechoice2.Value
myDoc.Close SaveChanges:=False
strFile = Dir()
Wend
wdApp.Quit
Application.ScreenUpdating = True
End With
End Sub
Your radiobuttons are inlineshapes so you need a separate loop for them
to keep in line with your current code, it would be something like
Dim shp As InlineShape
For Each shp In .InlineShapes
j = j + 1
myWkSht.Cells(i, j) = shp.OLEFormat.Object.Value
Next shp
However I wouldn't want to rely on Word always giving me the right order and there could be other inlineshapes so it might be better to check the controls first:
With myDoc
'content controls
For Each CCtl In .ContentControls
Select Case CCtl.Title
Case "name"
myWkSht.Cells(i, 1) = CCtl.Range.Text
'similar for age and gender
Case "checkbox1"
myWkSht.Cells(i, 4) = CCtl.Checked 'true and false are easier to evaluate in Excel than the checkmark symbols
'same for checkbox 2
End Select
Next CCtl
'option buttons
For Each shp In .InlineShapes
If shp.Type = wdInlineShapeOLEControlObject Then 'skip other inlineshapes
Select Case shp.OLEFormat.Object.Name
Case "singleSelectQuestionOption1" 'name it something unique
myWkSht.Cells(i, 6) = shp.OLEFormat.Object.Value
'similar for option button 2
End Select
End If
Next shp
End With

Paste not working between Excel and Word through VBA

I have a workbook which creates Word reports based on a Word template and tables in the workbook.
Depending on the equipment type, it copies a range from the spreadsheet and pastes it to two bookmark locations in the word document (bmInternal and bmExternal). I tried using PasteAppendTable, but this only works once. If I try to use it twice, for each bookmark, it copies nothing both times. As such I used Paste for one and PasteAppendTable for the second (PasteAppendTable is much neater as the formatting is better).
This worked fine, but I made changes to the code, not related to this, and now the Paste (which goes to bmInternal) isn't working. I can't see why when I've not changed anything regarding that part:
Sub Data2Word()
Application.GoTo Reference:=ActiveSheet.Range("A2")
GoAgain:
On Error Resume Next
Dim vItem As String
'Dim vImagePath As String
Dim vCurrentRow As Integer
Dim vDesc As String
Dim vN2 As String
Dim vGuide As String
Dim vUnit As String
Dim vBlock As String
Dim wrdPic As Word.InlineShape
Dim rng As Excel.Range 'our source range
Dim rngText As Variant
Dim rngText2 As Variant
Dim wdApp As New Word.Application 'a new instance of Word
Dim wdDoc As Word.Document 'our new Word template
Dim myWordFile As String 'path to Word template
Dim wsExcel As Worksheet
Dim tmpAut
'Find Item and type
vItem = ActiveCell.Value
vDesc = ActiveCell.Offset(0, 2)
vN2 = ActiveCell.Offset(0, 1)
vGuide = ActiveCell.Offset(0, 3)
vBlock = ActiveCell.Offset(0, 4)
vUnit = Left(vItem, 3)
If ActiveSheet.Range("rngREPORTED") = "Yes" Then
MsgBox vItem & " already has a report."
Exit Sub
End If
'initialize the Word template path
'here, it's set to be in the same directory as our source workbook
myWordFile = "W:\Entity\Inspect\WORD\INSPECTION TEMPLATES\Inspection Template - 20160511.dotx"
'open a new word document from the template
Set wdDoc = wdApp.Documents.Add(myWordFile)
If vGuide = "IGE01" Then
rngText = "rngEXCH"
rngText2 = "rngEXCHE"
ElseIf ActiveCell.Offset(, 4) = "Mono" Then
'Do Mono
rngText = "rngMONO"
Else
ActiveWorkbook.Names.Add Name:="rngItemSub", RefersTo:=Worksheets("SubEquipment").Range("B" & ActiveCell.Offset(0, 6) & ":C" & ActiveCell.Offset(0, 7) + ActiveCell.Offset(0, 6))
CarryOn:
rngText = "rngItemSub"
End If
'Insert Tables
'get the range of the data
Set rng = Range(rngText)
rng.Copy 'copy the range
wdDoc.Bookmarks("bmInternal").Range.Paste 'AppendTable
If vGuide = "IGE01" Then
Set rng = Range(rngText2)
rng.Copy
End If
wdDoc.Bookmarks("bmExternal").Range.PasteAppendTable
wdDoc.Bookmarks("bmItem").Range.InsertAfter vItem
wdDoc.Bookmarks("bmDesc").Range.InsertAfter vDesc
wdDoc.Bookmarks("bmN2").Range.InsertAfter vN2
wdDoc.Bookmarks("bmGuide").Range.InsertAfter vGuide
wdDoc.Bookmarks("bmBlock").Range.InsertAfter vBlock
wdDoc.Variables("wvItem").Value = vItem
ActiveDocument.Fields.Update
With wdDoc
Set wrdPic = .Bookmarks("bmImage").Range.InlineShapes.AddOLEObject(ClassType:="AcroExch.Document.7", Filename:="W:\Entity\Inspect\T&I\2016\Various Items\Photos\Sorted\" & vItem & ".pdf", LinkToFile:=False, DisplayAsIcon:=False)
wrdPic.ScaleHeight = 55
wrdPic.ScaleWidth = 55
End With
wdApp.Visible = True
wdApp.Activate
wdDoc.SaveAs "W:\Entity\Inspect\WSDATA\REPORTS\2016\" & vUnit & "\" & vItem & " " & vN2 & " THO.docx" 'Mid(ActiveDocument.Name, 1, Len(ActiveDocument.Name) - 4)
MoveHere:
ActiveWorkbook.Sheets("AllItems").Range("G" & ActiveCell.Offset(0, 8)).Value = "Yes"
ActiveWorkbook.Save
End Sub
I think DocVariables are easier to use that Bookmarks. Do a quick Google search on Word DocVariables. Get things setup correct in Word, and then run the script below.
Sub PushToWord()
Dim objWord As New Word.Application
Dim doc As Word.Document
Dim bkmk As Word.Bookmark
sWdFileName = Application.GetOpenFilename(, , , , False)
Set doc = objWord.Documents.Open(sWdFileName)
'On Error Resume Next
objWord.ActiveDocument.variables("FirstName").Value = Range("FirstName").Value
objWord.ActiveDocument.variables("LastName").Value = Range("LastName").Value
objWord.ActiveDocument.variables("AnotherVariable").Value = Range("AnotherVariable").Value
objWord.ActiveDocument.Fields.Update
'On Error Resume Next
objWord.Visible = True
End Sub

Excel Macro to give report title based on Cell Value

I am very new to macro programming and currently creating a macro that splits a table into new worksheets dependent on a unique variable, then copies and pastes each worksheet into a single word document split by page breaks.
What I cannot work out how to do, is create a macro that gives each table on each page a title based on the value of a cell.
Option Explicit
Sub Run_All()
Call Organise_Table
Call Rename_Column
Call Isblank
Call Split_Table
Call SumColumn
Call ExceltoWord
Call Report_Title
End Sub
Sub Organise_Table()
Columns(1).EntireColumn.Delete
Columns(1).EntireColumn.Delete
Columns(2).EntireColumn.Delete
Columns(3).EntireColumn.Delete
Columns(3).EntireColumn.Delete
End Sub
Sub Rename_Column()
Range("A1") = "Contribution Type"
Range("B1") = "RefNo"
Range("C1") = "Title"
Range("D1") = "Initals"
Range("E1") = "Surname"
Range("F1") = "Balance Brought Forward"
Range("G1") = "Annual Interest Added"
Range("H1") = "Contributions Added"
Range("I1") = "Total Fund Value"
End Sub
Sub Isblank()
Application.ScreenUpdating = False
On Error Resume Next
With Range("F1:I14")
.SpecialCells(xlCellTypeBlanks).Formula = "0"
.Value = .Value
End With
Err.Clear
Application.ScreenUpdating = True
End Sub
Sub Split_Table()
Dim lr As Long
Dim Ws As Worksheet
Dim vcol As Integer
Dim i As Integer
Dim iCol As Long
Dim myarr As Variant
Dim Title As String
Dim titlerow As Integer
vcol = 2
Set Ws = Sheets("Sheet1")
Title = "A1:I14"
Application.ScreenUpdating = False
lr = Ws.Cells(Ws.Rows.Count, vcol).End(xlUp).Row
titlerow = Ws.Range(Title).Cells(1).Row
iCol = Ws.Columns.Count
Ws.Cells(1, iCol) = "Unique"
For i = 2 To lr
On Error Resume Next
If Ws.Cells(i, vcol) <> "" And Application.WorksheetFunction.Match(Ws.Cells(i, vcol), Ws.Columns(iCol), 0) = 0 Then
Ws.Cells(Ws.Rows.Count, iCol).End(xlUp).Offset(1) = Ws.Cells(i, vcol)
End If
Next i
myarr = Application.WorksheetFunction.Transpose(Ws.Columns(iCol).SpecialCells(xlCellTypeConstants))
Ws.Columns(iCol).Clear
For i = 2 To UBound(myarr)
Ws.Range(Title).AutoFilter field:=vcol, Criteria1:=myarr(i) & ""
If Not Evaluate("=ISREF('" & myarr(i) & "'!A1)") Then
Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = myarr(i) & ""
Else
Sheets(myarr(i) & "").Move after:=Worksheets(Worksheets.Count)
End If
Ws.Range("A" & titlerow & ":A" & lr).EntireRow.Copy Sheets(myarr(i) & "").Range("A1")
Sheets(myarr(i) & "").Columns.AutoFit
Next i
Ws.AutoFilterMode = False
Ws.Activate
End Sub
Sub SumColumn()
Dim LastRow As Long
Dim iRow As Long
Dim iCol As Integer
Dim nSheets As Integer
For nSheets = 1 To 3
With Worksheets(nSheets)
LastRow = 0
For iCol = 6 To 9
iRow = .Cells(65536, iCol).End(xlUp).Row
If iRow > LastRow Then LastRow = iRow
Next iCol
For iCol = 6 To 9
.Cells(LastRow + 1, iCol) = Application.WorksheetFunction.Sum(Range(.Cells(1, iCol), .Cells(LastRow, iCol)))
Next iCol
iCol = 1
.Cells(LastRow + 1, iCol).Value = ("Total")
End With
Next nSheets
End Sub
Sub ExceltoWord()
Dim Ws As Worksheet
Dim Wkbk1 As Workbook
Dim strdocname As String
Dim wdapp As Object
Dim wddoc As Object
Dim orng As Object
Dim wdAutoFitwindow As String
Set Wkbk1 = ActiveWorkbook
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.EnableEvents = False
strdocname = "\\VDC.COM\User\HomeDrives\GFSNRE\Desktop\Test19.Doc" 'Change this to whatever directory the report will be in
'file name & folder path
On Error Resume Next
'error number 429
Set wdapp = GetObject(, "Word.Application")
If Err.Number = 429 Then
Err.Clear
'create new instance of word application
Set wdapp = CreateObject("Word.Application")
End If
wdapp.Visible = True
'define paths to file
If Dir(strdocname) = "" Then
'MsgBox "The file" & strdocname & vbCrLf & "was not found " & vbCrLf & "C:\Path\Name.doc", _
' vbExclamation, "The document does not exist "
'Exit Sub
Set wddoc = wdapp.Documents.Add
Else
Set wddoc = wdapp.Documents.Open(strdocname)
End If
For Each Ws In Wkbk1.Worksheets
Ws.Range("A1:I14").Copy
Set orng = wddoc.Range
orng.collapse 0
orng.Paste
orng.End = wddoc.Range.End
orng.collapse 0
orng.insertbreak Type:=7
Range("A1:I14").Borders.LineStyle = xlContinuous
wddoc.AutofitBehavior wdAutoFitwindow
Next Ws
lbl_Exit:
Set orng = Nothing
Set wddoc = Nothing
Set wdapp = Nothing
Set Wkbk1 = Nothing
Set Ws = Nothing
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.EnableEvents = True
Exit Sub
End Sub
Sub Report_Title()
Dim Ws As Worksheet
Dim MyText As String
Dim MyRange As Object
Set MyRange = ActiveWorkbook.Range
MyText = Ws.Range("E3").Value
' Selection Example:
Selection.InsertBefore (MyText)
' Range Example: Inserts text at the beginning
' of the active document.
MyRange.InsertBefore (MyText)
End Sub
There is one error here :
Dim Ws As Worksheet
Dim MyText As String
Dim MyRange As Object
Set MyRange = ActiveWorkbook.Range
MyText = Ws.Range("E3").Value '<==== WS is not properly defined yet
You are using Ws. to say in which worksheet you are working in, which is a good thing. But, as it is a procedure-level variable, it is not pointing anywhere useful. You probably need something like :
Set MyRange = ActiveWorkbook.Range
Set Ws = ActiveWorkbook.Sheets("Sheet1") 'assuming you want to read "E3" on the sheet "Sheet1" of the active workbook, that's the line to add
MyText = Ws.Range("E3").Value '<==== WS is now properly defined
If you go to debugging mode, you should have nothing in "MyText" in your version, and something in mine. The content of E3 in the sheet Sheet1.
Two things:
You should not turn off error handling for the entire code. If
things aren't working VBA can't tell you why or where the problem
is. While it's standar practise to use On Error Resume Next when
using GetObject/CreateObject it's also standard practise to turn
error handling back on AFTER the If...End If. You need to add the
line: On Error GoTo 0 where you have no error handler code.
Based on your sample code, write in the Title before pasting the table.
So something like this:
For Each Ws In Wkbk1.Worksheets
Ws.Range("A1:I14").Copy
Set orng = wddoc.Range
orng.collapse 0
orng.Text = Ws.Range([cell reference with title]) & vbCr
orng.collapse 0
orng.Paste
orng.End = wddoc.Range.End
orng.collapse 0
orng.insertbreak Type:=7
Range("A1:I14").Borders.LineStyle = xlContinuous
wddoc.AutofitBehavior wdAutoFitwindow
Next Ws

VBA code to read tables from Word document

Need help to modify this VBA code to read multiple tables from a Word document. It only reads one table, but I would like to import more than one into the same Excel sheet.
Sub ImportWordTables()
'Imports a table from Word document
Dim wdDoc As Object
Dim wdFileName As Variant
Dim TableNo As Integer 'number of tables in Word doc
Dim iTable As Integer 'table number index
Dim iRow As Long 'row index in Excel
Dim iCol As Integer 'column index in Excel
wdFileName = Application.GetOpenFilename("Word files (*.doc*),*.doc*", , _
"Browse for file containing table to be imported")
If wdFileName = False Then Exit Sub '(user cancelled import file browser)
Set wdDoc = GetObject(wdFileName) 'open Word file
With wdDoc
TableNo = wdDoc.tables.Count
If TableNo = 0 Then
MsgBox "This document contains no tables", _
vbExclamation, "Import Word Table"
ElseIf TableNo > 1 Then
TableNo = InputBox("This Word document contains " & TableNo & " tables." & vbCrLf & _
"Enter table number of table to import", "Import Word Table", "1")
End If
With .tables(TableNo)
'copy cell contents from Word table cells to Excel cells
For iRow = 1 To .Rows.Count
For iCol = 1 To .Columns.Count
Cells(iRow, iCol) = WorksheetFunction.Clean(.cell(iRow, iCol).Range.Text)
Next iCol
Next iRow
End With
End With
Set wdDoc = Nothing
End Sub
So this is the code, but it doesn't entirely answer my questions.
I just need the tables from the pdf.
Sub Imp_Into_XL(PDF_File As String, Each_Sheet As Boolean)
'This procedure get the PDF data into excel by following way
'1.Open PDF file
'2.Looping through pages
'3.get the each PDF page data into individual _
sheets or single sheet as defined in Each_Sheet Parameter
Dim AC_PD As Acrobat.AcroPDDoc 'access pdf file
Dim AC_Hi As Acrobat.AcroHiliteList 'set selection word count
Dim AC_PG As Acrobat.AcroPDPage 'get the particular page
Dim AC_PGTxt As Acrobat.AcroPDTextSelect 'get the text of selection area
Dim WS_PDF As Worksheet
Dim RW_Ct As Long 'row count
Dim Col_Num As Integer 'column count
Dim Li_Row As Long 'Maximum rows limit for one column
Dim Yes_Fir As Boolean 'to identify beginning of page
Li_Row = Rows.Count
Dim Ct_Page As Long 'count pages in pdf file
Dim i As Long, j As Long, k As Long 'looping variables
Dim T_Str As String
Dim Hld_Txt As Variant 'get PDF total text into array
RW_Ct = 0 'set the intial value
Col_Num = 1 'set the intial value
Application.ScreenUpdating = False
Set AC_PD = New Acrobat.AcroPDDoc
Set AC_Hi = New Acrobat.AcroHiliteList
'set maximum selection area of PDF page
AC_Hi.Add 0, 32767
With AC_PD
'open PDF file
.Open PDF_File
'get the number of pages of PDF file
Ct_Page = .GetNumPages
'if get pages is failed exit sub
If Ct_Page = -1 Then
MsgBox "Pages Cannot determine in PDF file '" & PDF_File & "'"
.Close
GoTo h_end
End If
'add sheet only one time if Data retrive in one sheet
If Each_Sheet = False Then
Set WS_PDF = Worksheets.Add(, Worksheets(Sheets.Count))
WS_PDF.Name = "PDF3Text"
End If
'looping through sheets
For i = 1 To Ct_Page
T_Str = ""
'get the page
Set AC_PG = .AcquirePage(i - 1)
'get the full page selection
Set AC_PGTxt = AC_PG.CreateWordHilite(AC_Hi)
'if text selected successfully get the all the text into T_Str string
If Not AC_PGTxt Is Nothing Then
With AC_PGTxt
For j = 0 To .GetNumText - 1
T_Str = T_Str & .GetText(j)
Next j
End With
End If
If Each_Sheet = True Then
'add each sheet for each page
Set WS_PDF = Worksheets.Add(, Worksheets(Sheets.Count))
End If
'transfer PDF data into sheet
With WS_PDF
If Each_Sheet = True Then
.Name = "Page-" & i
'get the PDF data into each sheet for each PDF page
'if text accessed successfully then split T_Str by VbCrLf
'and get into array Hld_Txt and looping through array and fill sheet with PDF data
If T_Str <> "" Then
Hld_Txt = Split(T_Str, vbCrLf)
For k = 0 To UBound(Hld_Txt)
T_Str = CStr(Hld_Txt(k))
If Left(T_Str, 1) = "=" Then T_Str = "'" & T_Str
.Cells(k + 1, 1).Value = T_Str
Next k
Else
'information if text not retrive from PDF page
.Cells(1, 1).Value = "No text found in page " & i
End If
Else
'get the pdf data into single sheet
If T_Str <> "" Then
Hld_Txt = Split(T_Str, vbCrLf)
Yes_Fir = True
For k = 0 To UBound(Hld_Txt)
RW_Ct = RW_Ct + 1
'check begining of page if yes enter PDF page number for any idenfication
If Yes_Fir Then
RW_Ct = RW_Ct + 1
.Cells(RW_Ct, Col_Num).Value = "Text In Page - " & i
RW_Ct = RW_Ct + 2
Yes_Fir = False
End If
'check for maximum rows if exceeds start from next column
If RW_Ct > Li_Row Then
RW_Ct = 1
Col_Num = Col_Num + 1
End If
T_Str = CStr(Hld_Txt(k))
If Left(T_Str, 1) = "=" Then T_Str = "'" & T_Str
.Cells(RW_Ct, Col_Num).Value = T_Str
Next k
Else
RW_Ct = RW_Ct + 1
.Cells(RW_Ct, Col_Num).Value = "No text found in page " & i
RW_Ct = RW_Ct + 1
End If
End If
End With
Next i
.Close
End With
Application.ScreenUpdating = True
MsgBox "Imported"
h_end:
Set WS_PDF = Nothing
Set AC_PGTxt = Nothing
Set AC_PG = Nothing
Set AC_Hi = Nothing
Set AC_PD = Nothing
End Sub
You can use this to do something with each table in the document:
Dim oTbl As Table
For Each oTbl In ActiveDocument.Tables
' Do something
Debug.Print oTbl.Columns.Count & " " & oTbl.Rows.Count
Next
You'll need to figure out how you want the user to specify which table/tables to work with.
Something like this, perhaps:
Sub UserChosenTables()
Dim oTbl As Table
Dim sTemp As String
Dim aTables() As String
Dim x As Long
sTemp = InputBox("Which tables", "Select tables")
If Len(sTemp) = 0 Then ' user entered nothing
Exit Sub
End If
aTables = Split(sTemp, ",")
' of course you'll want to add more code to CYA in case the user
' asks for a table that's not there or otherwise enters something silly.
' You might also want to let them enter e.g. ALL if they want you to do all of them
' (but don't know how many there are)
For x = LBound(aTables) To UBound(aTables)
Set oTbl = ActiveDocument.Tables(CLng(aTables(x)))
' do [whatever] with table here
Debug.Print oTbl.Columns.Count & " " & oTbl.Rows.Count
Next
End Sub