OneNote2013-Reference to undeclared namespace prefix:'one' error - excel

started with OneNote vba today, so got samples program over the net to try out. Made basic changes to the following (which creates a new page in OneNote) as I have OneNote 2013. But every program I try to run returns the error -
Reference to undeclared namespace prefix:'one' error (for the lines marked in bold).
Can anyone let me know what am I doing wrong here. I need to get an assignment done through which I could run OCR for a printscreen and get the data back to excel but to start with that i thought it would be a good thing to get the basics right. It has taken an entire day and I still cannot make anything work.
By the way references for Onenote 15.0 object library and xml v6.0 have been made. I'm a beginner in VBA and any help is appreciated.
Sub CreateNewPage()
' Connect to OneNote 2013.
' To see the results of the code,
' you'll want to ensure the OneNote 2013 user
' interface is visible.
Dim OneNote As OneNote.Application
Set OneNote = New OneNote.Application
' Get all of the Notebook nodes.
Dim nodes As MSXML2.IXMLDOMNodeList
Set nodes = GetFirstOneNoteNotebookNodes(OneNote)
If Not nodes Is Nothing Then
' Get the first OneNote Notebook in the XML document.
Dim node As MSXML2.IXMLDOMNode
Set node = nodes(0)
Dim noteBookName As String
noteBookName = node.Attributes.getNamedItem("name").Text
' Get the ID for the Notebook so the code can retrieve
' the list of sections.
Dim notebookID As String
notebookID = node.Attributes.getNamedItem("ID").Text
' Load the XML for the Sections for the Notebook requested.
Dim sectionsXml As String
OneNote.GetHierarchy notebookID, hsSections, sectionsXml, xs2013
Dim secDoc As MSXML2.DOMDocument60
Set secDoc = New MSXML2.DOMDocument60
If secDoc.LoadXML(sectionsXml) Then
' select the Section nodes
Dim secNodes As MSXML2.IXMLDOMNodeList
Set secNodes = secDoc.DocumentElement.SelectNodes("//one:Section")
If Not secNodes Is Nothing Then
' Get the first section.
Dim secNode As MSXML2.IXMLDOMNode
Set secNode = secNodes(0)
Dim sectionName As String
sectionName = secNode.Attributes.getNamedItem("name").Text
Dim sectionID As String
sectionID = secNode.Attributes.getNamedItem("ID").Text
' Create a new blank Page in the first Section
' using the default format.
Dim newPageID As String
OneNote.CreateNewPage sectionID, newPageID, npsDefault
' Get the contents of the page.
Dim outXML As String
OneNote.GetPageContent newPageID, outXML, piAll, xs2013
Dim doc As MSXML2.DOMDocument60
Set doc = New MSXML2.DOMDocument60
' Load Page's XML into a MSXML2.DOMDocument object.
If doc.LoadXML(outXML) Then
' Get Page Node.
Dim pageNode As MSXML2.IXMLDOMNode
Set pageNode = doc.SelectSingleNode("//one:Page")
' Find the Title element.
Dim titleNode As MSXML2.IXMLDOMNode
Set titleNode = doc.SelectSingleNode("//one:Page/one:Title/one:OE/one:T")
' Get the CDataSection where OneNote store's the Title's text.
Dim cdataChild As MSXML2.IXMLDOMNode
Set cdataChild = titleNode.SelectSingleNode("text()")
' Change the title in the local XML copy.
cdataChild.Text = "A Page Created from VBA"
' Write the update to OneNote.
OneNote.UpdatePageContent doc.XML
Dim newElement As MSXML2.IXMLDOMElement
Dim newNode As MSXML2.IXMLDOMNode
' Create Outline node.
Set newElement = doc.createElement("one:Outline")
Set newNode = pageNode.appendChild(newElement)
' Create OEChildren.
Set newElement = doc.createElement("one:OEChildren")
Set newNode = newNode.appendChild(newElement)
' Create OE.
Set newElement = doc.createElement("one:OE")
Set newNode = newNode.appendChild(newElement)
' Create TE.
Set newElement = doc.createElement("one:T")
Set newNode = newNode.appendChild(newElement)
' Add the text for the Page's content.
Dim cd As MSXML2.IXMLDOMCDATASection
Set cd = doc.createCDATASection("Text added to a new OneNote page via VBA.")
newNode.appendChild cd
' Update OneNote with the new content.
OneNote.UpdatePageContent doc.XML
' Print out information about the update.
Debug.Print "A new page was created in "
Debug.Print "Section " & sectionName & " in"
Debug.Print "Notebook " & noteBookName & "."
Debug.Print "Contents of new Page:"
Debug.Print doc.XML
End If
Else
MsgBox "OneNote 2013 Section nodes not found."
End If
Else
MsgBox "OneNote 2013 Section XML Data failed to load."
End If
Else
MsgBox "OneNote 2013 XML Data failed to load."
End If
End Sub
Private Function GetAttributeValueFromNode(node As MSXML2.IXMLDOMNode, attributeName As String) As String
If node.Attributes.getNamedItem(attributeName) Is Nothing Then
GetAttributeValueFromNode = "Not found."
Else
GetAttributeValueFromNode = node.Attributes.getNamedItem(attributeName).Text
End If
End Function
Private Function GetFirstOneNoteNotebookNodes(OneNote As OneNote.Application) As MSXML2.IXMLDOMNodeList
' Get the XML that represents the OneNote notebooks available.
Dim notebookXml As String
' OneNote fills notebookXml with an XML document providing information
' about what OneNote notebooks are available.
' You want all the data and thus are providing an empty string
' for the bstrStartNodeID parameter.
OneNote.GetHierarchy "", hsNotebooks, notebookXml, xs2013
' Use the MSXML Library to parse the XML.
Dim doc As MSXML2.DOMDocument60
Set doc = New MSXML2.DOMDocument60
If doc.LoadXML(notebookXml) Then
**Set GetFirstOneNoteNotebookNodes = doc.DocumentElement.SelectNodes("//one:Notebook")**
Else
Set GetFirstOneNoteNotebookNodes = Nothing
End If
End Function

