質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
COM

COM(Component Object Model)はMicrosoftによるコンポーネントテクノロジーであり、 ソフトウェアの再利用を目的とした技術を指します。

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

1770閲覧

ExcelVBAからC# DLLに配列を渡したい

mtk57

総合スコア1

COM

COM(Component Object Model)はMicrosoftによるコンポーネントテクノロジーであり、 ソフトウェアの再利用を目的とした技術を指します。

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2022/06/03 23:23

■前提・実現したいこと

ExcelVBAからC#で作成したDLLのメソッドに配列を渡したいです。

■発生している問題・エラーメッセージ

ExcelVBAを実行すると以下のメッセージが出ます。(以下VBAコードの★の行)

コンパイルエラー
関数またはインターフェースが予約されているか、またはVisual Basicでサポートされていないオートメーションタイプが関数で使用されています。

■該当のソースコード

VBA

1Sub test() 2 Dim obj As MyComLibMain 3 Dim ret As String 4 Dim arg As MyComLibArg 5 6 Dim strArray(2) As String 7 8 strArray(0) = "111" 9 strArray(1) = "222" 10 strArray(2) = "333" 11 12 Set arg = New MyComLibArg 13 arg.myBool = True 14 arg.myInt = 123 15 arg.myString = "hoge" 16 arg.myStrArray = strArray ★ここでエラーが起きる 17 18 Set obj = New MyComLibMain 19 20 ret = obj.StructArgsFunc(arg) 21 22 MsgBox ret 23End Sub

C#

1using System; 2using System.Runtime.InteropServices; 3 4namespace MyComLib 5{ 6 [ComVisible(true)] 7 [InterfaceType(ComInterfaceType.InterfaceIsDual)] 8 public interface IMyComLibMain 9 { 10 string StructArgsFunc(object obj); 11 } 12 13 [ComVisible(true)] 14 [InterfaceType(ComInterfaceType.InterfaceIsDual)] 15 public interface IMyComLibArg 16 { 17 int myInt { get; set; } 18 string myString { get; set; } 19 bool myBool { get; set; } 20 string[] myStrArray { get; set; } 21 } 22 23 [ClassInterface(ClassInterfaceType.None)] 24 public class MyComLibArg : IMyComLibArg 25 { 26 public int myInt { get; set; } 27 public string myString { get; set; } 28 public bool myBool { get; set; } 29 public string[] myStrArray { get; set; } 30 } 31 32 [ClassInterface(ClassInterfaceType.None)] 33 public class MyComLibMain : IMyComLibMain 34 { 35 public string StructArgsFunc(object arg) 36 { 37 try 38 { 39 if (arg == null) 40 { 41 return "arg is null."; 42 } 43 44 if (!(arg is MyComLibArg)) 45 { 46 return "arg is not MyComLibArg type."; 47 } 48 49 var obj = arg as MyComLibArg; 50 51 var primitiveArg = $"obj.myInt={obj.myInt}\nmyString={obj.myString}\nmyBool={obj.myBool}"; 52 var arrays = ""; 53 54 foreach(var s in obj.myStrArray) 55 { 56 arrays += s; 57 } 58 59 return $"success! ({primitiveArg}, {arrays}"; 60 61 } 62 catch (Exception ex) 63 { 64 return ex.Message; 65 } 66 } 67 } 68}

■自分で調べたことや試したこと

・配列以外の型(int, bool, string)については渡せています。
・Dim strArray(2) As Stringを、「As Variant」や「As Object」に変えてもダメでした。

■使っているツールのバージョンなど補足情報

  • 開発環境:VisualStudio2022
  • Excel:64bit

<プロジェクトの情報>
・「アセンブリをCOM参照にする」:ON
・対象プラットフォーム:x64
・アセンブリに署名する:あり

<REGASMの情報>
・登録時
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm /tlb /codebase /v MyComLib.dll

どうかよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

プロパティの参照は出来ましたが、設定ができませんでした。
メソッドで渡せた(ref でないとダメ)ので、どうにもならないようなら代用してみては?

C#

1using System.Runtime.InteropServices; 2 3namespace ClassLibrary1 4{ 5 [ComVisible(true)] 6 [Guid("D57EE44E-7D09-452D-ACE7-226EE85340A2")] 7 public interface IClass1 8 { 9 string[] strArray { 10 [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] 11 get; 12 [param: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] 13 set; 14 } 15 16 void SetValue([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] ref string[] value); 17 } 18 19 [ComVisible(true)] 20 [Guid("292DF7BD-1554-4BD7-8B15-A3A6850C4A8E")] 21 [ClassInterface(ClassInterfaceType.None)] 22 public class Class1 : IClass1 23 { 24 public string[] strArray { get; set; } = new string[] { "1", "2", "3" }; 25 26 public void SetValue(ref string[] value) { 27 strArray = value; 28 } 29 } 30}

VBA

1Dim c As New ClassLibrary1.Class1 2Dim s1() As String 3 4s1 = c.strArray ’OK 5c.strArray = s1 'コンパイルエラー(関数またはインターフェースが~) 6c.SetValue s1 'OK

投稿2022/06/04 06:37

KOZ6.0

総合スコア2639

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mtk57

2022/06/04 07:57

おお!なるほど!設定をメソッドにすると出来るのですね!勉強になります! ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問