How do you work with simple arrays in VBA?

M

Mel

PPT 2003/2007

I'm trying to understand arrays. I just want to capture the slides
currently selected and then running some actions on each of them,
which causes the selection to be lost, so I have to capture the slide
numbers before the action loop.

Likewise, I'm trying to do the same with selected shapes on a slide,
where I want to run a loop for each selected shape, but in doing so I
loose the selection so I need to first capture the selected shapes
names (I guess) and then run on all of them.

I've read and tried several things but it escapes me. Can someone show
me how this is done? Here's a feeble attempt I made...

Sub TestArray()

Dim iSldSelCnt As Integer
iSldSelCnt = ActiveWindow.Selection.SlideRange.Count

Dim iSldSelNum() As Integer
ReDim iSldSelNum(iSldSelCnt - 1) As Integer

Dim iSld As Long
iSld = 0

Dim oSld As Slide
For Each oSld In ActiveWindow.Selection.SlideRange
iSldSelNum(iSld) = oSld.SlideNumber
iSld = iSld + 1
Next oSld

ActivePresentation.Slides(iSldSelNum).Shapes.AddShape _
Type:=msoShapeRectangle, _
Left:=50, Top:=50, Width:=100, Height:=200

'ActiveWindow.Selection.SlideRange(iSldSelNum).Shapes.AddShape _
' Type:=msoShapeRectangle, _
' Left:=50, Top:=50, Width:=100, Height:=200

End Sub


Thanks,
-Melina
 
D

David Marcovitz

Don't use selection to do what you want. It is rarely a good idea. I have a
section in my book about arrays that might help you understand them.

Instead of:

For Each oSld In ActiveWindow.Selection.SlideRange

Try

For Each oSld In ActivePresentation.Slides

Or if you have to do this with selected slides, get your parameters at the
beginning, such as:

start = ActiveWindow.Selection.SlideRange(1).SlideIndex
end = ActiveWindow.Selection.SlideRange.Count

For i = start To End

....


Next i

Sorry, I have class in 10 minutes so I don't have time to look over this any
more. One more quick thing. Put the Dim at the top of the procedure and keep
the ReDim where it is.

--David

PPT 2003/2007

I'm trying to understand arrays. I just want to capture the slides
currently selected and then running some actions on each of them,
which causes the selection to be lost, so I have to capture the slide
numbers before the action loop.

Likewise, I'm trying to do the same with selected shapes on a slide,
where I want to run a loop for each selected shape, but in doing so I
loose the selection so I need to first capture the selected shapes
names (I guess) and then run on all of them.

I've read and tried several things but it escapes me. Can someone show
me how this is done? Here's a feeble attempt I made...

Sub TestArray()

Dim iSldSelCnt As Integer
iSldSelCnt = ActiveWindow.Selection.SlideRange.Count

Dim iSldSelNum() As Integer
ReDim iSldSelNum(iSldSelCnt - 1) As Integer

Dim iSld As Long
iSld = 0

Dim oSld As Slide
For Each oSld In ActiveWindow.Selection.SlideRange
iSldSelNum(iSld) = oSld.SlideNumber
iSld = iSld + 1
Next oSld

ActivePresentation.Slides(iSldSelNum).Shapes.AddShape _
Type:=msoShapeRectangle, _
Left:=50, Top:=50, Width:=100, Height:=200

'ActiveWindow.Selection.SlideRange(iSldSelNum).Shapes.AddShape _
' Type:=msoShapeRectangle, _
' Left:=50, Top:=50, Width:=100, Height:=200

End Sub


Thanks,
-Melina

--
David M. Marcovitz
Author of _Powerful PowerPoint for Educators_
http://www.PowerfulPowerPoint.com/
Microsoft PowerPoint MVP
Associate Professor, Loyola University Maryland
 
M

Mel

The challenge is I need loop through objects in just the slides I
select, not all of slides. So, out of 10 slides I selected slides 2,
4, and 8. I need to loop through objects only on those slides. As I do
the actions on one slide, the other slides selected loose their
selection and PPT can find the next slide in the selection because
it's now de-selected. The same happens with selected shapes, I
noticed. When I select 3 out 7 of my slide shapes, once I start
working with them, deleting, replacing, etc, PPT deselects the other
shapes. Is there a way to make the routine collect the slide numbers
or shape names in the selection beforehand and then loop through each
of those?

Thanks,
-Melina
 
M

Mel

I tried learning about using collections instead of arrays and wrote
the following which in my tests collected slide numbers and shape
names and looped through them after the selection was deselected. Any
comments on using collections as opposed to arrays like I'm doing
below?

Thanks,
Melina

Sub WorkSelectedSlidesDeselected()
Dim oSld As Slide
Dim oSldNum As Variant
Dim SelectedSlides As New Collection
Dim oPrez As Presentation
Set oPrez = ActivePresentation

'Note current selected slides
For Each oSld In ActiveWindow.Selection.SlideRange
SelectedSlides.Add oSld.SlideNumber
Next oSld

'Loose slide selection
oPrez.Slides(1).Select

'Loop through originally selected slides anyway
For Each oSldNum In SelectedSlides
ActivePresentation.Slides(oSldNum).Shapes.AddLabel _
(Orientation:=msoTextOrientationHorizontal, _
Left:=100, Top:=100, Width:=60, Height:=150) _
.TextFrame.TextRange.Text = "Hello world."
Next oSldNum

End Sub

Sub WorkSelectedShapesDeselected()
Dim oShp As Shape
Dim oShpNm As Variant
Dim SelectedShapes As New Collection
Dim oPrez As Presentation
Set oPrez = ActivePresentation
Dim iCurrSld As Long
iCurrSld = ActiveWindow.Selection.SlideRange.SlideNumber

'Note current selected shapes
For Each oShp In ActiveWindow.Selection.ShapeRange
SelectedShapes.Add oShp.Name
Next oShp

'Loose shape selection
ActiveWindow.Selection.Unselect

'Loop through originally selected shapes anyway
For Each oShpNm In SelectedShapes
oPrez.Slides(iCurrSld).Shapes(oShpNm).Flip msoFlipHorizontal
Next oShpNm

End Sub
 
M

Mel

Hi Steve. Your array below gets a compile error "Constant Expression
Required" on the "raySlides(1 To lSlideCount)". I tried this earlier
in my own code and got the same. Even if it worked, I don't see where
it's adding items to the array, and I'm wondering if it would put
noncontiguous slides into it?

Did you see my post in this thread about using collections instead.
They actually worked and I'm wanting to know if I should go with that.
Arrays seem so very difficult to me. I even read one author say
collections are easier on resources. Your thoughts?

In answer to your other point about selecting, this routine picks up
after a user selects shapes, then this does all sorts of things with
them and some of it causes a loss of selection. Another part picks up
after the user selects a choice of slides, which might be
noncontiguous. The routine then loops through each object in each of
those slides, and some of those tasks cause loss of slide selection.
So, that's why I can't stick inside the sliderange or shaperange
throughout the actions. I have to memorize what those are and then
loop through the memorization as selections then change or are lost. I
know it's complicated, but that's my life. <g>

Let me know what you think of my collections code.

-Melina

I'm trying to understand arrays. I just want to capture the slides
currently selected and then running some actions on each of them,
which causes the selection to be lost, so I have to capture the slide
numbers before the action loop.
Likewise, I'm trying to do the same with selected shapes on a slide,
where I want to run a loop for each selected shape, but in doing so I
loose the selection so I need to first capture the selected shapes
names (I guess) and then run on all of them.
I've read and tried several things but it escapes me. Can someone show
me how this is done? Here's a feeble attempt I made...

Coupla things for starters ...

Use Longs instead of Integers unless you have specific need for an int.
Nearly everything in PPT uses Longs and in 32-bit systems, they're more
efficient anyhow.