Use
doc.SetProperty "SelectionNamespaces", "xmlns:one='http://schemas.microsoft.com/office/onenote/2013/onenote'"
before you call the SelectNodes method, to specify your namespace.

you need to specify a namespace. "one:" is not a namespace, it is just an alias for one.
your XML document should have something like xmlns:one="http://schemas.microsoft.com/office/onenote/12/2004/onenote"
at the top.
the namespace is what I have bolded above.
check the MSXML API docs to see how to specify a namespace when you do a query.

Related

Lotusscript: Retrieve the images in the body of an email

In my agent, I try to retrieve all the files that are in the current email. My attached code works fine, except for the images in the body of the email. I manage to retrieve all the files and images that were attached to the email except the pictures that were copied and pasted in the middle of the email text. Here is my code:
Dim session As New NotesSession
Dim doc As NotesDocument
Dim db As NotesDatabase
Dim item As Variant
Dim CurrentDocColl As NotesDocumentCollection
Set db = Session.Currentdatabase
Set CurrentDocColl = db.Unprocesseddocuments
Set doc = CurrentDocColl.Getfirstdocument
While Not doc Is Nothing
Set item = doc.GETFIRSTITEM("Body")
If doc.HasEmbedded Then
ForAll attachment In item.EmbeddedObjects
Call attachment.ExtractFile (pathname & "\" & attachment.Name)
End ForAll
End If
Set doc=CurrentDocColl.Getnextdocument(doc)
Wend
How can I retrieve these images?
Thank you very much for your help
I have an agent that does a lot of that, but it's not short. What you have to do is run the document through an XML DomParser, walk down the DOM tree and when you find a node with "JPEG" or "PNG" in the name (the inline images themselves), stream the data to a file and save it. The code is combination of an agent I found online (which I couldn't find again, otherwise I would give credit) and work I've done. You won't be able to copy/paste this sample code and expect it to work, I've removed things (like declaring variables and supporting functions) for brevity.
Sub Initialize
Dim dxlExp As NotesDXLExporter
Set dxlExp = s.CreateDXLExporter
Call dxlExp.setInput(Doc)
Set DomParser=s.CreateDOMparser()
Call DomParser.Setinput(dxlExp)
Dim dxlImp As NotesDXLImporter
Set dxlImp = s.Createdxlimporter()
Call dxlImp.Setinput(domParser)
Call dxlImp.SetOutput(db)
On Event PostDomParse From DomParser Call DomInputProcessed
Call dxlExp.Process
End Sub
Sub DomInputProcessed(DomParser As NotesDomParser)
Dim DomNode As NotesDomNode
Set DomNode = DomParser.Document
Call walkTree(DomParser, DomNode)
Exit Sub
End Sub
Sub walkTree (DomParser As NotesDOMParser, node As NotesDOMNode)
Select Case node.NodeType
Case DOMNODETYPE_DOCUMENT_NODE: ' If it is a Document node
domParser.Output( "<?xml version='1.0' encoding='utf-8'?>"+LF )
Set child = node.FirstChild ' Get the first node
Dim numChildNodes As Integer
numChildNodes = node.NumberOfChildNodes
While numChildNodes > 0
Set child = child.NextSibling ' Get next node
numChildNodes = numChildNodes - 1
Call walkTree(DOMParser, child)
Wend
Case DOMNODETYPE_DOCUMENTTYPE_NODE: ' It is a <!DOCTYPE> tag
domParser.Output("<!DOCTYPE "+ node.NodeName+ ">" + LF)
Case DOMNODETYPE_TEXT_NODE: ' Plain text node
value = xmlReplace(node.NodeValue)
domParser.Output(value)
Case DOMNODETYPE_ELEMENT_NODE: ' Most nodes are Elements
Select Case node.NodeName
Case "jpeg"
Dim jpegfile As String
' Step 1, write the MIME file
Dim base64node As NotesDOMNode
Set base64Node = node.Firstchild
Dim base64Out As NotesStream
Set base64Out = s.createStream()
Dim bytesWritten As Long
bytesWritten = base64Out.Writetext(base64Node.NodeValue)
' Step 2, Read the MIME file and decode it.
Set db=s.currentdatabase
Set doc=db.createDocument()
Set m=doc.Createmimeentity("Image1")
Call m.setContentFromText(base64Out, "image/jpeg", 1727)
Call m.Decodecontent()
Dim JPEGOut As NotesStream
Set JPEGOut = s.createStream()
jpegFile = RandomFileName(baseDir, ".jpg")
JPEGOut.open(jpegFile)
Call m.Getcontentasbytes(JPEGOut, True)
Call JPEGOut.Close()
attachmentNamesStr = attachmentNamesStr + jpegFile + "~"
' Step 3, remove the jpeg and its child node
' We do this by just not sending anything to the DomParser output.
Case "png"
' Same as JPEG except it's PNG.
End Select
End Select 'node.NodeType
End If 'Not node.IsNull
End Sub

