이 때 만일 변경할 데이터가 너무 많다면 VBA를 이용해야겠습니다. 마치 한글에서 메일머지 기능을 이용하듯이 엑셀 양식에 데이터를 넣어두고 파워포인트에는 차트를 복사해서 양식을 갖춰 놓은 상태에서 매크로로 슬라이드(차트)복사 후 엑셀 데이터 업데이트 작업을 일괄 처리합니다.
차트개체는 가로세로 방향, 추가된 개체, 서식 등이 모두 다르기 때문에 상황에 따라 변수가 있을 수 있지만 주된 흐름은 아래 방법을 이용해서 처리할 수 있겠습니다.
여기서는 엑셀에 데이터가 4개의 세트가 있고
파워포인트에 복사된 차트('Chart 1'이라는 이름)가 하나 1슬라이드에 있을 때
4번에 걸쳐 1슬라이드를 계속 복제한 다음
해당 슬라이드의 Chart 1 차트 내용을 엑셀의 다음 영역의 데이터를 각각 반영한다고 가정합니다.
(한 가지 더 고려할 것이 있는데, 자세히 보니 데이터 라벨을 표시하도록 했는데 G열의 데이터를 라벨에 포함하도록 하고 있네요. 조금 복잡해지지만 이것도 반영하도록 했습니다.)
VBA에서 데이터 원본 소스 변경은
차트.SetSourceData <셀영역> 이 부분이 핵심입니다.
4번 순환하면서 위 명령을 이용해 기존 데이터 영역크기만큼 아래 셀영역을 다음 데이터소스영역으로 지정해주면 됩니다.
여기서 주의할 것은 데이터 반영 전에 반드시 엑셀 창을 활성화시켜줘야 자료가 반영됩니다.
매크로 실행 영상을 확인하세요. 파워포인트는 차트 작업에 있어 엑셀에 의존하기 때문에 작업 처리 시간이 좀 걸립니다.
특히 데이터라벨이 있는 경우 여기서는 G열의 해당열들의 값이 나타나도록 반영했습니다.
반영할 주소가 다르다면 코드를 수정해야 합니다. 이 부분은 엑셀파일상황에 따라 변수가 있습니다.
엑셀에서 차트를 다루는 것보다 파워포인트 VBA 에서는 조금 더 손이 가는 것이 사실입니다.
잘 안될 경우에는 엑셀에서 매크로를 녹화해서 참고하면 됩니다.
Option Explicit
'Const xlFile = "PPT 연동용 엑셀 예시.xlsx"
'Const xlRange = "B2:D5"
Const ChartName = "Chart 1" '차트 개체 이름
Sub ManipulateChart()
Dim xlSht As Object
Dim xlRange As Object, xlNewRange As Object
Dim sRange As String
Dim sld As Slide, sldNew As Slide
Dim shp As Shape
Dim cht As Chart
Dim srs As Series, DtLabel As DataLabel
Dim i As Integer, j As Integer, k As Integer
Set sld = ActiveWindow.View.Slide
For i = 1 To 4 '4번 반복
'슬라이드 복제
Set sldNew = sld.Duplicate(1)
sldNew.MoveTo sld.Parent.Slides.Count
Set shp = sldNew.Shapes(ChartName)
Set cht = shp.Chart
'엑셀 창 띄우기(필수)
cht.ChartData.ActivateChartDataWindow
'차트 소스데이터 range 구하기
sRange = getSourceData(cht) ' "B2:D5"
Set xlSht = cht.ChartData.Workbook.Worksheets(1)
Set xlRange = xlSht.Range(sRange)
'차트 소스 영역 수정
Set xlNewRange = xlRange.Offset(xlRange.Rows.Count * (i - 1))
'Debug.Print xlSht.Name & "!" & xlNewRange.Address
cht.SetSourceData Source:=xlSht.Name & "!" & xlNewRange.Address
'차트 제목수정
cht.ChartTitle.Text = xlNewRange(1)
'데이터라벨에 출력할 셀 Range 수정
For j = 1 To cht.SeriesCollection.Count
Set srs = cht.SeriesCollection(j)
If srs.HasDataLabels Then
'srs.ApplyDataLabels
With srs.DataLabels
If .ShowRange Then
.Format.TextFrame2.TextRange.InsertChartField _
msoChartFieldRange, "=" & xlSht.Name & "!" & _
"$G$" & xlNewRange(1).Row + 1 & ":$G$" & xlNewRange.Row + 3
.ShowRange = True
End If
'Debug.Print "=" & xlSht.Name & "!" & _
"$G$" & xlNewRange(1).Row + 1 & ":$G$" & xlNewRange.Row + 3
End With
End If
Next j
'cht.Refresh
'DoEvents
xlSht.Parent.Close '엑셀 창 닫기
Next i
End Sub
Sub test1()
Debug.Print getSourceData(ActiveWindow.Selection.ShapeRange(1).Chart)
End Sub
Sub test2()
With ActiveWindow.Selection.ShapeRange(1).Chart
.ChartData.ActivateChartDataWindow
.SetSourceData Source:="Sheet1!$B$10:$D$13"
'.Refresh
End With
End Sub
Sub test3()
Dim DtLabel As DataLabel
Dim srs As Series
Dim cht As Chart
Dim j%, k%
Set cht = ActiveWindow.Selection.ShapeRange(1).Chart
cht.ChartData.ActivateChartDataWindow
For j = 1 To cht.SeriesCollection.Count
Set srs = cht.SeriesCollection(j)
If srs.HasDataLabels Then
'srs.ApplyDataLabels
For k = 1 To srs.DataLabels.Count '//not working
Set DtLabel = srs.DataLabels(k)
If DtLabel.ShowRange Then
DtLabel.Format.TextFrame2.TextRange.InsertChartField msoChartFieldRange, "=Sheet1!G$11:$G$13", 0
'DtLabel.Format.TextFrame2.TextRange.InsertAfter ", "
DtLabel.ShowRange = True
End If
If DtLabel.ShowValue Then
DtLabel.ShowValue = True
'DtLabel.Format.TextFrame2.TextRange.InsertChartField msoChartFieldValue
End If
DtLabel.AutoText = True
Next k
End If
Next j
cht.ChartData.Workbook.Close
End Sub
Sub test4()
Dim DtLabel As DataLabel
Dim srs As Series
Dim cht As Chart
Dim j%, k%
Set cht = ActiveWindow.Selection.ShapeRange(1).Chart
cht.ChartData.ActivateChartDataWindow
For j = 1 To cht.SeriesCollection.Count
Set srs = cht.SeriesCollection(j)
If srs.HasDataLabels Then
With srs.DataLabels
If .ShowRange Then
.Format.TextFrame2.TextRange.InsertChartField msoChartFieldRange, "=Sheet1!G$7:$G$9", 0
.ShowRange = True
End If
End With
End If
Next j
cht.ChartData.Workbook.Close
End Sub
Function getSourceData(oCht As Chart) As String
Dim sform1 As String, sform2 As String
Dim srs1 As Series, srs2 As Series
Dim r1 As Object, r2 As Object
Dim oSht As Object
'oCht.ChartData.ActivateChartDataWindow
Set srs1 = oCht.SeriesCollection(1)
Set srs2 = oCht.SeriesCollection(oCht.SeriesCollection.Count)
sform1 = srs1.Formula
sform2 = srs2.Formula
Set oSht = oCht.ChartData.Workbook.Worksheets(1)
Set r1 = oSht.Range(Split(sform1, ",")(1))(1)
Set r2 = oSht.Range(Split(sform2, ",")(2)).Item(UBound(srs1.Values))
getSourceData = r1.Offset(-1).Address & ":" & r2.Address
'oSht.Parent.Close
End Function
여기서 사용된 차트는 별도의 엑셀 원본에 연결(Link)된 차트인데
파워포인트 파일에 포함된 차트의 경우도 작동할 겁니다.
'PPT+VBA' 카테고리의 다른 글
연결된 차트의 시트변경시 연결 자동 복구 (0) | 2022.08.20 |
---|---|
PPT의 표(테이블)를 엑셀시트에 일괄 복사 (0) | 2022.08.13 |
도형병합(교차)를 이용한 두 도형의 충돌체크 (0) | 2022.08.12 |
그룹도형, 차트, 스마트아트, 표 등의 텍스트 일괄 변경 (0) | 2022.08.08 |
텍스트박스를 일괄 도형으로 변환하기 (0) | 2022.07.10 |
[Web Viewer 추가기능]온라인 구글문서 PPT슬라이드에 띄우기 (1) | 2022.06.24 |
도형의 윤곽선은 안쪽 정렬도 가능 (1) | 2022.06.04 |
미리캔버스 슬라이드마스터 크기, 글꼴, 글머리기호 복구하기 (0) | 2022.06.03 |
최근댓글