Excel2000のVBA(WindowsXP Pro ver 2002 SP2上)環境で、添付ファイル付きで既定のメーラーを起動するコードを教えて下さい。(余計なものをインストールせず)

【動作環境、条件】
①OSに元から入っていないバージョンの.NET Frameworkなどを必要としないこと
②将来的にWindows7やExcel2003になっても使用不能にならないこと
③既定のメーラーの機能を活かしたい。
(環境に添付ファイルサイズ最大2MBの制限があり、OEの分割送信機能が必須)
(基本はOE・MAPI系で構わないが, 指名することは避けたい)
【現在まで自分で調べたこと】
1、標準のCDOを使えばVBAで送信できるが、既定のメーラーが持つ機能を使えない。
(アドレス帳、分割送信、送信認証 など)
2、「mailto:」プロトコルは、添付ファイルに対応できない。
3、送りたいファイルを右クリックして「送る」⇒「メール受信者」(.MAPImail)で既定のメーラーが立ち上がり、SendToフォルダにある同アイコンにファイルをD&Dしても同様に立ち上がる。しかし、Excel2000VBAからそれをやるコードがわからない。
4、Application.Dialogs(xlSendMail).Show のようなコードはエラーになる。
プログラミング素人ではないのですが
とにかく時間が無いため、お願いします。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2013/04/03 22:07:05
  • 終了:2013/04/10 22:10:04
id:jack_sonic

レジストリから既定のメーラーが何になっているかはわかります。oeに限ったコードでも
欲しいです。なんとかexcelVBAで送れるようにしたいです。
もうCDOでも実用性の高いものを頂けるなら構わないです。
お願いいたします。宛先は複数です。

ベストアンサー

id:cx20 No.4

cx20回答回数606ベストアンサー獲得回数1072013/04/10 01:50:01

ポイント1000pt

3、送りたいファイルを右クリックして「送る」⇒「メール受信者」(.MAPImail)

既定のメーラにてファイルを添付する機能は OS 付属のコンポーネントである sendmail.dll により実装されていますが、シェル拡張用のコンポーネントである為、通常の、Win32 API に比べ、呼び出し方が少し面倒です。

具体的には、SendMail コンポーネントの IDropTarget インターフェイスを取得し、DragEnter / Drop メソッドを呼び出す必要があります。

ただし、この IDropTarget インターフェイスは、既定の状態では VBA にて使用できない(参照設定が行われていない)為、呼び出す手段を考える必要があります。
方法として考えられるのは、以下にあるような方法かと思います。

<タイプライブラリ化し VBA より呼び出す方法>
■ OLELIB.TLB (tl_ole.zip に内包)
http://www.mvps.org/emorcillo/download/vb6/tl_ole.zip
■ Sending a file to "Mail Recipient" using sendmail.dll
http://www.mvps.org/emorcillo/en/code/vb6/sendmail.shtml

<Win32 API 形式の DLL を作成し、VBA より呼び出す方法>
■ Convert MFC/C++ to VB [Small Code]-VBForums
http://www.vbforums.com/showthread.php?269271-Convert-MFC-C-to-VB-Small-Code

<単体 EXE として実装する方法>
■ SendTo mail recipient - CodeProject
http://www.codeproject.com/Articles/3839/SendTo-mail-recipient
■ SendTo mail recipient
http://www.arstdesign.com/articles/sendtomail.html
■ SendTo mail recipient (part II)
http://www.arstdesign.com/articles/sendto.exe.html


このうち、上記の「タイプライブラリ化し VBA より呼び出す方法」にて紹介しているサンプルコードを動作するのに必要な部分だけを切り出したタイプライブラリ用のソースファイル(oleliblt.odl)を用意してみました。

/*
 File : oleliblt.odl
 Compile : midl.exe oleliblt.odl [Enter]
 */

