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)
-
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
【VB.NET】Excelの最終行までの取得方法
Microsoft ASP
-
-
4
Application.Runエラー(1004)
Excel(エクセル)
-
5
VB.NETでのイベントの途中終了
Visual Basic(VBA)
-
6
String"から型'Double'への変換は無効です。 とエラーが出ます。
Visual Basic(VBA)
-
7
DateTimePickerでに年月までしか選択できないようにしたいです。
Visual Basic(VBA)
-
8
FORMが開いているかどうかの確認方法
Visual Basic(VBA)
-
9
VBからEXCELのセルの値を取得する方法
Visual Basic(VBA)
-
10
VBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。
Excel(エクセル)
-
11
.NET上でエクセル上に罫線を引く
Visual Basic(VBA)
-
12
Hideについて(.NET)
Visual Basic(VBA)
-
13
VB.NETの配列にExcelから読み込んできたデータを格納したい
Visual Basic(VBA)
-
14
VB.NETで他のEXEを実行させる
Visual Basic(VBA)
-
15
DataGridViewに複数テーブルのデータをセットしたい
Visual Basic(VBA)
-
16
Vb.netのグローバル変数の宣言の仕方の質問
Visual Basic(VBA)
-
17
VB2010でExcelの行をコピーして挿入する
Visual Basic(VBA)
-
18
VBからExcelを起動しExcel終了を判定したい
Visual Basic(VBA)
-
19
VBでフォルダ単位のFTP
Visual Basic(VBA)
-
20
EXCELをバッチコマンドで起動したとき、引数を渡せますか
その他(プログラミング・Web制作)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
[C#]Arraylistに追加した構造体...
-
VBA コレクションに2次元配列...
-
number_formatが勝手に四捨五入
-
classの再定義エラーについて
-
どういうプログラムを関数化を...
-
エラーの理由が分りません。Pri...
-
PHP Catchable fatal error の...
-
ExcelVBAで部分一致(*)をしたい
-
可変変数にアロー演算子を使いたい
-
Dosブロンプトでtabを出力したい
-
shシェルスクリプト 空白行の...
-
wordの差し込み印刷で文字...
-
「取得先」という表現について
-
switch()文で値の大小比較
-
バッチファイルでpingの結果を...
-
phpでcookieがうまく保存されない
-
DTOとEntityの差は何ですか。
-
開始と終了を指定して、その間...
-
format関数について
-
PHPのセッションについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA コレクションに2次元配列...
-
VB.NETからVBAマクロ(引数)を呼...
-
PHPでの画像の形式の変換
-
VB.NETSystem.Xml 要素数を得る...
-
エラーの理由が分りません。Pri...
-
CSVファイルをブラウザのキャッ...
-
PHP、ヒアドキュメント内でのIF...
-
既存関数の上書き
-
【シェル】case文でワイルドカ...
-
PHPの変数値をリンクさせたい
-
可変変数にアロー演算子を使いたい
-
どういうプログラムを関数化を...
-
ExcelVBAで部分一致(*)をしたい
-
サブネットマスクを用いたIP制...
-
PHP Catchable fatal error の...
-
VB6のコンボボックスのテキスト...
-
protectedなのにアクセスできな...
-
[C++]std:mapの扱いを教えて頂...
-
次のhtml・cssでspan内の文字を...
-
classの再定義エラーについて
おすすめ情報