3 つの主要な Office アプリ (Excel、PowerPoint、Word) で動作する単一の VBA コード モジュールを作成したいと考えています。
オブジェクト モデルはアプリごとに異なるため、Excel VBE で PowerPoint 固有のコードを記述した場合、プロジェクトはコンパイルされません。最初に行う方法は、条件付きコンパイラ定数を使用することです。ただし、これにより、VBE が現在ホストされている MSO アプリに応じて、VBE がエラーを吐き出す原因となります。
以下の簡単な例では、VBA コードが実行されているアプリに応じて、シート、スライド、またはドキュメントに画像を追加します。Excel でコンパイルしようとすると、(条件付きコンパイラの If...Then ステートメント内にあるにもかかわらず) PowerPoint コードがコンパイルされず、その逆も同様です。他の 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 のアイデアを拡張すると、CreateObject 関数を GetObject に置き換えると、次のようなことがうまくいくと思います (アドイン内からプロシージャが呼び出されるため、インスタンスが既に存在するため)。
' 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