VBA deletes image in body instead of header in MS-Word - vba

I have MS Word files that have a header with 2 Text Boxes and one image (as logo) and some tables, texts and images in body.
I'm trying to remove the image in header (logo) with this VBA code:
Dim tmp As Shape
Dim dShape As Shape
For Each tmp In ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Shapes
If tmp.Type = msoPicture Then
Set dShape = tmp
End If
Next
dShape.Delete
In the first test it worked correctly! After that it removes body image instead of header image!!!

It seems we should first select the Shape we want to delete!!
I don't know why when I say shape1.Delete it thinks : let me see, mmmm... I think i is better to do shape2.Delete , so i'll do that.
any way this works:
dShape.Select
dShape.Delete
VBA is a fool (Just like its platform)!

Related

PowerPoint VBA change picture of inserted audio file

I'm struggling with the following issue in Powerpoint:
I insert an audio file into a slide; the inserted shape looks like below:
I want to change the default picture (the speaker) with a picture loaded from a file. I can do this by going to "Audio format -> Change picture -> From a file" menu
The shape will now look like this, showing the picture loaded from file:
How can I do this from VBA code?
a) Using Fill.UserPicture is not working, as UserPicture is something else - the shape will look like this:
b) Using the classic technique of remembering original shape position, deleting it and replacing it with a new shape/picture doesn't work here, as it will also delete the audio.
Thank you for any suggestion,
Adrian
Thanks to John SR Wilson, here is a working approach (as Change Picture is not exposed in vba):
Set oMed = ActivePresentation.Slides(1).Shapes(1) 'For example!
T = oMed.Top
L = oMed.Left
With oMed
.MediaFormat.SetDisplayPictureFromFile ("PATH TO IMAGE")
.Height = 40 ' image will be 100% of original size so resize to about 40 points (you can change the value if you want)
.Top = T
.Left = L
End With

Set background color of headers and footers

