6

現在、次のようなVBAコードを使用して、Officeアプリケーションからデスクトップアプリケーションへの通信(文字列の受け渡し)に使用する共有ライブラリの場所を指定しています。VBAコード/マクロはアドイン(.ppa)に存在する必要があります。

Private Declare Sub sharedLibPassString CDecl Lib "/Users/myUserName/Library/Application Support/myCompanyName/MySharedLib.dylib" Alias "PassString" (ByVal aString As String)

VBAマクロのコードでは、次のことができます。

Call sharedLibPassString(myString)

/Users/myUserName/通信は機能していますが、パーツを現在のユーザーのホームディレクトリに置き換えたいと思います。通常、Macでは、を指定します~/Library/Application Support/...が、~/構文が機能せず、「ファイルが見つかりません」というランタイムエラーが発生します。

次の環境変数メソッドを使用すると、~/必要な場所が取得されることがわかりました。

Environ("HOME")

CDecl Libただし、私が知る限り、Environ実行時に評価されるため、ステートメントのこの部分を作成する方法がわかりません。

~/VBAのユーザーのホームディレクトリ()で共有ライブラリの場所を指定する方法はありますか?


これが私の環境/アプローチに関するいくつかのメモです:

  • 私はMacを使用していますが、解決策があればPCでも同様だと思います。
  • それは問題ではないと思いますが、私が使用しているOfficeアプリケーションはPowerPoint(2011)です。
  • 共有ライブラリのデフォルトの場所ではなく、アプリケーションサポートディレクトリ内の領域にアクセスしようとしている理由は、デスクトップアプリケーションで、インストーラーがなく、インストーラーがなくても共有ライブラリを配置できるようにするためです。ユーザーまたは管理者の特権。同じタスクを実行するためのより良い解決策または場所がある場合、これも非常に役立ちます。
4

2 に答える 2

2

長い返信をして申し訳ありませんが、これをかなりうまく説明したかっただけです。

このページ(Declare ステートメントの解剖学)から、次のことがわかります。

Lib キーワードは、関数を含む DLL を指定します。DLL の名前は、Declare ステートメント内の文字列に含まれていることに注意してください。(強調追加)

実験の結果、文字列定数以外を指定しようとすると、VBE に叱られました。

私が認識している唯一の回避策は、実行時に文字列定数を書き換える必要があることです。

これがどのように行われるかの例を以下に示します: 現在のプロジェクトの Module1 にデラレーション ステートメントがあり、意図的にモジュールの先頭にこの形式で宣言を記述したとします。

Private Declare Sub sharedLibPassString CDecl Lib _
"/Users/myUserName/Library/Application Support/myCompanyName/MySharedLib.dylib" _
Alias "PassString" (ByVal aString As String)

これを介してコードを介してそのモジュールにアクセスできます(開発者マクロ設定の下にリストされているトラストセンターのVBAへのアクセス許可が必要です):

Dim myModule
set myModule = ActivePresentation.VBProject.VBComponents("Module1").CodeModule

CodeModule を取得したら、2 行目を直接置き換えることができます。

myModule.ReplaceLine 2, Environ("HOME") & " _"

任務完了!

これを行う場合、宣言されたサブルーチンを呼び出す前にパスを更新する必要があります。VBA が変更を認識できるように、実行を中断する必要があります。また、ブレーク モード中はコードを変更できません。

これを行っていた場合、コードを壊さないように、正しい行を置き換えたいと思います。myModule.Lines(2,1)行の文字列値を返すこれを呼び出すことで、2行目の内容を確認できます。

ただし、正しい行を見つけてそれを置き換える、より堅牢なソリューションを次に示します (myModule が上記のように既に定義されていると仮定します)。

Dim SL As Long, EL As Long, SC As Long, EC As Long
Dim Found As Boolean
SL = 1     ' Start on line 1
SC = 1     ' Start on Column 1
EL = 99999 ' Search until the 99999th line
EC = 999   ' Search until the 999th column
With myModule
    'If found, the correct line will be be placed in the variable SL
    'Broke search string into two pieces so that I won't accidentally find it.
    Found = .Find("/Users/myUserName/Library/Application Support/myCompanyName/" & _
             "MySharedLib.dylib", SL, SC, EL, EC, True, False, False)
    If Found = True Then
        'Replace the line with the line you want, second paramater should be a string of the value.
        .ReplaceLine SL, Environ("HOME") & " _"
    End If
End With
于 2012-10-30T16:33:12.707 に答える
2

私は Mac を持っていないので、これは不完全な回答であり、役立つかどうかはわかりませんが、いくつかのアイデアです。

Windows では、外部ライブラリで宣言された関数を最初に呼び出そうとするまで、VB は外部ライブラリをロードしません。また、declare ステートメントでファイル名のみを指定すると、システム パスを使用して検索します。あなたと同じことをしたら、ファイル名のみを指定して動的パスからライブラリをロードし、システム API 呼び出しを行って、現在の作業ディレクトリをライブラリのディレクトリに設定してからロードします。PATH 環境変数を変更することもおそらく機能します。

2 番目のアイデア: /tmp ディレクトリ内のファイル名へのパスをハードコードすることができます。次に、ロードする前に、目的のライブラリをその場所に自動的にコピーします。ファイルが別のプロセスで使用されていることに注意してください。ただし、それが必要なファイルとは異なるバージョンのファイルである場合にのみエラーになります。

于 2012-10-30T17:53:17.690 に答える