電子書籍の厳選無料作品が豊富!

エクセルでマクロを使ったソフト(他人が作ったもの)を使っているのですが、
計算の途中で「インデックスが有効範囲にありません」という
エラーが出てしまい困っています。
同じ量の他の数値(サンプル数91、属性9)でやるとエラーがでないのですが、今やっている文字列のときだけエラーが出るといった場合
何が考えられるでしょうか?以下はデバッグ結果です。

'For j = 2 To M - 1 '列に関する繰り返し
MaxMax = MaxI
iflag = 0
For j = 2 To iR - 1 '上限?

kkk = 1

For i2 = 1 To MaxI
For i = 1 To MaxMax
If C(i) = "" Or B(i2, j) = "" Then
'Exit For
Else
If Trim(C(i)) = Trim(B(i2, j)) Then
D(kkk) = B(i2, j)
B(i2, j) = ""
kkk = kkk + 1
Else
If InStr(1, C(i), B(i2, j), 1) <> 0 Then
D(kkk) = C(i)
C(i) = ""
kkk = kkk + 1
iflag = 1
End If
End If
End If
Next i
'If iflag = 1 Then
' B(i2, j) = ""
' iflag = 0
'End If
Next i2
For i = 1 To MaxMax
For i2 = 1 To MaxI
If C(i) = "" Or B(i2, j) = "" Then
'Exit For
Else
D(kkk) = C(i) & B(i2, j)
kkk = kkk + 1
End If
Next i2
Next i

For i = 1 To kkk - 1 '簡略,exp.P and TP,,
For i2 = 1 To kkk - 1
If i <> i2 And D(i) <> "" And D(i2) <> "" Then
If Len(D(i)) > Len(D(i2)) Then
L1 = Len(D(i))
L2 = Len(D(i2))
If Comp(D(i), D(i2), L1, L2) = 1 Then
D(i) = ""
'Exit For
End If
Else
L2 = Len(D(i))
L1 = Len(D(i2))
If Comp(D(i2), D(i), L1, L2) = 1 Then
D(i2) = ""
'Exit For
End If
End If


End If
Next i2
Next i

i2 = 1
For i = 1 To kkk - 1
If D(i) <> "" Then
Cells(i2, iR + j) = D(i)
C(i2) = D(i) ←ここがエラー
i2 = i2 + 1
End If
Next i


MaxMax = i2 - 1
Next j

上記文章だけでは何も分からないとは思うのですが、
何か分かる方がいらっしゃればお願いいたします。

A 回答 (8件)

『変数の宣言箇所と代入箇所を教えてください。


 例えば』
っていうのと、
『推定される kkk の最大値よりも変数 C の配列サイズを大きめに取っておかないとダメでしょう。おそらく。』
『Dim C(100) As Long
 この100の箇所の変更が必要ではないですか?』
この意味が伝わらなかったでしょうか。



Dim C(1 To 5000)
といった変数宣言箇所を見つけて、この5000を10000に変更してください。
プロシージャの最初のほうに記述があるはずです。

この回答への補足

よく分かっていませんでした。
宣言箇所は下記のことでしょうか。

Const iStartR = 1
Const iStarL = 4
Const NN = 100
Const MM = 50

Dim i As Integer, j As Integer, k As Integer, k1 As Integer, i1 As Integer, ii As Integer, i2 As Integer
Dim iNumber(NN) As Integer, iSum As Integer, iKind As Integer
Dim Y(NN), Y_Stander
Dim a(NN, MM), AA(NN, MM, NN), B(NN * MM, NN)
Dim MaxK As Integer, iR As Integer, MaxI As Integer, iflag As Integer, kkk As Integer, MaxMax As Integer
Dim C(NN * MM), D(3 * NN * MM), CP(NN * MM)
Dim L1 As Integer, L2 As Integer, RRR As Integer
Dim SheetName As String, sP As String
Dim N As Integer, M As Integer
Dim iSumL As Integer 'まとめシートに出力用

現在Const NNとConst MMの値を変えて再計算しています。
結果がでましたら、お礼の方書かせて頂きます。

補足日時:2009/12/05 23:50
    • good
    • 0
この回答へのお礼

MMを100にして10000行まで計算できるようにしたのですが、
やはり計算の範囲を超えてしまいました。
最大が109*100で、それを超えると6つ目のDimのD(3*NN*MM)でオーバーフローしてしまいます。
重ねての質問で申し訳ないのですが、さらに拡大した行で計算するにはどのような方法があるでしょうか?
Integerを全部Longに変えてみたのですが、同じ場所でオーバーフローしてしまいます(他にも変えるべき場所があるのでしょうか)

最初の質問については分かるようになってきました。
度々ご回答ありがとうございました。

お礼日時:2009/12/06 10:45