I have been able to change the background color of Word tables in the body of the document with: oSourceTable.Shading.BackgroundPatternColor = wdRed. However, the same code does not work for header or footer Word tables. I have also tried setting the Section back color as well, but to no avail. The code runs, but the Headers and Footers are always displayed with white backgrounds.
I have done mostly Excel VBA, and only a little bit of Word VBA so maybe I am missing something obvious here. Thanks in advance for any ideas and/or suggestions.
As requested, here is the code I am using. vTableBackColors is just an array of colors. This code is for the body tables and is working perfectly.
For Each oWordTable In oWordDoc.Tables
lIndex = lIndex + 1
oWordTable.Shading.BackgroundPatternColor = vTableBackColors(lIndex)
Next
I tried to do the same thing for the header and footer tables, but it does not work. I tried using the Header/Footer tables as below.
For Each oWordSection In oWordDoc.Sections
For Each oWordTable In oWordSection.Headers.Item(wdHeaderFooterPrimary).Range.Tables
' I selected this one to see if it would make a difference.
oWordTable.Select
oWordTable.Shading.BackgroundPatternColor = m_HeaderBackColor
Next
For Each oWordTable In oWordSection.Footers.Item(wdHeaderFooterPrimary).Range.Tables
oWordTable.Shading.BackgroundPatternColor = m_FooterBackColor
Next
Next
I also tried using the Section Headers / Footers directly. Before and after checking shows that the BackgroundPatternColor has changed as desired, but it is not displayed.
oWordSection.Headers.Item(wdHeaderFooterPrimary).Range.Shading.BackgroundPatternColor = m_HeaderBackColor
Here is a screenshot showing the colorized body tables and the unchanged header.
Is it possible that, unlike the Body table colors, the Header / Footer colors are never displayed as such by the Word designer, but are only true at runtime?
Thanks for any additional information.
«I have been able to change the background color of Word tables in the body of the document with: oSourceTable.Shading.BackgroundPatternColor = red.» That would not work unless you have defined 'red' as an RGB value.
As for the header/footer issue, this works for me:
For Each oWordSection In oWordDoc.Sections
For Each oWordTable In oWordSection.Headers.Item(wdHeaderFooterPrimary).Range.Tables
oWordTable.Shading.BackgroundPatternColorIndex = wdRed
Next
For Each oWordTable In oWordSection.Footers.Item(wdHeaderFooterPrimary).Range.Tables
oWordTable.Shading.BackgroundPatternColorIndex = wdRed
Next
Next
Perhaps your underlying problem is in the value you have assigned to 'm_HeaderBackColor' and 'm_FooterBackColor' - which your posted code doesn't show. It's also possible your code is addressing the wrong headers/footers (i.e. maybe it's not the primary ones you need to address).

Move image without copy/paste

Right now I have a Word macro that moves an image in front of specific text by copying and pasting it to that location. This works pretty well, but it is costly. If I have 1,000s of images in my word doc it could take 30 minutes to run the macro.
There has to be a better way right?
Can I move the image anchor without copy/pasting the entire image?
My end goal is to take text + an image that is aligned in a table (text left, image right), break it out of the table, but maintain that left/right nature.
Specifically, I am looking for images in tables (row 1 column 2) and want to move them to the beginning of the text in that same table (1st column, 1st row). Here is a snippet:
For Each shape In innerTable.Cell(1, 2).Range.InlineShapes
If shape.Type = wdInlineShapePicture Then
shape.Select
Selection.Cut
innerTable.Range.Paragraphs(1).Range.Characters(1).Paste
'Do it only for the 1st image found:
Exit For
End If
Next
Note, I am leaving out some safety checks for simplicity sake (this assumes I already have found a table of valid size, etc.
It is only possible to move a Shape if the target is on the same page. In that case, a Shape can be moved by changing its Top and Left properties. Unfortunately (extremely), there is no way to move an image by changing the anchor point. So the only way to move an image to another page (or story) is using copy/paste.
If an InlineShape is to be moved, just assign InlineShape.Range.FormattedText to the target Range. Or, extend a range with text to also include the InlineShape. As far as Word is concerned, an InlineShape is a character.
To achieve the stated end goal
take text + an image that is aligned in a table (text left, image
right), break it out of the table, but maintain that left/right nature
use a table with an additional column, on the right. Put the image in it as an InlineShape. Then the entire row can be handled, for example as follows.
This creates a new row in the desired position, copies the Range.FormattedText of the row to be moved to the new row. Removes the additional row this creates and also deletes the original row.
Sub MoveRow()
Dim tbl As Word.Table
Dim rwToMove As Word.Row
Dim rwTarget As Word.Row
Dim rwBeforeTarget As Word.Row
Dim posNewRow As Long
posNewRow = 1
Set rwToMove = Selection.Rows(1)
Set tbl = rwToMove.Range.Tables(1)
Set rwBeforeTarget = tbl.Rows(posNewRow)
Set rwTarget = tbl.Range.Rows.Add(rwBeforeTarget) '(posNewRow)
rwTarget.Range.FormattedText = rwToMove.Range.FormattedText
tbl.Rows(posNewRow + 1).Delete
rwToMove.Delete
End Sub

Save all Pictures of slide into single JPG image using VBA

I would like to do the following in VBA powerPoint:
I have a powerPoint with six pictures on it. Ideally I would like to group the six pictures to create one new picture as a .jpg, then export the .jpg picture to a file. After exporting the photo, I would like to then delete the 6 individual pictures so I can import the single .jpg picture.
I have used this to start: Save all Shapes of slide into single JPG image . I understand the comment, but do not know how to execute it.
If there is a better way to do this, please share.
Thank you!
This will convert the currently selected shapes to a PNG, paste it back onto the slide and delete the original shapes.
You may want to modify this to ensure that something is selected and quit gracefully if not, or if it's just for your own use, let PPT/VBA scold you if you forget to select something.
Sub ConvertSelectionToImage()
Dim oShapes As ShapeRange
Dim oGroup As Shape
Dim oSingleShape As Shape
' Get a reference to the selected shapes
Set oShapes = ActiveWindow.Selection.ShapeRange
' Group them so we can later pick up their coordinates
Set oGroup = oShapes.Group
' copy to clipboard
oGroup.Copy
' paste from clipboard as PNG to retain transparency
Set oSingleShape = ActiveWindow.Selection.SlideRange.Shapes.PasteSpecial(ppPastePNG)(1)
' Position the pasted PNG to match original shapes
With oSingleShape
.Left = oGroup.Left
.Top = oGroup.Top
End With
' And delete the original shapes
oGroup.Delete
End Sub

How to choose a different header image in MS Word 2013 using a macro/button

I'd like to create a Word stationary template with ability to cycle through different colored logos in its header. My company uses a logo in five different colors and I would like to create a single template with a button that would allow me to cycle through the different colored logos every time I create a new document from this template. Can this be done, perhaps with a little VBA?
Edit:
After working with an answer from Olle Sjögren I've come up with the following working script:
Option Explicit
Public imgCounter As Integer
Sub cycle_logos()
Dim I As Variant
Dim logoColors(4) As String
logoColors(0) = "logo_magenta.png"
logoColors(1) = "logo_teal.png"
logoColors(2) = "logo_orange.png"
logoColors(3) = "logo_red.png"
logoColors(4) = "logo_grayscale.png"
For Each I In logoColors
ActiveDocument.StoryRanges(wdPrimaryHeaderStory).ShapeRange.Item(I).Visible = msoFalse
Next I
imgCounter = imgCounter + 1
If imgCounter = 5 Then imgCounter = 0
ActiveDocument.StoryRanges(wdPrimaryHeaderStory).ShapeRange.Item(logoColors(imgCounter)).Visible = msoTrue
End Sub
It is worth mentioning how I came up with the image names, since I didn't find a way to do this from inside Word. I renamed the template extension to zip and unzipped it. In the extracted files I opened word\header2.xml (this may vary, depending on the position in the document) and edited the nodes containing the names of pictures, i.e. <wp:docPr/>, e.g.:
<wp:docPr name="Picture 1" id="1"/>
became:
<wp:docPr name="logo_magenta.png" id="1"/>
etc. I then replaced the XML file in the ZIP with my edited version and changed the extension back to dotm.
As mentioned, there are several ways to do this. I would suggest storing the images outside of the template, otherwise all documents based on the templates would include all logo images, even if they are not shown, making the documents bigger than they need to be. That approach makes installing the template a bit harder, since you would have to copy the images to the clients as well as the template file.
To answer your question regarding addressing the images in the header - you can address then through the correct story range object. In my example I assume that they are in the primary header. To tell the different images apart, you can use the Name property or the index in the Item collection:
ThisDocument.StoryRanges(wdPrimaryHeaderStory).ShapeRange.Item("Picture 1").Visible = msoTrue
ThisDocument.StoryRanges(wdPrimaryHeaderStory).ShapeRange.Item(1).Visible = msoFalse