• ベストアンサー

2次配列について Null値?

例えば、あるセル範囲(ここではA1:B3としておきます)に [ 1 ] [ 4 ] [ 2 ] [ 5 ] [ 3 ] [ ] というように数値が入力されているとします。 RefEdit1つと[実行]ボタン1つ、[キャンセル]ボタン1という簡単なユーザーフォームを作成して以下のようなコードを書きます。 ' 実行ボタンに登録したコード Private Sub CommandButton1_Click() Dim myRange As String Dim dat As Variant myRange = RefEdit1.Text dat = Range(myRange) '選択したセル範囲のデータをdatに代入 Unload UserForm1 'ユーザーフォームの終了 End Sub ' キャンセルボタンに登録したコード Private Sub CommandButton2_Click() Unload UserForm1 'ユーザーフォームの終了 End Sub それで質問なのですが、この場合、dat(3,2)には何が入っていることになっているのでしょうか。Null値なるものが代入されているのでしょうか、、、 最終的にデータ行列において、各列のデータ数を取得したいのですがどうすればよいでしょうか。1列目=3、2列目=2といったように。 もしNull値?が代入されていることになっており、2次配列においてNull値を判断する関数でもあればそれをカウントして、列数-Nullの数で取得できるだろうと考えてはいるのですが。

  • backs
  • お礼率85% (564/660)

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

RangeのValueプロパティを IsEmpty関数で判断することになります Private Sub CommandButton1_Click()   Dim r As Range, r1 As Range   Set r = Range(RefEdit1.Text)   For Each r1 In r     If IsEmpty(r1.Value) Then       MsgBox r1.Address(0, 0) & "未入力です"     End If   Next End Sub といった具合に # 字下げは全角スペースです

backs
質問者

お礼

回答ありがとうございます。 IsEmpty()で数値が入力(代入)されているかどうか判断できたのですね。これを使ってうまく各列のデータ数を取得することができました。

その他の回答 (2)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.3

(1)RefEdit1コントロールは、VBのコントロールですが、エクセルとの連携で使うことを考えられているようです。余談ですが A=Application.inputbox("範囲",type:=8)と同じ用途のようです。 (2)そこで、エクセルに話題を移すと、 >2次配列について Null値?は、質問者の独断ではないですか。表のイメージ的には、エクセルのセル範囲や表は配列とイメージできますが、VBやエクセルVBAの配列と言ってよいのでしょうか。もちろんCells(行、列)の指定などしょっちゅう使っておりますが。 (3)RefEdit1で範囲指定したとき、その影として配列d(x、y)が背後で作られている確証はお持ちですか。 多分作られてない (4)従って、質問は、エクセルのセルそのものの、空白セルの判別法の話題として聞けばよいことになります。 実行時にRefEdit1で範囲指定ーー>VBのRefEdit1の機能で配列に セルのデータが移る。その際、セルの値と違う移り方をする、 なら本質問は成り立ちます。 しかしそうではない=別に配列を作らないと思う。 (5)結局実行時にRefEdit1で範囲指定でVBから返してもらえる データは、範囲を表す、文字列だけ、ではないですか。 エクセルVBAの、.Addressで返る文字列ではないですか。 (6)既存回答も(5)のとおり、その範囲文字列を、エクセルVBAで使って処理して、そのエクセルのセルの値を問題にし、エクセルでいう、空白セルはどうして判別できるかの答えとなっていると思う。 (7)ただし結局、実行時にRefEdit1で範囲指定でVBから返してもら得るデータは範囲の文字列を使うには、エクセルの世界では、 Range(範囲文字列)で捉えられるが、今はエクセル世界ではないので、橋渡しがどうかとなると、同じくRange(範囲文字列) で使えるようです。 そして、ForEeachが使えて、メンバーのセルを捉えられる (8)そして、空白はIsEmptyで捉えられる。 (9)エクセルの世界でも Sub test08() If IsEmpty(Cells(10, "B")) Then MsgBox "空白" & Cells(10, "B").Address Else MsgBox "空白でない" & Cells(10, "B").Address End If はできる。 ーー Sub test09() If Cells(10, "B") = "" Then MsgBox "空白" & Cells(10, "B").Address Else MsgBox "空白でない" & Cells(10, "B").Address End If End Sub でもできる。 (10)VBの世界で test09()ができるか。 Private Sub CommandButton1_Click() MsgBox RefEdit1.Value Dim rng As Range, r As Range Set rng = Range(RefEdit1.Value) For Each r In rng If r.Value = "" Then MsgBox r.Address & "空白です" Else MsgBox r.Address & "空白でないです" End If Next End Sub が可能と思うが。 ーー (10)Nullという言葉は他言語やアクセスでは使うようですが エクセルVBAではIsNull関数があり、シートのワークシート関数ではNullという言葉は出てきません。 NullとEmpty http://www.moug.net/tech/acvba/0050010.htm

backs
質問者

お礼

回答ありがとうございます。 随分と丁寧に説明してくださってありがとうございます。コンピュータ内部のことは複雑なので、本来的には理解しておかなければならんのでしょうが、、、私にはけっこう難しいないようです(^_^;)

  • tom11
  • ベストアンサー率53% (134/251)
回答No.2

こんにちは、 以下のコードを実行すると ************************************************* Private Sub CommandButton1_Click() Dim c As Variant Dim x As Integer Dim y As Integer c = Range(RefEdit1.Value) Debug.Print RefEdit1.Value For x = LBound(c, 1) To UBound(c, 1) For y = LBound(c, 2) To UBound(c, 2) Debug.Print x, y, c(x, y), IsNull(c(x, y)), IsEmpty(c(x, y)) Next Next End Sub ****************************************************** 実行結果 Sheet1!$A$1:$B$3 1 1 1 False False 1 2 4 False False 2 1 2 False False 2 2 5 False False 3 1 3 False False 3 2 False True ******************************************************* 配列の空白部分は、nullでは、表現できないようです。 emptyで、表現できるようです。 あとlbound,uboundを利用すれば、 行の数と、列の数は、計算できますね。

backs
質問者

お礼

回答ありがとうございます。 具体的なプログラムを提示してくださってありがとうございます。 話は別になりますが、Debug.Printとするとイミディエイトウィンドウに出力できたのですね。私は今まで知りませんで、途中の計算結果はMsgBoxでイチイチ表示しておりましたからとても参考になりました。

関連するQ&A

  • 複数のユーザーフォームをコマンドボタンにて表示・非表示させるには

    VBA勉強中のものです。 複数のユーザーフォームをコマンドボタンを使用して画面への表示切替を考えております。 例)ユーザーフォーム1,ユーザーフォーム2,ユーザーフォーム3のそれぞれにコマンドボタン1,コマンドボタン2,コマンドボタン3を作成し、   コマンドボタン1→ユーザーフォーム1を表示   コマンドボタン2→ユーザーフォーム2を表示   コマンドボタン3→ユーザーフォーム3を表示 とするようなことを考えおります。  そこで、下記のようにコードを作成したのでですが,一度表示させたユーザーフォームを再度表示させようとコマンドボタンをクリックしたら、「フォームはすでに表示させているのでモーダル表示はできません」とエラーがでてしまいます。   どなたか、どのようにしたらいいかご教授ねがいます。 サンプルコード) --------------------------------------------------- 'UserForm1のコード Private Sub CommandButton2_Click() Call UserForm2_show UserForm1.Hide End Sub Private Sub CommandButton3_Click() Call UserForm3_show UserForm1.Hide End Sub ---------------------------------------------------- 'UserForm2のコード Private Sub CommandButton1_Click() Call UserForm1_show UserForm2.Hide End Sub Private Sub CommandButton3_Click() Call UserForm3_show UserForm2.Hide End Sub ------------------------------------------------------- 'UserForm3のコード Private Sub CommandButton1_Click() Call UserForm1_show UserForm3.Hide End Sub Private Sub CommandButton2_Click() Call UserForm2_show UserForm3.Hide End Sub ------------------------------------------------------------ '標準モジュール コード Sub UserForm1_show() UserForm1.Show End Sub Sub UserForm2_show() UserForm2.Show End Sub Sub UserForm3_show() UserForm3.Show End Sub

  • ユーザーフォームの切り替えについて・・・

    UserForm1とUserForm2の2つのユーザーフォームがあります。 UserForm1の中にあるcommandButton1をクリックすると、UserForm2が表示される仕組みになっています。 (ちなみに、UserForm2にもコマンドボタンがあり、クリックするとUserForm1に戻るようになっています) UserForm1の方に、 Private Sub CommandButton1_Click() UserForm2.Show 0 Unload UserForm1 End Sub UserForm2の方に、 Private Sub CommandButton1_Click() UserForm1.Show 0 Unload UserForm2 End Sub と記述してあります。 ところが、それぞれのユーザーフォームには、閉じると同時にブックが閉じるように Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) ActiveWorkbook.Save 'ブックを保存 ActiveWorkbook.Close 'ブックを閉じる Application.Quit 'excelを終了 End If End Sub というコードを記述しているため、UserForm1からUserForm2へ移るときにブックが閉じてしまいます。 右上の「×」を押したときだけブックを閉じるようにしたいのですが、どういうコードを書いたらいいのですか? 宜しくお願いします。(*´Д`人)

  • ユーザーフォームに入力したデーターが転記できない

    いつもお世話になります。 Windows7 excell2010 です。 いろんなものに勉強してここまでに作成したユーザーフォームですが、データーは入力できるのですがコマンドボタンをクリックしても各セルに反映されません。 色々と試行錯誤していますがうまくゆきません。 どこに不具合があるかわからず恐れ入りますがどなたかご指導いただけませんか。 参考にコードは参考に下記にします。 ユーザフォームのVBAは下記です コード ※Module1 Sub 売上() Do UserForm1.Show Loop End Sub Sub 入金() Do UserForm2.Show Loop End Sub ※UserForm1 Private Sub UserForm_Initialize() With ComboBox1 .AddItem "1" .AddItem "2" .AddItem "3" End With End Sub Private Sub CommandButton1_Click() n = Cells(Rows.Count, 1).End(xlUp).Row + 1 Cells(n, 2) = UserForm1.TextBox1.Text Cells(n, 3) = UserForm1.TextBox2.Text Cells(n, 4) = UserForm1.TextBox3.Text Cells(n, 11) = UserForm1.ComboBox1.Text Unload Me End Sub Private Sub CommandButton2_Click() Unload Me End End Sub ※UserForm2 Private Sub CommandButton1_Click() n = Cells(Rows.Count, 1).End(xlUp).Row + 1 Cells(n, 2) = UserForm2.TextBox1.Text Cells(n, 3) = UserForm2.TextBox2.Text Cells(n, 4) = UserForm2.TextBox3.Text Unload Me End Sub Private Sub CommandButton2_Click() Unload Me End End Sub

  • マクロ ユーザーフォームが表示されない

    いつも回答して頂き、ありがとうございます。 Sub UserForm1() UserForm1.Show End Sub と記述しましたが、エラーが発生し、ユーザーフォームが表示してくれません。 コンパイルエラー:Functionまたは変数が必要です フォームはコマンドボタンを一つ配置し、 Private Sub CommandButton1_Click() Unload UserForm1 End Sub と記述してあるだけです。何が悪いのでしょうか?御教授の程宜しくお願い致します。

  • EXCEL VBAのユーザーフォームに引数を渡す方法について

    すいません、EXCEL VBAのユーザーフォームに引数を渡す方法についてご質問があります。 シート上にコマンドボタンを2つ用意する。 コマンドボタン1を押すと変数mは1 コマンドボタン2を押すと変数mは2 としてユーザーフォームを呼び出す。 Public m As Integer Private Sub CommandButton1_Click()  m = 1  Call フォーム呼び出し(m) End Sub Private Sub CommandButton2_Click()  m = 2  Call フォーム呼び出し(m) End Sub Sub フォーム呼び出し(m As Integer)  UserForm1.Show End Sub 次にユーザフォームにコマンドボタンを1個置き、 ボタンを押したとき、mが1であれば「ボタン1」 mが2であれば「ボタン2」 とメッセージボックスを出し、ユーザーフォームを閉じる。 Private Sub CommandButton1_Click()   If m = 1 Then    MsgBox "ボタン2"   ElseIf m = 2 Then    MsgBox "ボタン2"   End If  Unload UserForm1 End Sub プロシージャ間の引数渡しは色々なテキストに載っているのですが ユーザーフォームに引数を渡す方法はどうも見つからず、 Private Sub CommandButton1_Click(m) としても、コンパイルエラーとなってしまいます。 よろしくご教示をお願いいたします。

  • リストボックスから項目を選択してセルに入力したいのです

    EXcel2003でマクロ作成中です。エクセルシートのN列を右クリックすると、ユーザーォームが現れ、その中のリストボックスから項目を選択すると選択文字が白色に反転します。 ユーザーホームの下方に設置した「入力する」ボタンをクリックする、アクティブセルにテキスト文字列が挿入されます。 Option Explicit Private Sub CommandButton1_Click() With ListBox1 If .ListIndex = -1 Then MsgBox "項目を選択してくだい" Else ActiveCell.Value = ListBox1.list(ListBox1.ListIndex) End If End With Unload UserForm1 End Sub --------------------------- Private Sub CommandButton2_Click() Unload UserForm1 End Sub ------------------------------ これと同じものをB列につくりました。エクセルシートのB列を右クリックすると、リストボックスが表示されますが、その中の項目を選択しようとすると、一瞬にしてユーザーフォーム自体が消えてしまい項目を 選択できません。 Private Sub CommandButton1_Click() With ListBox2 If .ListIndex = -1 Then MsgBox "項目を選択してくだい" Else ActiveCell.Value = ListBox2.list(ListBox2.ListIndex) End If End With Unload UserForm2 End Sub ----------------------------- Private Sub CommandButton2_Click() Unload UserForm2 End Sub ------------------------------------------ まったく同じものを作って内容だけかえたのですが、できません。 どうしてでしょうか?ご教授おねがいします。

  • VBA スタック容量が足りない・・・

    こんばんわ! エクセルのVBAを使った管理システムを作ろうと思うのですが、色々考えて下記のような状態にしてみたのですが、ユーザーフォームをモードレスにするとスタック容量が足りなくなります。 Sub aaa_date() If Range("a1") = 1 Then bbb_date.Show ElseIf Range("a1") = 2 Then ccc_date.Show ElseIf Range("a1") = 3 Then ddd_date.Show End If Call aaa_date End Sub bbb_date(ユーザーフォーム)に↓ Private Sub CommandButton1_Click() Range("a1") = 2 Unload Me End Sub Private Sub CommandButton2_Click() Range("a1") = 3 Unload Me End Sub ccc_date(ユーザーフォーム)に↓ Private Sub CommandButton1_Click() Range("a1") = 1 Unload Me End Sub Private Sub CommandButton2_Click() Range("a1") = 3 Unload Me End Sub ddd_date(ユーザーフォーム)に↓ Private Sub CommandButton1_Click() Range("a1") = 1 Unload Me End Sub Private Sub CommandButton2_Click() Range("a1") = 2 Unload Me End Sub ※bbb_dateとccc_dateとddd_dateはそれぞれにあるボタンを押すとA7セルの値を変更するようにして、aaa_dateでどのフォームを表示するのかを選択しています。 ※実際にはもっと沢山ユーザーフォームがあります。 上記の状態では動作するのですが、エクセルの表に値を入力したいので、bbb_dateとccc_datとddd_datをvbModeless(モードレス状態)にすると、スタック容量が足りませんと出ます。 別のやり方でもよいですので、ユーザーフォームを切り替える良い方法があったらお願いします。

  • Excel電子印鑑をユーザーフォームのみで扱いたい

    EXCELのアドイン“Excel電子印鑑ver2.0”をユーザーフォームからのみで扱いたいのですが、 うまくいきません。 ユーザーフォーム1のコマンドボタンを押す          ↓      電子印鑑を押印          ↓ ユーザーフォーム1にもどる(再表示) という流れにしたいのですが、sendkeys部分をカットしたような処理となります。 Sendkeyはアクティブウインドウでないといけないということで 押印する前にユーザーフォームを閉じております。 そして押印した後、またユーザーフォームに戻りたいのですが、うまくいきません。 下記のコードでuserform1.showを消すとうまく押印まで処理はできています。 よろしくお願いします。 Private Sub CommandButton1_Click() Unload Me SendKeys "{F10}ED"  UserForm1.Show End Sub

  • 2つのユーザーフォームの表示切替(Excel2002VBA)

    Excel2002VBAを使用しています。 UserForm1 に CommandButton1 を配置したものと UserForm2 に CommandButton2 を配置したもの があります。 UserForm1が表示されている時、CommandButton1 を クリックすると、UserForm2 が表示され UserForm1 が非表示になり、 UserForm2 が表示されている時  CommandButton2 をクリックすると UserForm1 が 表示され UserForm2 が非表示になる というように 画面上にどちらか一方だけユーザーフォームを表示 させたいのですが上手くいきません。 CommandButton1 の Clickイベントに UserForm2.show vbmodeless Unload UserForm1 CommandButton2 の Clickイベントに UserForm1.show vbmodeless Unload UserForm2 と記述したのですが、実行すると、 ”このオブジェクトは、ロードまたはアンロード することはできません。”とエラー表示が出てき ます。 何とぞご教授よろしくお願いいたします。

  • Excel VBAで別のブックからユーザーフォームの閉じる

    Excel VBAで別のブックからユーザーフォームの閉じたいのですが うまくいきません。 教えてください。 Private Sub CommandButton2_Click() Application.Visible = False Unload Workbook.("材料リスクマップ検索Ver2.xls")UserForm3・・・・※ Workbooks.Close userform3:=ThisWorkbook.Path & "あああ.xls" Workbooks("\いいい.xls").Close savechanges:=False UserForm1.Show vbModeless End Sub ※印のところが赤字にかわります。 コマンドボタン2は、いいい.xlsにあり、フォームを閉じたいのはあああ.xlsのUserform3です。 その後、ファイル名いいい.xlsは閉じます。 コードが間違っているかと思いますが、どんな風にすればよいかわかりません。初歩的なこととは思いますがよろしくお願い致します。

専門家に質問してみよう