• ベストアンサー

EXCEL インデックスが有効範囲にありません

エクセルでマクロを使ったソフト(他人が作ったもの)を使っているのですが、 計算の途中で「インデックスが有効範囲にありません」という エラーが出てしまい困っています。 同じ量の他の数値(サンプル数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 上記文章だけでは何も分からないとは思うのですが、 何か分かる方がいらっしゃればお願いいたします。

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

  • ベストアンサー
  • end-u
  • ベストアンサー率79% (496/625)
回答No.4

『変数の宣言箇所と代入箇所を教えてください。  例えば』 っていうのと、 『推定される kkk の最大値よりも変数 C の配列サイズを大きめに取っておかないとダメでしょう。おそらく。』 『Dim C(100) As Long  この100の箇所の変更が必要ではないですか?』 この意味が伝わらなかったでしょうか。 Dim C(1 To 5000) といった変数宣言箇所を見つけて、この5000を10000に変更してください。 プロシージャの最初のほうに記述があるはずです。

upas
質問者

お礼

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

upas
質問者

補足

よく分かっていませんでした。 宣言箇所は下記のことでしょうか。 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の値を変えて再計算しています。 結果がでましたら、お礼の方書かせて頂きます。

その他の回答 (7)

  • end-u
  • ベストアンサー率79% (496/625)
回答No.8

>最大が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 などのように、個々明確に型を宣言したほうが良いと思います。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.7

こんにちは。 最初に、ツールで集計を取ってみると、以下の変数が使われずに浮いているようですから、この後もあるようです。 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 もあるようです。本当は、全体を見通して、その上で修正しないと正確なところは出てこないと思います。 出来れば、全体の構造をみた上で、編集や調整をしたほうがよいと思います。ただ、インターネット検索しても、ヒットしないようですから、この作者のコードの著作権の考え方の確認をしたほうが良いのではないでしょうか?インターネットで公開されているものなら、出典等を公開していただくか、作者ご本人に内容を確認していただいたほうがよいと思うのです。

upas
質問者

お礼

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

  • bin-chan
  • ベストアンサー率33% (1403/4213)
回答No.6

#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を「今やっている文字列のサンプル数」以上に意義しなおすと解決しそうですね。

upas
質問者

お礼

サンプル数は同じ91です。 サンプルにはそれぞれの属性が9つ(例:A2B1C2D4E6F7G4H4など)はいっており、サンプル同士の共通の属性の組み合わせを求めます。 #4さまのお礼の方にも書かせていただいたのですが、 109*100の計算が限度でそれでもやはり行数が足りないのです…。 最初の質問とは違ってしまいますが エクセルのMax行(6万?)まで計算できるようにするにはどのようにすればいいでしょうか。 IntegerをLongに変えたのですがうまく反映されませんでした。 度々回答して頂きありがとうございました。

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

同じようなエラー(「「インデックスが有効範囲にありません」)は ーー配列の上限超え 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の配列定義されている部分は見えないようだ。実際はどうなっているかな。

upas
質問者

お礼

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

  • bin-chan
  • ベストアンサー率33% (1403/4213)
回答No.3

#1です。 VBAソースをコピペされているので、VBEは開けますね? 1)68行目にカーソルをおいてf9キーを押してください。 2)f5キーで実行。 68行目で一時停止するので、カーソルをkkkにもっていくと値が表示されます。 f8キーを押すと一行ずつ実行します。f5キーで連続実行。 73行目でiの値も確認してください。 #2さんのご指摘の確認も、カーソルをcにもっていくと値が表示されますので確認してください。

upas
質問者

お礼

最初に書き忘れたのですが計算では、サンプルの中の属性の組み合わせをみています。集合の計算のはずです(細かい計算内容は分からないのですが…) 一度消してしまったので再計算してました。以下はデバッグ画面で書かれていたことを書きます。 68行目はi=7816 kkk=9283でした。 73行目がどこをさしているのか分からなかったのですが、iにはすべて7816という数字が入っていました(デバッグ画面だからでしょうか?) i2は#2の方の方にも書きましたが5001が入っています。 それぞれの値が何を指しているのか?は申し訳ないのですが分かりませんでした。 色々と無知で申し訳ありません。回答ありがとうございました。

  • end-u
  • ベストアンサー率79% (496/625)
回答No.2

>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 の要素が一致する量が多いからなのでしょうね。

upas
質問者

お礼

変数Cは、デバッグでは補足欄のようになっています。 D(i)にマウスカーソルを当てると、B11H4F1J1というセルに入力されている文字が書いてあります。 i2は5001となっていました。 5001行目で計算が止まっているので、5001は行数のことのような気がします。 ということはCはセルのことで設定の最大行数が5001となっているということなのでしょうか。 長文読んで回答して頂きありがとうございました。

upas
質問者

補足

'よこ方向の×算 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

  • bin-chan
  • ベストアンサー率33% (1403/4213)
回答No.1

> C(i2) = D(i) ←ここがエラー この行を71行目と数える場合の68行目 > For i = 1 To kkk - 1 ここの変数kkkは、うまくいく場合・いかない場合でそれぞれいくつですか? 6行目で1を設定、16・21・38行目で加算していますが どこかで加算される回数が異なるはず。 空白(何もない=NULL)と思っているが実はスペースがあるために KKKの加算結果が異なるのでは?

upas
質問者

お礼

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

関連するQ&A