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

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

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

Re[3]: 二次元配列(x,y)


(過去ログ 120 を表示中)

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

■72115 / inTopicNo.1)  二次元配列(x,y)
  
□投稿者/ あり得んロッペン (1回)-(2014/05/19(Mon) 16:42:45)

分類:[.NET 全般] 

2014/05/19(Mon) 16:45:23 編集(投稿者)
VB2008初心者です。


二次元配列で、簡単な表のようなものを作りたいです。

                                x
         
   A(1,1)A(1,2)A(1,3)A(1,4)A(1,5)
y   A(2,1)A(2,2)A(2,3)A(2,4)A(2,5)
   A(3,1)A(3,2)A(3,3)A(3,4)A(3,5)


xは7までの
yは20までと想定してます。


作り方のイメージが湧きません
カンマ区切りの入れ方が分かりません。


 '二次元配列文字列変数の宣言
        Dim data(7, 20) As Integer

        For x As Integer = 1 To 7
            For y As Integer = 1 To 20
                data(x - 1, y - 1) = x + y
                Console.Write(data(x - 1, y - 1))
            Next
            Console.WriteLine()
        Next


ご教授願います。

引用返信 編集キー/
■72116 / inTopicNo.2)  Re[1]: 二次元配列(x,y)
□投稿者/ Hongliang (197回)-(2014/05/19(Mon) 16:54:53)
うーん?
個々の要素に格納される値が、整数ではなく整数のペアって事ですか?
であれば、整数しか扱えないIntegerでは当然無理ですが。
(まあ、上位16ビットと下位16ビットでとかの昔ながらの方法もないではないですが)
Point型なり、あるいは整数のペアを扱える自作の構造体なりを使って、それの配列を作ることになります。

> Dim data(7, 20) As Integer
これだとxは0〜7までの8個、yは0〜20までの21個になりますが大丈夫ですか?
引用返信 編集キー/
■72117 / inTopicNo.3)  Re[1]: 二次元配列(x,y)
□投稿者/ shu (570回)-(2014/05/19(Mon) 17:00:02)
No72115 (あり得んロッペン さん) に返信

提示されたコードだと

23456789101112131415161718192021
345678910111213141516171819202122
4567891011121314151617181920212223
56789101112131415161718192021222324
678910111213141516171819202122232425
7891011121314151617181920212223242526
89101112131415161718192021222324252627

のように出力されると思いますが
どのように出力したいのでしょう?

xが横でyが縦方向なら少なくともfor文のx,yは逆である必要があります。

引用返信 編集キー/
■72118 / inTopicNo.4)  Re[2]: 二次元配列(x,y)
□投稿者/ あり得んロッペン (2回)-(2014/05/19(Mon) 17:04:56)
No72116 (Hongliang さん) に返信

> 個々の要素に格納される値が、整数ではなく整数のペアって事ですか?
整数のペアです。

> Point型なり、あるいは整数のペアを扱える自作の構造体なりを使って、それの配列を作ることになります。
Point型ですか、調べてみます。

>>Dim data(7, 20) As Integer
> これだとxは0〜7までの8個、yは0〜20までの21個になりますが大丈夫ですか?
失礼しました。
1〜7 1〜20 でした。
引用返信 編集キー/
■72119 / inTopicNo.5)  Re[2]: 二次元配列(x,y)
□投稿者/ あり得んロッペン (3回)-(2014/05/19(Mon) 17:10:26)
2014/05/19(Mon) 17:13:16 編集(投稿者)
No72117 (shu さん) に返信


> どのように出力したいのでしょう?
はい、下記の様に出力したいです。

         
   A(1,1)A(1,2)A(1,3)A(1,4)A(1,5)
    A(2,1)A(2,2)A(2,3)A(2,4)A(2,5)
   A(3,1)A(3,2)A(3,3)A(3,4)A(3,5)


> xが横でyが縦方向なら少なくともfor文のx,yは逆である必要があります。
逆でしたか、ありがとうございます!


まだ Aや()が無い状態でまず

1,1 1,2 1,3

と簡単な表示から作りたいのですが、そこから詰まってしまっています。

引用返信 編集キー/
■72122 / inTopicNo.6)  Re[3]: 二次元配列(x,y)
□投稿者/ 魔界の仮面弁士 (8回)-(2014/05/19(Mon) 17:47:46)
No72119 (あり得んロッペン さん) に返信
>>xが横でyが縦方向なら少なくともfor文のx,yは逆である必要があります。
> 逆でしたか、ありがとうございます!

