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

ここで「Kaplan-Meyer 生存分析に便利なソフトを教えて」と質問した shuu_01 です。ここで VisualBasic のソースのありかを教えて頂き、自分に使いやすいようソースを書き換えようと奮闘中です(それまで VisualBasic の経験がなく 無謀!と実感中です)。

元々のソースはグラフが1本だけだったので、肺癌だと「腺癌」「扁平上皮癌」「小細胞癌」、、といろんな癌の種類別にグラフを数本 書くのが目標です。そこで、

Sub km_test()
Dim nc As Integer, gr() As String
nc = 2
ReDim gr(nc)
gr(0) = "腺癌"
gr(1) = "扁平上皮癌"
gr(2) = "小細胞癌"
km_group_test nc, gr
End Sub

Sub km_group_test(nc As Integer, gr As String)

End Sub

というソースを書くと:

String の変数 gr の色が変わり、「 ByRef引数の型が一致しません 」というエラーが出ます。
Integer の変数 nc ではエラーが出ません。
きちんと型を一致させているつもりなのに、なぜ???

このQ&Aに関連する最新のQ&A

A 回答 (2件)

関数の第2変数が文字列なのに、呼び出し側が文字列の配列を渡しているようです。



関数の呼び出し側を
km_group_test nc, gr(1)
とかにするか、関数を
Sub km_group_test(nc As Integer, gr() As String)
とかにしないと、型が違うと思います。
    • good
    • 1
この回答へのお礼

fumufumu_2006 さん、ありがとう!!
「 ByRef引数の型が一致しません 」で検索するといろいろ出てきても僕に当てはまるのを探し出せないで、困り抜いていました。
エラーはスッときれいに消えました。ありがとうございました。

お礼日時:2008/02/23 20:51

gr()


配列
    • good
    • 0
この回答へのお礼

okormazd さん、回答ありがとうございます。「1番、短い回答はこれか!」と、自分の仕事(医師として検査所見をレポートする)をサクサク片付けるための参考にしたいです。

お礼日時:2008/02/23 20:59

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q配列の参照渡しで型が一致しません。

エクセル2003です。
いつもお世話になります。
以下のコードを実行すると「配列の型が一致しません。」というエラーが出ます。
typeNameで確認しても配列の型はvariant()で正しいと思うのですが。。。
皆様のお知恵を拝借させていただけないでしょうか。

--------------------------------------
Sub main()
Dim e As Variant
e = fuN()
Call pRo(e)  '←ここでエラーになる。
End Sub

Function fuN() As Variant
Dim a(0) As Variant
a(0) = "zero"
fuN = a
End Function

Sub pRo(ByRef c() As Variant)
'処理っす
End Sub
--------------------------------------

Aベストアンサー

簡単にいっていまうと、Variantは小難しい事を考えなくてもそういう風に使えるよ、っていうことです。
イメージ的にはVriant型のでっかい変数の中にVariantの配列が入ってるみたいな感じですかね。

参考URL:http://pc.nikkeibp.co.jp/article/NPC/20070803/279065/

QExcel VBA ByRef引数の型?

Excel2010でセルに関数式を埋め込むマクロを書いています。
そこで、「ByRef引数の型が一致しません」というエラーが出て困っています。
プログラムの中からエラーの出る所だけを取り出してtest1,test2として試したところ、
test1はエラーが出て、test2はプログラムが動いて目的とするセルに関数式が挿入されました。

Sub test1()
dim i, myR as integer
myR = 30
For i = 7 To 31
Cells(4, i) = "=IF(" & ConvertToLetter(i) & i - 4 & "="""","""",SUM(" & ConvertToLetter(i) & "5:" & ConvertToLetter(i) & myR & ")/(" & myR & "-COUNTIF(" & ConvertToLetter(i) & "5:" & ConvertToLetter(i) & myR & ","""")))"
next i
End Sub

test1でConvertToLetter(i)のiが青色で選択され「ByRef引数の型不一致」エラーとなってしまいます。

そこで、試しに一度変数iの値をkに渡して同じプログラムをtest2として実行してみました。
Sub test2()
dim i, k, myR as integer
myR = 30
For i = 7 To 31
k=i
Cells(4, i) = "=IF(" & ConvertToLetter(k) & i - 4 & "="""","""",SUM(" & ConvertToLetter(k) & "5:" & ConvertToLetter(k) & myR & ")/(" & myR & "-COUNTIF(" & ConvertToLetter(k) & "5:" & ConvertToLetter(k) & myR & ","""")))"
next i
End Sub

