![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
VB.NETから参照型引数付きのFunctionのVBAマクロを呼び出す方法
Excel2003のVBEの標準モジュールModule1にあるFunctionのマクロtest(引数)をVB.NETから呼び出して、引数に設定した値をVBA側で加工して、加工された値をVB.NETで取り出したいのですが、VB.NET側でどのように記述してよいのかがよく分かりません。
具体的には、以下のVBAをVB.NETから呼び出すにはどのように記述すればよいのでしょうか。できましたらそのままVB.NETのConsoleApplicationのModule1のSub Main()の中にコピーペーストして動くコードと参照設定を教えていただけると助かります。
---Excel2003のVBA(C:\test\Book1.xls)----------
Function test(ByRef data As Long) As Long
If data = 0 Then
test = 0
data = 0
Else
test = 1
data = 100 / data
End If
End Function
----------------------------------------------
よろしくお願いします(WindowsXP,VisualStudio2010,Excel2003VBE)
A 回答 (6件)
- 最新から表示
- 回答順に表示
No.6
- 回答日時:
こんにちは。
>参照型の引数として呼び出すことは原理的にできないのでしょうか。
そうですね。。。
できないと思われます。
戻り値は取れるんですけどね。
ただ値を取得するのであれば、すでに解答したので対応出ると思いますが、
細かい事は、実際のソースを見て判断しないと何とも言えません。
いろいろ考えてみましたが、Excelのバージョンを考えると、
作り変えた方が早いのではないでしょうか。
私はそういう場合、クラスに作り変えたりします。
時間が経てば、そのうちひらめく場合もありますけど(^o^)
今はお役に立てなくてごめんなさい。
逆にひらめいたら、教えて下さい(*・∇-)
こんにちは。
参照型の引数として呼び出すことができないということが分かっただけでも質問してよかったです。
そのほかにもいろいろな回避策を教えていただきまして大変参考になりました。
ありがとうございました。
No.5
- 回答日時:
こんにちは。
こんなのはどうでしょう?
クリップボードに値をコピーさせてみては。
タイプライブラリは無かった事に。。。
Microsoft Forms 2.0 Object Library
VBAと.NETの参照設定に追加します。
VBAの参照設定に無い場合は、FM20.DLLを参照から追加して下さい。
参考URLを付けておきます。
------VBA------------------------------------
Function test(ByRef data As Long) As Long
Dim CB As DataObject
Set CB = New DataObject
If data = 0 Then
test = 0
data = 0
Else
test = 1
data = 100 / data
End If
'クリップボードのクリア
Application.CutCopyMode = False
'クリップボードに値をセット
CB.SetText data
'コピーの実行(これを実行しないとクリップボードにコピーされません。)
CB.PutInClipboard
End Function
---------.NET------------------
Imports Excel = Microsoft.Office.Interop.Excel
Module Module1
Sub Main()
Try
Dim oExcel As New Excel.Application
Dim oBook As Excel.Workbook
Dim oBooks As Excel.Workbooks = oExcel.Workbooks
Dim strPath As String
Dim Result As Long
Dim data As Long
'C:\test\Book1.xlsを実行ファイルに指定する。
strPath = "C:\test\Book1.xls"
'Excelオブジェクトの設定
oExcel.Visible = False
oBook = oBooks.Open(strPath)
data = 1
'Excel側のFunctionを実行する
Result = oExcel.Run("'" & oBook.Name & "'!test", data)
'クリップボードに保存された値を取得
If Clipboard.ContainsText() Then
MsgBox(Clipboard.GetText())
End If
'解放
oBook.Close(False)
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook)
oBook = Nothing
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBooks)
oBooks = Nothing
oExcel.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
oExcel = Nothing
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Module
プログラムの実行でクリップボードにコピーの動作がないようでしたら、
こちらで対応できそうなのですが…
参考URL:http://officetanaka.net/excel/vba/tips/tips20.htm
この回答への補足
angel_Zさん
こんにちは。
いろいろ提案をしていただきましてありがとうございます。
教えていただきました戻り値経由による方法、および今回のクリップボード経由による方法を確認しました。呼び出し先で変更された結果を呼び出し元で得ることができたのですが1つ問題があります。
すでにあるVABのマクロをVB.NETからそのまま呼び出して利用したいのですが、これらのマクロの引数は、サンプル例のように整数型の変数が1個だけではなく、複数の引数を持っています。型も整数型だけではなく他の型も混在していたり、ユーザー定義型もあります。クリップボードでこれらの引数の値のすべてを返すことは可能でしょうか。できたとしても処理が複雑になるような気がしているのですが。。。
マクロ自体も複数あり、各マクロ内部の処理も大掛かりな処理をしていてVBへの移植が大変なので、少しの修正程度で、できれば何も手を加えずそのまま呼び出したかったのですが、参照型の引数として呼び出すことは原理的にできないのでしょうか。
よろしくお願いします。
No.4
- 回答日時:
こんにちは。
相談ですが、
エクセル側のFunction testを修正する事が可能ですか?
可能でしたら、
Function test(ByRef data As Long, Optional fg As Integer = 0) As Long
'fg 0:VBAより 1:.NETより
If data = 0 Then
test = 0
data = 0
Else
If fg = 0 Then
test = 1
data = 100 / data
Else
test = 100 / data
End If
End If
End Function
に修正して、.NET側のマクロの呼び出しで、
'Excel側のFunctionを実行する
Result = oExcel.Run("'" & oBook.Name & "'!test", data,1)
にすると、100が帰ってきます。
VBA側は、fgはデフォルト0で省略可能なので、
変更しなくてOKなのですが。
こちらが一番簡単な変更なのかと考え方を変えてみたのですが、
いかがでしょうか?
変更できない場合は、
自作のDLL作成で両方の参照設定や、
API使用などありそうですが、
ややこしいです。。。
この回答への補足
angel_Zさん
返答ありがとうございます。
>エクセル側のFunction testを修正する事が可能ですか?
少しの修正は可能ですが、引数には反映されず、結果が戻り値で返るのは、ちょっと問題があります。引数として返されるのであれば上記のコードの程度の修正はOKです。
>変更できない場合は、
>自作のDLL作成で両方の参照設定や、
>API使用などありそうですが、
>ややこしいです。。。
かなりややこしそうで苦戦しております。ANo.3 で教えていただきましたリンク先のサンプルで確認していますがもう少し時間がかかりそうです。結果は ANo.3 のところにご報告致します。
よろしくお願いします。
No.3
- 回答日時:
こんにちは。
参照渡しでしたね。
この辺りが参考になりそうですが、
http://hpcgi1.nifty.com/MADIA/vbnet/wwwlng.cgi?p …
タイプライブラリを用意して、
両方に参照設定の必要がありますね。
この回答への補足
angel_Zさん
返答ありがとうございます。
分からないことだらけでいろいろ確認していて返答が遅くなってしまいました。
> この辺りが参考になりそうですが、
> http://hpcgi1.nifty.com/MADIA/vbnet/wwwlng.cgi?p …
> タイプライブラリを用意して、
> 両方に参照設定の必要がありますね。
> 変更できない場合は、
> 自作のDLL作成で両方の参照設定や、
> API使用などありそうですが、
> ややこしいです。。。
ややこしくても、このようにすることで問題が解決するのであれば、やってみる価値はあると思いましたので、リンク先のサンプルを参考にして確認してみました。どこかが間違っているのかもしれませんが、下記のMsgBox(t_o.data)の結果は100にはならず1のままでした。
---Excel2003のVBA(C:\test\Book1.xls)----------
Option Explicit
Function test(ByRef t_o As ClassLibrary1.T) As Long
If t_o.data = 0 Then
test = 0
t_o.data = 0
Else
test = 1
t_o.data = 100 / t_o.data
End If
End Function
---VB.NET(ConsoleApplication)-------------
Imports Excel = Microsoft.Office.Interop.Excel
Module Module1
Sub Main()
Try
Dim oExcel As New Excel.Application
Dim oBook As Excel.Workbook
Dim oBooks As Excel.Workbooks = oExcel.Workbooks
Dim strPath As String
Dim Result As Long
'Dim data As Long
Dim t_o As New ClassLibrary1.T ' <--変更
'C:\test\Book1.xlsを実行ファイルに指定する。
strPath = "C:\test\Book1.xls"
'Excelオブジェクトの設定
oExcel.Visible = False
oBook = oBooks.Open(strPath)
'data = 1
t_o.data = 1 ' <--変更
'Excel側のFunctionを実行する
'Result = oExcel.Run("'" & oBook.Name & "'!test", data)
Result = oExcel.Run("'" & oBook.Name & "'!test", t_o) ' <--変更
'確認用
MsgBox(Result)
'MsgBox(data)
MsgBox(t_o.data) ' <--変更
'解放
oBook.Close(False)
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook)
oBook = Nothing
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBooks)
oBooks = Nothing
oExcel.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
oExcel = Nothing
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Module
---VB.NET(ClassLibrary1)-----------------------
Public Structure T
'Public data As Long 'Longではエラーに?
Public data As Integer
End Structure
------------------------------------------------
もし、angel_Zさんの意図されている方法と異なっていましたらご指摘ください。
よろしくお願いします。
No.2
- 回答日時:
こんにちは。
これではどうですか?
'参照設定の追加 COM
'Microsoft Excel xx.0 Object Libraryを追加
Imports Excel = Microsoft.Office.Interop.Excel
Sub Main()
Try
Dim oExcel As New Excel.Application
Dim oBook As Excel.Workbook
Dim oBooks As Excel.Workbooks = oExcel.Workbooks
Dim strPath As String
Dim Result As Long
'C:\test\Book1.xlsを実行ファイルに指定する。
strPath = "C:\test\Book1.xls"
'Excelオブジェクトの設定
oExcel.Visible = False
oBook = oBooks.Open(strPath)
'Excel側のFunctionを実行する
Result = oExcel.Run("'" & oBook.Name & "'!test", 引数)
'確認用
Msgbox(Result)
'解放
oBook.Close(False)
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook)
oBook = Nothing
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBooks)
oBooks = Nothing
oExcel.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
oExcel = Nothing
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
この回答への補足
angel_Zさん。こんにちは。
返答ありがとうございます。
教えていただきましたコードで確認してみました。
エラーは出ず実行して正常に終了するのですが
VBA側で変更した引数の値が
VB.NETの引数には反映されてこないようです。
--------------------
(省略)
Dim data As Long '<-----追加
data = 1 '<-----追加
'Excel側のFunctionを実行する
Result = oExcel.Run("'" & oBook.Name & "'!test", data) ' <-----修正
'確認用
MsgBox(Result)
MsgBox(data) '<-----追加
(省略)
--------------------
MsgBox(data)のdataの期待値は100ですが実際は1のままです。
よろしくお願いします。
No.1
- 回答日時:
「
http://dobon.net/vb/dotnet/programing/eval.html」の「CSharpCodeProviderを使用した方法」が参考になるのではないでしょうか。参考URL:http://dobon.net/vb/dotnet/programing/eval.html
この回答への補足
yamaj_bizさん
返答ありがとうございます。
すでにあるVABのマクロの処理をVBでも処理したいのですが、そのマクロはサンプル例のように単純ではなく、かなり大掛かりな処理をしています。それでVBへの移植が大変なので、そのままVABのマクロを呼び出せないのかを検討しています。
よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBAでfunctionを利用しようとしたときに「引数は省略できません」というエラーが出ます 1 2022/10/15 16:30
- Visual Basic(VBA) VBAでファイル名を指定して保存するとき 4 2023/03/26 21:55
- Visual Basic(VBA) エクセルのマクロとシートの保護について教えてください。 1 2022/10/18 08:36
- その他(プログラミング・Web制作) IT初心者です 仕事で、vb.netで作成されたdllをvbaで呼び出すプログラムを作成しろと言われ 1 2023/03/27 08:22
- Visual Basic(VBA) パーソナルXLSBのfuctionを呼び出すと「Functionが定義されていません」のエラーになる 2 2022/08/22 22:51
- Visual Basic(VBA) エクセルのマクロについて教えてください。 4 2023/07/03 09:11
- Visual Basic(VBA) Excle VBA Findメソッドについて 3 2022/07/15 13:56
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 1 2023/08/08 15:45
- Visual Basic(VBA) VBAでoutlook365が起動しません。 4 2022/08/25 13:31
- Excel(エクセル) Excel-VBAの「しばらくお待ちください」のダイアログが自動的に閉じない 2 2023/05/24 15:31
このQ&Aを見た人はこんなQ&Aも見ています
-
プロが教えるわが家の防犯対策術!
ホームセキュリティのプロが、家庭の防犯対策を真剣に考える 2組のご夫婦へ実際の防犯対策術をご紹介!どうすれば家と家族を守れるのかを教えます!
-
Excelマクロを引数付で起動
Visual Basic(VBA)
-
VB.NETでのイベントの途中終了
Visual Basic(VBA)
-
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
-
4
VBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。
Excel(エクセル)
-
5
一つのトランザクションでSELECTとUPDATEできますか? (ADO.NET)
SQL Server
-
6
String"から型'Double'への変換は無効です。 とエラーが出ます。
Visual Basic(VBA)
-
7
【Excel VBA】マクロでExcel自体を終了させたい
Excel(エクセル)
-
8
DataGridViewに複数テーブルのデータをセットしたい
Visual Basic(VBA)
-
9
「エクセルファイルが開いていたら開かない」としたい
Visual Basic(VBA)
-
10
VBAをVBに変換する方法
その他(プログラミング・Web制作)
-
11
VB.NETで DataRow()を利用して、値からコードを取得したい。
Visual Basic(VBA)
-
12
Application.Runエラー(1004)
Excel(エクセル)
-
13
エクセルでエラーが出て困っています。
Excel(エクセル)
-
14
Hideについて(.NET)
Visual Basic(VBA)
-
15
【VB】タブ切り替え時のイベント
Visual Basic(VBA)
-
16
文字列の後ろから必要分だけ削除したい。
Visual Basic(VBA)
-
17
VB.net 任意の例外を発生させるには・・・
Visual Basic(VBA)
-
18
VB.NETで他のプロジェクトで作成したフォームを使う方法
Visual Basic(VBA)
-
19
Functionで戻り値を複数返す方法
Visual Basic(VBA)
-
20
VB.NETで1→A、2→B、26→Z、27→AAの変換をしたい
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
PHPでの画像の形式の変換
-
可変変数にアロー演算子を使いたい
-
VBA コレクションに2次元配列...
-
Let's Encryptで自動更新がされ...
-
number_formatが勝手に四捨五入
-
デフォルトの定義済みクラスに...
-
【Objective-c】rubyの__send__...
-
VB.NETからVBAマクロ(引数)を呼...
-
関数の動きと記述方法の意味を...
-
メール本文の構成 行頭空白
-
VB6のコンボボックスのテキスト...
-
Dosブロンプトでtabを出力したい
-
shシェルスクリプト 空白行の...
-
DTOとEntityの差は何ですか。
-
【C#】DataGridViewの最大列数...
-
wordの差し込み印刷で文字...
-
「取得先」という表現について
-
EXCEL、マクロ-改ページ行番号...
-
ファイル名に日付の挿入
-
VBAで重複チェックの仕方を教え...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA コレクションに2次元配列...
-
エラーの理由が分りません。Pri...
-
可変変数にアロー演算子を使いたい
-
VB.NETからVBAマクロ(引数)を呼...
-
PHP、ヒアドキュメント内でのIF...
-
VB.NETSystem.Xml 要素数を得る...
-
どういうプログラムを関数化を...
-
vb作成したらでbeep音が鳴りま...
-
次のhtml・cssでspan内の文字を...
-
classの再定義エラーについて
-
既存関数の上書き
-
protectedなのにアクセスできな...
-
配列の操作時にLNK2001外部シン...
-
UNIX CP "で上書きしません"
-
PHPでの画像の形式の変換
-
PHPプログラム上で「URLを直接...
-
Let's Encryptで自動更新がされ...
-
ExcelVBAで部分一致(*)をしたい
-
VB6のコンボボックスのテキスト...
-
ASPのResponse.WriteをPHPでは...
おすすめ情報