dougbert
02-16-2012, 03:55 PM
Hi all,
I'm using Office 2010 Professional Plus.
I receive an exported slide set containing just charts and tables from a third-party vendor. So, I have no control over the source.
My first macro copies the charts and tables from the exported slide set to a macro-enabled template. That works just fine.
My second macro (which compiles without errors) then loops through all the shapes on all the slides that have been transferred to the template to position, format, etc. the charts and tables they contain. Oddly, if I step through the macro one line at a time using <F8>, the macro executes flawlessly. However, if I press <F5> to execute this same macro, the code stops "somewhere" within a loop designed to query a chart's embedded data table and format the series data points (bars) with the conditional color.
I'll display the portion of the loop where execution stops "somewhere" in a moment. Since PowerPoint 2007 SP2, MS requires us to first Activate the ChartData member of the Chart class, which opens the embedded data table within Excel. Then, we MUST minimize the activated Excel data table in order to work with its contents. Finally, when we're done working with the embedded data table, we must quit the Excel application that is activated, before working with something like the .Chart.SeriesCollection(1).Points(j) members in the chart itself.
Since my data table query is working in a query/assign/format loop, things happen VERY fast. MY SUSPICION is that I'm opening/minimizing/querying/closing Excel faster than it can handle in a loop. I tried placing a While loop right after the line that minimizes Excel in an attempt to sloooowww things down for Excel. Adding 100 million loops of adding one to 'x' DID slow things down, but execution would still stop on one of the following lines during a RUN.
First, here's the 'portion' of the loop where execution could stop on ANY line, except the color value assignment lines. The errors varied depending upon where execution stopped. However, I don't believe they are actual errors, since manual line by line exection revealed NO errors.
I would appreciate ANY suggestions or observations!!!
The lines in the loop 'portion' of my code where execution might/has stop(ped) randomly:
'Open embedded data table in Excel application
.Activate
'Minimize data table (required by MS to manipulate or query table)
.Workbook.Application.WindowState = -4140
'Determine data point value and set color
If .Workbook.Worksheets("Sheet1").Cells(k, 2) < 3 And .Workbook.Worksheets("Sheet1").Cells(k, 2) > 0 Then
oBarClr = "Red"
End If
If .Workbook.Worksheets("Sheet1").Cells(k, 2) >= 3 And .Workbook.Worksheets("Sheet1").Cells(k, 2) < 4 Then
oBarClr = "Yellow"
End If
If .Workbook.Worksheets("Sheet1").Cells(k, 2) >= 4 Then
oBarClr = "Green"
End If
.Workbook.Application.Quit
Here is the entire DRAFT version of my code:
Option Explicit
Sub FixUpShapesAndFormatTables()
' This macro removes extra OLE control objects, conditionally formats charts and re-formats tables
Dim lRow As Long
Dim lCol As Long
Dim oSd As Slide
Dim oSp As Shape
Dim oBarClr As String
Dim i As Long
Dim j As Long
Dim k As Long
Dim x As Long
Dim pts As Points
Dim ptsCnt As Long
Dim iNo_of_Rows As Long
' Visit every slide in presentation
For Each oSd In ActivePresentation.Slides
' Check every shape on slide
For Each oSp In oSd.Shapes
With oSp
' If the shape is a msoOLEControlObject, delete the shape
If oSp.Type = msoOLEControlObject Then
oSp.Delete
' Skip to next shape
GoTo NextShape
End If
' Check if shape is a chart
If oSp.Type = msoChart Then
If .Chart.HasTitle = True Then
.Chart.HasTitle = False
End If
If .Chart.HasLegend = True Then
.Chart.HasLegend = False
End If
.Height = 250
'Determine number of points in series
Set pts = .Chart.SeriesCollection(1).Points
ptsCnt = pts.Count
j = 1
'Determine number of rows in data table for chart
With .Chart.ChartData
.Activate
'Minimize data table (required by MS to manipulate or query table)
.Workbook.Application.WindowState = -4140
x = 1
While Len(.Workbook.Worksheets("Sheet1").Cells(x, 2)) > 0
x = x + 1
Wend
iNo_of_Rows = x - 1
.Workbook.Application.Quit
End With
'Format color for the bars in the chart depending upon data point value from data table
While j <= ptsCnt
For k = 2 To iNo_of_Rows
With .Chart.ChartData
'Open embedded data table in Excel application
.Activate
'Minimize data table (required by MS to manipulate or query table)
.Workbook.Application.WindowState = -4140
'Determine data point value and set color
If .Workbook.Worksheets("Sheet1").Cells(k, 2) < 3 And .Workbook.Worksheets("Sheet1").Cells(k, 2) > 0 Then
oBarClr = "Red"
End If
If .Workbook.Worksheets("Sheet1").Cells(k, 2) >= 3 And .Workbook.Worksheets("Sheet1").Cells(k, 2) < 4 Then
oBarClr = "Yellow"
End If
If .Workbook.Worksheets("Sheet1").Cells(k, 2) >= 4 Then
oBarClr = "Green"
End If
.Workbook.Application.Quit
End With
'Apply color to data point in series
With .Chart.SeriesCollection(1).Points(j)
If oBarClr = "Red" Then
.Interior.Color = RGB(255, 0, 0) 'red
ElseIf oBarClr = "Yellow" Then
.Interior.Color = RGB(255, 255, 0) 'yellow
Else
.Interior.Color = RGB(0, 255, 0) 'green
End If
'Increment counter to next data point
j = j + 1
End With
Next k
Wend
End If
'Check if shape is a table
If oSp.Type = 19 Then
' Position and resize table
.Top = 80
.Left = 50
.Width = 600
.Height = 0.1
With .Table
' Delete first column
.Columns(1).Delete
' Set remaining column width
.Columns(1).Width = 600
' Go through table by rows and columns
For lRow = 1 To .Rows.Count
For lCol = 1 To .Columns.Count
' Set cell margin
With .Cell(lRow, lCol)
.Shape.TextFrame.MarginLeft = 10
End With
' Format text in cells
With .Cell(lRow, lCol).Shape.TextFrame.TextRange
If lRow = 1 Then
.Font.Bold = msoTrue
.Font.Underline = msoFalse
.Font.Color = vbWhite
.Font.Size = 14
.Font.Name = "Arial"
.ParagraphFormat.Alignment = ppAlignCenter
Else
.Font.Bold = msoFalse
.Font.Underline = msoFalse
.Font.Color = vbBlack
.Font.Size = 12
.Font.Name = "Arial"
.ParagraphFormat.Alignment = ppAlignLeft
End If
End With
Next lCol
Next lRow
End With
End If
End With
NextShape:
Next oSp
NextSlide:
Next oSd
Set pts = Nothing
Set oSp = Nothing
Set oSd = Nothing
End Sub
I'm using Office 2010 Professional Plus.
I receive an exported slide set containing just charts and tables from a third-party vendor. So, I have no control over the source.
My first macro copies the charts and tables from the exported slide set to a macro-enabled template. That works just fine.
My second macro (which compiles without errors) then loops through all the shapes on all the slides that have been transferred to the template to position, format, etc. the charts and tables they contain. Oddly, if I step through the macro one line at a time using <F8>, the macro executes flawlessly. However, if I press <F5> to execute this same macro, the code stops "somewhere" within a loop designed to query a chart's embedded data table and format the series data points (bars) with the conditional color.
I'll display the portion of the loop where execution stops "somewhere" in a moment. Since PowerPoint 2007 SP2, MS requires us to first Activate the ChartData member of the Chart class, which opens the embedded data table within Excel. Then, we MUST minimize the activated Excel data table in order to work with its contents. Finally, when we're done working with the embedded data table, we must quit the Excel application that is activated, before working with something like the .Chart.SeriesCollection(1).Points(j) members in the chart itself.
Since my data table query is working in a query/assign/format loop, things happen VERY fast. MY SUSPICION is that I'm opening/minimizing/querying/closing Excel faster than it can handle in a loop. I tried placing a While loop right after the line that minimizes Excel in an attempt to sloooowww things down for Excel. Adding 100 million loops of adding one to 'x' DID slow things down, but execution would still stop on one of the following lines during a RUN.
First, here's the 'portion' of the loop where execution could stop on ANY line, except the color value assignment lines. The errors varied depending upon where execution stopped. However, I don't believe they are actual errors, since manual line by line exection revealed NO errors.
I would appreciate ANY suggestions or observations!!!
The lines in the loop 'portion' of my code where execution might/has stop(ped) randomly:
'Open embedded data table in Excel application
.Activate
'Minimize data table (required by MS to manipulate or query table)
.Workbook.Application.WindowState = -4140
'Determine data point value and set color
If .Workbook.Worksheets("Sheet1").Cells(k, 2) < 3 And .Workbook.Worksheets("Sheet1").Cells(k, 2) > 0 Then
oBarClr = "Red"
End If
If .Workbook.Worksheets("Sheet1").Cells(k, 2) >= 3 And .Workbook.Worksheets("Sheet1").Cells(k, 2) < 4 Then
oBarClr = "Yellow"
End If
If .Workbook.Worksheets("Sheet1").Cells(k, 2) >= 4 Then
oBarClr = "Green"
End If
.Workbook.Application.Quit
Here is the entire DRAFT version of my code:
Option Explicit
Sub FixUpShapesAndFormatTables()
' This macro removes extra OLE control objects, conditionally formats charts and re-formats tables
Dim lRow As Long
Dim lCol As Long
Dim oSd As Slide
Dim oSp As Shape
Dim oBarClr As String
Dim i As Long
Dim j As Long
Dim k As Long
Dim x As Long
Dim pts As Points
Dim ptsCnt As Long
Dim iNo_of_Rows As Long
' Visit every slide in presentation
For Each oSd In ActivePresentation.Slides
' Check every shape on slide
For Each oSp In oSd.Shapes
With oSp
' If the shape is a msoOLEControlObject, delete the shape
If oSp.Type = msoOLEControlObject Then
oSp.Delete
' Skip to next shape
GoTo NextShape
End If
' Check if shape is a chart
If oSp.Type = msoChart Then
If .Chart.HasTitle = True Then
.Chart.HasTitle = False
End If
If .Chart.HasLegend = True Then
.Chart.HasLegend = False
End If
.Height = 250
'Determine number of points in series
Set pts = .Chart.SeriesCollection(1).Points
ptsCnt = pts.Count
j = 1
'Determine number of rows in data table for chart
With .Chart.ChartData
.Activate
'Minimize data table (required by MS to manipulate or query table)
.Workbook.Application.WindowState = -4140
x = 1
While Len(.Workbook.Worksheets("Sheet1").Cells(x, 2)) > 0
x = x + 1
Wend
iNo_of_Rows = x - 1
.Workbook.Application.Quit
End With
'Format color for the bars in the chart depending upon data point value from data table
While j <= ptsCnt
For k = 2 To iNo_of_Rows
With .Chart.ChartData
'Open embedded data table in Excel application
.Activate
'Minimize data table (required by MS to manipulate or query table)
.Workbook.Application.WindowState = -4140
'Determine data point value and set color
If .Workbook.Worksheets("Sheet1").Cells(k, 2) < 3 And .Workbook.Worksheets("Sheet1").Cells(k, 2) > 0 Then
oBarClr = "Red"
End If
If .Workbook.Worksheets("Sheet1").Cells(k, 2) >= 3 And .Workbook.Worksheets("Sheet1").Cells(k, 2) < 4 Then
oBarClr = "Yellow"
End If
If .Workbook.Worksheets("Sheet1").Cells(k, 2) >= 4 Then
oBarClr = "Green"
End If
.Workbook.Application.Quit
End With
'Apply color to data point in series
With .Chart.SeriesCollection(1).Points(j)
If oBarClr = "Red" Then
.Interior.Color = RGB(255, 0, 0) 'red
ElseIf oBarClr = "Yellow" Then
.Interior.Color = RGB(255, 255, 0) 'yellow
Else
.Interior.Color = RGB(0, 255, 0) 'green
End If
'Increment counter to next data point
j = j + 1
End With
Next k
Wend
End If
'Check if shape is a table
If oSp.Type = 19 Then
' Position and resize table
.Top = 80
.Left = 50
.Width = 600
.Height = 0.1
With .Table
' Delete first column
.Columns(1).Delete
' Set remaining column width
.Columns(1).Width = 600
' Go through table by rows and columns
For lRow = 1 To .Rows.Count
For lCol = 1 To .Columns.Count
' Set cell margin
With .Cell(lRow, lCol)
.Shape.TextFrame.MarginLeft = 10
End With
' Format text in cells
With .Cell(lRow, lCol).Shape.TextFrame.TextRange
If lRow = 1 Then
.Font.Bold = msoTrue
.Font.Underline = msoFalse
.Font.Color = vbWhite
.Font.Size = 14
.Font.Name = "Arial"
.ParagraphFormat.Alignment = ppAlignCenter
Else
.Font.Bold = msoFalse
.Font.Underline = msoFalse
.Font.Color = vbBlack
.Font.Size = 12
.Font.Name = "Arial"
.ParagraphFormat.Alignment = ppAlignLeft
End If
End With
Next lCol
Next lRow
End With
End If
End With
NextShape:
Next oSp
NextSlide:
Next oSd
Set pts = Nothing
Set oSp = Nothing
Set oSd = Nothing
End Sub