Excel VBA to read MS Word comments unique ID - excel

I'm writing an Excel macro to read MS Word comments and put it in a sheet. To do this I'm using this VBA Functions:
Set myWord = New Word.Application
Set myDoc = myWord.Documents.Open(varFile)
For Each thisComment In myDoc.Comments
With thisComment
destSheet.Cells(rowToUse, colToUse + 2).Value = .Range.Text
destSheet.Cells(rowToUse, colToUse + 5).Value = .Scope.Text
End With
rowToUse = rowToUse + 1
Next thisComment
Is there a VBA function that could give me the internal number of the comment? I cannot use INDEX because it gave me the location of the comment inside the collection, and it change if the user insert another comments.
What I need is to be able to identify the comments inside the sheet, so I can Append/Update/Delete comments (specially Update) on the sheet.
I'm using MS Word comments to insert "qualitative coding" info on my documents, controling with added specific info (for each comment) in a Excel sheet.
Warm regards

Related

How can I create an Excel VBA to find/replace text within header/footers in a MS Word Document?

Despite my lack of coding experience and using code stolen from various other posts, I have managed to cobble together an Excel VBA that opens up an existing Word document and then customizes it using values in specific cells in my excel workbook. So for example, the VBA searches the Word document for specified phrases like "[Client Name]" and "[Contract Date]" (and so on), and then replaces them with the specified Excel cell values such as "Bob's Burgers, Inc." and "Jan. 9, 2011" (as the case may be). It works great except the "[Client Name]" in each of the Word document's four Headers are completely ignored by the find/replace process.
In short, I am looking for the snippet of code that would modify the existing macro so that it finds/replaces in the headers/footers at the same time as the main body of the document. If this isn't possible, what would the vba code to add an additional find/replace macro to find each instance of "[Client Name]" in each header and replace with the needed custom phrase from Excel?
Here is the find/replace part of my macro as it currently reads:
Set WA = CreateObject("Word.Application")
WA.Documents.Open (pathh)
WA.Visible = True
For oCell = 1 To 44
from_text = Sheets("ReplaceLIST").Range("A" & oCell).Value
to_text = Sheets("ReplaceLIST").Range("B" & oCell).Value
With WA.ActiveDocument
Set myRange = .Content
With myRange.Find
.Execute FindText:=from_text, ReplaceWith:=to_text, Replace:=2
End With
End With
Next oCell

Excel VBA to loop through cell column and paste in word

What I've done so far :-
1. VBA script to open a template word document. copy the value from column(A1) and paste it in a word document by using the find function.
2. I have done this with two columns for two different locations in a word document.
3. Then, I have saved the document using the value from column(A1).
What I wish to do:-
1. Right now, this runs only for one word document.
2. I wish to run a loop such that I can copy each row into a word document, save it and move onto the next row and save the template word document with a unique name(i.e, from column A)
3. based on the code below, I'm guessing I need two loops, I just can't figure it out and would love some help.
Code I've written so far:-
1. some of them return the function call and didn't think it would be useful, thus I didn't paste it.
Set appWd = CreateObject("Word.Application")
appWd.Visible = True
Set docWD = appWd.Documents.Open("C:\Users\Draft.docx")
'Select Sheet where copying from in excel
Set sheet1 = Sheets("Sheet1")
Set wdFind = appWd.Selection.Find
ClipT = " "
ClipEmpty.SetText ClipT
sheet1.Range("A1").Copy
wdFind.Text = "DateHere"
Call FormatPaste
sheet1.Range("B1").Copy
wdFind.Text = "EntryHere"
Call FormatPaste
saveCell1 = sheet1.Range("B1").Text
dir2 = "C:\Users\" & saveCell1
docWD.SaveAs (dir2 & ".docx")

Extract Data from Word Document to an Excel SpreadSheet

