My task is place image from external app at specified position in document. For example - i have Rich Text content control, and my image must appear on this content control. This is example of code:
Dim cc As ContentControl
Set cc = ActiveDocument.ContentControls(1)
ActiveDocument.Shapes.AddPicture filename:=filename, LinkToFile:=False, SaveWithDocument:=True, Anchor:=cc.Range
Inserted image located at the same height, but vertical is located on the left. According to documentation this behavior is correct, but i need to set it right above my ContentControl object. Is it possible to do it? Maybe i can calculate length of paragraph in pixel and set Left parameter in Shapes.AddPicture method?
The AddPicture function returns a shape object which you can configure as desired:
Dim cc As ContentControl
Dim shp As shape
Set cc = ActiveDocument.ContentControls(1)
Set shp = ActiveDocument.Shapes.AddPicture(filename:=filename, LinkToFile:=False, SaveWithDocument:=True, Anchor:=cc.Range)
shp.Left = 20
shp.Top = -100
You can also set the RelativeHorizontalPosition and RelativeVerticalPosition properties of the shape object to specify how the left and top values are to be interpreted.
Related
I'm trying to animate selected text in a presentation.
I found a way to animate a shape, but not only a portion of it.
Dim effNew As Effect
Dim shpFirst As Shape
Set shpFirst = ActivePresentation.Slides(ActiveWindow.View.Slide.SlideIndex).Shapes(4)
Set effNew = ActivePresentation.Slides(ActiveWindow.View.Slide.SlideIndex).TimeLine.MainSequence.AddEffect _
(Shape:=shpFirst, effectId:=msoAnimEffectBounce)
There are two properties that might help, but they are read-only:
effNew.TextRangeStart
effNew.TextRangeLength
I'm trying to insert a image in the first page header of a document, trough VBA.
There are multiple lines that can do this, but each has it problem, which I will list:
This is my favorite method, but it inserts the image not in the header of first page, but all the remaining ones, and it also doesn't allow me to set the position:
ActiveDocument.Sections(1).Headers(2).Shapes.AddPicture ("C:\1.jpg")
This returns an out of bounds error:
Set shpCanvas=ActiveDocument.Shapes.AddCanvas(Left:=0, Top:=0, Width:=180, Height:=50)
shpCanvas.CanvasItems.AddPicture FileName:="C:\1.jpg", LinkToFile:=False, SaveWithDocument:=True
Inserts the image directly, but its usually out of position, stays in the middle of the header where I'd rather have it on the left
ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Range.InlineShapes.AddPicture ("C:\1.jpg")
I'm just a beginner with VBA and word, I apologize for any grotesque ideas I might have
The first code example does work for me - I see the picture on the first page. But since you don't describe how your document is structured I may not be testing what you're using...
You should not try to use a canvas.
The difference between a Shape and an InlineShape is that Word handles the latter like a text character. If the third line is positioning the picture in the middle of the line that paragraph is probably formatted as "centered", rather than "left". Try changing the paragraph formatting.
To position the result when using a Shape an object variable is required to be able to handle what has been inserted. For example:
Dim shp As Word.Shape, ils As Word.InlineShape
Set shp = ActiveDocument.Sections(1).Headers(2).Shapes.AddPicture("C:\1.jpg")
shp.Top = 0
shp.Left = 0
An object is declared, then the picture being inserted is assigned to the object, in one step. Subsequently, the object variable can be used to address the picture.
Thanks for your help, more correctly it worked like this
Dim shp2 As Word.Shape
Dim shp3 As Word.InlineShape
Set shp3 = ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Range.InlineShapes.AddPicture("C:\1.jpg")
Set shp2 = shp3.ConvertToShape
shp2.Top = 0
shp2.Left = 0
I want to place a logo at the top right hand corner at each page in a document. This functionality is already present in a Word add-in that is managed by us. However this feature does not work correctly. The add-in converts the image to a shape and then places this image a fixed distance from the left document corner. This works for documents that are A4 formats, but whenever the orientation or size of the document changes, the logo placement is off.
I have tried numerous strategies to resolve this, but haven't found a method that is satisfactory. My current strategy is to determine the distance between the left page side and the logo dynamically and then make this position relative to the right side of the page by calling the .RelativeHorizontalPosition property and linking it to the right margin area.
Unfortunately interacting with the .Left property of the Shape object has been troublesome. The .Left property does not take on the value I assign it, but takes on a negative value. I have checked the parameter I assign it numerous times. Would anyone know why this is the case and how to resolve it?
Example Code
Private Sub AddLogos(section As Section, header As HeaderFooter)
Dim wordApp As Word.Application = Globals.ThisAddIn.Application
Dim pageWidth As Single = section.PageSetup.PageWidth
Dim imgFilePath As String = "filepath"
Dim leftDistanceA4 As Single = 11
Dim logo As Word.Shape
Try
If wordApp.ActiveDocument.SaveFormat >= 12 Then
logo = header.Range.InlineShapes.AddPicture(m_sImageLogo, False, True).ConvertToShape()
Else 'Word 97-2003 Support
logo = header.Shapes.AddPicture(imgFilePath, False, True)
End If
Catch ex As Exception
Throw New Exception("Error message.")
End Try
Dim distanceFromRightPageEdge = wordApp.CentimetersToPoints(21 - leftDistanceA4)
Dim distanceFromLeftPageEdge = pageWidth - distanceFromRightPageEdge
With logo
.RelativeVerticalPosition = WdRelativeVerticalPosition.wdRelativeVerticalPositionPage
.Left = distanceFromLeftPageEdge
.RelativeHorizontalPosition = WdRelativeHorizontalPosition.wdRelativeHorizontalPositionRightMarginArea
End With
Instead of setting the left position to an absolute value, you can make it relative and essentially "right-align" the shape. If you set the RelativeHorizontalPosition and Left properties as shown below, the image will be placed in the top-right corner, and will maintain its relative position to that corner even when the document's format or size is altered.
Const imgpath As String = "[your path]"
Dim app As New Microsoft.Office.Interop.Word.Application
Dim doc As Microsoft.Office.Interop.Word.Document = app.Documents.Add()
Dim head As Microsoft.Office.Interop.Word.HeaderFooter = doc.Sections(1).Headers(1)
Dim img As Microsoft.Office.Interop.Word.Shape = head.Shapes.AddPicture(imgpath, False, True)
With img
.RelativeHorizontalPosition = Microsoft.Office.Interop.Word.WdRelativeHorizontalPosition.wdRelativeHorizontalPositionMargin
.Left = Microsoft.Office.Interop.Word.WdShapePosition.wdShapeRight
End With
app.Visible = True
'dispose references
Edit: If you need more control over positioning than simply anchoring the image to the top-right corner of the page, inline shapes do not inherently possess that. Instead, consider using a borderless table in the header to provide more control over its contents. Once the image is a child of the table, you have access to all the table formatting controls to use on your image:
Const imgpath As String = "[your path]"
Const imgMarginCM As Integer = 2
Dim app As New Microsoft.Office.Interop.Word.Application
Dim doc As Microsoft.Office.Interop.Word.Document = app.Documents.Add()
Dim head As Microsoft.Office.Interop.Word.HeaderFooter = doc.Sections(1).Headers(1)
Dim tbl As Microsoft.Office.Interop.Word.Table = doc.Tables.Add(head.Range, 1, 1)
With tbl
.Borders.Enable = False
.AutoFitBehavior(Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitWindow)
.Cell(1, 1).Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphRight
.Cell(1, 1).TopPadding = app.CentimetersToPoints(imgMarginCM)
.Cell(1, 1).RightPadding = app.CentimetersToPoints(imgMarginCM)
.Cell(1, 1).Range.InlineShapes.AddPicture(imgpath, False, True)
End With
app.Visible = True
'dispose references
Of course, if you have other items in the header then you would create a table with multiple cells and adjust the spacing appropriately, but for this example I'm just putting a borderless single-cell table in the header and setting its autofit behavior to fitwindow so that the table will fill the width of the page even when margins or format are changed. Then I just set the top and right padding of the cell with the image, and the behavior you are looking for is achieved.
I wrote some code for a client which isn't working correctly on his machine (Win 10, Office 365) but is on mine (Win 10, Office 2016). The code inserts an image to the header then positions it and resizes it. I use the ConvertToShape method so I can access properties like width, height and position of the Shape class.
Dim pic As Shape
Dim shp As Word.InlineShape
Set shp = thisDocument.Sections.Item(1).Headers(wdHeaderFooterPrimary).Range.InlineShapes.AddPicture(fpImage) ' insert the image to the header
Set pic = shp.ConvertToShape ' THIS LINE CAUSES THE PROBLEM
The method causes the image to disappear. 'Pic' is still available and setting it's properties causes no error, but it is not visible. It's .visible property returns true.
Any ideas? Thanks.
Answer provided to cross-post at Microsoft Community
There is a way to do this with only an inline shape, by setting up a table to position the text on the left and the picture on the right. An additional advantage of this method is that, if you set the table's AutoFitBehavior property to wdAutoFitFixed and set the column width to the width you want for the shape, Word will automatically resize the picture to that width and keep the aspect ratio.
Here's a little sample macro:
Sub x()
Dim fpImage As String
Dim strExistingHeaderText
Dim tbl As Table
Dim shp As InlineShape
fpImage = "D:\Pictures\bunnycakes.jpg"
With ActiveDocument
strExistingHeaderText = _
.Sections(1).Headers(wdHeaderFooterPrimary).Range.Text
Set tbl = .Tables.Add( _
Range:=.Sections(1).Headers(wdHeaderFooterPrimary).Range, _
numrows:=1, numcolumns:=2, _
AutoFitBehavior:=wdAutoFitFixed)
tbl.Columns(2).Width = InchesToPoints(1.5)
tbl.Columns(1).Width = InchesToPoints(5#)
tbl.Cell(1, 1).Range.Text = strExistingHeaderText
'tbl.Borders.Enable = False
Set shp = tbl.Cell(1, 2).Range.InlineShapes.AddPicture(fpImage)
End With
End Sub
.addPicture requires width and height, but this could end up distorting the image. Is there any way to use .LockAspectRatio = msoCTrue when adding the file image?
Also, how do you stipulate a page to put the canvas or the picture? Macro recorder needs to be stopped before one can work on images somehow.
Set sCanvas = ActiveDocument.Shapes _
.AddCanvas(Left:=MillimetersToPoints(20), Top:=MillimetersToPoints(20), _
Width:=300, Height:=200)
Set CanvasShapes = sCanvas.CanvasItems
With CanvasShapes
.AddPicture FileName:="C:\somepath\image.png", _
Left:=0, Top:=0, Width:=150, Height:=100
...
End With
Set the canvas size to 0 and lock it's aspect ratio, then add the picture. The canvas will scale to accommodate it. After the image is loaded, then scale the canvas as needed:
Set sCanvas = ActiveDocument.Shapes.AddCanvas(MillimetersToPoints(20), MillimetersToPoints(20), 0, 0)
sCanvas.LockAspectRatio = True
Set CanvasShapes = sCanvas.CanvasItems
With CanvasShapes
.AddPicture "C:\somepath\image.png"
End With
'Scale the canvas here.
You could try to obtain the dimensions using the code here (pasted below for reference)
Sub test()
Dim objShell As Object
Dim objFolder As Object
Dim objFile As Object
Dim fPath As Variant 'MUST be a variant, not a string
Dim fName As String
fPath = "C:\somepath"
fName = "image.png"
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(fPath)
Set objFile = objFolder.ParseName(fName)
MsgBox objFile.ExtendedProperty("Dimensions")
End Sub
This will give you the dimensions of the picture which you can then use.
It looks like the output is ? w x h ? so you'll need to parse it, but this should work.
Note that if you want to use a variable to define the file path, it must be declared as a variant, per here
If you check the definition of the AddPicture method you will find that except for FileName all of the arguments are optional, so Height and Width are not required.
Unless you have a specific reason for adding a canvas it is also unnecessary to add a canvas before adding a picture.
Word has no concept of pages so you cannot specify that the picture should appear on a certain page.
Managed to find a way to put a picture to a specific page (page 2 in example below) in MS Word:
Dim pNum as long
pNum = 2
Selection.GoTo What:=wdGoToPage, Count:= pNum