[[20151115213605]] 『6つ構文を重ねると詰む』(頭中将) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『6つ構文を重ねると詰む』(頭中将)

要約の通りではあるのですが、詳しく説明します。
6つの数字(セル上に任意で入力)から1ずつ引き、引いた後の各々の数の十の位の和が一定値を超過した時点でその時の6つの数字を表示するという物です。
例として全て70の時、一回目の試行で全て69となるので和には36が代入され、二回目はあわせて72、三回目は108…となります。
for next構文を6つ組み合わせて行ったところ、オーバーフロー状態になってしまいました(Nextの後の文字が原因でエラーが発生していると踏んだため削除しました)。
変数の数が多すぎる(6つ+for構文で6つ+下限値を定めたのでさらに6つ=18個)のが問題かもしれないのですが、どうも減らすことも出来ず……。
解決法を教えてください。

< 使用 Excel:Excel2010、使用 OS:unknown >


今のコードを示してもらえますか?

(γ) 2015/11/15(日) 21:45


Sub main()
'6つの数字はSheet1のA1〜A6に記入
'「一定値はSheet1のB1に記入
    Dim cl As Range, i As Integer, j As Integer, ctr As Long, tot As Long, comm As String, dt As Variant
    dt = Sheets("Sheet1").Range("A1:A6")
    Do
        ctr = ctr + 1
        For i = 1 To 6
            dt(i, 1) = Val(Sheets("Sheet1").Range("A" & i)) - ctr
            tot = tot + Int((Val(Sheets("Sheet1").Range("A" & i)) - ctr) / 10)
            If tot > Sheets("Sheet1").Range("B1").Value Then
                comm = ""
                    For j = 1 To 6
                    comm = comm & dt(j, 1) & Chr(10)
                    Next j
                MsgBox "一定値を超えた時点での十の位の和" & Chr(10) & tot
                MsgBox "その時の6つの数字" & Chr(10) & comm
                Exit Sub
            End If
        Next i
    Loop
End Sub
(mm) 2015/11/16(月) 10:42

 質問内容と提示コードがあまりにもかけ離れているので自己削除
 2015/11/6(火)  21:52

Dim a As Integer, b As Integer, c As Integer, d As Integer, e As Integer, f As Integer
a = Cells(2, 2).Value
b = Cells(2, 3).Value
c = Cells(2, 4).Value
d = Cells(2, 5).Value
e = Cells(2, 6).Value
f = Cells(2, 7).Value
g = Cells(4, 2).Value
h = Cells(4, 3).Value
i = Cells(4, 4).Value
j = Cells(4, 5).Value
k = Cells(4, 6).Value
l = Cells(4, 7).Value
S = 0
For m = a To g Step -1
S = S + Int((m - 1) / 10)
For n = b To h Step -1
S = S + Int((n - 1) / 10)
For o = c To i Step -1
S = S + Int((o - 1) / 10)
For p = d To j Step -1
S = S + Int((p - 1) / 10)
For q = e To k Step -1
S = S + Int((q - 1) / 10)
For r = f To l Step -1
S = S + Int((r - 1) / 10)
If S >= 210 Then
Exit Do
Exit Do
Exit Do
Exit Do
Exit Do
Exit Do
End If
Next a
Next b
Next c
Next d
Next e
Next f
End Sub
これです、ものすごい面倒なコードです(210は一定値)
(頭中将) 2015/11/16(月) 20:50

こんにちは。
・きちんとインデントをつけるようにしましょう。
・変数はきちんと宣言しましょう。
・繰り返しの変数が対応していません。

まずは文法エラーのでないものをアップしてみましょう。
(γ) 2015/11/16(月) 21:28


・インデントを付け忘れたのは申し訳ありません。
・変数は宣言していますが流石に長いのでf以降カットしました
・繰り返し変数はaからfをmからrに置き換えたのですが、やっぱりエラーが出て上手いこといかないのでそこのm〜rを削除したところ文法エラーは出ませんでしたがオーバーフロー致しました。ただの理解不足です。
(頭中将) 2015/11/16(月) 21:44

こんにちは。

>変数の数が多すぎる(中略)のが問題かもしれない
あれ、そうですか??
だって、エクセルシートの行数は100万行以上あるんですよ。
そんな膨大な数のセルを管理できるのに
変数はたった18個でパンクしちゃうなんて
差をつけすぎじゃないですか。

ホントに変数の数が問題なのか試してみませんか。
うんとシンプルなコードで。
こんなのでエラーが出るでしょうか。
エラーが出たなら、変数の数を何個にまで減らせばエラーが消えるでしょう。

Sub test

    dim x1 as long
    dim x2 as long
    dim x3 as long
       :
    dim x18 as long

    x1 = 1
    x2 = 2
    x3 = 3
       :
    x18 = 18

    msgbox x1
    msgbox x2
    msgbox x3
       :
    msgbox x18
End sub

( 佳 ) 2015/11/16(月) 22:15


>・インデントを付け忘れたのは申し訳ありません。
いえいえ別に申し訳ないことはないです。
あなたが分かりにくいだけなので、こちらのことは気にする必要ないです。

ところで、ステップ実行というのをご存じですか?
一行ずつ実行できるやつ、F8キーを押していくやつです。
これで、どんな計算がされているのかを、ご自分でためして、
それが想像しているものと同じか、考えてみてはいかがでしょうか。

(γ) 2015/11/16(月) 22:17


こんにちは。

素朴な疑問、最初の数値が6つより少なければ、
希望通りの結果が出るのでしょうか。

たとえば、最初の数値が3つとか。いかがでしょう。

( 佳 ) 2015/11/16(月) 22:27


それぞれのセルに入っている値は何ですか?
変数宣言がIntegerですが、すべての値はIntegerの範囲(-32768〜32767)に収まりますか?
変数Sの宣言がありませんが、実はIntegerだったりしませんか?
変数宣言をLongにするとどうなりますか?
(???) 2015/11/17(火) 11:02

 >>(頭中将) 2015/11/16(月) 20:50 アップのコード

 これですといわれますが、これではないでしょ?
 Do/Loop構文ではないのに、Exit Do ????
 これでは実行以前にコンパイルエラーですね。

 回答者に検討してもらうためには、ちゃんと「本物のコード」をアップいただかないと困ります。

 で、「これです」といわれる、そのおかしなコードに変数定義とインデントを付けたものが以下です。
 仮に Do/Loop 構文のコードであっても、同じ場所に Exit Do が複数登場している。
 これは、おかしいねと 一目瞭然ですね。

 γさんもいわれるとおり、インデントは誰のためでもない、あなた自身のためですよ。

 Sub Test()
    Dim a As Long, b As Long, c As Long, d As Long, e As Long, f As Long, g As Long, h As Long, i As Long, j As Long, k As Long, l As Long
    Dim s As Long, m As Long, n As Long, o As Long, p As Long, q As Long, r As Long
    a = Cells(2, 2).Value
    b = Cells(2, 3).Value
    c = Cells(2, 4).Value
    d = Cells(2, 5).Value
    e = Cells(2, 6).Value
    f = Cells(2, 7).Value
    g = Cells(4, 2).Value
    h = Cells(4, 3).Value
    i = Cells(4, 4).Value
    j = Cells(4, 5).Value
    k = Cells(4, 6).Value
    l = Cells(4, 7).Value
    s = 0
    For m = a To g Step -1
        s = s + Int((m - 1) / 10)
        For n = b To h Step -1
            s = s + Int((n - 1) / 10)
            For o = c To i Step -1
                s = s + Int((o - 1) / 10)
                For p = d To j Step -1
                    s = s + Int((p - 1) / 10)
                    For q = e To k Step -1
                        s = s + Int((q - 1) / 10)
                        For r = f To l Step -1
                            s = s + Int((r - 1) / 10)
                            If s >= 210 Then
                                Exit Do
                                Exit Do
                                Exit Do
                                Exit Do
                                Exit Do
                                Exit Do
                            End If
                        Next r
                    Next q
                Next p
            Next o
        Next n
    Next m
 End Sub

(β) 2015/11/17(火) 18:55


 追加で。

 オーバーフローとは関係がありませんが

 >>6つの数字(セル上に任意で入力)

 ということですから、セルには 70 が入るかもしれないし、 5 かもしれないし、1234 かもしれないわけですよね?

 とすると

 >>各々の数の十の位

 これは、その数字を10で割ったものとは異なりますよね?

 さらに追加で。

 たとえばセルの値が 10 だったとします。 1 を引いて 9。この10の位をどう考えるかということも
 ルールづけが必要ですね。
 また、どんどん引いていくと、いつかマイナスになるかもしれませんね。
 その場合のルールづけも必要ですね。
 さらに、マイナスになってもどんどん引いていくとすれば、 たとえば -12 となったときの10の位をどう考えるのか
 そういったルールづけも必要ですね。

(β) 2015/11/17(火) 19:23


 私は質問者さんのトライはすばらしいと思います。
 コードだけ欲しいという方が多い中で、
 ご自分で勉強しようとされている点、すばらしいと思います。

 提示いただいたものは少なくとも、動きませんので、
 オーバーフローするところまで行っていません。
 勘違いで別のコードをコピペしているのでは?

 追加で二つのことを書きますね。

 (1)Exit Do に対応する Do がありません。
    これはたぶん、Exit Forのつもりだろうと思います。
    しかし、6つ続けても意味がありません。
    決して二つ目以降のExit For が実行されることはありません。

    脱出判定をして脱出OKであれば、
    最後の処理をしたあと Exit Subしてしまうのがよいのでは?

 (2)ループの使い方を確認するために、以下のコードをためしてみてください。
    違いがわかるでしょうか。

 Sub testA()
     Dim s As Long
     Dim i As Long, j As Long, k As Long

     For i = 3 To 1 Step -1
         For j = 3 To 1 Step -1
             For k = 3 To 1 Step -1
                 s = i + j + k
                 Debug.Print i; j; k; s
             Next
         Next
     Next
 End Sub

 Sub testB()
     Dim s As Long
     Dim i As Long, j As Long, k As Long

     For i = 3 To 1 Step -1
         s = s + i
         For j = 3 To 1 Step -1
             s = s + j
             For k = 3 To 1 Step -1
                 s = s + k
                 Debug.Print i; j; k; s
             Next
         Next
     Next
 End Sub
(γ) 2015/11/17(火) 20:52

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.