I have a requirement to extract a value from a word document on a daily basis and write it to an excel workbook. I currently do this manually and it is border line regarding the most efficient method for me
Using Excel file create a vba script and add any word document references.
2 Using the word navigate to the table “9. STOCKS...” (extracted example below – Appendix A) and read the Diesel (ltrs) daily usage highlighted in red.
3.Write this value to a spreadsheet cell.
The date for this value is also key but it held in another part of the word document (Appendix B). Dates are also in the file name but we trust the internal value more than the word document name. With knowledge from points 3 and 4 extract the associated date to an adjacent spreadsheet cell.
The table is displayed below, because of the formatting I'm not able to send you the exact table but I will be able to send the values of it.
9.STOCKS (As of 00:01 hrs on Day of report issue).
Stock Held
Daily Usage
Minimum Stock
Diesel (ltrs)
390436
15012
25000
Nitrogen (mm)
35
1
19
Champion 1033 (totes)
15
1
4
Nexguard (Boilers)
4
0.25
4 x 200 ltrs
Appendix B:
Beatrice Period of Report:
00:01 – 24:00 10th August 2010
If you have any doubts regarding my question please get back to me, I appreciate your efforts and wanted to thanks in advance
here's some code making use of late binding (declare objects rather than word.application etc). From Excel 2003, it
opens a WORD document
searches for string "minimum stock"
moves the cursor some lines/words further
expands/selects the WORD cursor
pastes this WORD selection into EXCEL
steps 2-5 are repeated for "Period of report:" (note that the ":" is a word boundary, so we need to jump 8 words to the right to arrive at the date)
For WORD I copied the text from your Q just as is (no table, just plain text). If you use tables instead, you may need to play with the units of the various Move statements (e.g. for cells unit:=12); the strategy remains the same: find a constant text, move cursor to final destination, expand selection, create a word range and transfer.
Both items are placed into the current cell in Excel and its right neighbor.
Sub GrabUsage()
Dim FName As String, FD As FileDialog
Dim WApp As Object, WDoc As Object, WDR As Object
Dim ExR As Range
Set ExR = Selection ' current location in Excel Sheet
'let's select the WORD doc
Set FD = Application.FileDialog(msoFileDialogOpen)
FD.Show
If FD.SelectedItems.Count <> 0 Then
FName = FD.SelectedItems(1)
Else
Exit Sub
End If
' open Word application and load doc
Set WApp = CreateObject("Word.Application")
' WApp.Visible = True
Set WDoc = WApp.Documents.Open(FName)
' go home and search
WApp.Selection.HomeKey Unit:=6
WApp.Selection.Find.ClearFormatting
WApp.Selection.Find.Execute "Minimum Stock"
' move cursor from find to final data item
WApp.Selection.MoveDown Unit:=5, Count:=1
WApp.Selection.MoveRight Unit:=2, Count:=2
' the miracle happens here
WApp.Selection.MoveRight Unit:=2, Count:=1, Extend:=1
' grab and put into excel
Set WDR = WApp.Selection
ExR(1, 1) = WDR ' place at Excel cursor
'repeat
WApp.Selection.HomeKey Unit:=6
WApp.Selection.Find.ClearFormatting
WApp.Selection.Find.Execute "Period of Report:"
WApp.Selection.MoveRight Unit:=2, Count:=8
WApp.Selection.MoveRight Unit:=2, Count:=3, Extend:=1
Set WDR = WApp.Selection
ExR(1, 2) = WDR ' place in cell right of Excel cursor
WDoc.Close
WApp.Quit
End Sub
You can create a button and call that sub from there, or link GrabUsage() to a function key.
I commented out the WApp.Visible = True because in production you don't want WORD even to show up, but you will need it for debugging and playing with the cursor movements.
The disadvantage of late binding (and not using references to the Word library) is the hardcoding of units (6=story, 5=line, 2=word) instead of using Word enumerations, but I sometimes get OS crashes with early binding .... not very sexy but it seems to work.
The FileDialog object needs a reference to the MS Office Office Library. AFAIK this is standard in Excel 2003, but better to check than to crash.
And I didn't include code to check if the items are really found; I leave this to your creativity.
Hope that helps.

Create PowerPoint charts from MS Access queries

I have an Access db to track metrics and "number crunch" data to build PowerPoint presentations. I do about 40 presentations per month, and they are 98% charts.
I run queries one at a time (using SQL statements), take the resulting data and copy it into an Excel template (I made a mock table in this "template" so the chart is already built and formatted), then copy the chart as a picture into a PowerPoint template.
So there is a lot of manual work.
How can I run multiple queries in Access with VBA on the same dataset/table (I have to do sales by quarter, by month, by region, by state, by site and all of these are Top5 aggregate, hence the reasons for the charts), and then send the resulting data to a specific Excel workbook, while defining what goes into what cell range?
If I get all the data into Excel, and have the charts ready to go, is there some VBA that will take the charts from Excel (activeworksheet) and paste them into PowerPoint as pictures in a quad view layout?
Can I do the same thing with an Access to PowerPoint approach and cut out Excel?
I am a novice at best.
You don't need to use Excel at all ! Use MS Access Charts in a report and some VBA code to put them into Powerpoint directly. There is already an example here
One "gotcha" is if you generate graphs in a group ie you design the report with a graph that is inside a group - so when you run the report you will get numerous graphs created.
It is a bit tricky to get hold of each of these graphs and drop them into Powerpoint but here is some code that will take care of it. This works in Access 2003
'Loop through all the controls in this report and pickout all the graphs
For Each c In pReport.Controls
'Graphs initially appear to be in an Object Frame
If TypeOf c Is ObjectFrame Then
'Check the Class of the object to make sure its a Chart
If Left$(c.Class, 13) = "MSGraph.Chart" Then
'Check if this graph must be cloned (required if the graph is in a group in the MS Access report)
If Not IsGraphToBeCloned(pReport.Name, c.ControlName) Then
InsertGraphToPptSlide c, "", pReport.Name
Else
InsertGraphGroupToPpt pReport.Name, c
End If
End If
End If
Next
This will find all the graphs in the report, if the graph is in a group then we call the InsertGraphGroupToPPt function.
The trick here is that we know we have the same base graph multiple times - but populated with different data. So in Powerpoint what you need to do is paste the base graph into powerpoint slides n times - where n is the number of groups and then update the graphs query properties
eg
Function UpdateGraphInPowerpoint(sql As String, OrigGraph As ObjectFrame, Groups As dao.Recordset, GroupName As String, ReportName As String) As Boolean
//Copyright Innova Associates Ltd, 2009
On Error GoTo ERR_CGFF
On Error GoTo ERR_CGFF
Dim oDataSheet As DataSheet
Dim Graph As Graph.Chart
Dim lRowCnt, lColCnt, lValue As Long, CGFF_FldCnt As Integer
Dim CGFF_Rs As dao.Recordset
Dim CGFF_field As dao.Field
Dim CGFF_PwrPntloaded As Boolean
Dim lheight, lwidth, LLeft, lTop As Single
Dim slidenum As Integer
Dim GraphSQL As String
Dim lGrpPos As Long
'Loop thru groups
Do While Not Groups.EOF
'We want content to be added to the end of the presentation - so find out how many slides we already have
slidenum = gPwrPntPres.Slides.Count
OrigGraph.Action = acOLECopy 'Copy to clipboard
slidenum = slidenum + 1 'Increment the Ppt slide number
gPwrPntPres.Slides.Add slidenum, ppLayoutTitleOnly 'Add a Ppt slide
'On Error Resume Next 'Ignore errors related to Graph caption
gPwrPntPres.Slides(slidenum).Shapes(1).TextFrame.TextRange.Text = ReportName & vbCrLf & "(" & Groups.Fields(0).Value & ")" 'Set slide title to match graph title
gPwrPntPres.Slides(slidenum).Shapes(1).TextFrame.TextRange.Font.Size = 16
gPwrPntPres.Slides(slidenum).Shapes.Paste 'Paste graph into ppt from clipboard
Set Graph = gPwrPntPres.Slides(slidenum).Shapes(2).OLEFormat.Object
Set oDataSheet = Graph.Application.DataSheet ' Set the reference to the datasheet collection.
oDataSheet.Cells.Clear ' Clear the datasheet.
GraphSQL = Replace(sql, "<%WHERE%>", " where " & GroupName & " = '" & Groups.Fields(0).Value & "'")
Set CGFF_Rs = ExecQuery(GraphSQL)
CGFF_FldCnt = 1
' Loop through the fields collection and get the field names.
For Each CGFF_field In CGFF_Rs.Fields
oDataSheet.Cells(1, CGFF_FldCnt).Value = CGFF_Rs.Fields(CGFF_FldCnt - 1).Name
CGFF_FldCnt = CGFF_FldCnt + 1
Next CGFF_field
lRowCnt = 2
' Loop through the recordset.
Do While Not CGFF_Rs.EOF
CGFF_FldCnt = 1
' Put the values for the fields in the datasheet.
For Each CGFF_field In CGFF_Rs.Fields
oDataSheet.Cells(lRowCnt, CGFF_FldCnt).Value = IIf(IsNull(CGFF_field.Value), "", CGFF_field.Value)
CGFF_FldCnt = CGFF_FldCnt + 1
Next CGFF_field
lRowCnt = lRowCnt + 1
CGFF_Rs.MoveNext
Loop
' Update the graph.
Graph.Application.Update
DoEvents
CGFF_Rs.Close
DoEvents
Groups.MoveNext
Loop
UpdateGraphInPowerpoint = True
Exit Function
End Function
Since you are a novice, perhaps you should break the task down into parts and automate the parts one at a time. Each step will provide benefits (i.e. time savings) and you can learn as you go.
It is hard to make specific recommendations based upon lack of specific information (what version etc.). That having been said, perhaps a good first step would be to link the Excel tables to the access queries so that the spreadsheets can auto-update every month and you will not have to cut and paste data from Access into Excel. You can do this linking entirely within Excel.
If you are using Excel 2007 click on "Data" in the Ribbon and then click on "From Access".
What you're asking is a lot of work:
Via VBA you'd have to open Excel (Excel Application manipulation from Access) , update your charts (Range manipulation, Data Update) if you have the rights then I would suggest having your pivot charts connected to the Access data and not pasted into the workbook, nevertheless I've been in enough situations where that was not possible. Then you would have to open your PowerPoint presentation and copy from the Excel to the PowerPoint. I've done all of these and know how much work it can save by creating a macro (via VBA) to do this. It's a lot of code.