Don't use SlideNumber ... use SlideIndex. SlideNumber gives you the
number that'll appear on the slide if numbering is enabled. If the
user's changed the starting number to something other than 1, that'll
throw EVERYTHING off. SlideIndex gives you the value you EXPECT no
matter what.

If it were mine to do, I'd probably declare an array of Slides.
[AIRCODEWARNING]

Dim lCounter as Long
Dim lSlideCount as Long

lSlideCount = ActiveWindow.Selection.SlideRange.Count

Dim raySlides(1 to lSlideCount) as Slide
For lCounter = 1 to lSlideCount
Set raySlides(lCounter) = _
ActiveWindow.Selection.SlideRange(lCounter)
Next

Then step through the array adding shapes, along the lines of

With raySlides(lCounter)
.Shapes.AddEtceteraEtceteraAndSoOn
End With

But couldn't you do more like:

Dim oSld As Slide
For Each oSld In ActiveWindow.Selection.SlideRange
oSlde.Shapes.Add Blah Blah Blah
Next




Sub TestArray()
Dim iSldSelCnt As Integer
iSldSelCnt = ActiveWindow.Selection.SlideRange.Count
Dim iSldSelNum() As Integer
ReDim iSldSelNum(iSldSelCnt - 1) As Integer
Dim iSld As Long
iSld = 0
Dim oSld As Slide
For Each oSld In ActiveWindow.Selection.SlideRange
iSldSelNum(iSld) = oSld.SlideNumber
iSld = iSld + 1
Next oSld
ActivePresentation.Slides(iSldSelNum).Shapes.AddShape _
Type:=msoShapeRectangle, _
Left:=50, Top:=50, Width:=100, Height:=200
'ActiveWindow.Selection.SlideRange(iSldSelNum).Shapes.AddShape _
' Type:=msoShapeRectangle, _
' Left:=50, Top:=50, Width:=100, Height:=200
Thanks,
-Melina

==============================
PPT Frequently Asked Questionshttp://www.pptfaq.com/

PPTools add-ins for PowerPointhttp://www.pptools.com/
 
J

John Wilson

Hi Mel

As well as the good advice from Steve & David maybe you could try setting an
object variable to reference the selected slides?

Sub Add_shapes()
Dim osldR As SlideRange
Dim osld As Slide
Dim oshp As Shape
Set osldR = ActiveWindow.Selection.SlideRange
For Each osld In osldR
For Each oshp In osld.Shape
'do whatever
Next oshp
Next osld
End Sub

Not tested air code BTW!
--
john ATSIGN PPTAlchemy.co.uk

Free PPT Hints, Tips and Tutorials
http://www.pptalchemy.co.uk/powerpoint_hints_and_tips_tutorials.html






Mel said:
Hi Steve. Your array below gets a compile error "Constant Expression
Required" on the "raySlides(1 To lSlideCount)". I tried this earlier
in my own code and got the same. Even if it worked, I don't see where
it's adding items to the array, and I'm wondering if it would put
noncontiguous slides into it?

Did you see my post in this thread about using collections instead.
They actually worked and I'm wanting to know if I should go with that.
Arrays seem so very difficult to me. I even read one author say
collections are easier on resources. Your thoughts?

In answer to your other point about selecting, this routine picks up
after a user selects shapes, then this does all sorts of things with
them and some of it causes a loss of selection. Another part picks up
after the user selects a choice of slides, which might be
noncontiguous. The routine then loops through each object in each of
those slides, and some of those tasks cause loss of slide selection.
So, that's why I can't stick inside the sliderange or shaperange
throughout the actions. I have to memorize what those are and then
loop through the memorization as selections then change or are lost. I
know it's complicated, but that's my life. <g>

Let me know what you think of my collections code.

-Melina

I'm trying to understand arrays. I just want to capture the slides
currently selected and then running some actions on each of them,
which causes the selection to be lost, so I have to capture the slide
numbers before the action loop.
Likewise, I'm trying to do the same with selected shapes on a slide,
where I want to run a loop for each selected shape, but in doing so I
loose the selection so I need to first capture the selected shapes
names (I guess) and then run on all of them.
I've read and tried several things but it escapes me. Can someone show
me how this is done? Here's a feeble attempt I made...

