今は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 参照の例外が実行時に発生する可能性があります。」
とか怒られます。本とかみてもこんな感じで書いてあるみたいです。
どなたかこの無能な私にアドバイスをお願いします。
というかそんなに何度も怒られることしてないような気がする!!!
No.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を使ってはどうでしょうか?
実はVB5で昔自分で作ったプログラムVB.net2015を移植しております。
.netもいつかどこかでほんのちょっと触ったような。
ご回答でまとめていただいたのと、
ほかの皆様のものを参考に
呼び出し側 calc(ibox)
呼ばれる側
Private Sub calc(ByVal ibox() As Integer) ←この書き方が分からなかった。
で今く動ているようです。
Functionプロシージャ-は今回戻り値が必要ないのと、
あと3日ぐらいしないと頭がついていかない?のでひとまず見送ります。
oject型も知りませんでした。
大変参考になりました。ありがとうございます。
No.3
- 回答日時:
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の中に書いてもダメでしょうか?(うちのは確かに古いバージョンではありますが・・・・)
ごめんなさい。投稿したあとに気が付いて、補足のほうに入れたのですが、
お手間とらせました。
私が悪うございました。
プログラム本体でも動きましたよ。
No.2
- 回答日時:
呼び出す側。
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を呼び出される側で使用しなければ、配列の値をそのまま配列として渡してしまうなんてのも。
たびたび回答ありがとうございます。
しかし、上記ですと
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だと簡単ですかねぇ。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBA Userformで一部別シートに転記がしたいのですが 2 2023/05/24 13:08
- Visual Basic(VBA) ①ExcelVBAでカレンダーを作り、別のユザーフォームで日付を入力したいのですがエラーになります。 1 2023/02/17 18:39
- Excel(エクセル) エクセルVBAでオブジェクトが必要です 2 2022/09/10 16:37
- Visual Basic(VBA) 【Excel VBA】自動メール送信の機能追加 5 2022/09/29 12:53
- Visual Basic(VBA) 【変更】ファイルを閉じてダイアログで保存した時、更新したシートだけの処理の実行をする 5 2022/03/26 18:31
- Visual Basic(VBA) VBAプログラミング 2 2022/11/27 12:07
- Visual Basic(VBA) 標準モジュール Public mOnTime As Date Sub sample() '実行プロシ 1 2023/02/22 15:44
- Visual Basic(VBA) 【追加】ファイルを閉じてダイアログで保存した時だけ処理の実行をする 3 2022/03/23 15:43
- Visual Basic(VBA) EXCEL VBAにて動的にCheckBOXを複数作成し、同BOXにイベントを追加したい 1 2023/03/16 07:05
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る EXEの実行内容の結果によって、戻り値を0か1かで返したい 1 2023/07/04 16:40
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
配列数式の解除
-
VBのFunctionで、配列を引数...
-
VBA 1次元配列を2次元に追加する
-
ListViewで、非表示列って作れ...
-
配列変数の添字が範囲外ですと...
-
for each の現在の配列ポインタ...
-
2次元動的配列の第一引数のみを...
-
2つ以上の変数を比較して最大数...
-
fortranのwrite文について
-
VBAで近似曲線の係数取得
-
subの配列引数をoptionalで使う...
-
VLOOKUP関数で、一番下...
-
【VBA】配列とWorksheetFunctio...
-
Dim は何の略ですか?
-
delphiで配列を、コピーするには。
-
Access 2007 複数のテキストボ...
-
エクセルで最小値から0を除く方法
-
VB6 配列を初期化したい
-
Excel-VBAの配列「Public Const...
-
VBのコントロール配列を二次元...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
配列数式の解除
-
2つ以上の変数を比較して最大数...
-
VBA 1次元配列を2次元に追加する
-
特定のセル範囲で4文字以上入力...
-
for each の現在の配列ポインタ...
-
VBのFunctionで、配列を引数...
-
subの配列引数をoptionalで使う...
-
VB6 配列を初期化したい
-
ListViewで、非表示列って作れ...
-
配列変数の添字が範囲外ですと...
-
Excel-VBAの配列「Public Const...
-
2次元動的配列の第一引数のみを...
-
VBAで近似曲線の係数取得
-
VLOOKUP関数で、一番下...
-
配列に同じ値を入れる方法
-
エクセルで最小値から0を除く方法
-
linest関数に配列を渡す
-
配列を任意の数値で埋める方法
-
Dim は何の略ですか?
-
配列内の内容を全て表示する方法
おすすめ情報
No2さん。すみません。classの外に書いてました。
とりあえずコピペのほうは動きました。