Creating tables for copy from Word to Excel

So, I needed to take some data done in MS Word tables, and manipulate in excel.
I decided to get it from word to excel via a VBA subroutine to "save time".
My source word document contained like twentysomething tables.
I took my source document's tables, extracted my data and made a new document, with a new table, only needing me to copy and paste it into excel.
However, while the final table before copy looks good in word. When i copy it to excel, it breaks up the cells that contain whole paragraphs into separate cells.
As most excel peeps would know, even though a solution looks like in excel, doing a merge and center - that only preserves the content in the uppermost cell in the selection!
So, any advice, on either a better merge and center, or a better "time saver" alltogether, would be great.
Here's a sample of the code so far:
Sub First()
Dim tableLength, tableIndex
tableLength = ThisDocument.Tables.Count
Dim tblReport As Table
Dim docReport As Document
Set docReport = Documents.Add
Set tblReport = docReport.Tables.Add(Selection.Range, 1, 2)
With tblReport
Dim fieldOne, subvalueAription, subvalueA, subvalueB, subvalueC
For tableIndex = 1 To tableLength
fieldOne = ThisDocument.Tables(tableIndex).Rows(2).Cells(2).Range.Text
subvalueA = Trim(ThisDocument.Tables(tableIndex).Rows(4).Cells(2).Range.Text)
subvalueB = "A: " & Trim(ThisDocument.Tables(tableIndex).Rows(5).Cells(2).Range.Text)
subvalueC = "B: " & Trim(ThisDocument.Tables(tableIndex).Rows(6).Cells(2).Range.Text)
subvalueAription = subvalueA & subvalueB & subvalueC & "C: "
Dim rowNext As row
Set rowNext = .Rows.Add
rowNext.Cells(1).Range.Text = fieldOne
rowNext.Cells(2).Range.Text = subvalueA & subvalueB & subvalueC
Next
End With
End Sub
Excel uses a different line terminator than Word. In order to avoid the problem with the text from the Word table being split over several Excel cells, you need to handle the line terminator conversion yourself.
'Word > Excel
newText = Replace(wordText, vbCrLf, vbLf)
I'm posting this by memory, but that's the root of that problem.

Resources