このtest2は、きちんと実行され、目的とするG4(~AE4)のセルに
=IF(G3="","",SUM(G5:G30)/(30-COUNTIF(G5:G30,"")))
という式が挿入されました。

質問1:なぜ、test1がダメで、test2ならうまくいくのかという理由がわかりません。
質問2:うまくいったtest2と同じ式を、もっと長いプログラムの中に入れるとやはり「ByRef引数の型が一致しません」エラーが出てプログラムが止まってしまいます。test2単独のプログラムならうまく動くのに、他のプログラムの一部に埋め込むとエラーが出る理由もわかりません。

VBAプログラムを試行錯誤しながら勉強している初心者です。どなたかご教示お願いします。

ちなみに、ConvertToLetterは、
Function ConvertToLetter(iCol As Integer) As String
Dim iAlpha As Integer
Dim iRemainder As Integer
iAlpha = Int((iCol - 1) / 26)
iRemainder = iCol - (iAlpha * 26)
If iAlpha > 0 Then
ConvertToLetter = Chr(iAlpha + 64)
End If
If iRemainder > 0 Then
ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64)
End If
End Function
という、関数で定義しています。

Excel2010でセルに関数式を埋め込むマクロを書いています。
そこで、「ByRef引数の型が一致しません」というエラーが出て困っています。
プログラムの中からエラーの出る所だけを取り出してtest1,test2として試したところ、
test1はエラーが出て、test2はプログラムが動いて目的とするセルに関数式が挿入されました。

Sub test1()
dim i, myR as integer
myR = 30
For i = 7 To 31
Cells(4, i) = "=IF(" & ConvertToLetter(i) & i - 4 & "="""","""",SUM(" & ConvertToLetter(i) & "5:" & ConvertToLetter(i)...続きを読む

Aベストアンサー

まず、

Function ConvertToLetter(iCol As Integer) As String

は「参照渡し」になっています。

引数の渡し方の指定子であるByVal、ByRefを省略すると、自動的にByRefになります。つまり

Function ConvertToLetter(ByRef iCol As Integer) As String

と書いているのと同じなのです。

んで、test1では

For i = 7 To 31
Cells(4, i) = "=IF(" & ConvertToLetter(i)

のように「参照渡しが許されないFor文のループ変数を、参照渡ししようとしている」ので「ByRef引数の型不一致」のエラーになります。

test2では

For i = 7 To 31
k=i
Cells(4, i) = "=IF(" & ConvertToLetter(k)

のように「参照渡しが許されないFor文のループ変数を渡さず、普通の変数を参照渡ししている」ので、エラーにはなりません。

解決方法は「ConvertToLetterの引数を値渡しに変える」です。つまり

Function ConvertToLetter(iCol As Integer) As String

Function ConvertToLetter(ByVal iCol As Integer) As String
に変えれば、すべて解決します。

引数にByRefを付けたり、何も書かない場合は「引数の値を関数内で書き換えてしまうと、書き換えた結果が呼び出し元にも影響してしまう」ので、故意にそういう事をするのでなければ、必ず「ByVal」を指定しましょう。

自作関数の引数は、バグを産まない為にも「必ずByValかByRefのどちらかを明記する」ようにしましょう。

まず、

Function ConvertToLetter(iCol As Integer) As String

は「参照渡し」になっています。

引数の渡し方の指定子であるByVal、ByRefを省略すると、自動的にByRefになります。つまり

Function ConvertToLetter(ByRef iCol As Integer) As String

と書いているのと同じなのです。

んで、test1では

For i = 7 To 31
Cells(4, i) = "=IF(" & ConvertToLetter(i)

のように「参照渡しが許されないFor文のループ変数を、参照渡ししようとしている」ので「ByRef引数の型不一致」のエラーになります。

