How get i get an AddedPicture center on a page word - vba

To get around the fact that the manual way to insert a pdf in a word don't give really good quality result.
I'm trying to insert pictures that have been nicely converted from a pdf to png with Imagemagick in a word with a macro.
The moment where i struggle is when i want the picture to get in a middle of each page and don't overlap each over.
I come up with this but i don't understand why it seems that AllowOverlap and wdShapeCenter do nothing while wdWrapTopBottom work properly. The picture get stuck to the top-left corner'
Sub Test()
Dim objShape As Shape
strPath = "Some.png"
'insert the image
Set objShape = ActiveDocument.Shapes.AddPicture( _
FileName:=strPath, LinkToFile:=False, _
SaveWithDocument:=True)
objShape.WrapFormat.AllowOverlap = False
objShape.Top = WdShapePosition.wdShapeCenter
objShape.WrapFormat.Type = wdWrapTopBottom
End Sub
I tried to use Selection.InlineShapes.AddPicture to resolve the overlap problem but i can't get the picture move from the top-left corner neither.
Thanks for your help

For example:
Sub Demo()
Application.ScreenUpdating = False
Dim Shp As Shape
With Dialogs(wdDialogInsertPicture)
.Display
If .Name <> "" Then
Set Shp = ActiveDocument.Shapes.AddPicture(FileName:=.Name, _
LinkToFile:=False, SaveWithDocument:=True, Anchor:=Selection.Range)
With Shp
.LockAspectRatio = True
.Height = InchesToPoints(2)
.RelativeHorizontalPosition = wdRelativeHorizontalPositionMargin
.Left = wdShapeCenter
.RelativeVerticalPosition = wdRelativeVerticalPositionMargin
.Top = wdShapeCenter
.WrapFormat.AllowOverlap = False
End With
End If
End With
Application.ScreenUpdating = True
End Sub
With the above code, the inserted pic will be positioned in the center of the page. If there's already one centered there, the existing pic will be pushed down.
In light of your additional information, you should use something like:
Sub Demo()
Application.ScreenUpdating = False
Dim iShp As InlineShape, sWdth As Single, sHght As Single
With Dialogs(wdDialogInsertPicture)
.Display
If .Name <> "" Then
Set Shp = .InlineShapes.AddPicture(FileName:=.Name, _
LinkToFile:=False, SaveWithDocument:=True, Range:=Selection.Range)
With ActiveDocument.PageSetup
sWdth = .PageWidth - .LeftMargin - .RightMargin
sHght = .PageHeight - .TopMargin - .LeftMargin
End With
With iShp
.LockAspectRatio = True
.Width = sWdth
If .Height > sHght Then .Height = sHght
End With
End If
End With
Application.ScreenUpdating = True
End Sub

Finaly with your help I come up with this.
It center and place on it's own page pictures from a Folder.
Sub Folder_Picture_To_Word()
Dim shp As Shape
Dim intResult As Integer
Dim strPath As String
Dim strFolderPath As String
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
'the dialog is displayed to the user
intResult = Application.FileDialog(msoFileDialogFolderPicker).Show
'checks if user has cancled the dialog
If intResult <> 0 Then
'dispaly message box
strFolderPath = Application.FileDialog(msoFileDialogFolderPicker _
).SelectedItems(1)
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
Set objFolder = objFSO.GetFolder(strFolderPath)
'loops through each file in the directory and prints their names and path
For Each objFile In objFolder.Files
'get file path
strPath = objFile.Path
Selection.InsertAfter ChrW(12)
'insert the image
Set shp = ActiveDocument.Shapes.AddPicture(FileName:=strPath, _
LinkToFile:=False, SaveWithDocument:=True, Anchor:=Selection.Range)
With shp
'.LockAspectRatio = True
'.Height = InchesToPoints(8)
.RelativeHorizontalPosition = wdRelativeHorizontalPositionMargin
.Left = wdShapeCenter
.RelativeVerticalPosition = wdRelativeVerticalPositionMargin
.Top = wdShapeCenter
.WrapFormat.Type = wdWrapTopBottom
.WrapFormat.AllowOverlap = False
End With
'Go to next Page to get ready for a new picture
Selection.GoTo What:=wdGoToPage, Which:=wdGoToNext
Next objFile
Selection.GoTo What:=wdGoToPage, Which:=wdGoToPrevious 'Go to second last page
'To delete the extra jump page made in the loop
Selection.Delete
End If
End Sub

Related

How to insert an image on all pages using Word VBA?

I want to insert an image on every page.
I know that the command is Next in a For loop.
Sub InsertImage()
Dim oILS As InlineShape, oShp As Shape
Set oILS = Selection.InlineShapes.AddPicture(FileName:= _
"C:\Users\" & LCase(Environ("UserName")) & "\Desktop\SubEscritorio3\Ejercicios Matemáticas\Barra.png", LinkToFile:=False, _
SaveWithDocument:=True)
Set oShp = oILS.ConvertToShape
With oShp
.WrapFormat.Type = wdWrapBehind
.Left = -55
.Top = 471.1
.Height = 21.5
.Width = 522
End With
End Sub
Well, I found the way to do it on all pages. If it helps anyone, here it is:
Sub Demo()
Dim Rng As Range, i As Long, Shp As Shape, ImageName As String
ImageName = "C:\Users\" & LCase(Environ("UserName")) & "\Desktop\SubEscritorio3\Ejercicios Matemáticas\Barra.png"
With ActiveDocument
Set Rng = .Range(0, 0)
For i = 1 To .ComputeStatistics(wdStatisticPages)
Set Rng = Rng.GoTo(What:=wdGoToPage, Name:=i)
Set Rng = Rng.GoTo(What:=wdGoToBookmark, Name:="\page")
Rng.Collapse wdCollapseStart
Set Shp = .InlineShapes.AddPicture(FileName:=ImageName, SaveWithDocument:=True, Range:=Rng).ConvertToShape
With Shp
.Left = -55
.Top = 471.1
.Width = 522
.Height = 21.5
.WrapFormat.Type = wdWrapBehind
End With
Next
End With
End Sub

Macro update for VBA PPT to fit contents of a slide to a specific predefined workarea

I have a macro for VBA PPT to fit contents of a slide to a specific predefined workarea, now I select the required shapes to be fit into workarea and run this tool slide by slide. can anybody suggest how can I select multiple slides and get all the shapes (except placeholders) in those slides fit to the same work area
Sub FitContents()
Dim shp, grid, ZenSmartGroup, ZenWorkGrid As Shape
Dim SelectShapes As Variant
Dim targetSlides As SlideRange
Dim thisSlide, oSld As Slide
Dim theseShapes As ShapeRange
Set thisSlide = ActivePresentation.Slides(1)
Dim GridTop, GridLeft, GridHeight, GridWidth As Single
If ActiveWindow.Selection.Type = ppSelectionSlides Then
Set targetSlides = ActiveWindow.Selection.SlideRange
End If
For Each oSld In targetSlides
For Each shp In oSld.Shapes
If Not ActivePresentation.Slides(1).Tags("Font Size") = "" Then
If shp.HasTextFrame Then
If shp.TextFrame.HasText Then
shp.TextFrame.TextRange.Font.Size = ActivePresentation.Slides(1).Tags("Font Size")
End If
End If
End If
Next
If ActivePresentation.Slides(1).Tags("Grid Height") = "" Then
MsgBox "Please set grid size in Prezent Admin > Settings", vbInformation, "Set Grid Size"
End
End If
GridTop = ActivePresentation.Slides(1).Tags("Grid Top")
GridLeft = ActivePresentation.Slides(1).Tags("Grid Left")
GridHeight = ActivePresentation.Slides(1).Tags("Grid Height")
GridWidth = ActivePresentation.Slides(1).Tags("Grid Width")
oSld.Select
ActiveWindow.ViewType = ppViewSlide
ActiveWindow.Selection.ShapeRange.Group.Select
With ActiveWindow.Selection.ShapeRange(1)
.Top = GridTop
.Left = GridLeft
.LockAspectRatio = frmFitToGrid.chkAspectRatio
.Width = GridWidth
.Height = GridHeight
If frmFitToGrid.optHeight = True Then
.Height = GridHeight
End If
'If .Width > GridWidth Then
If frmFitToGrid.optWidth = True Then
.Width = GridWidth
End If
.Tags.Add "Type", "ZenSmartGroup"
.Name = "ZenSmartGroup"
End With
Set grid = oSld.Shapes.AddShape(msoShapeRectangle, GridLeft, GridTop, GridWidth, GridHeight)
grid.Fill.Visible = msoFalse
grid.Line.Visible = msoTrue
grid.Line.ForeColor.RGB = RGB(0, 255, 0)
grid.Line.Weight = 2.25
'grid.Select
grid.Name = "ZenWorkGrid"
SelectShapes = Array("ZenSmartGroup", "ZenWorkGrid")
'Set theseShapes = thisSlide.Shapes.Range(SelectShapes)
'theseShapes.Align msoAlignMiddles, msoFalse
'theseShapes.Align msoAlignCenters, msoFalse
Set ZenSmartGroup = oSld.Shapes("ZenSmartGroup")
Set ZenWorkGrid = oSld.Shapes("ZenWorkGrid")
'Align Middle (Horizontal Center)
If Not (frmFitToGrid.chkAlignLeft) Then
ZenSmartGroup.Top = ZenWorkGrid.Top + ((ZenWorkGrid.Height - ZenSmartGroup.Height) / 2)
End If
'Align Center (Vertical Center)
If Not (frmFitToGrid.chkAlignTop) Then
ZenSmartGroup.Left = ZenWorkGrid.Left + ((ZenWorkGrid.Width - ZenSmartGroup.Width) / 2)
End If
grid.Delete
'ActiveWindow.Selection.ShapeRange.Align msoAlignMiddles, msoFalse
'ActiveWindow.Selection.ShapeRange(1).Delete
'ActiveWindow.Selection.ShapeRange.Align msoAlignCenters, msoTrue
oSld.Shapes.Range.Ungroup
Next
End Sub
NOTE: code below serves as an example, as it cannot be tested given the information in your post. Please adapt it to your situation as needed.
I've included several (hopefully) helpful additions to your code in order to improve readability and maintainability. These include:
Error Checking - make sure the user has provided all the values required for the macro to effectively execute, and...
... declare your variables as close as possible to their first use.
Note the use of targetSlides as the focus object for all the selected slides. This way you avoid to continually reference ActivePresentation.Slides(1). (Note this was an assumption on my part, adjust the code as necessary)
'--- make sure the user has selected at least two slides
Dim targetSlides As SlideRange
If ActiveWindow.Selection.Type = ppSelectionSlides Then
Set targetSlides = ActiveWindow.Selection.SlideRange
Else
MsgBox "Please select two or more slides in the left-hand slide overview panel.", _
vbCritical + vbInformation + vbOKOnly, "Select Slides for Grids"
Exit Sub
End If
'--- make sure the grid values are set
If targetSlides(1).Tags("Grid Height") = vbNullString Then
MsgBox "Please set grid size in Prezent Admin > Settings", _
vbCritical + vbInformation + vbOKOnly, "Set Grid Size"
End
End If
'--- assumes ONLY the first slide in the target slides has the Grid tags
Dim gridTop As Long
Dim gridLeft As Long
Dim gridHeight As Long
Dim gridWidth As Long
Dim fontSize As Double
With targetSlides(1)
gridTop = .Tags("GRID TOP")
gridLeft = .Tags("GRID LEFT")
gridHeight = .Tags("GRID HEIGHT")
gridWidth = .Tags("GRID WIDTH")
fontSize = IIf(.Tags("FONT SIZE") <> vbNullString, .Tags("FONT SIZE"), 0#)
End With
Break code into separate subs or functions to increase the readability of the logic.
It's easy to get lose the overall point of the solution when you have to mentally summarize large blocks of code. In my example, the main logic loop is:
Dim sld As Slide
For Each sld In targetSlides
ResetTextSize fontSize, sld
Dim slideShapes As ShapeRange
Set slideShapes = SelectAllShapes(sld)
CreateShapeGrid sld, slideShapes, _
gridTop, gridLeft, gridHeight, gridWidth
Next
Before looking at the full solution below, look at some of the supporting subs and functions. Most especially, note the function IsPlaceholder which checks a Shape on any slide to see if it's part of the layout (and shouldn't be selected) or not.
Full code module:
Option Explicit
Sub FitContents()
'--- make sure the user has selected at least two slides
Dim targetSlides As SlideRange
If ActiveWindow.Selection.Type = ppSelectionSlides Then
Set targetSlides = ActiveWindow.Selection.SlideRange
Else
MsgBox "Please select two or more slides in the left-hand slide overview panel.", _
vbCritical + vbInformation + vbOKOnly, "Select Slides for Grids"
Exit Sub
End If
'--- make sure the grid values are set
If targetSlides(1).Tags("Grid Height") = vbNullString Then
MsgBox "Please set grid size in Prezent Admin > Settings", _
vbCritical + vbInformation + vbOKOnly, "Set Grid Size"
End
End If
'--- assumes ONLY the first slide in the target slides has the Grid tags
Dim gridTop As Long
Dim gridLeft As Long
Dim gridHeight As Long
Dim gridWidth As Long
Dim fontSize As Double
With targetSlides(1)
gridTop = .Tags("GRID TOP")
gridLeft = .Tags("GRID LEFT")
gridHeight = .Tags("GRID HEIGHT")
gridWidth = .Tags("GRID WIDTH")
fontSize = IIf(.Tags("FONT SIZE") <> vbNullString, .Tags("FONT SIZE"), 0#)
End With
Dim sld As Slide
For Each sld In targetSlides
ResetTextSize fontSize, sld
Dim slideShapes As ShapeRange
Set slideShapes = SelectAllShapes(sld)
CreateShapeGrid sld, slideShapes, _
gridTop, gridLeft, gridHeight, gridWidth
Next
End Sub
Sub ResetTextSize(ByVal fontSize As Double, ByRef sld As Slide)
'--- (re)set the font sizes in all shapes with text, as long
' as it's not a placeholder shape on the current slide
If fontSize > 0 Then
Dim shp As Shape
For Each shp In sld.Shapes
If Not IsPlaceholder(sld, shp) Then
If shp.HasTextFrame Then
If shp.TextFrame.HasText Then
shp.TextFrame.TextRange.Font.Size = fontSize
End If
End If
End If
Next
End If
End Sub
Function IsPlaceholder(ByRef sld As Slide, ByRef shp As Shape) As Boolean
With sld.Shapes.Placeholders
IsPlaceholder = False
If .Count > 0 Then
Dim i As Long
For i = 1 To .Count
If .Item(i).Name = shp.Name Then
IsPlaceholder = True
Exit Function
End If
Next i
End If
End With
End Function
Function CollectionToArray(ByRef c As Collection) As Variant()
Dim a() As Variant: ReDim a(0 To c.Count - 1)
Dim i As Integer
For i = 1 To c.Count
a(i - 1) = c.Item(i)
Next
CollectionToArray = a
End Function
Function SelectAllShapes(ByRef sld As Slide) As ShapeRange
'--- creates a Collection of all the non-placeholder shape names, then
' convert the names to an array to create a ShapeRange object
Dim shp As Shape
Dim shps As Collection
Set shps = New Collection
For Each shp In sld.Shapes
If Not IsPlaceholder(sld, shp) Then
shps.Add shp.Name
End If
Next shp
If shps.Count > 0 Then
Dim shpsArray() As Variant
shpsArray = CollectionToArray(shps)
Set SelectAllShapes = sld.Shapes.Range(shpsArray)
Else
Set SelectAllShapes = Nothing
End If
End Function
Sub CreateShapeGrid(ByRef sld As Slide, ByRef slideShapes As ShapeRange, _
ByVal gridTop As Long, ByVal gridLeft As Long, _
ByVal gridHeight As Long, ByVal gridWidth As Long)
'--- position the group of shapes
With slideShapes.Group
.top = gridTop
.left = gridLeft
.LockAspectRatio = frmFitToGrid.chkAspectRatio
.width = gridWidth
.height = gridHeight
If frmFitToGrid.optHeight = True Then
.height = gridHeight
End If
'If .Width > GridWidth Then
If frmFitToGrid.optWidth = True Then
.width = gridWidth
End If
.Tags.Add "Type", "ZenSmartGroup"
.Name = "ZenSmartGroup"
End With
'--- now create a grid over the shapes
Dim grid As Shape
Set grid = sld.Shapes.AddShape(msoShapeRectangle, gridLeft, gridTop, gridWidth, gridHeight)
grid.Fill.Visible = msoFalse
grid.Line.Visible = msoTrue
grid.Line.ForeColor.RGB = RGB(0, 255, 0)
grid.Line.Weight = 2.25
'grid.Select
grid.Name = "ZenWorkGrid"
SelectShapes = Array("ZenSmartGroup", "ZenWorkGrid")
'Set theseShapes = thisSlide.Shapes.Range(SelectShapes)
'theseShapes.Align msoAlignMiddles, msoFalse
'theseShapes.Align msoAlignCenters, msoFalse
Set ZenSmartGroup = sld.Shapes("ZenSmartGroup")
Set ZenWorkGrid = sld.Shapes("ZenWorkGrid")
'Align Middle (Horizontal Center)
' If Not (frmFitToGrid.chkAlignLeft) Then
' ZenSmartGroup.Top = ZenWorkGrid.Top + ((ZenWorkGrid.Height - ZenSmartGroup.Height) / 2)
' End If
'
' 'Align Center (Vertical Center)
' If Not (frmFitToGrid.chkAlignTop) Then
' ZenSmartGroup.Left = ZenWorkGrid.Left + ((ZenWorkGrid.Width - ZenSmartGroup.Width) / 2)
' End If
grid.Delete
'ActiveWindow.Selection.ShapeRange.Align msoAlignMiddles, msoFalse
'ActiveWindow.Selection.ShapeRange(1).Delete
'ActiveWindow.Selection.ShapeRange.Align msoAlignCenters, msoTrue
slideShapes.Ungroup
End Sub

InlineShapes exported as image add border

Using below code for saving MS Word images and converting into base64.
When exporting the image it adds some borders.
Original Image
after export
If singleline.Range.InlineShapes.Count > 0 Then
Dim shp1 As InlineShape
Dim mchart1 As Shape
Set shp1 = singleline.Range.InlineShapes(1)
shp1.Select
Selection.Copy
Set mchart1 = ActiveDocument.Shapes.AddChart(xl3DAreaStacked, , , shp1.Width, shp1.Height)
mchart1.Chart.ChartData.Workbook.Application.Quit
mchart1.Chart.Paste
mchart1.Chart.Export ("c:\here\" + CStr(i) + ".png")
mchart1.Chart.Delete
b64strng = ConvertFileToBase64("c:\here\" + CStr(i) + ".png")
Kill "c:\here\" + CStr(i) + ".png"
End If
Is there any fix or Alternative to export images?
I don't see any difference between your screenshots, possibly because of the dark browser background. Is the border visible after the Export command, or after the ConvertFileToBase64 function?
It appears you're trying to export a non-chart graphic by using a chart kludge. You'll get better results by enlisting PowerPoint to do the graphics export. Here's a sample macro that shows how to export Word graphics from PowerPoint. You can modify this to export a single Shape or ShapeRange (your graphic) instead of a complete slide.
Public Sub ExportMap()
Dim pptPres As PowerPoint.Presentation
Dim pptSlide As PowerPoint.Slide
Dim pptShapeRange As PowerPoint.ShapeRange
Dim Path$, File$
Dim oRange As Range
Application.ScreenUpdating = False
If ActiveDocument.ProtectionType = wdAllowOnlyFormFields Then
ActiveDocument.Unprotect
End If
myDate$ = Format(Date, "m-d-yyyy")
Set pptApp = CreateObject("PowerPoint.Application")
Path$ = ActiveDocument.Path & Application.PathSeparator
File$ = "WorldMap " & myDate$ & ".png"
Set pptPres = pptApp.Presentations.Add(msoFalse)
Set oRange = ActiveDocument.Bookmarks("WholeMap").Range
oRange.CopyAsPicture
Set pptSlide = pptPres.Slides.Add(1, ppLayoutBlank)
On Error Resume Next
With pptPres.PageSetup
.SlideSize = 7
.SlideWidth = 1150
.SlideHeight = 590
End With
Set pptShapeRange = pptSlide.Shapes.PasteSpecial(ppPasteEnhancedMetafile, Link:=msoFalse)
With pptShapeRange
.Top = .Top + 6
' .Left = .Left + 510
End With
pptSlide.Export Path$ & File$, "PNG"
pptApp.Quit
Set pptPres = Nothing
Set pptApp = Nothing
Set pptSlide = Nothing
If ActiveDocument.ProtectionType = wdNoProtection Then
ActiveDocument.Protect Type:=wdAllowOnlyFormFields, noreset:=True
End If
Application.ScreenUpdating = True
MsgBox "All done! Check the folder containing this template for a file called '" & File$ & "'."
End Sub

Text Box Rotation Issue

I am trying to write a macro to insert a custom watermark in my Word document.
The code works perfectly for the first two pages of the document but thereafter the the Textbox does not rotate to -45 as mentioned in the code
What am I doing wrong?
Sub CustomWatermark()
Dim activeDoc As Document
Dim rngDoc As Range
Dim shpTextBox As Shape
Dim lngPages As Long
Dim i As Long
Dim strWatermark As String
Set activeDoc = ActiveDocument
lngPages = activeDoc.Range.Information(wdNumberOfPagesInDocument)
strWatermark = InputBox("Enter Watermark")
With activeDoc
For i = 1 To lngPages
Set rngDoc = .GoTo(What:=wdGoToPage, Name:=i)
rngDoc.Collapse wdCollapseStart
Set shpTextBox = .Shapes.AddTextbox(Orientation:=msoTextOrientationHorizontal, _
Left:=InchesToPoints(1), _
Top:=InchesToPoints(4), _
Width:=InchesToPoints(6), _
Height:=InchesToPoints(2), _
Anchor:=rngDoc)
With shpTextBox
.Line.Visible = msoFalse
.Rotation = -45
.WrapFormat.Type = wdWrapBehind
.TextFrame.HorizontalAnchor = msoAnchorCenter
.TextFrame.VerticalAnchor = msoAnchorMiddle
With .TextFrame.TextRange
.Font.AllCaps = True
.Font.Size = "60"
.Font.ColorIndex = wdGray25
.ParagraphFormat.Alignment = wdAlignParagraphCenter
.Text = strWatermark
End With
End With
Next
End With
End Sub
It looks that, selecting all their range and doing rotation at once, works...
Sub CustomWatermarkBis()
Dim activeDoc As Document, rngDoc As Range, shpTextBox As Shape
Dim lngPages As Long, i As Long, strWatermark As String, shR As ShapeRange
Dim arrRot As Variant, k As Long
Set activeDoc = ActiveDocument
lngPages = activeDoc.Range.Information(wdNumberOfPagesInDocument)
ReDim arrRot(0 To lngPages - 1)
strWatermark = InputBox("Enter Watermark Text")
With activeDoc
For i = 1 To lngPages
Set rngDoc = .GoTo(What:=wdGoToPage, Name:=i)
rngDoc.Collapse wdCollapseStart
Set shpTextBox = .Shapes.AddTextbox(Orientation:=msoTextOrientationHorizontal, _
Left:=InchesToPoints(1), _
Top:=InchesToPoints(4), _
Width:=InchesToPoints(6), _
Height:=InchesToPoints(2), _
Anchor:=rngDoc)
With shpTextBox.TextFrame.TextRange
.Font.AllCaps = True
.Font.Size = "60"
.Font.ColorIndex = wdGray25
.ParagraphFormat.Alignment = wdAlignParagraphCenter
.Text = strWatermark
End With
shpTextBox.Name = "T" & i
arrRot(k) = shpTextBox.Name: k = k + 1
Next
Set shR = .Shapes.Range(arrRot)
End With
With shR
.Select
.Line.Visible = msoFalse
.Rotation = -45
.WrapFormat.Type = wdWrapBehind
.TextFrame.HorizontalAnchor = msoAnchorCenter
.TextFrame.VerticalAnchor = msoAnchorMiddle
End With
Selection.Collapse
End Sub
Re-ordering your code to add the text before changing the rotation should solve the issue. It certainly does for me in Word 365.
EDIT: That approach worked for me exactly twice and now I can't repeat it. Adding the text box to the header does work reliably though, and results in a much tidier document.
Sub CustomWatermarkInHeader()
Dim activeDoc As Document
Dim rngDoc As Range
Dim strWatermark As String
Dim docSection As Section
Dim shpTextBox As Shape
Set activeDoc = ActiveDocument
strWatermark = InputBox("Enter Watermark")
With activeDoc
For Each docSection In .Sections
Set rngDoc = docSection.Headers(wdHeaderFooterPrimary).Range
rngDoc.Collapse wdCollapseStart
Set shpTextBox = .Shapes.AddTextbox(Orientation:=msoTextOrientationHorizontal, _
Left:=InchesToPoints(1), _
Top:=InchesToPoints(4), _
Width:=InchesToPoints(6), _
Height:=InchesToPoints(2), _
Anchor:=rngDoc)
With shpTextBox
With .TextFrame
.HorizontalAnchor = msoAnchorCenter
.VerticalAnchor = msoAnchorMiddle
With .TextRange
.Font.AllCaps = True
.Font.Size = "60"
.Font.ColorIndex = wdGray25
.ParagraphFormat.Alignment = wdAlignParagraphCenter
.Text = strWatermark
End With
End With
.Line.Visible = msoFalse
.Rotation = -45
.WrapFormat.Type = wdWrapBehind
End With
Next
End With
End Sub
However, you may want to consider:
adding the text box to the header instead of cluttering your document with a text box on every page. You will achieve the same result with fewer text boxes.
Using the built-in functionality to add a custom watermark. You can find this on the Design tab of the ribbon.
Instead of:
.Rotation = -45
Try:
.ThreeD.IncrementRotationZ -45
https://learn.microsoft.com/en-us/office/vba/api/word.threedformat

MS Word Caption with the Image Name

The code below works like a charm. It allows the user to pick a folder with .jpgs and other image types into a 2 image per page. The Current code just captions the image as "Picture". What I am needing assistance with is getting the image name as caption minus the .jpg. Any direction would be great:
Sub AddPic()
Dim fd As FileDialog
Dim oTbl As Table
Dim oILS As InlineShape
Dim vrtSelectedItem As Variant
'''''''''''''''
'Add a 1 row 2 column table to take the images
'''''''''''''''
Set oTbl = Selection.Tables.Add(Selection.Range, 4, 1)
With oTbl
.AutoFitBehavior (wdAutoFitWindow)
End With
'''''''''''''''
Set fda = Application.FileDialog(msoFileDialogFilePicker)
With fda
.Title = "Select image files and click OK"
.Filters.Add "Images", "*.gif; *.jpg; *.jpeg; *.bmp; *.tif; *.png"
.FilterIndex = 2
If .Show = -1 Then
CaptionLabels.Add Name:="Picture"
For Each vrtSelectedItem In .SelectedItems
With Selection
Set oILS = .InlineShapes.AddPicture(FileName:= _
vrtSelectedItem, LinkToFile:=False, SaveWithDocument:=True, _
Range:=Selection.Range)
oILS.Range.InsertCaption Label:="Picture", TitleAutoText:="", Title:="", _
Position:=wdCaptionPositionBelow, ExcludeLabel:=0
.MoveRight wdCell, 1
End With
Next vrtSelectedItem
If Len(oTbl.Rows.Last.Cells(1).Range) = 2 Then oTbl.Rows.Last.Delete
Set fd = Nothing
End If
End With
'''''''''''''''
For Each pic In ActiveDocument.InlineShapes
With pic
.LockAspectRatio = msoFalse
If .Width > .Height Then ' horizontal
.Width = InchesToPoints(5.5)
.Height = InchesToPoints(3.66)
Else ' vertical
.Width = InchesToPoints(5.5)
End If
End With
Next
'''''''''''''''
Selection.WholeStory
Selection.Font.Bold = wdToggle
Selection.Font.Bold = wdToggle
Selection.Font.Color = wdColorBlack
'''''''''''''''
End Sub
It appears vrtSelectedItem provides the information that's required, so the only problem is cutting off the file extension.
This can be done by string manipulation. In the code snippet below, taken from the question, the location of the . in the file name is ascertained, as well as the length of the file name. The Mid function is then used to extract the text to the left of that point.
Dim dotPos as long, lenName as Long
Dim capt as String
For Each vrtSelectedItem In .SelectedItems
dotPos = Instr(vrtSelectedItem, ".")
lenName = Len(vrtSelectedItem)
capt = Mid(vrtSelectedItem, lenName + (dotPos - 1 - lenName ))
With Selection
Set oILS = .InlineShapes.AddPicture(FileName:= _
vrtSelectedItem, LinkToFile:=False, SaveWithDocument:=True, _
Range:=Selection.Range)
oILS.Range.InsertCaption Label:="Picture", TitleAutoText:="", Title:=capt, _
Position:=wdCaptionPositionBelow, ExcludeLabel:=0
.MoveRight wdCell, 1
End With
Next vrtSelectedItem