プロが教えるわが家の防犯対策術!

今はsubプロ-シージャーって言うのかもしれませんが

呼び出し側
Dim ibox(5) As Integer
Dim numz As Integer
処理
'subプロ-シージャー
calc(ibox(1), ibox(2), ibox(3), ibox(4))

呼ばれる側
Private Sub calc(ibox(1), ibox(2), ibox(3), ibox(4))
End Sub
ができません。
「BC30311 型 'Integer' の値を 'Object()' に変換できません」



呼び出し側
calc1(numz)
呼ばれる側
Private Sub calc(numz)
End Sub
としても
「BC42104 変数 'numz' は、値が割り当てられる前に使用されています。Null 参照の例外が実行時に発生する可能性があります。」

とか怒られます。本とかみてもこんな感じで書いてあるみたいです。
どなたかこの無能な私にアドバイスをお願いします。

というかそんなに何度も怒られることしてないような気がする!!!

質問者からの補足コメント

  • No2さん。すみません。classの外に書いてました。
    とりあえずコピペのほうは動きました。

      補足日時:2018/11/20 18:19

A 回答 (4件)

> 今はsubプロ-シージャーって言うのかもしれませんが



こういう言い方をしている、ということは、過去のBasicとかを使っていたということでしょうか。
もしそうなら、その知識は全部忘れるくらいの気持ちでいた方がいいでしょう。

> というかそんなに何度も怒られることしてないような気がする!!!

「プログラムは思った通りに動かない。書いた通りに動く」
昔から伝わる格言です。
プログラマがどう思おうと、コンピュータが間違いと言えば間違いなのです。
コンピュータに合わせるしかありません。


旧来のBasicでは、 GOSUBの呼び出し元と呼び出し先とで同じ変数を使っていました。

Visual Basicでは、プロシージャの呼び出し元と呼び出し先とでは基本別な変数を使います。
名前が同じでも、同じ変数を指すとは限りません。
このあたりの考え方(ローカル変数)は本にもちゃんと書いてあるはずです。


> Private Sub calc(ibox(1), ibox(2), ibox(3), ibox(4))

この宣言側での引数は、「どんな引数をなんという名前で受け取るか」であって、呼び出し側の 「calc(ibox(1), ibox(2), ibox(3), ibox(4))」と同じ表記になるとは限りません。

引数は「新しいローカル変数を用意する」ようなものです。
Private Sub foo(a)
End Sub
というのは
Private Sub foo(a as Object)
End Sub
であり、
Private Sub foo()
Dim a as Object =呼び出したときに指定された値
End Sub
と同等になります。

そうして見ると
Private Sub calc(ibox(1), ibox(2), ibox(3), ibox(4))

第一引数: 名前:ibox 型: Object型の添字が1まで使える配列
 Dim ibox(1) as Object に相当
と宣言しているのに
calc(ibox(1), ibox(2), ibox(3), ibox(4)

ibox(1): 配列 iboxの添字(1)の要素 型:Integer
を第一引数に指定しているので、
「指定されたIntegerから、プロシージャが要求しているObject配列への変換なんかできない」
とエラーになっています。


また、iboxという名前の引数を複数使って宣言していることでもエラーになっているはずです。
 Dim ibox(1) as Object
 Dim ibox(2) as Object
 Dim ibox(3) as Object
 Dim ibox(4) as Object
としているのと同じだからです。

解決策は既に出ているように
・それぞれ別の名前の単独の値を受けとる引数にする
・配列をまとめて受けとるようにする
です。



> 呼び出し側
> Dim numz As Integer
 ※
> calc1(numz)
> 呼ばれる側
> Private Sub calc(numz)
 ※ ↑sub名はcalcであってますか?
  calc1と一致していませんが?
> End Sub

 ※ の部分に、 numz=0 等と値を代入するような命令はありますか?
if文等の分岐がある場合は、全ての分岐で何か代入するようになっていますか?

無い場合は、 numzに値を入れないまま、calc1(numz)で「入っている値」を使うことになります。
「BC42104 変数 'numz' は、値が割り当てられる前に使用されています。Null 参照の例外が実行時に発生する可能性があります。」
というのは、そのことを警告しています。
プロシージャの引数に指定する、ということは、その値を使って計算したい、という意味になります。
肝心の値を決めないままでいいのか?という警告です。
警告なので「それで問題無い」と断言できるのなら無視してかまいません。


従来のGOSUBのように、 calc1の中で
numz =計算結果
みたいにして、それを呼び出し元で使おうとしてませんか?
先に書いたように、 呼び出し元のnumzと呼び出し先のプロシージャのnumzとは名前は同じでも別の存在なので、このままでは期待通りには動きません。
計算内容にもよりますが、 Functionを使ってはどうでしょうか?
    • good
    • 1
この回答へのお礼

実はVB5で昔自分で作ったプログラムVB.net2015を移植しております。
.netもいつかどこかでほんのちょっと触ったような。

ご回答でまとめていただいたのと、
ほかの皆様のものを参考に
呼び出し側 calc(ibox)

   呼ばれる側
Private Sub calc(ByVal ibox() As Integer) ←この書き方が分からなかった。

で今く動ているようです。
Functionプロシージャ-は今回戻り値が必要ないのと、
あと3日ぐらいしないと頭がついていかない?のでひとまず見送ります。

oject型も知りませんでした。

大変参考になりました。ありがとうございます。

お礼日時:2018/11/22 13:36

No.2です。



Public Class Form1 '★

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim ibox(5) As Integer

ibox(1) = 1
ibox(2) = 20
ibox(3) = 300
ibox(4) = 44

calc(ibox)
End Sub

Private Sub calc(ByVal ibox)

For i As Integer = 1 To 4
MsgBox(ibox(i))
Next

End Sub

End Class '★

FoamのClassの中に書いてもダメでしょうか?(うちのは確かに古いバージョンではありますが・・・・)
    • good
    • 0
この回答へのお礼

ごめんなさい。投稿したあとに気が付いて、補足のほうに入れたのですが、
お手間とらせました。

私が悪うございました。

プログラム本体でも動きましたよ。

お礼日時:2018/11/20 18:34

呼び出す側。



Dim ibox(5) As Integer

ibox(1) = 1
ibox(2) = 20
ibox(3) = 300
ibox(4) = 44

calc(ibox)

呼び出される側。

Private Sub calc(ByVal ibox)

For i As Integer = 1 To 4
MsgBox(ibox(i))
Next

End Sub

Index0を呼び出される側で使用しなければ、配列の値をそのまま配列として渡してしまうなんてのも。
    • good
    • 0
この回答へのお礼

たびたび回答ありがとうございます。
しかし、上記ですと
2015だとエラーになってしまいます。

私の作り方が悪いのかと思い、新しいプロジェクトをつくってまんま貼り付けてもできません。
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim ibox(5) As Integer

ibox(1) = 1
ibox(2) = 20
ibox(3) = 300
ibox(4) = 44

calc(ibox)
End Sub
End Class
Private Sub calc(ByVal ibox)

For i As Integer = 1 To 4
MsgBox(ibox(i))
Next

End Sub
全文

エラー BC30451 'calc' は宣言されていません。アクセスできない保護レベルになっています。 WindowsApplication8 c:\users\haruka2\documents\visual studio 2015\Projects\WindowsApplication8\WindowsApplication8\Form1.vb 10 アクティブ

エラー BC30001 名前空間では有効でないステートメントです。 WindowsApplication8 c:\users\haruka2\documents\visual studio 2015\Projects\WindowsApplication8\WindowsApplication8\Form1.vb 13 アクティブ

.netが嫌いになってきました。pythonだと簡単ですかねぇ。

お礼日時:2018/11/20 18:16

呼ばれる側


Private Sub calc(ibox(1), ibox(2), ibox(3), ibox(4))

呼ばれる側
Private Sub calc(ibox1 as Integer, ibox2 as Integer, ibox3 as Integer, ibox4 as Integer)
に変えてください

後段も同様です、型宣言して使ってください
    • good
    • 0
この回答へのお礼

できました。ありがとうございます。
しかしibox(1) がなんで ibox1 になるんでしょうか?

お礼日時:2018/11/20 17:54

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!