>最大が109*100で、それを超えると6つ目のDimのD(3*NN*MM)でオーバーフローしてしまいます。


>重ねての質問で申し訳ないのですが、さらに拡大した行で計算するにはどのような方法があるでしょうか?
>Integerを全部Longに変えてみたのですが、同じ場所でオーバーフローしてしまいます(他にも変えるべき場所があるのでしょうか)

Sub test()
  'これはエラーです。演算結果がInteger範囲値を超えるのでオーバーフローです。
  '(Integer * Integer の演算結果は Integer)
  MsgBox 3 * 200 * 200

  'Longの型宣言文字『&』を付加すると良いです。
  '(Long * Integer の演算結果は Long)
  MsgBox 3& * 200 * 200
End Sub


Const NN = 200
Const MM = 200
D(3& * NN * MM)
としてください。

または
Const NN As Long = 200
Const MM As Long = 200
Const X As Long = 3
Dim D(X * NN * MM) As Variant '文字列ならString
などのように、個々明確に型を宣言したほうが良いと思います。
    • good
    • 0

こんにちは。



最初に、ツールで集計を取ってみると、以下の変数が使われずに浮いているようですから、この後もあるようです。

iStartR, iStarL ,k ,k1 ,i1 ,ii ,iNumber ,iSum ,iKind ,Y(NN) ,Y_Stander ,a(NN, MM) ,AA(NN, MM, NN)
MaxK ,CP(NN * MM) RRR ,SheetName, sP, N, iSumL

エラーが起こる周辺を出して解決する場合、ここでは、C()の配列で問題が起こるようなら、単純に、変数の宣言部分を増やせばよいのですが。

>Dim C(NN * MM), D(3 * NN * MM) 'バランスが合わないので、
   ↓
Dim C(3 * NN * MM), D(3 * NN * MM)

とすれば合うはずです。

この書いた人は、素人ではないようですから、それで、「68行目はi=7816 kkk=9283」(本来は、この時点でアウト)でエラーが発生するような問題は起こるはずがないと思いますから、使い方自体が想定外のミスではないでしょうか?

また、3次元配列変数まで使っているようですし、このコードは、Variant 型が多いようですから、数万個のIndex を越えるような宣言は、注意したほうがよいのではないかと思います。また、インクリメント変数も、Integer にしていますが、1万を標準的に越えているので、本来は、Long 型のほうが無難ですね。

ユーザー定義関数のComp もあるようです。本当は、全体を見通して、その上で修正しないと正確なところは出てこないと思います。

出来れば、全体の構造をみた上で、編集や調整をしたほうがよいと思います。ただ、インターネット検索しても、ヒットしないようですから、この作者のコードの著作権の考え方の確認をしたほうが良いのではないでしょうか?インターネットで公開されているものなら、出典等を公開していただくか、作者ご本人に内容を確認していただいたほうがよいと思うのです。
    • good
    • 0
この回答へのお礼

長文を読んで回答して頂きありがとうございます。
はい、おっしゃる通りこの式を書いたのはきちんとした人なので、間違っているのは私だと思います。
やはり1万行を超えるようなこと自体想定外なのでしょうね…。
作者本人に連絡をとれるツテは一応あるのですが、私自身の些細なミスかもしれないと思い今回質問させていただきました。

C()に関してのアドバイスもしていただきありがとうございました。

お礼日時:2009/12/06 12:32

#1、#3です。



#4さんの回答への補足に答えがありますね

> Dim C(NN * MM), D(3 * NN * MM), CP(NN * MM)
(中略)
> Const NN = 100
> Const MM = 50

配列Cの大きさを MM*NN=50×100=5000と演算結果で定義している。
(#4さんの指摘にある 「Dim C(1 To 5000)」の部分です)

> i2は#2の方の方にも書きましたが5001が入っています。
参照可能なのが5000までだから、定義されていない5001を参照しようとしてエラーになっていますね。

ご質問本文
> 同じ量の他の数値(サンプル数91、属性9)でやるとエラーがでない
> 今やっている文字列のときだけエラーが出る
「今やっている文字列のサンプル数」とは100を越えてますか?
NNを「今やっている文字列のサンプル数」以上に意義しなおすと解決しそうですね。
    • good
    • 0
この回答へのお礼

サンプル数は同じ91です。
サンプルにはそれぞれの属性が9つ(例:A2B1C2D4E6F7G4H4など)はいっており、サンプル同士の共通の属性の組み合わせを求めます。

#4さまのお礼の方にも書かせていただいたのですが、
109*100の計算が限度でそれでもやはり行数が足りないのです…。
最初の質問とは違ってしまいますが
エクセルのMax行(6万?)まで計算できるようにするにはどのようにすればいいでしょうか。
IntegerをLongに変えたのですがうまく反映されませんでした。

度々回答して頂きありがとうございました。

お礼日時:2009/12/06 11:00

同じようなエラー(「「インデックスが有効範囲にありません」)は


ーー配列の上限超え
Sub test01()
Dim d(3)
For i = 0 To 4
d(i) = 1
Next
End Sub
ーーシートインデックス指定
現状シートは4つしかない。Sheets(5)は存在しない。
Sub test03()
For i = 1 To 5
Sheets(i).Range("A1") = 1
Next i
End Sub
などで出る。
>C(i2) = D(i) ←ここがエラー
なら、実行しているうちにi2が表す数が、配列のg右舷上限定義を超えてしまっている、エラーでしょう。
質問のコード部分にはC、Dの配列定義されている部分は見えないようだ。実際はどうなっているかな。
    • good
    • 0
この回答へのお礼

#4さまの補足に書かせていただいたのですが、
5000までしか行を用意していなかったがそれでは足りないということだったようです。
現在は10900行までしか用意できずそちらでも苦戦しています…。
長文を読んでご回答して頂きありがとうございました。

お礼日時:2009/12/06 10:51

#1です。



VBAソースをコピペされているので、VBEは開けますね?

1)68行目にカーソルをおいてf9キーを押してください。
2)f5キーで実行。

68行目で一時停止するので、カーソルをkkkにもっていくと値が表示されます。

f8キーを押すと一行ずつ実行します。f5キーで連続実行。
73行目でiの値も確認してください。



#2さんのご指摘の確認も、カーソルをcにもっていくと値が表示されますので確認してください。
    • good
    • 0
この回答へのお礼

最初に書き忘れたのですが計算では、サンプルの中の属性の組み合わせをみています。集合の計算のはずです(細かい計算内容は分からないのですが…)

一度消してしまったので再計算してました。以下はデバッグ画面で書かれていたことを書きます。

68行目はi=7816 kkk=9283でした。
73行目がどこをさしているのか分からなかったのですが、iにはすべて7816という数字が入っていました(デバッグ画面だからでしょうか?)
i2は#2の方の方にも書きましたが5001が入っています。
それぞれの値が何を指しているのか?は申し訳ないのですが分かりませんでした。

色々と無知で申し訳ありません。回答ありがとうございました。

お礼日時:2009/12/05 21:53

>C(i2) = D(i) ←ここがエラー



変数 C って何ですか?
変数の宣言箇所と代入箇所を教えてください。
例えば

Dim C(100) As Long

For i = 0 To 100
  C(i) = Cells(i).Value
Next

とか

Dim C As Variant

C = Application.Transpose(Range("A1:A100").Value)

とかの箇所。

単純に考えれば、Loopインデックスの変数 i2 が、配列変数 C の添字の最大値を超えている為のエラーでしょう。
デバッグ時に C(i2) の i2 部分にマウスカーソルをあてると
i2=???
という感じで変数の中身が見れますから確認してください。
推定される kkk の最大値よりも変数 C の配列サイズを大きめに取っておかないとダメでしょう。おそらく。
変数 C への値代入方法にもよりますが
Dim C(100) As Long
この100の箇所の変更が必要ではないですか?

>同じ量の他の数値(サンプル数91、属性9)でやるとエラーがでないのですが、
>今やっている文字列のときだけエラーが出るといった場合
よく解らないけど、C と B の要素が一致する量が多いからなのでしょうね。

この回答への補足

'よこ方向の×算
iflag = 0
For i = 1 To MaxI '第2列を基準に入れる
If B(i, 1) = "" Then
ii = i - 1
Exit For
Else
C(i) = B(i, 1)
End If
Next i

補足日時:2009/12/05 21:31
    • good
    • 0
この回答へのお礼

変数Cは、デバッグでは補足欄のようになっています。
D(i)にマウスカーソルを当てると、B11H4F1J1というセルに入力されている文字が書いてあります。

i2は5001となっていました。
5001行目で計算が止まっているので、5001は行数のことのような気がします。
ということはCはセルのことで設定の最大行数が5001となっているということなのでしょうか。

長文読んで回答して頂きありがとうございました。

お礼日時:2009/12/05 21:31

> C(i2) = D(i) ←ここがエラー


この行を71行目と数える場合の68行目
> For i = 1 To kkk - 1
ここの変数kkkは、うまくいく場合・いかない場合でそれぞれいくつですか?

6行目で1を設定、16・21・38行目で加算していますが
どこかで加算される回数が異なるはず。

空白(何もない=NULL)と思っているが実はスペースがあるために
KKKの加算結果が異なるのでは?
    • good
    • 0
この回答へのお礼

申し訳ありません、今の私の知識ではデバッグの文章を読んでも
kkkについてよく分かりませんでした。
空白~というのはありそうです。探してみます。
わざわざ長文を読んで回答して頂きありがとうございました。

お礼日時:2009/12/05 19:15

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