[
   uuid(578a13f1-ad1a-4fa8-8def-25c1b45874de),
   helpstring("OLELIB Lite"),
   version(0.01)
]
library oleliblt {

    importlib("stdole2.tlb");

    typedef unsigned char BYTE;
    typedef LONG BOOL;

    typedef enum HRESULTS {
        S_OK = 0,
        S_FALSE = 1
    } HRESULTS;

    typedef enum DROPEFFECTS {
        DROPEFFECT_NONE = 0,
        DROPEFFECT_COPY = 1,
        DROPEFFECT_MOVE = 2,
        DROPEFFECT_LINK = 4,
        DROPEFFECT_SCROLL = 0x80000000,
    } DROPEFFECTS;

    typedef struct UUID {
        LONG Data1;
        SHORT Data2;
        SHORT Data3;
        BYTE Data4[8];
    } UUID;

    [
        odl,
        uuid(00000122-0000-0000-C000-000000000046)
    ]
    interface IDropTarget : IUnknown {

        HRESULT DragEnter(
            [in] IDataObject *pDataObj,
            [in] LONG grfKeyState,
            [in] LONG ptX,
            [in] LONG ptY,
            [in, out] DROPEFFECTS *pdwEffect);

        HRESULT DragOver(
            [in] LONG grfKeyState,
            [in] LONG ptX,
            [in] LONG ptY,
            [in, out] DROPEFFECTS *pdwEffect);

        HRESULT DragLeave();

        HRESULT Drop(
            [in] IDataObject *pDataObj,
            [in] LONG grfKeyState,
            [in] LONG ptX,
            [in] LONG ptY,
            [in, out] DROPEFFECTS *pdwEffect);
    };

    typedef enum ESTRRET {
        STRRET_WSTR = 0,
        STRRET_OFFSET = 1,
        STRRET_CSTR = 2
    } ESTRRET;

    typedef struct STRRET {
        ESTRRET uType;
        BYTE cStr[260];
    } STRRET;

    typedef enum SHGNO_Flags {
        SHGDN_NORMAL = 0,
        SHGDN_INFOLDER = 1,
        SHGDN_FORADDRESSBAR = 0x4000,
        SHGDN_FORPARSING = 0x8000,
    } SHGNO_Flags;

    typedef enum SHCONTF {
        SHCONTF_FOLDERS             = 0x0020,
        SHCONTF_NONFOLDERS          = 0x0040,
        SHCONTF_INCLUDEHIDDEN       = 0x0080,
        SHCONTF_INIT_ON_FIRST_NEXT  = 0x0100,
        SHCONTF_NETPRINTERSRCH      = 0x0200,
        SHCONTF_SHAREABLE           = 0x0400,
        SHCONTF_STORAGE             = 0x0800,
    } SHCONTF;

    [
        odl,
        uuid(000214F2-0000-0000-C000-000000000046)
    ]
    interface IEnumIDList : IUnknown {

        HRESULT Next(
            [in] LONG celt,
            [in, out] LONG *rgelt,
            [out, retval] LONG *pceltFetched);

        HRESULT Skip(
            [in] LONG celt);

        HRESULT Reset();

        HRESULT Clone(
            [out, retval] IEnumIDList **ppenum);
    };

    [
      odl,
      uuid(000214E6-0000-0000-C000-000000000046)
    ]
    interface IShellFolder : IUnknown {

        HRESULT ParseDisplayName(
            [in] long hwndOwner,
            [in] long pbcReserved,
            [in] long lpszDisplayName,
            [in, out] long* pchEaten,
            [in, out] long* ppidl,
            [in, out] long* pdwAttributes);

        HRESULT EnumObjects(
            [in] long hwndOwner,
            [in] SHCONTF grfFlags,
            [out, retval] IEnumIDList** ppenumIDList);

        HRESULT BindToObject(
            [in] long pidl,
            [in] long pbcReserved,
            [in, out] UUID *riid,
            [in, out] long *ppvOut);

        HRESULT BindToStorage(
            [in] long pidl,
            [in] long pbcReserved,
            [in, out] UUID *riid,
            [out, retval] IStorage **ppvObj);

        HRESULT CompareIDs(
            [in] long lparam,
            [in] long pidl1,
            [in] long pidl2);

        HRESULT CreateViewObject(
            [in] long hwndOwner,
            [in, out] UUID* riid,
            [out, retval] long *ppvOut);

        HRESULT GetAttributesOf(
            [in] long cidl,
            [in, out] long* apidl,
            [in, out] long* rgfInOut);

        HRESULT GetUIObjectOf(
            [in] long hwndOwner,
            [in] long cidl,
            [in, out] long *apidl,
            [in, out] UUID  *riid,
            [in, out] long *prgfInOut,
            [out, retval] long *ppvOut);

        HRESULT GetDisplayNameOf(
            [in] long pidl,
            [in] SHGNO_Flags uFlags,
            [in, out] STRRET* lpName);

        HRESULT SetNameOf(
            [in] long hwndOwner,
            [in] long pidl,
            [in] long lpszName,
            [in] SHGNO_Flags uFlags,
            [out, retval] long* ppidlOut);
    };

    [
        dllname("OLE32.DLL")
    ]
    module ole32 {
        [entry("CLSIDFromString")]
        HRESULT CLSIDFromString(
            [in] LPWSTR lpszProgID,
            [in, out] UUID *lpclsid);

        [entry("CoCreateInstance")]
        LONG CoCreateInstance(
            [in] UUID *CLSID,
            [in] stdole.IUnknown *pUnkOuter,
            [in] CLSCTX dwClsContext,
            [in] UUID *IID,
            [out] void *ppv);

        [entry("CoTaskMemFree")]
        LONG CoTaskMemFree(
            [in] LONG Ptr);

    }

    [
        dllname("KERNEL32.DLL")
    ]
    module kernel32 {
        [entry("RtlMoveMemory")]
        void MoveMemory(
            [in] void *pDest,
            [in] void *pSource,
            [in] LONG ByteLen);
    }

    [
        dllname("SHELL32.DLL")
    ]
    module shell32 {
        [entry("SHGetDesktopFolder")]
        HRESULT SHGetDesktopFolder(
            [out, retval] IShellFolder **ppshf);
    }

    [
        dllname("dummy")  
    ]
    module constants {
        const LPSTR IIDSTR_IShellFolder = "{000214E6-0000-0000-C000-000000000046}";
    }

};
<使用方法>
1. MIDL コンパイラ(Visual C++ or Windows SDK 付属ツール)によりコンパイルを実施
   C:\work\oleliblt> midl.exe oleliblt.odl [Enter]
   → 上記のコンパイルにより「oleliblt.tlb」が作成されます。