配列をどのように管理するかは自由なので、
「data(行, 列)」と管理しようと
「data(x, y)」と管理しようと構いません。

ただ、「Console.Write」を使って行ごとに出力するとなると、
 1  2  3  4
 5  6  7  8
のような順で出力していくことになるわけですから、元の配列がどうであれ、
外側のループは縦軸(行方向、Y方向)として、
内側のループは横軸(列方向、X方向)とした方が、
データの出力については都合が良いわけです。



> まだ Aや()が無い状態でまず
文面をそのまま解釈すると、こういうコードになりそうですが…。

Module Module1

    Sub Main()
        Const XMax As Integer = 5
        Const YMax As Integer = 3

        For Y As Integer = 1 To YMax
            For X As Integer = 1 To XMax
                Dim sX As String = StrConv(CStr(X), VbStrConv.Wide)
                Dim sY As String = StrConv(CStr(Y), VbStrConv.Wide)
                Console.Write("A({1},{0})", sX, sY)
            Next
            Console.WriteLine()
        Next

        MsgBox("出力完了", MsgBoxStyle.SystemModal)
    End Sub

End Module

引用返信 編集キー/
■72123 / inTopicNo.7)  Re[3]: 二次元配列(x,y)
□投稿者/ 魔界の仮面弁士 (9回)-(2014/05/19(Mon) 18:03:41)
2014/05/19(Mon) 18:04:17 編集(投稿者)

No72118 (あり得んロッペン さん) に返信
>>Point型なり、あるいは整数のペアを扱える自作の構造体なりを使って、それの配列を作ることになります。
> Point型ですか、調べてみます。

X・Y 座標を扱うための型です。2 つの Integer 値を管理できます。

名前空間も含めた名前は「System.Drawing.Point 構造体」と言いますが、
この型は、System.Drawing.DLL を参照設定していないと使えないのでご注意下さい。
Windows Forms アプリケーションであれば、最初から参照されていますが、
コンソール アプリケーションの場合は、上記 DLL への参照を加える必要があります。


> >>Dim data(7, 20) As Integer
>>これだとxは0〜7までの8個、yは0〜20までの21個になりますが大丈夫ですか?
> 失礼しました。
> 1〜7 1〜20 でした。

VB.NET では、1 から始まる配列を扱えません。(C# や VBA では扱えるのですが)


配列の要素は常に 0 始まりとなりますので、

 (1) 配列は data(0 To 7, 0 To 20) の範囲で作成するが、
  インデックスが 0 番のデータは使わない。

 (2) 配列を data(0 To 6, 0 To 19) の範囲で作成し、
  インデックスを 1 つずらした値として管理する。

のいずれかで対応してみて下さい。
引用返信 編集キー/
■72127 / inTopicNo.8)  Re[4]: 二次元配列(x,y)
□投稿者/ あり得んロッペン (4回)-(2014/05/20(Tue) 10:04:27)
No72123 (魔界の仮面弁士 さん) に返信


> VB.NET では、1 から始まる配列を扱えません。(C# や VBA では扱えるのですが)
そうなのですか、インデックスに+1して1から表示も駄目なのでしょうか。
 C#とごっちゃになってました。


提示頂きましたコードありがとうございます。
参考にさせて頂きます。

もう一つ質問なのですが、
こちらをWindows Form アプリで表示する場合は

("A({1},{0})", sX, sY)

こちらを変数に代入してTextBoxに表示させるという感じでしょうか。
ボタン押したら表示するように只今模索中です。

たまたま参考にして作ったコードの表示形式がコンソールだったもので。
引用返信 編集キー/
■72129 / inTopicNo.9)  Re[5]: 二次元配列(x,y)
□投稿者/ あり得んロッペン (5回)-(2014/05/20(Tue) 15:45:31)

> ■No72123 (魔界の仮面弁士 さん) に返信
>
>
>>VB.NET では、1 から始まる配列を扱えません。(C# や VBA では扱えるのですが)
> そうなのですか、インデックスに+1して1から表示も駄目なのでしょうか。
>  C#とごっちゃになってました。
>
>
> 提示頂きましたコードありがとうございます。
> 参考にさせて頂きます。
>
> もう一つ質問なのですが、
> こちらをWindows Form アプリで表示する場合は
>
> ("A({1},{0})", sX, sY)
>
> こちらを変数に代入してTextBoxに表示させるという感じでしょうか。
> ボタン押したら表示するように只今模索中です。
>
> たまたま参考にして作ったコードの表示形式がコンソールだったもので。
解決済み
引用返信 編集キー/
■72130 / inTopicNo.10)  Re[5]: 二次元配列(x,y)
□投稿者/ 魔界の仮面弁士 (10回)-(2014/05/20(Tue) 16:32:11)
No72127 (あり得んロッペン さん) に返信
> そうなのですか、インデックスに+1して1から表示も駄目なのでしょうか。
それが、先述の (2) 案になりますね。


>>VB.NET では、1 から始まる配列を扱えません。
>  C#とごっちゃになってました。

VB の配列と C# の配列とでは、
 VB は「Dim a(3) As Integer」 で、a(0)から『a(3)まで』の 4 個 の要素が用意される。
 C# は「int[] a = new int[3];」で、a[0]から a[2]まで の『3 個』の要素が用意される。
という点を混同しやすいかもしれませんね。


ちなみに、「1 から始まる配列」というのは、Excel の Range.Value が返す
COM の SAFEARRAY であるとか、.NET の Array.CreateInsance などを通じて
生成された特殊なケースに限られます。
(C# であれ VB.NET であれ、配列は原則として 0 から始まります)



>> (C# や VBA では扱えるのですが)
済みません! どうやら逆に覚えていたみたいです。

0 ベースではない配列というのは、VB.NET であれば扱えるけれど、
C# だと(一次元配列で無い限り)扱えない、ということのようで。
http://gushwell.ldblog.jp/archives/51422659.html


【C#】
// a[1〜3] な一次元配列を作成
dynamic a = Array.CreateInstance(typeof(int), new int[] { 3 }, new int[] { 1 });

// いずれもエラー:『型 'System.Int32[*]' のオブジェクトを型 'System.Int32[]' にキャストできません。』
// a[1] = 1;
// a[3] = 1;
// a[0] = 1;

// コードから実行すると False を返すが
// イミディエイト ウィンドウから実行すると True となる
Console.WriteLine(a is int[]);



【VB.NET】
' a(1〜3) な一次元配列を作成
Dim a As Object = Array.CreateInstance(GetType(Integer), New Integer() {3}, New Integer() {1})

a(1) = 1 'これは OK
a(3) = 1 ' これは OK
'a(0) = 1 ' 範囲外なので実行時例外

'コードから実行すると False を返すが
'イミディエイト ウィンドウから実行すると True となる
Console.WriteLine(TypeOf a Is Integer())



> こちらをWindows Form アプリで表示する場合は
二次元データの表現なら、DataGridView の方が適しているかも知れません。
(もしも DataGridView で表示させるのであれば、二次元配列よりも、DataTable で管理したほうが便利です)



> ボタン押したら表示するように只今模索中です。
元の コンソール版のコードに近い実装にするのなら、たとえばこんな感じでしょうか。


Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
 'TextBox は、予め MultiLine = True に設定しておく

 Const XMax As Integer = 5
 Const YMax As Integer = 3

 TextBox1.Clear()
 For Y As Integer = 1 To YMax
  For X As Integer = 1 To XMax
   Dim sX As String = StrConv(CStr(X), VbStrConv.Wide)
   Dim sY As String = StrConv(CStr(Y), VbStrConv.Wide)
   TextBox1.AppendText(String.Format("A({1},{0})", sX, sY))
  Next
  TextBox1.AppendText(ControlChars.NewLine)
 Next

 MsgBox("出力完了", MsgBoxStyle.SystemModal)
End Sub
引用返信 編集キー/
■72132 / inTopicNo.11)  Re[6]: 二次元配列(x,y)
□投稿者/ あり得んロッペン (6回)-(2014/05/20(Tue) 17:10:35)
No72130 (魔界の仮面弁士 さん) に返信


ご丁寧に補足頂きありがとうございます。

>>こちらをWindows Form アプリで表示する場合は
> 二次元データの表現なら、DataGridView の方が適しているかも知れません。
> (もしも DataGridView で表示させるのであれば、二次元配列よりも、DataTable で管理したほうが便利です)

そうですね、DataGridViewは頭によぎりました。
指示では2次元配列でとのことなもので。


>TextBox1.AppendText
こちらでしたか!
どうも上書きされてしまって一番最後の A(3,5) しか表示されなかったので、
奮闘しておりました。
追加での出力ですね、助かりました。


すいません!
度々質問になってしまうのですが、
例えば個々の項目 A(1,1)A(1,2)等をテキストボックスごとに分けての
表示をするには、テキストボックスにループで順番に入れていく事は可能でしょうか。

textbox1に、A(1,1)
textbox2に、A(1,2)

上記のような形で、textboxを設置しています。


調べつつテキストボックスのループらしき物を組み込みましたが、
ロジックがよく分からないです。

こちらもFor Nextの入れ子で回せるのでしょうか。



Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


        Const XMax As Integer = 5
        Const YMax As Integer = 3

        For Y As Integer = 1 To YMax
            For X As Integer = 1 To XMax
                Dim sX As String = StrConv(CStr(X), VbStrConv.Wide)
                Dim sY As String = StrConv(CStr(Y), VbStrConv.Wide)


                Dim str As String = String.Format("A({1},{0})", sX, sY)

                For i As Integer = 1 To 5

                    Controls("TextBox" & i).Text = i
                Next

                TextBox1.Text = str.ToString

            Next
        Next


    End Sub
End Class

引用返信 編集キー/
■72136 / inTopicNo.12)  Re[7]: 二次元配列(x,y)
□投稿者/ 魔界の仮面弁士 (11回)-(2014/05/20(Tue) 19:26:52)
No72132 (あり得んロッペン さん) に返信
> そうですね、DataGridViewは頭によぎりました。
> 指示では2次元配列でとのことなもので。

