2013-10-02 2 views
0

세 가지 주요 Office 응용 프로그램 (Excel, PowerPoint, Word)에서 작동하는 단일 VBA 코드 모듈을 작성하고 싶습니다.여러 Office 응용 프로그램에서 작동하는 VBA 코드를 작성하는 방법

개체 모델이 각 응용 프로그램마다 다르기 때문에 Excel VBE에서 PowerPoint 용으로 작성된 코드를 작성하면 프로젝트가 컴파일되지 않습니다. 처음에는 조건부 컴파일러 상수를 사용하는 것으로 나타납니다. VBE가 VBE가 현재 호스팅되고있는 MSO 응용 프로그램에 따라 VBE에서 오류가 발생합니다.

아래의 단순화 된 예제에서 어떤 그림을 시트, 슬라이드 또는 문서에 추가할지 여부에 따라 app에서 VBA 코드를 실행하고 있습니다. Excel에서 컴파일하려고하면 PowerPoint 코드가 컴파일되지 않습니다 (조건부 컴파일러 If ... Then 문안에 있더라도!). 그 반대의 경우도 마찬가지입니다. 다른 MSO 버전에 배포 할 때 호환성 문제를 일으키는 다른 MSO 앱에 대한 참조를 추가하지 않으면 어떻게됩니까?

컴파일러가 조건 컴파일러 상수에 의해 효과적으로 "주석 처리"되어야하는 코드를 계속 보는 방식은 매우 이상합니다/성가신 행동입니다! 나는 내 자신의 질문에 대답 할 수 없어요 때문에

' Set the compiler constant depending on which MSO app is hosting the VBE 
' before saving as the respective .ppam/.xlam/.dotm add-in 
#Const APP = "EXL" 

Option Explicit 

Dim curSlide As Integer 
Dim curSheet As Integer 

Public Sub InsertPicture() 
    Dim oShp as Shape 
    #If APP = "PPT" Then 
     ' Do PowerPoint stuff 
     ' The next 2 lines will throw "Invalid qualifier" and 
     ' "Variable not defined" errors respectively when compiling in Excel. 
     curSlide = ActiveWindow.View.Slide.SlideIndex 
     Set oShp = ActivePresentation.Slides(curSlide).Shapes.AddPicture & _ 
      (filename, msoFalse, msoTrue, 0, 0) 
    #ElseIf APP = "EXL" Then 
     ' Do Excel stuff 
     curSheet = ActiveWindow.ActiveSheet 
     Set oShp = ActiveSheet.AddPicture(filename, msoFalse, msoTrue, 0, 0) 
    #ElseIf APP = "WRD" Then 
     ' Do Word stuff 
    #End If 
End Sub 

은 : 당신의 생각 KazJaw에 확장

를,이 같은 인스턴스가 이미 있기 때문에 존재하기 때문에 (GetObject를 사용하여 CreateObject 함수를 대체 작동 할 수 생각 절차는 추가) 내에서 호출되는 :

' CONDITIONAL COMPILER CONSTANTS 
' Set this value before saving to .ppam, .xlam or .dotm 
#Const APP = "EXL" ' Allowed Values : PPT, EXL or WRD 

Sub One_Sub_For_Word_Excel_PP(filename As String, Optional SlideIndex as Integer) 
    #If APP = "PPT" Then 
     Dim appPPP As Object 
     Set appPPT = GetObject(, "PowerPoint.Application") 
     appPPT.ActivePresentation.Slides(SlideIndex).Shapes.AddPicture & _ 
      (filename,msoFalse,msoTrue,0,0) 
    #ElseIf APP = "EXL" Then 
     Dim appEXL As Object 
     Set appEXL = GetObject(, "Excel.Application") 
     appEXL.ActiveSheet.AddPicture(filename, msoFalse, msoTrue, 0, 0) 
    #ElseIf APP = "WRD" Then 
     Dim appWRD As Object 
     Set appWRD = GetObject(, "Word.Application") 
     appWRD.ActiveDocument.AddPicture(filename, msoFalse, msoTrue, 0, 0) 
    #End If 
End Sub 
+0

솔직히 말해서 내가 준비하려고하는 솔루션을 사용하고자하는 상황을 상상할 수는 없습니다. 하나의 옵션이 있지만 매우 비효율적입니다. 그런 솔루션에 관심이 있습니까? –

+0

상황은 MSO의 많은 기능이 모든 앱에서 공통적 인 방식을 반영합니다. 필자가 쓰고있는 글은 똑같은 사건에 속한다. 3 가지 주요 MSO 애플리케이션에서 동일한 기능을 사용할 수 있기를 바란다. 그렇다. 솔루션에 관심이 있지만 "매우 비효율적 인"것을 말하면 무엇을 의미 하는가? 프로그래머 또는 사용자 또는 컴퓨터의 경우? –

+0

두 가지 추가 옵션 : [COM 추가 기능] (http://msdn.microsoft.com/en-us/library/office/aa141383(v=office.10) .aspx) 또는 "Auto_Open" 이벤트에서 프로그래밍 방식으로 세 라이브러리의 각각에 대한 참조가 활성화되어 컴파일되도록해야합니다. (PPT 또는 XLS에서 실행되는 응용 프로그램을 사용하여 후자를 수행했습니다) –

답변

1

당신이 시도 할 수 :

또는
Public AppName as String 
Public App as Object 
Sub One_Sub_For_Word_Excel_PP(filename As String, Optional SlideIndex as Integer) 
    AppName = Application.Name 
    Set App = Application 
    Select Case AppName 
     Case "Microsoft PowerPoint" 
      App.ActivePresentation.Slides(SlideIndex).Shapes.AddPicture & _ 
       (filename,msoFalse,msoTrue,0,0) 

     Case "Microsoft Excel" 
      App.ActiveSheet.AddPicture(filename, msoFalse, msoTrue, 0, 0) 

     Case "Microsoft Word" 
      App.ActiveDocument.AddPicture(filename, msoFalse, msoTrue, 0, 0) 

     End Select 
End Sub 

, COM 추가 기능을 작성합니다.

+1

훨씬 더 깨끗한 - 조건부 컴파일러 상수 없음 :-) 사례 옵션의 원래 Excel 및 Word 줄이 올바르지 않지만 전체 솔루션이 작동한다고 추가해야합니다. David 감사합니다! –

0

나는 당신이 준비하려고하는 솔루션을 사용하고자하는 상황을 상상할 수없는 내 대하여 의견에 명시된 바와 같이. 그러나 다른 응용 프로그램 라이브러리에 대한 참조를 설정하지 않아도 제한 사항을 설정하는 경우에도 한 가지 솔루션이 있습니다. 그러한 시도는 효율적이지 않을 것이며 결코 이와 같은 것을 추천하지 않는다는 것을 명심하십시오.

다음 테스트 서브 루틴은 MS Word, MS PowerPoint, MS Excel의 세 응용 프로그램 모두에서 작동합니다. 코드 내부의 주석에있는 추가 정보.

Sub One_Sub_For_Word_Excel_PP() 

    Dim XLS As Object 
    Dim PP As Object 
    Dim WRD As Object 

    'this will open instances of all application- to avoid any errors 
    Set XLS = CreateObject("Excel.Application") 
    Set PP = CreateObject("PowerPoint.Application") 
    Set WRD = CreateObject("Word.Application") 


    'your code here 
    'remember- do not use vba constants like msoFalse but use _ 
    their numeric values instead 

    'simple test 
    If Application.Name = "Microsoft Excel" Then 
     'do things only for excel 
     Debug.Print XLS.Name 
    ElseIf Application.Name = "Microsoft PowerPoint" Then 
     'do things only for PP 
     Debug.Print PP.Name 
    Else 
     'do things only for Word 
     Debug.Print WRD.Name 
    End If 

    Set XLS = Nothing 
    Set PP = Nothing 
    Set WRD = Nothing 
End Sub 
+0

감사합니다. KazJaw. 3 가지 MSO 앱의 인스턴스를 모두 생성한다고 가정하기 때문에 이것이 필요하다고 생각하지 않습니다. 내가 필요한 것은 호스팅 MSO ​​응용 프로그램에 따라 올바른 개체 모델을 해결하는 솔루션입니다. 앱의 인스턴스는 하나 뿐이며 코드가 실행되지만 전체 코드는 개별 .ppam/.xlam/.dotm 추가 기능에 저장됩니다. 예를 들어, .ppam/.xlam/.dotm 추가 기능 안에 앉을 수있는 슬라이드, 시트 또는 문서에 원을 추가하는 단일 코드를 어떻게 작성 하시겠습니까? –

0

는 등

#Const APP = "EXL" 

#If APP = "PPT" Then 

아닌가요?

+0

KazJaw가 말한 내용과이 질문에 대한 답을 얻을 수 없기 때문에 원본 게시물을 편집하여 두 사람 모두에게 감사 할만한 글을 남겼습니다. –

+0

이 질문에 대한 답을 제공하지 않습니다. 비평하거나 저자의 설명을 요청하려면 게시물 아래에 의견을 남겨 둡니다. –

+0

@Shimon Rachienko : 죄송 합니다만, 귀하의 분석에 동의하지 않습니다. –

0

VBA 사용 가능 앱 내에서 동일한 코드를 실행할 수 있다고 가정합니다 (다른 앱을 반드시 호출 할 필요는 없음). 그래서 ...

Sub One_Sub_To_Rule_Them_All() 
' Modified version of KazJaw's previous post 

    Dim oApp As Object 
    Set oApp = Application 

    Select Case oApp.Name 
     Case Is = "Microsoft Excel" 
     'do things only for excel 

     Case Is = "Microsoft PowerPoint" 
     'do things only for PP, eg 
      MsgBox oApp.ActivePresentation.Fullname 

     Case Is = "Microsoft Word" 
     ' do wordthings 

     Case Is = "Visio or CorelDraw or Whatever" 
     ' do whatever things 

     Case Else 
      MsgBox "Jumping up and down and waving hands and running around like headless chicken" 

    End Select 

    Set oApp = Nothing 

End Sub 

모든 같은,이 방법으로 그것을 할 것입니다. 다른 이의 제기 외에도 코드를 컴파일하기 위해 앱을 객체로 취급해야합니다. 그렇게하면 인텔리 센스를 버릴 수 있습니다. 사소한 손실이 아닙니다. 물론 Word에서 Word 부분을 개발하면 PPT의 PPT 부분을 개발할 수 있지만 그 경우에는 별도의 코드 모듈을 만들면 안됩니까?

관련 문제