2. VBE の [ツール]-[参照設定] により「oleliblt.tlb」を選択。
   → IDataObject / IDropTarget 等が参照できるようになります。

3. 以下のサイトにあるサンプルコードを入力します。
   ■ Sending a file to "Mail Recipient" using sendmail.dll
   http://www.mvps.org/emorcillo/en/code/vb6/sendmail.shtml

4. テストコードを作成します。
   Sub MailTest()
      Call SendToMailRecipient("C:\work\mailtest\test.txt")
   End Sub

5. テストコードを実行し、既定のメーラにてファイルが添付されることを確認します。

この方式にて、Windows 2000 + Excel 2000 環境で動作すること確認しました。

難点としては、特定のパスでタイプライブラリの参照を行った後、他の端末に
Excel ファイルを持って行った場合に「参照不可(MISSING)」となってしまう点でしょうか。

プログラムにより、動的に参照設定を行う方法はありますが、「参照不可」と、なってしまった場合、手動で再設定するしか無いようようです。
(この問題を回避する方法としては「毎回、Excel ブックオープン時にプログラムで参照設定を行い、クローズするときに、参照設定を解除する」という方法があるようです。)

<参考情報>
■ Office TANAKA - Excel VBA Tips[マクロで参照設定を操作する]
http://officetanaka.net/excel/vba/tips/tips100.htm

他1件のコメントを見る
id:cx20

コンパイル済みのタイプライブラリファイルは↓以下にアップしておきました。
http://cx20.main.jp/hatena/file/upload/hatena_1364994425_oleliblt.zip

2013/04/10 23:26:02
id:jack_sonic

ありがとうございます。試してみます。

2013/04/14 21:12:17

その他の回答(3件)

id:rafting No.1

ラフティング回答回数2652ベストアンサー獲得回数1762013/04/07 23:21:39


Sub try_3()
  Const HKEY = "HKEY_CLASSES_ROOT\mailto\shell\open\command\"
  Dim Flg  As Boolean
  Dim Arg  As String
  Dim sPath As String
  Dim i   As Long
  Dim b()  As Byte
  Dim tmp, ary

  On Error GoTo errHandler

  tmp = Selection.Value
  If IsArray(tmp) Then
    ReDim ary(1 To UBound(tmp))
    For i = 1 To UBound(tmp)
      ary(i) = Join(Application.Index(tmp, i, 0), "")
    Next
    Arg = Join(ary, vbLf)
  Else
    Arg = tmp
  End If
  
  '既定メーラー取得(WinXP)
  With CreateObject("WScript.Shell")
    sPath = .ExpandEnvironmentStrings(.RegRead(HKEY))
  End With
  sPath = Replace$(Replace$(sPath, """%1""", ""), "%1", "")
  Flg = InStr(1, sPath, "thunderbird", vbTextCompare)
  
  If Flg Then
    'thunderbirdだと文字化けしたのでUTFエンコード
    With CreateObject("ScriptControl")
      .Language = "JScript"
      Arg = .CodeObject.encodeURI(Arg)
    End With
  Else
    '簡易的にSJISエンコード
    b = StrConv(Arg, vbFromUnicode)
    Arg = ""
    For i = 0 To UBound(b)
      Arg = Arg & "%" & Right$("0" & Hex$(b(i)), 2)
    Next
  End If
  
  Arg = "mailto:メールアドレス?" & _
     "subject=件名&" & _
     "body=" & Arg

  Shell sPath & Arg

  Exit Sub
errHandler:
  MsgBox Err.Number & ":" & Err.Description
End Sub

とりあえずwinXPで Outlook/Outlook Express/thunderbird は動きました。
他環境だったりする場合、ここ
http://jehupc.exblog.jp/9727243/
の情報が参考になると思います。
http://oshiete.goo.ne.jp/qa/5977178.html

こんなんではイケませんか?

id:jack_sonic

この情報のページは既に見ましたが、
「mailto:」を使う方法では
添付ファイルを付けられないんです。
>  Arg = "mailto:メールアドレス?" & _
>     "subject=件名&" & _
>     "body=" & Arg

>  Shell sPath & Arg

とありますが、file= や attach= を追記しても無駄でした。

2013/04/08 21:51:08
id:nikodesu No.2

ニコ回答回数1025ベストアンサー獲得回数392013/04/09 21:46:47

ここは参考になりませんか?
http://oshiete.goo.ne.jp/qa/5977178.html
あと、ここで聞くのもいいかも
http://www.excel.studio-kazu.jp/kw/20100319143109.html

id:jack_sonic

すみません。全て見たことのある記事です。
また、上記でも言っていますが、「mailto:」プロトコルは既定のメーラーを起動してメール送信ができますが、いかんせん
絶対条件である「添付ファイル」を付けられないのです。NGです。申し訳ない。

2013/04/09 22:17:21
id:boost_beast No.3

boost_beast回答回数785ベストアンサー獲得回数312013/04/09 22:23:24

ExcelVBAでメールを作成してメーラーを起動するプログラムを作って
http://okwave.jp/qa/q5977178.html

こちらページの回答はどうでしょうか。

http://www.moug.net/tech/acvba/0090045.html

あとはこちらも。

id:jack_sonic

同様に既に見たことがありNGです。。

簡単そうに見えるかもしれませんが、
海外サイトも含めて数時間検索しまくっても見つからないレベルです。

2013/04/09 22:31:15
id:cx20 No.4

cx20回答回数606ベストアンサー獲得回数1072013/04/10 01:50:01ここでベストアンサー

ポイント1000pt

3、送りたいファイルを右クリックして「送る」⇒「メール受信者」(.MAPImail)

既定のメーラにてファイルを添付する機能は OS 付属のコンポーネントである sendmail.dll により実装されていますが、シェル拡張用のコンポーネントである為、通常の、Win32 API に比べ、呼び出し方が少し面倒です。

具体的には、SendMail コンポーネントの IDropTarget インターフェイスを取得し、DragEnter / Drop メソッドを呼び出す必要があります。

ただし、この IDropTarget インターフェイスは、既定の状態では VBA にて使用できない(参照設定が行われていない)為、呼び出す手段を考える必要があります。
方法として考えられるのは、以下にあるような方法かと思います。

<タイプライブラリ化し VBA より呼び出す方法>
■ OLELIB.TLB (tl_ole.zip に内包)
http://www.mvps.org/emorcillo/download/vb6/tl_ole.zip
■ Sending a file to "Mail Recipient" using sendmail.dll
http://www.mvps.org/emorcillo/en/code/vb6/sendmail.shtml

<Win32 API 形式の DLL を作成し、VBA より呼び出す方法>
■ Convert MFC/C++ to VB [Small Code]-VBForums
http://www.vbforums.com/showthread.php?269271-Convert-MFC-C-to-VB-Small-Code

<単体 EXE として実装する方法>
■ SendTo mail recipient - CodeProject
http://www.codeproject.com/Articles/3839/SendTo-mail-recipient
■ SendTo mail recipient
http://www.arstdesign.com/articles/sendtomail.html
■ SendTo mail recipient (part II)
http://www.arstdesign.com/articles/sendto.exe.html


このうち、上記の「タイプライブラリ化し VBA より呼び出す方法」にて紹介しているサンプルコードを動作するのに必要な部分だけを切り出したタイプライブラリ用のソースファイル(oleliblt.odl)を用意してみました。

/*
 File : oleliblt.odl
 Compile : midl.exe oleliblt.odl [Enter]
 */

[
   uuid(578a13f1-ad1a-4fa8-8def-25c1b45874de),
   helpstring("OLELIB Lite"),
   version(0.01)
]
library oleliblt {

    importlib("stdole2.tlb");

    typedef unsigned char BYTE;
    typedef LONG BOOL;

    typedef enum HRESULTS {
        S_OK = 0,
        S_FALSE = 1
    } HRESULTS;

    typedef enum DROPEFFECTS {
        DROPEFFECT_NONE = 0,
        DROPEFFECT_COPY = 1,
        DROPEFFECT_MOVE = 2,
        DROPEFFECT_LINK = 4,
        DROPEFFECT_SCROLL = 0x80000000,
    } DROPEFFECTS;

    typedef struct UUID {
        LONG Data1;
        SHORT Data2;
        SHORT Data3;
        BYTE Data4[8];
    } UUID;

    [
        odl,
        uuid(00000122-0000-0000-C000-000000000046)
    ]
    interface IDropTarget : IUnknown {

        HRESULT DragEnter(
            [in] IDataObject *pDataObj,
            [in] LONG grfKeyState,
            [in] LONG ptX,
            [in] LONG ptY,
            [in, out] DROPEFFECTS *pdwEffect);

        HRESULT DragOver(
            [in] LONG grfKeyState,
            [in] LONG ptX,
            [in] LONG ptY,
            [in, out] DROPEFFECTS *pdwEffect);

        HRESULT DragLeave();

        HRESULT Drop(
            [in] IDataObject *pDataObj,
            [in] LONG grfKeyState,
            [in] LONG ptX,
            [in] LONG ptY,
            [in, out] DROPEFFECTS *pdwEffect);
    };

    typedef enum ESTRRET {
        STRRET_WSTR = 0,
        STRRET_OFFSET = 1,
        STRRET_CSTR = 2
    } ESTRRET;

    typedef struct STRRET {
        ESTRRET uType;
        BYTE cStr[260];
    } STRRET;

    typedef enum SHGNO_Flags {
        SHGDN_NORMAL = 0,
        SHGDN_INFOLDER = 1,
        SHGDN_FORADDRESSBAR = 0x4000,
        SHGDN_FORPARSING = 0x8000,
    } SHGNO_Flags;

    typedef enum SHCONTF {
        SHCONTF_FOLDERS             = 0x0020,
        SHCONTF_NONFOLDERS          = 0x0040,
        SHCONTF_INCLUDEHIDDEN       = 0x0080,
        SHCONTF_INIT_ON_FIRST_NEXT  = 0x0100,
        SHCONTF_NETPRINTERSRCH      = 0x0200,
        SHCONTF_SHAREABLE           = 0x0400,
        SHCONTF_STORAGE             = 0x0800,
    } SHCONTF;

    [
        odl,
        uuid(000214F2-0000-0000-C000-000000000046)
    ]
    interface IEnumIDList : IUnknown {

        HRESULT Next(
            [in] LONG celt,
            [in, out] LONG *rgelt,
            [out, retval] LONG *pceltFetched);

        HRESULT Skip(
            [in] LONG celt);

        HRESULT Reset();

        HRESULT Clone(
            [out, retval] IEnumIDList **ppenum);
    };

    [
      odl,
      uuid(000214E6-0000-0000-C000-000000000046)
    ]
    interface IShellFolder : IUnknown {

        HRESULT ParseDisplayName(
            [in] long hwndOwner,
            [in] long pbcReserved,
            [in] long lpszDisplayName,
            [in, out] long* pchEaten,
            [in, out] long* ppidl,
            [in, out] long* pdwAttributes);

        HRESULT EnumObjects(
            [in] long hwndOwner,
            [in] SHCONTF grfFlags,
            [out, retval] IEnumIDList** ppenumIDList);

        HRESULT BindToObject(
            [in] long pidl,
            [in] long pbcReserved,
            [in, out] UUID *riid,
            [in, out] long *ppvOut);

        HRESULT BindToStorage(
            [in] long pidl,
            [in] long pbcReserved,
            [in, out] UUID *riid,
            [out, retval] IStorage **ppvObj);

        HRESULT CompareIDs(
            [in] long lparam,
            [in] long pidl1,
            [in] long pidl2);

        HRESULT CreateViewObject(
            [in] long hwndOwner,
            [in, out] UUID* riid,
            [out, retval] long *ppvOut);

        HRESULT GetAttributesOf(
            [in] long cidl,
            [in, out] long* apidl,
            [in, out] long* rgfInOut);

        HRESULT GetUIObjectOf(
            [in] long hwndOwner,
            [in] long cidl,
            [in, out] long *apidl,
            [in, out] UUID  *riid,
            [in, out] long *prgfInOut,
            [out, retval] long *ppvOut);

        HRESULT GetDisplayNameOf(
            [in] long pidl,
            [in] SHGNO_Flags uFlags,
            [in, out] STRRET* lpName);

        HRESULT SetNameOf(
            [in] long hwndOwner,
            [in] long pidl,
            [in] long lpszName,
            [in] SHGNO_Flags uFlags,
            [out, retval] long* ppidlOut);
    };

    [
        dllname("OLE32.DLL")
    ]
    module ole32 {
        [entry("CLSIDFromString")]
        HRESULT CLSIDFromString(
            [in] LPWSTR lpszProgID,
            [in, out] UUID *lpclsid);

        [entry("CoCreateInstance")]
        LONG CoCreateInstance(
            [in] UUID *CLSID,
            [in] stdole.IUnknown *pUnkOuter,
            [in] CLSCTX dwClsContext,
            [in] UUID *IID,
            [out] void *ppv);

        [entry("CoTaskMemFree")]
        LONG CoTaskMemFree(
            [in] LONG Ptr);

    }

    [
        dllname("KERNEL32.DLL")
    ]
    module kernel32 {
        [entry("RtlMoveMemory")]
        void MoveMemory(
            [in] void *pDest,
            [in] void *pSource,
            [in] LONG ByteLen);
    }

    [
        dllname("SHELL32.DLL")
    ]
    module shell32 {
        [entry("SHGetDesktopFolder")]
        HRESULT SHGetDesktopFolder(
            [out, retval] IShellFolder **ppshf);
    }

    [
        dllname("dummy")  
    ]
    module constants {
        const LPSTR IIDSTR_IShellFolder = "{000214E6-0000-0000-C000-000000000046}";
    }

};
<使用方法>
1. MIDL コンパイラ(Visual C++ or Windows SDK 付属ツール)によりコンパイルを実施
   C:\work\oleliblt> midl.exe oleliblt.odl [Enter]
   → 上記のコンパイルにより「oleliblt.tlb」が作成されます。

2. VBE の [ツール]-[参照設定] により「oleliblt.tlb」を選択。
   → IDataObject / IDropTarget 等が参照できるようになります。

3. 以下のサイトにあるサンプルコードを入力します。
   ■ Sending a file to "Mail Recipient" using sendmail.dll
   http://www.mvps.org/emorcillo/en/code/vb6/sendmail.shtml

4. テストコードを作成します。
   Sub MailTest()
      Call SendToMailRecipient("C:\work\mailtest\test.txt")
   End Sub

5. テストコードを実行し、既定のメーラにてファイルが添付されることを確認します。

この方式にて、Windows 2000 + Excel 2000 環境で動作すること確認しました。

難点としては、特定のパスでタイプライブラリの参照を行った後、他の端末に
Excel ファイルを持って行った場合に「参照不可(MISSING)」となってしまう点でしょうか。

プログラムにより、動的に参照設定を行う方法はありますが、「参照不可」と、なってしまった場合、手動で再設定するしか無いようようです。
(この問題を回避する方法としては「毎回、Excel ブックオープン時にプログラムで参照設定を行い、クローズするときに、参照設定を解除する」という方法があるようです。)

<参考情報>
■ Office TANAKA - Excel VBA Tips[マクロで参照設定を操作する]
http://officetanaka.net/excel/vba/tips/tips100.htm

他1件のコメントを見る
id:cx20

コンパイル済みのタイプライブラリファイルは↓以下にアップしておきました。
http://cx20.main.jp/hatena/file/upload/hatena_1364994425_oleliblt.zip

2013/04/10 23:26:02
id:jack_sonic

ありがとうございます。試してみます。