二次元配列でも良いのでは?

管理上、DataTable の方が相性が良いというだけであって、
二次元配列の内容を DataGridView に表示させてはいけないルールも無いですし。


Public Class Form1
 Private ColumnCount As Integer = 7
 Private RowCount As Integer = 20

 Private matrix1(ColumnCount - 1, RowCount - 1) As Integer
 Private matrix2(ColumnCount - 1, RowCount - 1) As String

 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  For x As Integer = 0 To ColumnCount - 1
   Dim sX As String = StrConv(CStr(x), VbStrConv.Wide)
   For y As Integer = 0 To RowCount - 1
    Dim sY As String = StrConv(CStr(y), VbStrConv.Wide)
    matrix1(x, y) = x * 100 + y
    matrix2(x, y) = String.Format("A({1},{0})", sX, sY)
   Next
  Next

  DataGridView1.AllowUserToAddRows = False
  DataGridView1.AllowUserToResizeColumns = False
  DataGridView1.AllowUserToResizeRows = False
  DataGridView1.RowHeadersVisible = False
  DataGridView1.ColumnHeadersVisible = False
  DataGridView1.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
  DataGridView1.EditMode = DataGridViewEditMode.EditOnEnter
  DataGridView1.RowCount = RowCount
  DataGridView1.ColumnCount = ColumnCount
 End Sub

 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
  For y As Integer = 0 To RowCount - 1
   For x As Integer = 0 To ColumnCount - 1
    DataGridView1(x, y).Value = matrix1(x, y) 'Integer の二次元配列
   Next
  Next
 End Sub

 Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
  For y As Integer = 0 To RowCount - 1
   For x As Integer = 0 To ColumnCount - 1
    DataGridView1(x, y).Value = matrix2(x, y) 'String の二次元配列
   Next
  Next
 End Sub
End Class


> 表示をするには、テキストボックスにループで順番に入れていく事は可能でしょうか。
その場合は、TextBox も配列で管理するのが良いでしょう。
http://dobon.net/vb/dotnet/control/buttonarray.html

現在は Controls から、"TextBox11" などのコントロール名を指定して
処理する方法を使っておられるようですが、多数の TextBox を
デザイン画面で一つ一つ貼っていく方法だと、管理しているデータの
要素数が変更したときに対応しにくいかと思います。

(DataGridView や ListView などのように、最初から行・列で
 データを管理しているコントロールならば対応もしやすいですが)

であれば、TextBox 自体もコードから動的に生成・配置するようにし、
それを二次元配列として管理するようにすれば、取り扱いも容易になるかと。
引用返信 編集キー/
■72140 / inTopicNo.13)  Re[8]: 二次元配列(x,y)
□投稿者/ あり得んロッペン (7回)-(2014/05/21(Wed) 09:44:29)
No72136 (魔界の仮面弁士 さん) に返信



> 管理上、DataTable の方が相性が良いというだけであって、
> 二次元配列の内容を DataGridView に表示させてはいけないルールも無いですし。

勘違いしてました。表示の指定までは無かったので、
DataGridViewがとても効率的ですね。参考になります。



> 現在は Controls から、"TextBox11" などのコントロール名を指定して
> 処理する方法を使っておられるようですが、多数の TextBox を
> デザイン画面で一つ一つ貼っていく方法だと、管理しているデータの
> 要素数が変更したときに対応しにくいかと思います。

要素数の変更ありますね。情報の編集も考慮していたので。
ご提示頂いたコードの処理の理解に励みます。

何から何までお手数お掛けしましてすみませんでした。
ありがとうございました!
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -