Problem inserting Image at a specific position - vba

I have been using the word VBA Shapes.AddPicture method (as in Add image to Word document at specified position) to insert a Png in a specific position of a document (near text previously found with Selection.Find.Execute...) and all has been working without problems for years, but now, without any change (nor in doc nor in code) the image has begun to go to top left corner and I couldn't find a reason...
Does someone know if something has change about that in last updates or what is happening?
I'm using properly updated 365 version and my code is:
Dim mySignatureShape As shape
Dim myImagePath as string
Selection.Find.Execute FindText:=" Text to find Here "
Selection.Collapse
myLeft = "-25"
myTop = "-49"
myImagePath = "Full Image Path Here"
Set mySignatureShape = ActiveDocument.Shapes.AddPicture(Filename:=myImagePath, LinkToFile:=False, _
SaveWithDocument:=True,
Anchor:=Selection.Range, _
Width:="275", Height:="150", _
Left:=myLeft, Top:=myTop)

Your code is missing anything to tell Word where to position the image in relation to the found text. As such, it could never have positioned the image 'near' that text unless the text was itself near the top of the page. Try:
Application.ScreenUpdating = False
Dim mySignatureShape As Shape
Dim myImagePath As String
Dim myLeft As Long, myTop As Long
myImagePath = "Full Image Path"
With Selection
.Find.Execute FindText:="Text to find"
.Collapse wdCollapseStart
myLeft = -25 + .Information(wdHorizontalPositionRelativeToPage)
myTop = -49 + .Information(wdVerticalPositionRelativeToPage)
Set mySignatureShape = ActiveDocument.Shapes.AddPicture(FileName:=myImagePath, LinkToFile:=False, _
SaveWithDocument:=True, Anchor:=.Range, Width:=275, Height:=150, Left:=myLeft, Top:=myTop)
End With
Application.ScreenUpdating = True

Related

Keep Picture Ratio in Word File

I add a picture via VBA in the Left Header Cell of a Word document - works fine with the following code. Now I want to keep the ratio of the Picture but want to change the size and I don't know how to do it:
Sub AutoOpen()
Dim dd1 As Document: Set dd1 = ActiveDocument
Dim rng1 As Range, seC As Section, an(2) As Long
Dim rngO As Range, rngAN As Range
Dim strToPict As String
For Each rngO In dd1.StoryRanges
ActiveDocument.ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
If rngO.StoryType = wdEvenPagesHeaderStory Then
Set rng1 = rngO.Duplicate
For Each seC In rng1.Sections
an(0) = seC.Headers(1).Range.InlineShapes(1).Height
an(1) = seC.Headers(1).Range.InlineShapes(1).Width
Set rngAN = seC.Headers(1).Range.InlineShapes(1).Range.Duplicate
seC.Headers(1).Range.InlineShapes(1).Delete
seC.Headers(1).Range.InlineShapes.AddPicture FileName:=strToPict, _
LinkToFile:=False, SaveWithDocument:=True, Range:=rngAN
With seC.Headers(1).Range.InlineShapes(1)
.Height = 50
.LockAspectRatio = True
End With
Next
Dim i As Long
ActiveDocument.Save
'Footer changing'
For i = 1 To ActiveDocument.Sections.Count
With ActiveDocument.Sections(i)
.Footers(wdHeaderFooterPrimary).Range.Text = ActiveDocument.Name + "Text"
End With
Next
End If
Next
End Sub
EDIT: I post the whole code of the Makro.
«I add a picture via VBA in the Left Header Cell of a Word document». There is no such thing as a 'Left Header Cell' in a Word document. The only headers (and footers) Word has are Primary, First Page and Even Pages.
And, as Timothy said, you "really need to learn to use the tools at you fingertips". Moreover, having found LockAspectRatio, a simple web search - if that was really necessary - would show you how to use it.
In any event, since all it seems you're trying to do is to resize the inlineshape and repeat the primary page header, you could use something along the lines of:
Sub AutoOpen()
Application.ScreenUpdating = False
Dim Rng As Range, iShp As InlineShape, Sctn As Section, StrNm As String
With Dialogs(wdDialogInsertPicture)
.Display
StrNm = .Name
End With
With ActiveDocument
If StrNm <> "" Then
Set Rng = .Sections.First.Headers(wdHeaderFooterPrimary).Range.Tables(1).Cell(1, 1).Range
Set iShp = .InlineShapes.AddPicture(FileName:=StrNm, _
LinkToFile:=False, SaveWithDocument:=True, Range:=Rng)
With iShp
.LockAspectRatio = True
.Height = 50
End With
End If
Set Rng = .Sections.First.Footers(wdHeaderFooterPrimary).Range
.Fields.Add Range:=Rng, Type:=wdFieldEmpty, Text:="FILENAME", PreserveFormatting:=False
Rng.InsertAfter vbTab & "Text"
For Each Sctn In .Sections
Sctn.Headers(wdHeaderFooterPrimary).LinkToPrevious = True
Sctn.Footers(wdHeaderFooterPrimary).LinkToPrevious = True
Next
End With
Application.ScreenUpdating = True
End Sub
You really need to learn to use the tools at you fingertips - IntelliSense, the Object Browser, and online help.
Scrolling through the options that IntelliSense gives you, or looking up InlineShape in the Object Browser, you would find LockAspectRatio. If you weren’t sure whether that was what you needed, pressing F1 would take you to the online help.

