PDA

View Full Version : Solved: New to VB. Macro to format object



RockMechMark
07-22-2011, 11:48 AM
I have no experience using Visual Basic with Powerpoint. My feet are only slightly wet in its use with Excel. I am requesting help with a very basic function to get me started.

I have several slides with four jpg objects, each toward the corners of the slide. I need to replace the jpgs. For now, I will do that manually. However, the two jpgs on the right have white space that extend off the slide. When I change the picture, it changes the size, position and cropping parameters. I would like to automate this a little. I see two approaches:

(1) I change the pictures manually, then I would like to execute a macro that changes the size, position, and cropping parameters of the right two jpgs back to what I want them. This could be done by either selecting an object and executing the appropriate macro (one per object position), or just executing one macro that selects the appropriate objects and changes the appropriate parameters.

(2) Change the cropping of the right two jpgs to zero, then prompt for changing the jpg for each of the four, then changing the cropping of the right two jpgs back to the final setting. This is possible because it is the cropping setting that forces the change in size and position.

Any takers? Thanks.

dougbert
08-11-2011, 12:06 AM
Hi RockMechMark,

If my solution works for you, please marked this thread as Solved by clicking on the Thread Tools menu just above your first post to the right. A nice rating is always appreciated too! :rotlaugh:

Welcome to PP VBA! Instead of just dropping some code here, and since this is new to you, I'm going to explain some of the code in advance to help get you started.

The strange thing about pics in any MS Office app is that if you select the pic on the active window and look at the Picture Tools menu, its size will be measured in inches. However, VBA code uses pixels instead. So, you need to do the conversions to get the results you want.

A PP slide is in landscape mode. A 4:3 ratio slide is intended to be printed on 11" x 8.5" paper in landscape orientation. There are 72 pixels/inch. So, a piece of paper (and the slide) is 828x612 pixels in size.

Since I can't actually see your project (unless you post a link to it on PhotoBucket or somewhere), I can only tell you how I tested the macro, and hopefully, you can make the mental adjustments. I'm going to keep this pretty basic until you reply. Then, we can tweak as necessary.

Testing: I placed 4 .jpg photos measuring 4"width x 3"height (288x216 pixels) in the extreme 4 corners of a PP slide. The macro first counts the number of photos in order to know how many times to go through the loop. It loops through the photos one at a time starting with #1 in the upper left, then #2 in the lower left, then #3 in the upper right, ... Each time through the loop each photo is cropped, resized, positioned, etc. individually, so feel free to customize. Photos #1&2 get resized to 200px in height. The aspect ratio is maintained by JUST changing EITHER the height or width (I chose height), not BOTH. Photos #3&4 get cropped first, then resized. I don't know how much white space are on your objects, so experiment with the cropping until it's correct.

Some terms:
.Height = the desired height of the photo in number of pixels
.Left = the number of pixels from the left side of the current photo to the left-hand side of the slide
.Top = the number of pixels from the top of the current photo to the top of the slide

In my opinion, the best way to see what the macro does with each line is to step through the macro one line at a time, and toggle back to see what happened on the slide.

Instructions: copy/paste the code into a regular module. Compile the code. Obviously, use copies of your slides for testing. What I do is create one slide the way I want to start it, highlight the slide in the preview pane on the left side, and press <Ctrl-D> a bunch of times to make duplicates. Now, highlight the first slide. Toggle to the code module and press <F8> repeatedly until you get to the Case 1 line. As you step though each line under Case 1, toggle back to the slide to see what that line did to the pic on the slide. After you've stepped through the loop to the end of the sub, you'll probably gain a much better understanding.

Here's the code:



Option Explicit
Sub FormatSlidePix()
Dim ShapeIndex As Integer
ActiveWindow.Activate
For i = 1 To ActiveWindow.Selection.SlideRange.Shapes.Count
With ActiveWindow.Selection.SlideRange.Shapes(i)
ActiveWindow.Selection.SlideRange.Shapes(i).Select
Select Case (i)
Case 1
.LockAspectRatio = msoTrue ' Locks aspect ratio
.Height = 200 ' Aspect ratio based on height of pic in pixels
.Left = 45
.Top = 20
.Name = "Picture 1"
Case 2
.LockAspectRatio = msoTrue ' Locks aspect ratio
.Height = 200 ' Aspect ratio based on height of pic in pixels
.Left = 45
.Top = 300
.Name = "Picture 2"
Case 3
.PictureFormat.CropRight = 72 ' 72px equals 1". So, white space is cropped 1" on right before pic is resized
.LockAspectRatio = msoFalse ' This allows cropping without retaining the full original pic
.Height = 200
.Left = 400
.Top = 20
.Name = "Picture 3"
Case 4
.PictureFormat.CropRight = 72 ' 72px equals 1". So, white space is cropped 1" on right before pic is resized
.LockAspectRatio = msoFalse ' This allows cropping without retaining the full original pic
.Height = 200
.Left = 400
.Top = 300
.Name = "Picture 4"
End Select
End With
Next i
ActiveWindow.Selection.Unselect
End Sub


Don't forget to save as a macro-enabled presentation.

Feel free to ask me any questions about how to tweak this further.
-dougbert

John Wilson
08-11-2011, 05:09 AM
PowerPoint never measures pictures (or anything) in PIXELS it always uses POINTS

I'm pretty sure you code as posted won't run unless you declare i as a variable

It is hardly ever sensible to select objects in vba code in PowerPoint
ActiveWindow.Selection.SlideRange.Shapes(i).Select
Does nothing (except slow the code)

Pictures are set to LockAspectRatio=msoTrue by default though it doesn't hurt to check!

You need to be very careful using CropRight (or the other crops) as they crop based on the ORIGINAL size NOT the current size and may not do what you expect.

You probably need to post an example of what you need though it's not clear what you need.

dougbert
08-11-2011, 04:45 PM
John,

Thanks for your critique.

Good catch on declaring (i) As Integer. I had aready posted the code and slipped the Option Explicit in at the last minute while editing my post without having actually run that code and forgetting that detail. So, I'll repost below with the correct declaration, so that it will run correctly.

I placed the .cropright in my code prior to resizing the .jpg for just the reason you mentioned. It seems to work pretty on the .jpg photos I tested.

Also, good catch on the pixels vs. points. I was working with .jpg images in pixels and didn't make the mental switch when working in PP. Mark, your .jpg photos are likely to measured in pixels. Anyways, I'm not here to debate 'units'. Just play with the values whatever their 'units' may be until it looks like you want it to look.

But, I did some experimenation with PP VBA 'unit' values by changing .top and .left values until the upper left-hand corner of my .jpg photo was just touching the lower right-hand corner of a slide (obviously completely off of the slide). Based upon working with the standard 4:3 slide in PP, the approximate dimensions of the slide would then be: 720x540 'units'!!! This is a ratio of 4:3. So, keep this in mind when working with the values in the code for .height, .top, .left and .cropright. Halfway left to right is ~360. Halfway top to bottom is ~270.

Mark, once again, I have no idea what your project looks like, so the code will require that you modify the 'unit' values until it works for your project.

Here's a link to my Test Photos: http://i1177.photobucket.com/albums/x353/dougbert69/TestPhotos.jpg
Here's a link to what the results were for the macro on the Test Photos: http://i1177.photobucket.com/albums/x353/dougbert69/TestPhotosResults.jpg

Here's my revised (more sensible and working!) code:



Option Explicit
Sub FormatSlidePix()
Dim i As Integer
ActiveWindow.Activate
For i = 1 To ActiveWindow.Selection.SlideRange.Shapes.Count
With ActiveWindow.Selection.SlideRange.Shapes(i)
Select Case (i)
Case 1
.LockAspectRatio = msoTrue ' Locks aspect ratio
.Height = 200 ' Aspect ratio based on height of pic in points
.Left = 45
.Top = 20
.Name = "Picture 1"
Case 2
.LockAspectRatio = msoTrue ' Locks aspect ratio
.Height = 200 ' Aspect ratio based on height of pic in points
.Left = 45
.Top = 300
.Name = "Picture 2"
Case 3
.PictureFormat.CropRight = 100 ' Any 'white space' is cropped by 100 points on right before pic is resized
.LockAspectRatio = msoFalse ' This allows cropping without retaining the full original pic
.Height = 200
.Left = 400
.Top = 20
.Name = "Picture 3"
Case 4
.PictureFormat.CropRight = 100 ' Any 'white space' is cropped by 100 points on right before pic is resized
.LockAspectRatio = msoFalse ' This allows cropping without retaining the full original pic
.Height = 200
.Left = 400
.Top = 300
.Name = "Picture 4"
End Select
End With
Next i
ActiveWindow.Selection.Unselect
End Sub


-dougbert

dougbert
08-11-2011, 05:58 PM
Too much white space on my links. Here they are with a better background to see the result more clearly....I hope.

Here's a link to my Test Photos: http://i1177.photobucket.com/albums/x353/dougbert69/TestPhotos-1.jpg

Here's a link to what the results were for the macro on the Test Photos: http://i1177.photobucket.com/albums/x353/dougbert69/TestPhotosResults-1.jpg. Notice that the 2 pix on the right side have been cropped by 100 'units' on the right side.

-dougbert

John Wilson
08-11-2011, 11:58 PM
Hi Dougbert

I didn't mean to sound quite so critical, I'm a professional PowerPoint programmer and we are sort of allergic to misinformation being posted on the net!

Understanding the difference between points and pixels is crucial. If I insert a pic from my camera maybe 3000x 2000 pixels and resize it to 300 x 200 POINTS it will still be 3000 pixels wide. Calling them "units" doesn't really help!

While your code looks like it works (because the pictures were not really resized much) you haven't grasped the strange problem with cropright etc (you're not alone)

If you start with a 800 wide image >> resize to say 200 and cropright 72. It will NOT crop an inch but a quarter of an inch (based on the original size) If you crop again by 100 nothing will happen.

If you are distributing images around the slide you need to know how big the slide is to start with - in points of course (not assume it's 826 x 612 or even 720 x 540 which is more likely)

You can get these dimesions by:
With ActivePresentation.PageSetup
MsgBox "Your slide is " & .SlideWidth & "x" & .SlideHeight
End With

dougbert
08-21-2011, 11:01 AM
John,

No offense taken. I defer to your professional experience. I'd be a fool to argue the 'point' with you. ;)

I was just offering code that has allowed me to manipulate .jpg objects effectively from my experience and would be relatively easy for RockMechMark to utilize as per his "very basic function" request.
Cheers! :beerchug:
-dougbert

RockMechMark
08-22-2011, 11:59 AM
Gentlemen,

Thanks so much for your replies. I have been on vacation the last two weeks, so therefore, I have not replied.

I had to reformat all of the jpegs on 132 different slides by hand before the last week of July. My co-worker left to present a paper of ours at a conference, but he needed these slides completed for an informal meeting with a professor and his grad students. However, I will have need in the very near future to perform formating by macro, so I will study the script you have provided and your comments to be sure I understand, then test the script for my application. It will take me a few days, because there are two or three things demanding my immediate attention. However, I will do the testing as soon as I can, because it will be very useful to me.

I really appreciate your help. I will post again to let you know how I fared or if I have any more questions. At first glance, it all seems very logical, but I could have some questions. Thanks again.

RockMechMark

RockMechMark
08-31-2011, 11:12 AM
Gentlemen,

I tested this code on a similar problem with two jpgs on each slide. I used the same concepts, but I had to change one thing. To get what I wanted, I had to set the aspect ratio to be kept constant before I cropped the jpg on the right. The reason is that the jpgs are graphs, and I needed to crop white space on the right (and on the bottom in this case). Not keeping the aspect ratio constant distorted the graph.

Dougbert, your solution worked very well for me with that modification. Thank you so much.

RockMechMark

dougbert
08-31-2011, 09:42 PM
You're very welcome. I'm happy for your success. Thanks for taking the time to report back.

-dougbert