test2...続きを読む

QEXCEL VBA で現在開いているブックのファイル名を取得する方法

EXCEL2003 VBAで業務を簡素化するために、現在開いているブックのファイル名を取得する方法が分かりません。
作業手順をマクロを使って処理していますが、オリジナルのワークブックをファイル名を変えて保存し、以後、このワークブックを読み込んで使用しています。
このときのVBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり、以後の業務に使用できません。
常にファイル名を取得出来るVBAをどなたか、教えて下さい。

Aベストアンサー

>現在開いているブックのファイル名
 ちょっと曖昧な表現かなぁという気もいたしますが、VBAが書いてあるブックのブック名は
ThisWorkbook.Name
で、現在 "アクティブにして" 操作対象になっているブックの名前は
ActiveWorkbook.Name
ですね。

 しかし、
>VBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり
というような文脈からすると、
ThisWorkbook.Name
の方ですかね。

QEXCELファイルのカレントフォルダを取得するには?

EXCELファイルのカレントフォルダを取得するには?

C:\経理\予算.xls

D:\2005年度\予算.xls

EXCEL97ファイルがあります。

VBAで
  カレントフォルダ名
(C:\経理\,D:\2005年度\)
を取得する事は可能でしょうか?

CURDIRでは上手い方法が見つかりませんでした。

Aベストアンサー

こんばんは。
Excel97 でも、同じですね。以下で試してみてください。

Sub test()
'このブックのパス
a = ThisWorkbook.Path
'アクティブブックのパス
b = ActiveWorkbook.Path
'Excelで設定されたデフォルトパス
c = Application.DefaultFilePath
'カレントディレクトリ
d = CurDir
MsgBox "このブックのパス   : " & a & Chr(13) & _
   "アクティブブックのパス: " & b & Chr(13) & _
   "デフォルトパス    : " & c & Chr(13) & _
   "カレントディレクトリ : " & d & Chr(13)
End Sub

QEXCEL VBAで計算値を四捨五入、切り上げ、切捨てする方法

ネットで探してみたのですが、計算結果を四捨五入して特定のセルを
返すにはどうしたらいいのでしょうか?

Sub hokangosa()

Dim ZPS As Double
Dim ZPOS As Double
Dim DMN As Double
MsgBox (" >>> 補間誤差自動計算 <<< ")
MsgBox (" >>> 初期値入力します <<< ")
ZPS = InputBox(">>> ステップを入力してください<<<")
ZPOS = Sheet1.Cells(22, 4).Value
DMN = ZPOS / ZPS
Sheet1.Cells(23, 6).Value = DMN
End Sub

ここでDMNの値を四捨五入したいです。

またこれとは別に切上げ、切捨ても教えていただけるとありがたいです。

Aベストアンサー

DMN = Application.WorksheetFunction.Round(ZPOS / ZPS, 0)
で、四捨五入
DMN = Application.RoundDown(ZPOS / ZPS, 0)
で切り捨て
DMN = Application.RoundUp(ZPOS / ZPS, 0)
で切り上げです。

引数で、対象桁を変更できます。

QFunctionの戻り値を配列にしたいのですが

vbを始めたばかりですがよろしくお願いします。

Functionの戻り値を配列にしたいのですが

Function fnc(ByVal a As Byte, ByVal b As Byte) As Integer()
fnc(0) = a + b
fnc(1) = a - b
End Function
というような使い方はできないのでしょうか?
一つのFunctionで二つの計算結果をかえすには
どうしたらよいのでしょうか?
お願いします。

Aベストアンサー

ローカル変数を使えば可能だと思いますよ

VB6.0の場合
Function fnc( byVal a as Byte, Byval b as Byte) as Integer
  dim ar(1) as Integer
  ar(0) = a + b
  ar(1) = a - b
  fnc = ar
End Function

VB.NETなら
Function fnc( byVal a as Byte, Byval b as Byte) as Integer
  dim ar(1) as Integer
  ar(0) = a + b
  ar(1) = a - b
  return ar
End Function

VB.NETでも fnc = ar と言った記述も出来ます

呼び出し側では 動的配列として返り値を受けます
dim results() as Integer
results = fnc( 5, 3 )
と言った具合です

QVBA 実行時エラー1004 rangeメソッドは失敗しました。globalオブジェクトのエラー

始めまして、VBA初心者のものです。
ただいまエクセルでグラフを作成しています。作業自体は単純作業の繰り返しなのでVBAを用いてやりたいのですが、マクロを実行したときに実行時エラー’1004’rangeメソッドは失敗しました。’_global’オブジェクトとメッセージが出て、実行できません。 デバックをすると以下の5行目で黄色のバーが出ていました。自分なりに原因を考えたのですがrangeの関係するところに、Range("A8:A1587,e8:e1587")というような変数を用いないやり方でやると上手くいくので、変数に関する定義がまずいと思うのですが、それ以上の事は分かりません。どなたか、分かる方がおりましたら、よろしくお願いします。また、プログラムは以下のようになります。

Sub 繰り返し()
'繰り返し
Dim s As Integer
For s = 0 To 17
Range("cells(8,1):cells(1580,1),cells(8,s+2):cells(1580,s+2)").Select
Range("cells(8,s+2)").Activate
Charts.Add
ActiveChart.ChartType = xlXYScatter
ActiveChart.SetSourceData Source:=Sheets("20081216_210647").Range( _
"cells(8,1):cells(1580,1),cells(8,s+2):cells(1580,s+2)"), PlotBy:=xlColumns
ActiveChart.SeriesCollection(1).Name = "=""0810p2x"""
ActiveChart.Location Where:=xlLocationAsNewSheet, Name:="0810p2x"
With ActiveChart
.HasTitle = True
.ChartTitle.Characters.Text = "0810p2x"
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "t"
.Axes(xlValue, xlPrimary).HasTitle = False
End With
Next
End Sub

始めまして、VBA初心者のものです。
ただいまエクセルでグラフを作成しています。作業自体は単純作業の繰り返しなのでVBAを用いてやりたいのですが、マクロを実行したときに実行時エラー’1004’rangeメソッドは失敗しました。’_global’オブジェクトとメッセージが出て、実行できません。 デバックをすると以下の5行目で黄色のバーが出ていました。自分なりに原因を考えたのですがrangeの関係するところに、Range("A8:A1587,e8:e1587")というような変数を用いないやり方でやると上手くいくので、変数に関する定義...続きを読む

Aベストアンサー

>ご指摘を受けたところを書き換えて回してみた結果、書き換えた箇所
>でエラーがでます。(実行時エラー’1004’’cells’メソッドは失敗
>しました。’global’オブジェクト)
>しかし、何が原因でエラーになるか自分では分かりません。

≪例1≫
Range(Cells(8, 1), Cells(1587, 2)).Select
上記の例では、RangeとかCellsの上位オブジェクトであるシート名が省略されています。
ActiveSheet.Range(ActiveSheet.Cells(8, 1), ActiveSheet.Cells(1587, 2)).Select
というわけです。
マクロ実行時に、Activeな(Excelで表示されている)シートが上位オブジェクトとして、自動的に認識されます。

≪例2≫
Sheets("Sheet2").Range(Cells(8, 1), Cells(1587, 2)).Select
上記の例では、Rangeのみシート名が記述されています。
Sheets("Sheet2").Range(ActiveSheet.Cells(8, 1), ActiveSheet.Cells(1587, 2)).Select
というわけです。
Activeなシートが、Sheet2の場合はエラーになりません。
しかし、ActiveなシートがSheet2以外の場合、エラーが発生します。
直前に、
Sheets("Sheet1").Select
などとしていれば、ActiveシートがSheet1になっていますから、エラーになります。

Sheets("Sheet2").Range(Sheets("Sheet2").Cells(8, 1), Sheets("Sheet2").Cells(1587, 2)).Select
と書いておけば安心です。
Withステートメントを使えばスッキリ纏めることができます。
With Sheets("Sheet2")
  .Range(.Cells(8, 1), .Cells(1587, 2)).Select
End With

# Sheets("Sheet2")の上位オブジェクトが省略されていることにも気がついてください。

>そこで自分で基礎を勉強したいのですが推薦できる参考書などがござ
>いましたら、教えていただけませんか?
私自身は、入門書程度の雑誌を1冊買っただけです。どれが良いとかはよく分かりません。
「マクロの記録」を活用して、参考コードを取得し、汎用性のあるコードに編集しています。
新しい単語があれば、文字カーソルを単語の上に置き、F1キーを押してVBAのヘルプを必ず見るようにしています。
躓いた時は、Web検索して欲しい情報を得たり、あるいは、こうした掲示板で先輩方のお力をお借りしています。

Excel(エクセル)VBA入門:目次
http://oshiete1.goo.ne.jp/kotaeru_reply.php3?q=4651404
エクセル入門・初級編
http://www.kenzo30.com/excel_kiso.htm

>ご指摘を受けたところを書き換えて回してみた結果、書き換えた箇所
>でエラーがでます。(実行時エラー’1004’’cells’メソッドは失敗
>しました。’global’オブジェクト)
>しかし、何が原因でエラーになるか自分では分かりません。

≪例1≫
Range(Cells(8, 1), Cells(1587, 2)).Select
上記の例では、RangeとかCellsの上位オブジェクトであるシート名が省略されています。
ActiveSheet.Range(ActiveSheet.Cells(8, 1), ActiveSheet.Cells(1587, 2)).Select
というわけです。
マクロ実行時に、Activeな...続きを読む

QVBAでfor文の中で、continueしたい

お世話になります。
VBAのfor文の中で、ある条件に合致したら、for の先頭に戻りたいのですが、
方法が分かりません。

VB.net 等の「 Continue For」に当たるものは、VBAに
ないのでしょうか?

何卒宜しくお願いします。

Aベストアンサー

Continue For は昔の VB6 までに物には実装されていませんね VB6 使いの私は知らなかった

for の先頭に戻りたいのではなく、 Next の直前に飛びたいのですよね?
幸いにも VBA には Goto ステートメントがありますので

Sub Sample1()
For i = 1 To 10
If 意除外条件 Then GoTo Next_no_mae

通常の総理

Next_no_mae:

Next i

End Sub

じゃダメですか?
これなら For の直後に飛ぶ事も可能ですが

もしくはこれぐらいしか対処方法はないのでは?
Sub Sample2()

For i = 1 To 10
If 除外条件 Then
Else
通常の総理
End If
Next i

End Sub

QVBAで配列引数を値渡しできない理由

Sub TestB(ByVal MyArray() As Integer)

のようにして、
配列引数をByValで渡そうとすると
エラーが出てしまいます。

http://vba.doorblog.jp/archives/51291826.html

このページにあるように
variantとして渡せば
エラーは出ないのですが
byrefとして扱われてしまいます。

なぜVBAでは配列を値渡しすることができないのでしょうか?
何が問題なのでしょうか?

Aベストアンサー

VBで配列を引数で渡す場合、先頭のアドレス(住所)を渡しています。
(C言語のポインター)
その為、サブルーチンの引数の型は、その「アドレスを表す変数」が値渡しか参照渡しかを表すことであって、配列の中身を値渡しか参照渡しかを指定している訳ではありません。
つまり、
Sub TestB(Byref MyArray() As Integer)
※MyArray変数がByref
Sub TestB(Byval MyArray As Variant)
※MyArray変数がByval

詳しくは、以下のサイトを参考にしてみてください。
https://msdn.microsoft.com/ja-jp/library/eek064h4.aspx

Q別のシートから値を取得するとき

Worksheets("シート名").Activate
上記のを行ってから別シートの値を取得するのですが、
この処理を行うと指定したシートへ強制的にとんでしまいます。。。

※イメージ
For ~ To ~
  Worksheets("シートA").Activate
  シートAの値取得
       :
  Worksheets("シートB").Activate
  シートBの値取得
Next

このイメージ処理を行うとものすごい勢いで画面がチカチカします。。。
シートを変えずに他のシートから値を取得する方法はないのでしょうか。
教えてください!

Aベストアンサー

Worksheets("シートA").Range("A1")

みたいな感じでできませんか?


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング