プロが教える店舗&オフィスのセキュリティ対策術

' -- Steo01 --
'Sub_Main01()を登録し,myFunc01を参照しました。
'--
Sub Main01()

Dim mArg1 As Long
Dim ret As Long

mArg1 = 5
ret = myFunc01(mArg1)

MsgBox "myFunc01参照後 mArg1 = " & mArg1
MsgBox "myFunc01参照後 戻り値 ret= " & ret

End Sub

’--
Public Function myFunc01(ByRef fArg1 As Long) As Long

fArg1 = fArg1 * 10 ' -- fArg=5*10
myFunc01 = fArg1 * 10 ' -- myFunc01=5*10*10

End Function

' - Step02 --
'1. Sub Main01()を開きました。
'2. アドイン_ボタンをクリックし、Myfunc01、に☑を入れました。
'3. オブジェクト_エクスプローラーに、
'__ VBAProject(Main01.xlsm)
'__ VBAProject(myFunc01.xlam)
'__ が表示されました。
'
' -- Steo3 --
続いて、表示された、Sub_Main01、を実行しましたが、
エラー「Sub または Function が定義されていません」が出ています?
何かCodeの修正についてアドバイスを頂きたく、お尋ねします。

(追記:Book1に、標準モジュールを二つ設けて、
M1にMain01を書き、M2にmyFunc01を書いて、Sub_Main01(),を実行すると、
正常な結果が表示されます)

質問者からの補足コメント

  • 1.ソース保存
    1.1_ \Documentsに、\Main01.xlsm
    1.2_ \Documentsに、\TestAddin1.xlsm
    1.3_ \AddInsに, \TestAddin1.xlam

    Q?方法A(参照設定)?方法B(呼び出し)?手順・?Code

    現在のエラー(添付画像)
    1.Main01.xlsmをクリックして、VBEを立ち上げ
    (VBAProject(Main01.xlsm)を表示)
    2.*.xlamと結び付ける方法が分からず、アドインボタンで、
    TestAddin1を選択。

    3.すると、VBAProject(Main01.xlsm)の上に、
    UTF01(TestAddin1.xlam)が表示された。
    WindFallerさんに貼って頂いた画像に近いように見えた。
    でもエラー!

    方法A・Bについて、追加のご説明を頂けませんでしょうか?

    「エクセル2013(32ビット)で、Ad」の補足画像1
      補足日時:2017/07/12 22:53
  • myFunc01の参照設定後の実行時画像を添付しました。

    「エクセル2013(32ビット)で、Ad」の補足画像2
      補足日時:2017/07/13 12:11
  • Mainを実行後、関数参照の成功時_画像添付
    *経過
    0._*.JPGの撮影日時を読み出す必要に迫られた。
    1._ユーザー定義関数が必要と知った。
    (ADODB.Streamや、WIA.ImageFile利用も知った)

    2._ついに日付読出し自作関数・myFunc完成

    3._このmyFuncを何処に置くか?

    3.1_Sub_Main、Call文、Functionに置くか?
    3.2_別のモジュールに、このmyFuncを置く(Code切り分け目的)
    3.3_クラス_モジュールに置く

    3.4_同一Project内で、Book1(Main)とBook2(myFunc)の構成
    (なお、Application.Run関数を使うBook間参照は、
    引数を渡せることは確認できたが、戻り値を得るCodeは?)

    3.5_myFuncをアドイン化して参照設定し、実行する手法--今回成功

    「エクセル2013(32ビット)で、Ad」の補足画像3
      補足日時:2017/07/13 22:31

A 回答 (5件)

こんにちは。



なんとか、最後までフォローしたいと思います。
まず、どうやら、私の中途半端な発言が混乱させてしまったようです。
ちゃんと整理して書かなかったのがいけなかったのだと思います。すみません。

ユーザー・アドインの使い方には二種類あります。
1.ワークシート上で使う方法
2.VBE上で使う方法

2. について、アドイン化は不要だというご意見の方もあるかと思います。ただ、アドイン化したほうが扱いやすいからにほかなりません。

ふたつの扱いは同じではありません。VBE のVBAのコードの中で正式に使う方法は、COMにしますが、VBA外の知識やツールが必要です。したがって、簡易型として参照設定という方法と、呼び出しという方法の二種類が簡単でよいかと思います。どちらにしても、アドイン化が楽ではないか、というのが私の考えです。

一目瞭然ですから、添付画像を見てください。ただ、VBE上でMsgBoxを出すために、Win32 API を使用しています。

・アドイン化したファイルのプロジェクト名を、VBAProject を一意の名前に変更しました。
ここでは、プロジェクト名:UTF01 ファイル名は、"TestAddin1.xlam"
VBAProject という名称ですと、エラーが出ます。

その後で参照設定をしました。

添付画像 参照
Sub Main01()

Dim mArg1 As Long
Dim ret As Long

mArg1 = 5
ret = myFunc01(mArg1)  
'↑きちんと呼び出せればこのまま使えます。
'呼び出せない時は、設定のひとつ以上が抜けています。UTF01.myFunc01 でも可能

MsgBox "myFunc01参照後 mArg1 = " & mArg1
MsgBox "myFunc01参照後 戻り値 ret= " & ret

End Sub

'/
アドイン化することで、
参照設定は自動化が可能です。
また、呼び出しも、パスの設定もなく可能です。

>'2. アドイン_ボタンをクリックし、Myfunc01、に☑を入れました。
これは、ワークシート側の組み込みですね。
VBA上で使う目的には、やり方が違います。

以下は、直接、本件とは関係がありませんが、関連情報として役に立つのではないかと思います。

Sub AddinToReferences()
'参照設定の自動化
 Dim ReferencePath As String
 ''要設定:セキュリティ・センター-マクロのプロジェクト設定」
 ''「VBA プロジェクトオブジェクトモデルへのアクセスを信頼する」のチェックボックスにチェックを付けます。
 ReferencePath = Application.UserLibraryPath & "\TestAddin1.xlam"
 If Dir(ReferencePath) <> "" Then
  On Error Resume Next
  ThisWorkbook.VBProject.References.AddFromFile ReferencePath
  If Err <> 0 Then
   MsgBox "セキュリティ・センターの設定がオフになっています。"
  End If
  On Error GoTo 0
 Else
  MsgBox "参照設定は失敗しました。", vbExclamation
 End If
End Sub


Sub RunnigAddin()
'VBAのアドインの呼び出し
Dim AddInName As String
Dim myAddin As AddIn
Dim ret
AddInName = "TestAddin1"
 On Error Resume Next
 Set myAddin = Application.AddIns(AddInName)
  If myAddin.Installed = False Then
    myAddin.Installed = True '自動アドインのインストール
  End If
  ret = Application.Run(myAddin.Name & "!myFunc01", 5)
  MsgBox ret
 On Error GoTo 0
End Sub

アドイン参照設定での使用状態
「エクセル2013(32ビット)で、Ad」の回答画像1
    • good
    • 0
この回答へのお礼

WindFallerさん、こんにちは。
いつもご丁寧なご回答を頂き、本当に、有難う御座います。
初めてアドインの扉を開けて中を覗いたという状態です。
WEB検索で探しまわって来ましたがまだ頭の整理ができません。
今、今回頂いた#1・#2のご回答をプリントアウトして、
逐一判読中です。?が残ったらまた、追加でお尋ねさせて下さい。

お礼日時:2017/07/12 15:40

追伸:



Sub AddinToReferences()
これは自動化してアドインを参照設定させるコードで、実際には、
Auto_Open や ThisWorkbook_Open に組み込むと良いでしょう。

終了する時に、参照設定があると終われないことがあります。以下は、そのためのマクロです。
それで、反対も書いて置くのを忘れました。
BeforeClose などに入れて置くのがよいと思います。

Sub SetOff_References()
'参照設定の自動解除
 Dim ReferencePath As String
 Dim ref As Object
  On Error Resume Next
  Set ref = ThisWorkbook.VBProject.References("UTF01") 'プロジェクト名
  
  ThisWorkbook.VBProject.References.Remove ref
  If Err <> 0 Then
   MsgBox "参照設定外しに失敗しました。", vbExclamation
  End If
  On Error GoTo 0
End Sub
    • good
    • 0
この回答へのお礼

こんばんは。
精読していますが、最初のアクションになる、次の手法がまだ理解できていません!
>『VBAのコードの中で、簡易型として参照設定という方法(A)と、
呼び出しという方法(B)の二種類が簡単でよいかと思います。』
頂いた添付画像は、手法A or 手法B を使った例ですか。
恐縮ですが、AとBの手法を、Step by Step でご紹介頂けませんでしょうか?
----
現時点で、エラーが出ている状況は、エラー画像も添えて、
お尋ねの追加コメントに書き込みました。
急ぎませんが、見て頂ければ幸いです。

お礼日時:2017/07/12 21:55

こんばんは。



画像があるので、とても助かります。
段階的に書いていればよいのですが、必要なコードを全部書いてしまいましたから、その段階が分からないと思います。

それから、ひとつ誤解を与えているか、それとも疑問を残しているかもしれませんので予め書いておきますが、別におすすめはしませんが、"CodeExplorer" は、codevba というユーティリティからのものです。モジュールの名称を変えたわけではありません。
http://codevba.com/

添付画像でひとつ足りないものは、参照設定です。

Sub Main01() すなわち Bの参照設定の手順
1. ワークシート側-開発-アドイン-
☑私のアドイン名はTestaddin1  (チェックを入れました)
OK

2.VBE画面に切り替えてください。プロジェクト・エクスプローラーでアドインが入っていることを確かめます。(この時に、VBAProject という名称があると、参照設定時にエラーが発生するので、今回は、UTF01に変更しました。)

3.マクロを実行する側(Main01)のVBEの上部メニューのツール-参照設定
UTF01 にチェックを入れて、OK (添付画像)

これで、Main01のマクロを実行してみてください。

--これでうまくできたはずです。--
・ここまで確認してみてください。

この手間を省くというのが、
参照設定の自動設定と参照設定の自動解除(Sub AddinToReferences/Sub SetOff_References)

画像は、参照設定の様子を描いたものです。
「エクセル2013(32ビット)で、Ad」の回答画像3
    • good
    • 0
この回答へのお礼

こんにちは。追加情報、有難う御座いました。
参照設定はできたと思いますが、まだエラーが出ます。
実行時の画像は、追加コメントに貼りました。
後一歩と思いますが、なかなか難しいです。

お礼日時:2017/07/13 12:07

オンラインで返事書きます。



>myFunc01の参照設定後の実行時画像を添付しました。
>2017/07/13 12:00:00

申し訳ありません。やはり、#1の画像で、私のCode Exploerer を使った画像が、間違えさせてしまっています。誤解されるようなことをしてしまいました。

アドインの項目
プロジェクト名: UTF01 (任意)VBAProject でなければよい
標準モジュール:そのままでよい
ユーザー定義関数: myFunc01()

参照設定されている名称:プロジェクト名
しかし、標準モジュールは同じではありません。
同じだから、エラーが出ています。(たぶん)
    • good
    • 0
この回答へのお礼

WindFallerさん、こんばんは。
何回ものアドバイス、大変有難う御座いました。

紆余曲折で遠回りしたようですが、ご支援の賜物で、
やっとアドイン_参照に成功しました。

追加コメントとして、成功時の画像を添付して、
お礼に代えさせて頂きます。

なお、この際に頂いた関連情報は、
時間をかけて、理解していきたいと思っています。

お礼日時:2017/07/13 22:36

それは、おめでとうございます。

(^^;

掲示板で、ここまで踏み入れる人は、私の知っている中では、たぶん初めてだと思います。この一歩の踏み出しは、やがて別な新しい世界に入っていくものだと信じます。

後、他人に使わせる時などには、参照設定の自動設定と自動解除のワザは、何かと後々に役に立つはずです。一度やれば、もう10年たっても忘れるものではありません。

ただ、私が覚えた頃の15年ぐらい前と違うのは、アドイン系の選択肢がかなり増えていることです。以前は、それひとつで良かったのです。

いきなりではないけれども、黒船がやってきたように無視できない存在になってきましたが、今は、私は、手も足もでないという感じです。

xll とか、新しい COM Addin とか、Excel DNAとか、聞いたことがあるとかと思いますが、以前のものとは大きく違ってきているのです。

それなのに、私は、余計なものに手を出したりして、肝心な所には手をつけていないのです。
    • good
    • 0
この回答へのお礼

一連の?に、ご丁寧に対応して頂き有難う御座いました。

写真撮影日をVBAシステム関数(FileDateTime)で代用していた、自作の写真Softを愛用してきましたが、
最近は画像圧縮や加工をすることが多くなり、直接撮影日時を読み出したくなりました。

数行のCodeを追加すればできると気楽に取り組みましたが、意外に難題でした。
写真ファイルの国際規格の理解、VBAの再学習、初めて目にしたクラスやアドインの理解等々、
あっという間に半年が経過していました。

この間、いろいろの分野で、いろいろ方々から、アドバイスを頂き、本当に有難う御座いました。

お礼日時:2017/07/14 13:41

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!