Insert a picture into an InlineShape

I’m writing a Document in which I have to include many Pictures. In the ongoing process the Pictures get changed many times.
My idea was to include Rectangle Shapes as placeholders and give them a suitable name. I created a Macro that selects the Shape, deletes the old Picture and inserts the new one into the Shape.
Sub InsertImage(Shape As String, Picture As String, Hight As Integer)
Dim shp As Word.Shape
Dim strFile As String
Dim strExt As String
strFile = "C:\Pictures"
strExt = ".png"
ActiveDocument.Shapes.Range(Array(Shape)).Select
Selection.TypeBackspace
Set shp = ActiveDocument.Shapes.AddPicture(Anchor:=Selection.Range, FileName:= _
strFile & "\" & Picture & strExt, LinkToFile:=False, SaveWithDocument:=True)
With shp
.LockAspectRatio = msoTrue
.Height = CentimetersToPoints(Hight)
End With
End Sub
Sub Insert1()
InsertImage "Shape01", "Pic01", 10
End Sub
I want this for floating Shapes as well as for InlineShapes.
When I set my Placeholder Shapes to InlineShapes the TypeBackspace line deletes the InlineShape and the picture does not get inserted into the InlineShape.
Thank you very much for the help. After many struggles, the solution with Tables + Bookmarks works perfekt.
Here is the code:
Sub InsertPic(Pic As String, Cut As Single)
Dim strFile As String
Dim strExt As String
Dim ils As InlineShape
strFile = "C:\Pictures“
strExt = ".png"
Application.ScreenUpdating = False
ActiveDocument.Bookmarks(Pic).Select
Selection.Delete
Set ils = Selection.InlineShapes.AddPicture(FileName:= _
strFile & "/" & Pic & strExt, _
LinkToFile:=False, SaveWithDocument:=True)
With ils
.PictureFormat.CropBottom = CentimetersToPoints(Cut)
.LockAspectRatio = msoTrue
.Height = .Range.Cells(1).Height
If .Width > .Range.Cells(1).Width Then
.Width = .Range.Cells(1).Width
End If
End With
ActiveDocument.Bookmarks.Add (Pic)
Application.ScreenUpdating = True
End Sub
Sub Insert01()
InsertPic "Image01", 20
MsgBox "Done"
End Sub
Some explanation:
For this code, the Bookmark and the Picture need the same Name. I made this to avoid mix-ups.
With the Selection.Delete command, the Bookmark gets also deleted, so I just added a new Bookmark with the same name at the end. I’m sure there are more elegant ways to solve this, but this solution works.
I have had many struggles because i wanted to crop the Picure. But the size gets changed to the size of the table-cell when its inserted and the cutting step comes afterwards. So the Picturs wasn´t filling the complete cell size. Therefore, I added a part to resize the Image to the table-cell Size. As well, im sure there are better ways to overcome this ...
Because of this resizing, the Makro needs a bit of time (at least for my document). So I disabled the Screenupdating.

Centered Text Box on Each Page in Word

So I am trying to write a code that adds a text box above a table on each page in a word document. This text box is to be centered to align with the table (I have no issues generating a centered table on each page). I have just recently started working in VBA so my knowledge is a little bit lacking. Here is my code so far, it is kind of a mish mash of what I could find online.
Sub TextMaker()
'
' TextMaker Macro
'
'
Dim i As Long, Rng As Range, Shp As Shape
Dim objDoc As Document
Dim objTextBox As Shape
Set objDoc = ActiveDocument
With ActiveDocument
For i = 1 To 5
Set Rng = .GoTo(What:=wdGoToPage, Name:=i)
Set Shp = .Shapes.AddTextbox(Orientation:=msoTextOrientationHorizontal, _
Left:=InchesToPoints(0.1), Top:=InchesToPoints(1.44), Width:=InchesToPoints(7.65), Height:=InchesToPoints(0.29), Anchor:=Rng)
With Shp
.RelativeHorizontalPosition = wdRelativeHorizontalPositionPage
.Left = wdShapeCenter
.RelativeVerticalPosition = wdRelativeVerticalPositionPage
.Top = InchesToPoints(1.44)
With .TextFrame.TextRange
.Text = "Ref. No.: T" & vbCr & "Signature "
Set Rng = .Paragraphs.First.Range
With Rng
.Font.ColorIndex = wdRed
.End = .End - 1
.Collapse wdCollapseEnd
End With
End With
End With
Next
End With
End Sub
The output works for the first two pages but on the 3rd page the alignment of the text box is not centered. I checked the positioning and the text box still says it is centered relative to page even though it is not.
The code works properly as long as the tables are not inserted, but the table generating code, if run after this one, does not put the tables on the same page as text boxes.
This is the 3rd page of my document, where things start to go wrong. The text box should be positioned above the table and centered in line with it.
In order to reproduce the document, create a blank document and run this table generation code:
Sub TableMaker()
For i = 1 To 5
ActiveDocument.Tables.Add Range:=Selection.Range, NumRows:=6, NumColumns:= _
2, DefaultTableBehavior:=wdWord9TableBehavior, AutoFitBehavior:= _
wdAutoFitFixed
Selection.Tables(1).Columns(1).Width = InchesToPoints(1.39)
Selection.Tables(1).Columns(2).Width = InchesToPoints(6.26)
Selection.Tables(1).Rows.Alignment = wdAlignRowCenter
With Selection.Tables(1).Rows
.WrapAroundText = True
.VerticalPosition = InchesToPoints(1.82)
.RelativeVerticalPosition = wdRelativeVerticalPositionPage
.DistanceTop = InchesToPoints(0)
.DistanceBottom = InchesToPoints(0)
.AllowOverlap = False
End With
'place cursor at end of page
Selection.EndKey Unit:=wdStory
'insert page break
Selection.InsertBreak Type:=wdPageBreak
Next i
End Sub
Or run the text generation code above and then this table generation code. Either way the formatting is not consistent. There will be no other text on these documents but an image will be placed below the tables on each page.
The problem is a combination of factors:
the table having text flow formatting. If I set that to "none" the textbox is centered correctly.
if the anchor range is outside the table, it works
I then tested the following and determined that the problem is because "Layout in cell" is activated (thanks for that screen shot BTW). When I put that in (see below) the text box is centered on the page because it's positioning is now independent of the table.
With Shp
.RelativeHorizontalPosition = wdRelativeHorizontalPositionPage
.Left = wdShapeCenter
.RelativeVerticalPosition = wdRelativeVerticalPositionPage
.Top = InchesToPoints(1.44)
.LayoutInCell = False

Word Macro to Mass Hyperlink variable length strings

I've been looking through the forums for a while now trying to find an answer to my problem, and either I'm dense or it hasn't been answered, so here I am.
Long story short, my job involves writing up word documents that list building deficits and provides hyperlinks to images of said deficits. The visible hyperlink text always follows the same format: '[site abbreviation][(image number)].JPG'. For example, if we are looking at 'Administrative Building', our images will be named 'AB(1).JPG', 'AB(2).JPG', etc, often into the mid-hundreds or thousands. In the word document, they are referenced as 'AB1', 'AB2' etc.
Currently, I have a macro that allows me to automatically create a hyperlink once I've selected the text, but I am trying to create a macro that will look through a document (or better yet, a highlighted selection) and assign hyperlinks to any text that starts with the site's abbreviation all at once.
My current attempt at a mass-hyperlinking macro is frustratingly close, but has one major error: while it will correctly hyperlink the first image name it finds, all subsequent images are linked with the next two characters included in the link. For example, if a sentence were to say "This is not correct (AB33), but this is correct (AB34)', my macro will hyperlink the text 'AB34' (which is correct) and 'AB33) ' (which is incorrect).
This is the macro I've been working with thus far (note that the text between the lines of 'XXXX...' are basic instructions for my coworkers to change the link destination as needed)
Option Explicit
Sub Mass_Hyperlink_v_1_1()
'incomplete: selects incorrect text after first link
Dim fileName As String
Dim filePath As String
Dim rng As Range
Dim tag As String
Dim FileType As String
Dim folder As String
Dim space As String
Dim start As String
Dim report_type As String
Dim temp As String
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'Do not touch anything above this line
'Answer the following for the current document. Leave all quotations.
report_type = "CL" 'CL = Checklist
'SR = Site Report
folder = "Doors" 'The name of the folder you are linking images from
'Must match folder exactly
tag = "FS" 'Put file prefix here (ex. if link says "AB123", put "AB")
space = "No" 'Does the image file have a space in it? (ex. if file name is "AB (23)", put "yes")
FileType = ".JPG" 'make sure filetype extensions match
'Do not touch anything below this line
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
If space = "Yes" Then
start = "%20("
Else: start = "("
End If
If report_type = "CL" Then
folder = "..\Images\" & folder
Else: folder = folder
End If
If report_type = "SR" Then
folder = "Images\" & folder
Else: folder = folder
End If
Set rng = ActiveDocument.Range
With rng.find
.MatchWildcards = True
Do While .Execute(findText:=tag, Forward:=False) = True
rng.MoveStartUntil (tag)
rng.Select
Selection.Extend
Selection.MoveRight Unit:=wdWord, Count:=1, Extend:=wdExtend
'I believe the issue is created here
Selection.start = Selection.start + Len(tag)
ActiveDocument.Range(Selection.start - Len(tag), Selection.start).Delete
fileName = Selection.Text
filePath = folder & "\" & tag & start & fileName & ")" & FileType
ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, address:= _
filePath, SubAddress:="", ScreenTip:="", TextToDisplay:= _
tag & Selection.Text
rng.Collapse wdCollapseStart
Loop
End With
End Sub
If I've explained this terribly wrong or not provided enough information, please let me know and I'll try to be more clear. And if there is a helpful resource that I'm simply too dense to have found, please let me know! thank you!
edit: if anyone knows how to only select words that start with the tag as opposed to words with the tag text in them, I'd be incredibly appreciative as well!
If you want to match a fixed tag followed by a variable number of digits:
Sub Tester()
TagMatches ActiveDocument, "AB"
End Sub
Sub TagMatches(doc As Document, tag As String)
Dim rng
Set rng = doc.Range
With rng.Find
.Text = tag & "[0-9]{1,}"
.Forward = True
.MatchWildcards = True
Do While .Execute
Debug.Print rng.Text
Loop
End With
End Sub
See: http://word.mvps.org/faqs/general/usingwildcards.htm

Adjust image properties with AddPicture Method word vba

I need to edit the properties of an image inserted by AddPicture method.
1) I need to adjust the height to 0.5" and the width is variable (lock the aspect ratio).
2) Wrap text = "In Front of Text"
Is this possile with this method? If so how do I add those properties? If not, what other method should I use and how?
Sub replaceWithImage()
Dim imageFullPath As String
Dim FindText As String
imageFullPath = "C:\Logo.jpg"
FindText = "PlaceHolder"
'Application.ScreenUpdating = False
With Selection
.HomeKey Unit:=wdStory
With .Find
.ClearFormatting
.text = FindText
' Loop until Word can no longer
' find the search string, inserting the specified image at each location
Do While .Execute
Selection.MoveRight
Selection.InlineShapes.AddPicture FileName:=imageFullPath, LinkToFile:=False, SaveWithDocument:=True
Loop
End With
End With
End Sub
I would do what you need in the following steps:
instead of this line:
Selection.InlineShapes.AddPicture FileName:=imageFullPath, _
LinkToFile:=False, SaveWithDocument:=True
I would do the same but using Object Variable:
'a) create new shape as object variable
Dim SHP 'As InlineShape/As Shape
Set SHP = Selection.InlineShapes.AddPicture(FileName:=imageFullPath, _
LinkToFile:=False, _
SaveWithDocument:=True)
'b) changes made according to SHP varialbe:
With SHP
'this will convert to 'in front of text'
.ConvertToShape
'this will keep ratio
.LockAspectRatio = msoTrue
'this will adjust width to 0.5 inch
.Width = InchesToPoints(0.5)
End With