Sending an email using VBA and IBM Lotus Notes

I know about topics dealing with similar problem but none of them solves directly my problem (or at least I don't see it). I am using following code:
Sub SendEmailUsingCOM()
'*******************************************************************************************
' Unlike OLE automation, one can use Early Binding while using COM
' To do so, replace the generic "object" by "commented" UDT
' Set reference to: Lotus Domino Objects
'*******************************************************************************************
Dim nSess As Object 'NotesSession
Dim nDir As Object 'NotesDbDirectory
Dim nDb As Object 'NotesDatabase
Dim nDoc As Object 'NotesDocument
Dim nAtt As Object 'NotesRichTextItem
Dim vToList As Variant, vCCList As Variant, vBody As Variant
Dim vbAtt As VbMsgBoxResult
Dim sFilPath As String
Dim sPwd As String
'*******************************************************************************************
'To create notesession using COM objects, you can do so by using.
'either ProgID = Lotus.NotesSession
'or ClsID = {29131539-2EED-1069-BF5D-00DD011186B7}
'Replace ProgID by the commented string below.
'*******************************************************************************************
Set nSess = CreateObject("Lotus.NotesSession") 'New:{29131539-2EED-1069-BF5D-00DD011186B7}
'*******************************************************************************************
'This part initializes the session and creates a new mail document
'*******************************************************************************************
sPwd = Application.InputBox("Type your Lotus Notes password!", Type:=2)
Call nSess.Initialize(sPwd)
Set nDir = nSess.GetDbDirectory("")
Set nDb = nDir.OpenMailDatabase
Set nDoc = nDb.CreateDocument
'*******************************************************************************************
'If you want to send it to multiple recipients then use variant array to get the names from
'the specified range as below
'Add / Remove Comment mark from vCCList as per your needs.
'*******************************************************************************************
vToList = Application.Transpose(Range("A1").Resize(Range("A" & Rows.Count).End(xlUp).Row).Value)
vCCList = Application.Transpose(Range("B1").Resize(Range("B" & Rows.Count).End(xlUp).Row).Value)
'*******************************************************************************************
'If you want to send it to multiple recipients then use variant array to get the names from
'the specified range as below
'Add / Remove Comment mark from vCCList as per your needs.
'*******************************************************************************************
With nDoc
Set nAtt = .CreateRichTextItem("Body")
Call .ReplaceItemValue("Form", "Memo")
Call .ReplaceItemValue("Subject", "Test Lotus Notes Email using COM")
With nAtt
.AppendText (Range("C2").Value)
'Decide if you want to attach a file.
vbAtt = MsgBox("Do you want to attach document?", vbYesNo, "Attach Document")
Select Case vbAtt
Case 6
.AddNewLine
.AppendText ("********************************************************************")
.AddNewLine
sFilPath = Application.GetOpenFilename
Call .EmbedObject(1454, "", sFilPath) '1454 = Constant for EMBED_ATTACHMENT
Case 7
'Do Nothing
End Select
End With
Call .ReplaceItemValue("CopyTo", vCCList)
Call .ReplaceItemValue("PostedDate", Now())
Call .Send(False, vToList)
End With
End Sub
The code stops at Set nSess = CreateObject("Lotus.NotesSession") saying Run-time error 429: ActiveX component can't create object
I saw some discussions about missing nnotes.dll but when I try to add it using Tools>References> and browse to the nnotes.dll file, it says "Can't add a reference to the specified file"
For sure I miss some basic knowledge, but I would just love to make it work and send specific ranges in excel via email.
Do you know, ideally step by step, what I should do?

How do I copy the contents of one word document to the end of another using vba?

Goal for my project:
I want to be able to copy the contents of one document and append that selection to the end of another document.
What it does... (this is just background info so you understand why I am trying to do this):
I am trying to dynamically produce a document which quotes a variety of information regarding different parts and materials involved for a product.
The document itself has a consistent format which I have broken down and separated into two documents. The first contains a bunch of data that needs to be entered manually, and is where I want to append all additional content. The second contains roughly a dozen custom fields which are updated from an excel spreadsheet in VBA. For a single part and as a single doc this works as I want it (my base case). However my issue is when there are multiple parts for a project.
The Problem:
For multiple parts I have to store information in an array which changes in size dynamically as each additional part is added. When someone has added all the necessary parts they can select a button called "Create Quote".
Create quote runs a procedure which creates/opens separate copies of the two template documents mentioned above (saved on my computer). It then iterates through the array of parts and updates all the custom field in the 2nd document (no problems). Now I just need the contents of the 2nd document appended to the end of the first which is my problem.
What I want:
Ideally, my procedure will continue to iterate through every part in the array - updating custom fields, copy then paste the updated text, repeat... Until every part is included in the newly generated quote.
What I Tried - this code can be found in my generate quote procedure
I have tried many of the examples and suggestions provided by people who had similar question, but I don't know if its because I am operating from an excel doc, but many of their solution have not worked for me.
This is my most recent attempt and occurs after each iteration of the for loop
wrdDoc2.Fields.Update 'Update all the fields in the format document
wrdDoc2.Activate
Selection.WholeStory ' I want to select the entire document
Selection.Copy ' Copy the doc
wrdDoc1.Activate ' Set focus to the target document
Selection.EndKey wdStory ' I want the selection to be pasted to the end of the document
Selection.PasteAndFormat wdPasteDefault
QUOTE PROCEDURE - I am only including a handful of the fields I am updating because its not necessary to show them all
Private Sub quote_button_Click()
On Error GoTo RunError
Dim wrdApp1, wrdApp2 As Word.Application
Dim wrdDoc1, wrdDoc2 As Word.Document
Set wrdApp1 = CreateObject("Word.Application")
Set wrdApp2 = CreateObject("Word.Application")
wrdApp1.Visible = True
wrdApp2.Visible = True
Set wrdDoc1 = wrdApp1.Documents.Add(Template:="C:\MWES\AQT_v1.1(start).docm", NewTemplate:=False, DocumentType:=0)
Set wrdDoc2 = wrdApp2.Documents.Add(Template:="C:\MWES\AQT_v2.1(format).docm", NewTemplate:=False, DocumentType:=0)
Dim propName As String
For i = LBound(part_array, 1) To UBound(part_array, 1)
For Each prop In wrdDoc2.CustomDocumentProperties
propName = prop.name
' Looks for and sets the property name to custom values of select properties
With wrdDoc2.CustomDocumentProperties(propName)
Select Case propName
Case "EST_Quantity"
.value = part_array(i, 0) ' "QTY" ' Sheet1.Cells(1, 3) 'NA
Case "EST_Metal_Number"
.value = part_array(i, 1) ' "METAL_#" ' Sheet1.Cells(2, 3) 'NA"
Case "EST_Metal_Name"
.value = part_array(i, 2) ' "METAL_N" ' Sheet1.Cells(5, 2)
End Select
End With
Next prop ' Iterates until all the custom properties are set
wrdDoc2.Fields.Update 'Update all the fields in the format document
wrdDoc2.Activate
Selection.WholeStory ' I want to select the entire document
Selection.Copy ' Copy the doc
wrdDoc1.Activate ' Set focus to the target document
Selection.EndKey wdStory ' I want the selection to be pasted to the end of the document
Selection.PasteAndFormat wdPasteDefault
Next i ' update the document for the next part
RunError: ' Reportd any errors that might occur in the system
If Err.Number = 0 Then
Debug.Print "IGNORE ERROR 0!"
Else
Dim strError As String
strError = "ERROR: " & Err.Number & vbCrLf & Err.Description & vbCrLf & Erl
MsgBox strError
Debug.Print strError & " LINE: " & Erl
End If
End Sub
I apologize this was so long winded. Let me know if there is anything confusing or you may want clarified. I think I included everything though.
I think you're close, so here are a couple of comments and an example.
First of all, you're opening two separate MS Word Application objects. You only need one. In fact, it's possible that the copy/paste is failing because you're trying to copy from one Word app to a document opened in the other. (Trust me, I've seen weird things like this.) My example below shows how to do this by only opening a single application instance.
Dim mswApp As Word.Application
Set mswApp = AttachToMSWordApplication() 'more on this function below...
Dim doc1 As Word.Document
Dim doc2 As Word.Document
Set doc1 = mswApp.Documents.Open("C:\Temp\combined.docx")
Set doc2 = mswApp.Documents.Open("C:\Temp\control.docx")
While I don't often write code for Word, I've found that there are so many different ways to get at the same content using different objects or properties. This is always a source of confusion.
Based on this answer, which has worked well for me in the past, I then set up the source and destination ranges to perform the "copy":
Dim destination As Word.Range
Dim source As Word.Range
Set source = doc1.Content
Set destination = doc2.Content
destination.Collapse Direction:=Word.wdCollapseEnd
destination.FormattedText = source
Here is the whole module for reference:
Option Explicit
Sub AddDocs()
Dim wordWasRunning As Boolean
wordWasRunning = IsMSWordRunning()
Dim mswApp As Word.Application
Set mswApp = AttachToMSWordApplication()
Dim doc1 As Word.Document
Dim doc2 As Word.Document
Set doc1 = mswApp.Documents.Open("C:\Temp\combined.docx")
Set doc2 = mswApp.Documents.Open("C:\Temp\control.docx")
Dim destination As Word.Range
Dim source As Word.Range
Set source = doc1.Content
Set destination = doc2.Content
destination.Collapse Direction:=Word.wdCollapseEnd
destination.FormattedText = source
doc2.Close SaveChanges:=True
doc1.Close
If Not wordWasRunning Then
mswApp.Quit
End If
End Sub
Here's the promised note on a couple functions I use in the sample. I've built up a set of library functions, several of which help me access other Office applications. I save these modules as .bas files (by using the Export function in the VBA Editor) and import them as needed. So if you'd like to use it, just save the code below in using a plain text editor (NOT in the VBA Editor!), then import that file into your project.
Suggested filename is Lib_MSWordSupport.bas:
Attribute VB_Name = "Lib_MSWordSupport"
Attribute VB_Description = "Variety of support functions operating on MS Word"
Option Explicit
Public Function IsMSWordRunning() As Boolean
Attribute IsMSWordRunning.VB_Description = "quick check to see if an instance of MS Word is running"
'--- quick check to see if an instance of MS Word is running
Dim msApp As Object
On Error Resume Next
Set msApp = GetObject(, "Word.Application")
If Err > 0 Then
'--- not running
IsMSWordRunning = False
Else
'--- running
IsMSWordRunning = True
End If
End Function
Public Function AttachToMSWordApplication() As Word.Application
Attribute AttachToMSWordApplication.VB_Description = "finds an existing and running instance of MS Word, or starts the application if one is not already running"
'--- finds an existing and running instance of MS Word, or starts
' the application if one is not already running
Dim msApp As Word.Application
On Error Resume Next
Set msApp = GetObject(, "Word.Application")
If Err > 0 Then
'--- we have to start one
' an exception will be raised if the application is not installed
Set msApp = CreateObject("Word.Application")
End If
Set AttachToMSWordApplication = msApp
End Function

How do I get my Excel data into Word's ContentControl

I have placed a Plain Text Content Control on my Document.
I opened the Macro and have the following code
Sub PrefillDocument()
'
' PrefillDocument Macro
'
'
Dim docName As ContentControls
Dim objExcel As Object
Dim FileName As String
FileName = ActiveDocument.Path & "\CountyData.xlsx"
Set objExcel = CreateObject("Excel.Application")
Set exWb = objExcel.Workbooks.Open(FileName)
MsgBox exWb.Sheets("4").Cells(1, 2) // Works
' Having problems trying to get the data from Excel into the content control
Set docName = ActiveDocument.SelectContentControlsByTag("Name") // Get
docName.Item.Title = exWb.Sheets("4").Cells(1, 2)
MsgBox docName.Title
'ActiveDocument.FormFields("Name").Result =
'ThisDocument.m_name.Caption = exWb.Sheets("Member's Data").Cells(2, 1)
exWb.Close
Set exWb = Nothing
End Sub
I have been told NOT to use any legacy controls so I am forced to use the newer ContentControls
docName is a collection of controls, and in this case, Word isn't going to let you apply a Title to every control in the Collection.
So you will need to iterate, e.g.
Dim cc as ContentControl
For Each cc In docName
cc.Title = exWb.Sheets("4").Cells(1, 2)
Next
or you could probably drop your docName declaration and do
Dim cc as ContentControl
For Each cc In ActiveDocument.SelectContentControlsByTag("Name")
cc.Title = exWb.Sheets("4").Cells(1, 2)
Next
For the question you posted in the comments, to update the actual content of the Control rather than the title, you need to know that the content is represented by a Word Range, and that you need to set the text of the range, e.g.
cc.Range.Text = exWb.Sheets("4").Cells(1.2)
You will still need to iterate through the collection of controls.

Page numbers or Header Info for embedded Excel file in Word Doc?

I'm trying to search an MS Word doc for embedded Excel files and save them to a different location.
1) I want to record the page number and or section name (based on header style) the embedded file was located in the Word Doc. How can I extract this info?
2) Is there anyway to get the original filename of the embedded Excel file?
Here is the code I'm using to search for embedded files. Originally
Working off the code first presented here: Extract Embeded Excel Workseet Data
Sub TestMacro2()
Application.ScreenUpdating = False
Application.DisplayAlerts = wdAlertsNone
Dim lNumShapes As Long
Dim lShapeCnt As Long
Dim xlApp As Object
Dim wrdActDoc As Document
Dim iRow As Integer
Dim iCol As Integer
Set wrdActDoc = ActiveDocument
For lShapeCnt = 1 To wrdActDoc.InlineShapes.Count
If wrdActDoc.InlineShapes(lShapeCnt).Type = wdInlineShapeEmbeddedOLEObject Then
If wrdActDoc.InlineShapes(lShapeCnt).OLEFormat.ProgID = "Excel.Sheet.8" Then
wrdActDoc.InlineShapes(lShapeCnt).OLEFormat.Edit
Set xlApp = GetObject(, "Excel.Application")
cpath = "location of interest"
xlApp.Workbooks(1).SaveAs cpath & " " & lShapeCnt
xlApp.Workbooks(1).Close
xlApp.Quit
Set xlApp = Nothing
End If
End If
Next lShapeCnt
End Sub
Note: Your code would be more efficient (and easier to read) if you assign an object that's re-used to a variable:
Dim ils as Word.InlineShape
Set ils = wrdActDoc.InlineShapes(lShapeCnt)
(1) The Range.Information method can return the page number. Something like:
Dim pageNumber as Long
pageNumber = ils.Range.Information(wdwdActiveEndPageNumber)
The other option is not as straight forward... I expect you really mean Heading style, not Header style. There is a built-in bookmark that will get the Heading preceding the current selection. That would be something like:
Dim secName as String
ils.Range.Select
secName = ActiveDocument.Bookmarks("\HeadingLevel").Range.Text
(2) If the file is not linked then your chances are slim. There's nothing VBA can get at directly, that's certain. Possibly, something might be stored in the WordOpenXML. You can check that by downloading the Open XML SDK Productivity Tool, opening such a document in it and inspecting that part of the Open XML. If it's in there then you can get at it in VBA using ils.Range.WordOpenXML to get the Open XML for the InlineShape, then parse that.

Resources