Coupla things for starters ...

Use Longs instead of Integers unless you have specific need for an int.
Nearly everything in PPT uses Longs and in 32-bit systems, they're more
efficient anyhow.

Don't use SlideNumber ... use SlideIndex. SlideNumber gives you the
number that'll appear on the slide if numbering is enabled. If the
user's changed the starting number to something other than 1, that'll
throw EVERYTHING off. SlideIndex gives you the value you EXPECT no
matter what.

If it were mine to do, I'd probably declare an array of Slides.
[AIRCODEWARNING]

Dim lCounter as Long
Dim lSlideCount as Long

lSlideCount = ActiveWindow.Selection.SlideRange.Count

Dim raySlides(1 to lSlideCount) as Slide
For lCounter = 1 to lSlideCount
Set raySlides(lCounter) = _
ActiveWindow.Selection.SlideRange(lCounter)
Next

Then step through the array adding shapes, along the lines of

With raySlides(lCounter)
.Shapes.AddEtceteraEtceteraAndSoOn
End With

But couldn't you do more like:

Dim oSld As Slide
For Each oSld In ActiveWindow.Selection.SlideRange
oSlde.Shapes.Add Blah Blah Blah
Next




Sub TestArray()
Dim iSldSelCnt As Integer
iSldSelCnt = ActiveWindow.Selection.SlideRange.Count
Dim iSldSelNum() As Integer
ReDim iSldSelNum(iSldSelCnt - 1) As Integer
Dim iSld As Long
iSld = 0
Dim oSld As Slide
For Each oSld In ActiveWindow.Selection.SlideRange
iSldSelNum(iSld) = oSld.SlideNumber
iSld = iSld + 1
Next oSld
ActivePresentation.Slides(iSldSelNum).Shapes.AddShape _
Type:=msoShapeRectangle, _
Left:=50, Top:=50, Width:=100, Height:=200
'ActiveWindow.Selection.SlideRange(iSldSelNum).Shapes.AddShape _
' Type:=msoShapeRectangle, _
' Left:=50, Top:=50, Width:=100, Height:=200
Thanks,
-Melina

==============================
PPT Frequently Asked Questionshttp://www.pptfaq.com/

PPTools add-ins for PowerPointhttp://www.pptools.com/

.
 
M

Mel

Yeah, my task description was a bit fuzzy. <g> The routine is a matter
of EITHER they chose specific objects on a slide OR they chose
specific slides. The first situation loops through the selected shapes
only and the second loops through all the objects on the selected
slides. They declare which they want to do in an opening dialog box
and then the code splits to do one or the other loop types. As to
selecting, if they choose the first option, they have to first
actually select the objects they want, of course, and the second
option doesn't involve selecting shapes - not even in the code.

I realize arrays are collections but I seem to always get stuck using
them - even in Excel programming. For some reason declaring, adding,
and calling them gives me fits. The difference with what I found to be
much easier was discovering the "New Collection" object that seems to
be more intuitive to me and I can run loops off it better. I don't
really know why. If I could better understand conventional arrays
better maybe it'd be different. Do you know of a good source that
explains them in practical terms? Whenever I read about them, it gets
so technical my brain starts twisting around in my skull. <g>

I'm thrilled to report this add-in project is now finished and
working. This morning it was demo'ed and ran through its paces by our
head of communications and a small focus group. Besides a few minor
hic-ups, it was in his words, "jaw dropping". He called and bragged to
our global VP of communication and the corporate CIO in Europe, who
asked for a private viewing and may want it deployed internationally.
Cool!

You know I couldn't have had this success without your help, Steve.
You made all the difference and helped me keep my sanity (what little
I have left). I hope I haven't worn out my welcome with you, 'cuz I'm
sure I'll run into more ruts as I do more projects and I'll need more
guidance I'm sure. <g> Thanks bunches!

-Melina
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top