2017-10-07 13 views
0

OpenXML SDK 2.5 및 C#을 사용하여 프로그래밍 방식으로 프레젠테이션을 만드는 시나리오가 있습니다. 슬라이드에는이 모양을 연결하는 커넥터와 함께 두 개의 모양이 있습니다.PowerPoint 슬라이드의 OpenXML 새로 고침 커넥터

PowerPoint에서 프레젠테이션을 열 때 모양과 커넥터가 모두 표시되지만 커넥터가 모양 사이에 제대로 배치되지 않았습니다. 슬라이드에서 셰이프 중 하나를 끌면 PowerPoint 즉시 커넥터를 새로 고치고 올바른 위치에 넣습니다.

내 질문 : 파일을 열 때 자동으로 커넥터 위치를 새로 고치는 openxml PowerPoint 슬라이드를 만들 수 있습니까?

답변

0

나는이 문제에 대한 해낸 해결책은 해킹 틱 아닌 것처럼 보일 수 감사하지만, 지금까지 내가 말할 수있는 더 나은 방법이 없습니다. 문제는 PowerPoint에서 내부적으로 커넥터 배치를 제어하고이를 새로 고치는 방법을 노출시키지 않는다는 것입니다. 테스트에서 필자는 PowerPoint가 필요한 경우 리프레시 중에 커넥터 유형을 동적으로 변경한다는 사실에 놀랐습니다.

새로 고침을 얻으려면 .pptm 파일에 VBA 매크로를 작성하고 C# 코드에서 호출해야했습니다. 모듈을 추가하고 특정 슬라이드와 연결되지 않도록 함수를 추가했습니다.

이 코드는 커넥터 새로 고침을 발생 시키도록 슬라이드의 각 모양을 이동합니다. 그룹 내에서 모양을 찾습니다. 삼각형과 다이아몬드 모양을 필터링합니다.

매크로가 실행되는 동안 PowerPoint를 숨기려면 코드에서 ActivePresentation을 사용하지 않아야합니다.

Public Sub FixConnectors() 
    Dim mySlide As Slide 
    Dim shps As Shapes 
    Dim shp As Shape 
    Dim subshp As Shape 

    Set mySlide = Application.Presentations(1).Slides(1) 
    Set shps = mySlide.Shapes 

    For Each shp In shps 
     If shp.AutoShapeType = msoShapeIsoscelesTriangle Or shp.AutoshapeType = msoShapeDiamond Then 
      shp.Left = shp.Left + 0.01 - 0.01 
     End If 
     If shp.Type = mso.Group Then 
      For Each subshp In shp.GroupItems 
       If subshp.AutoShapeType = msoShapeIsoscelesTriangle Or subshp.AutoshapeType = msoShapeDiamond Then 
        subshp.Left = subshp.Left + 0.01 - 0.01 
       End If 
      Next subshp 
     End If 
    Next shp 

    Application.Presentations(1).Save 
End Sub 

다음은 PowerPoint Interop을 사용하여 매크로를 실행하는 C# 코드입니다. Windows 프로세스로 파일을 닫았다가 다시 열면 가비지 수집기가 Interop에있는 핸들을 정리할 수 있습니다. 테스트에서 종료자가 실행되는 데 몇 초가 걸릴 수 있으므로 파일을 다시 연 후 GC 호출이 발생하여 응용 프로그램이 멈추지 않는 것처럼 보입니다.

using System; 
using System.Diagnostics; 
using OC = Microsoft.Office.Core; 
using PP = Microsoft.Office.Interop.PowerPoint; 

string filePath = "C:/Temp/"; 
string fileName = "Template.pptm"; 

// Open PowerPoint in hidden mode, run the macro, and shut PowerPoint down 
var pptApp = new PP.Application(); 
PP.Presentation presentation = pptApp.Presentations.Open(filePath + fileName, OC.MsoTriState.msoFalse, OC.MsoTriState.msoFalse, OC.MsoTriState.msoFalse); 
pptApp.Run(filename + "!.FixConnectors"); 
presentation.Close(); 
presentation = null; 
pptApp.Quit(); 
pptApp = null; 

// Reopen the file through Windows 
Process.Start(filePath + fileName); 

// Clear all references to PowerPoint 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 
GC.WaitForPendingFinalizers();