2013/04/14 21:12:17
  • id:cx20
    > 3、送りたいファイルを右クリックして「送る」

    C++ であれば、以下のコードかと思いますが、VBA で実装するのは厳しい気がします。

    ■ SendTo mail recipient - CodeProject
    http://www.codeproject.com/Articles/3839/SendTo-mail-recipient

    他の方法としては、.eml 形式のファイルを作成し ShellExecute で呼び出す(関連付けしたファイルを "open" で呼び出す)という方法があるようです。

    <参考情報>
    ■ ドラック&ドロップ: DOBON.NETプログラミング掲示板過去ログ
    http://dobon.net/vb/bbs/log3-5/2307.html
  • id:cx20
    > C++ であれば、以下のコードかと思いますが、VBA で実装するのは厳しい気がします。

    ちなみに、その部分だけ、EXE として作成し呼び出すという方法も NG でしょうか?
  • id:jack_sonic
    すみません、NGに近いです。
    添付するファイルが色々種類があるのと、
    WindowsのバージョンによってSendToフォルダの位置が違い、「送る」メニューにある
    メール受信者.MAPImailも若干違ってくるので、
    .MAPImailファイルと送りたいファイルの両方を
    引数として取れるような汎用的なものでないと活路がないです。

    基本的にはVBA単体になります。
    ただ、VBAでも宣言によってWin32APIをC++のように呼び出せるようにしたり、
    動的バインディングでWSHを使うといったことはできます。

    なんとかしてD&Dをコード化できないものでしょうか?
    あるいは、仰られた、.eml化を伴った具体的なコードなど。
    (ただ一旦.eml化すると編集ができなかったような・・?)
  • id:cx20
    VBA でドラッグ&ドロップを行う方法ですが、以下のサイトにサンプルがありました。
    参照設定で OLELIB.TLB を追加することで IDataObject / IDropTarget が使えるようになるようです。
    (XP + Excel 2003 環境でOEのメールにファイル添付できることを確認しました。)
    「余計なものをインストール無しで」ということであれば、この方法も NG が気がしますが・・・

    ■ Sending a file to "Mail Recipient" using sendmail.dll
    http://www.mvps.org/emorcillo/en/code/vb6/sendmail.shtml
    ■ OLELIB.TLB
    http://www.mvps.org/emorcillo/download/vb6/tl_ole.zip
  • id:jack_sonic
    Excel2003でも、情報として欲しいです。
    .NET Frameworkの新しいものと専用DLLが必要なのでしょうか。
    tl_ole.zipがコンパイル前のソースコードようですが、
    コンパイル後のものはありますでしょうか。
  • id:cx20
    > tl_ole.zipがコンパイル前のソースコードようですが、
    > コンパイル後のものはありますでしょうか

    解凍後のファイルに

    olelib.tlb

    が、含まれているかと思います。これを、参照設定してみてください。
  • id:cx20
    > .NET Frameworkの新しいものと専用DLLが必要なのでしょうか。

    ライブラリの実体は、OS 付属のコンポーネント(sendmail.dll)ですので
    .NET Framework や 追加の DLL は不要です。
    ただし、sendmail.dll はタイプライブラリ(COM のヘッダファイルに相当)が
    付属しておらず、VBA から参照することができない為、別途、タイプライブラリを用意する
    必要があります。

    難点としては、特定のパスでタイプライブラリの参照を行った後、他の端末に
    Excel ファイルを持って行った場合に「参照不可(MISSING)」となってしまう点でしょうか。

    プログラムにより、動的に参照設定を行う方法はありますが、「参照不可」と、なってしまった場合、手動で再設定するしか無いようようです。
    (この問題を回避する方法としては「毎回、Excel ブックオープン時にプログラムで参照設定を行い、クローズするときに、参照設定を解除する」という方法があるようです。)

    <参考情報>
    ■ Office TANAKA - Excel VBA Tips[マクロで参照設定を操作する]
    http://officetanaka.net/excel/vba/tips/tips100.htm


    > Excel2003でも、情報として欲しいです。

    タイプライブラリの方式については、Windows 2000 + Excel 2000 環境で動作すること確認しました。
    (「参照不可」となる問題以外は、大丈夫そうな気がします。)
  • id:jack_sonic
    ありがとうございます。参考になります。
  • id:cx20
    > ■ Sending a file to "Mail Recipient" using sendmail.dll
    > http://www.mvps.org/emorcillo/en/code/vb6/sendmail.shtml

    OLELIB.TLB から上記サンプルコードを動作するのに必要な部分だけを切り出した
    タイプライブラリを作成してみました。
    必要ということでしたら、アップしようかと思いますが、使用されますか?
  • id:jack_sonic
    >cx20さん
    是非お願いします。

    また、コメントですとポイント配分が出来ませんので、
    どうぞご遠慮なさらず回答欄をお使いください。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません