C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

共通のSubを複数のFormから使うには

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■103052 / inTopicNo.1)  共通のSubを複数のFormから使うには
  
□投稿者/ かりん (1回)-(2024/04/09(Tue) 14:35:38)

分類:[VB.NET/VB2005 以降] 

下の @ の部分に「エラー BC30179 structure 'datt' と structure 'datt' が 
namespace 'WindowsApp1' で競合しています」が出てしまい困っています。
よろしくお願いします。

Module Module1
    Public Sub MySub(ByVal dat() As datt)
        ' ここに共通の処理コードを書く
    End Sub
End Module


'Form1の構造体を宣言
Public Structure datt  '@ 
    Dim da1 As Single
    Dim da2 As Single
End Structure

Public Class Form1
    Dim dat(10) As datt

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Call MySub(dat)
    End Sub
End Class


'Form2の構造体を宣言
Public Structure datt
    Dim da1 As Single
    Dim da2 As Single
End Structure

Public Class Form2
    Dim dat(10) As datt

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Call MySub(dat)
    End Sub
End Class

引用返信 編集キー/
■103053 / inTopicNo.2)  Re[1]: 共通のSubを複数のFormから使うには
□投稿者/ とっちゃん (822回)-(2024/04/09(Tue) 15:13:48)
No103052 (かりん さん) に返信
> 下の @ の部分に「エラー BC30179 structure 'datt' と structure 'datt' が
> namespace 'WindowsApp1' で競合しています」が出てしまい困っています。
> よろしくお願いします。
>
datt.vb を作ってそこに定義すればよいです(もしくは、Module1.vb の Module 定義の外側)。

個人的にはMySub は Module に定義するのではなく datt 構造体の
メソッドとして定義するほうがいいのかな?と思います。
datt.MySub をインスタンスメソッドにすれば、パラメータで渡す必要もありません。


引用返信 編集キー/
■103054 / inTopicNo.3)  Re[1]: 共通のSubを複数のFormから使うには
□投稿者/ 魔界の仮面弁士 (3757回)-(2024/04/09(Tue) 15:34:55)
No103052 (かりん さん) に返信
> 下の @ の部分に「エラー BC30179 structure 'datt' と structure 'datt' が
> namespace 'WindowsApp1' で競合しています」が出てしまい困っています。

エラーメッセージの通り、名前空間が競合しています。
両者の定義は同一のようですし、重複した宣言を削除して一つだけにしてみてください。


(質問1) @をどのファイルに書いていますか?
 Module1.vb ?
 Form1.vb ?
 Form2.vb ?
 それ以外?

(質問2) Structure datt は、そのファイルのどこに書いていますか?
 ファイル直下?
 「Module Module1 〜 End Module」の配下?
 「Class Form1 〜 End Class」の配下?
 「Namespace ××〜End Namespace」の配下?


実際のところ、大切なのは質問2の方だったりします。(質問1は重要では無い)
現在は恐らく、ファイル直下に書いているのですよね。


今回の場合、Form1.vb や Form2.vb に書かれている『Public Structure datt』の宣言を削除し、
それを、Module1.vb の下に移動してみてください。恐らくはそれで改善されると思います。

あるいは Module1.vb とは別に、datt.vb のような別ファイルを用意し、そこに移動させても OK です。



> よろしくお願いします。

=== 以下蛇足 ===

VB の場合、作成時のプロジェクト名がそのまま既定の『ルート名前空間』になります。
今回の場合は、WindowsApp1 という名前ですね。

『ルート名前空間』は変更したり空欄にすることも可能ですが、通常は気にする必要はありません。
変更したい場合は、プロジェクトのプロパティ(My Project)の[アプリケーション]タブの[ルート名前空間]を使います。



さて、この『既定のルート名前空間』なのですが、現状のように
> Module Module1
> Public Sub MySub(ByVal dat() As datt)
> ' ここに共通の処理コードを書く
> End Sub
> End Module
と書いた場合、この MySub は「WindowsApp1 名前空間の Module1 モジュールの MySub メソッド」を意味します。

このメソッドを呼び出す場合には通常、
  MySub(データ)
もしくは
  Module1.MySub(データ)
などと書いていたかと思いますが、これを名前空間を省略せずに記述する場合、
 WindowsApp1.Module1.MySub(データ)
あるいは
 Global.WindowsApp1.Module1.MySub(データ)
という呼び出しになります。


> Public Class Form1
これも同様に、この型名の前に『既定のルート名前空間』が存在します。そのため、
 Dim f As Form1
というコードがあったら、それは
 'Dim f As Global.WindowsApp1.Form1
 Dim f As WindowsApp1.Form1
と同義であるということになります。


そして、本題となる
> Public Structure datt
ですが、型の宣言というのは、それがどのファイルに書かれているのかは重要ではありません。

それが Form1.vb に書かれていようと、Form2.vb に書かれていようと、
記述が「ファイルの直下」にあるのなら、それは
 WindowsApp1.datt
という名前になっているということになります。

そして名前空間の下に、同じ名前の型が存在していると、
今回のように BC30179 エラーになってしまいます。


もしも名前空間あるいは入れ子の型までのパスが異なっていれば、
それぞれが別物として扱われます。たとえば、こういう書き方は可能です。

 'Form1.vb
 Public Class Form1
  Public Structure datt
   :
  End Structure

Dim dat(10) As datt 'これは As WindowsApp1.Form1.datt 相当
  :
 End Class
'-------------------
 'Form2.vb
 Public Class Form2
  Public Structure datt
   :
  End Structure

Dim dat(10) As datt 'これは As WindowsApp1.Form2.datt 相当
  :
 End Class


この書き方の場合、2 つの datt は別の型として扱われます。

そのため、上記のように Class の中に配置した場合、Module1 側の
> Public Sub MySub(ByVal dat() As datt)
の部分で、datt の型を解決できなくなってしまいます。

これについては、
 Public Sub MySub(ByVal dat() As Form1.datt)
 End Sub
 Public Sub MySub(ByVal dat() As Form2.datt)
 End Sub
のように、それぞれ別の型に対するオーバーロードにすることはできますが、
今回はそもそも型を分ける必要は無いので、Structure datt も一つあれば十分でしょう。
引用返信 編集キー/
■103055 / inTopicNo.4)  Re[2]: 共通のSubを複数のFormから使うには
□投稿者/ 魔界の仮面弁士 (3758回)-(2024/04/09(Tue) 18:09:39)
2024/04/09(Tue) 18:10:27 編集(投稿者)

No103053 (とっちゃん さん) に補足
> 個人的にはMySub は Module に定義するのではなく datt 構造体の
> メソッドとして定義するほうがいいのかな?と思います。
> datt.MySub をインスタンスメソッドにすれば、パラメータで渡す必要もありません。

MySub は、「datt 構造体の配列」を処理しているようなので、
単一インスタンスに対するインスタンスメソッドだと都合が悪いかも知れません。
(MySub の実装にもよるけれど)


配列操作を datt 構造体自身に実装するとしたら、

 Public Structure datt
  Dim da1 As Single
  Dim da2 As Single
  Public Shared Sub MySub(dat() As datt)
   'For n = 0 To 10
   ' Debug.WriteLine(dat(n).da1)
   'Next
  End Sub
 End Structure


のように、共有メソッド(C# でいうところの静的メソッド)にするか、もしくは

 Class dattList
  Inherits List(Of datt)
  Public Sub MySub()
   'For n = 0 To 10
   ' Debug.WriteLine(Me(n).da1)
   'Next
  End Sub
 End Class

のように、コレクションクラスに対するインスタンスメソッドに変更する必要があるかもしれません。


あるいは、dat 配列に対する拡張メソッドを用意するという手も。

 Module Module1
  <System.Runtime.CompilerServices.Extension>
  Public Sub MySub(ByVal dat() As datt)
   'For n = 0 To 10
   ' Debug.WriteLine(dat(n).da1)
   'Next
  End Sub
 End Module



ただいずれにせよ、
「エラー BC30179 structure 'datt' と structure 'datt' が namespace 'WindowsApp1' で競合しています」
の原因は、『Public Structure datt』が 2 箇所に存在している事が原因なので、
> datt.vb を作ってそこに定義すればよいです(もしくは、Module1.vb の Module 定義の外側)。
などのようにして、まずは重複を排除することが肝要ですね。
MySub の記述位置を考えるのは、その後の話。
引用返信 編集キー/
■103057 / inTopicNo.5)  Re[3]: 共通のSubを複数のFormから使うには
□投稿者/ かりん (2回)-(2024/04/11(Thu) 16:12:09)
No103054 (魔界の仮面弁士 さん) に返信

ありがとうございました。
教えていただいたので解決しました。

とっちゃんさんにもお礼をいいます。

> 今回の場合、Form1.vb や Form2.vb に書かれている『Public Structure datt』の宣言を削除し、
> それを、Module1.vb の下に移動してみてください。恐らくはそれで改善されると思います。
>
> あるいは Module1.vb とは別に、datt.vb のような別ファイルを用意し、そこに移動させても OK です。

解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