Do-Loop с несколькими условиями в VBA - PullRequest
0 голосов
/ 27 октября 2019

Это мой первый вопрос здесь, и я должен признать, что я не смог найти никакого решения ни здесь, ни где-либо еще. Вот проблема:

Я хотел запрограммировать код, который должен делать следующее:

  • Спросить пользователя, сколько строк необходимо
  • Спроситьсколько нужно столбцов
  • Создайте матрицу, где в первом столбце нумеруются все строки, в первом ряду все столбцы нумеруются, а в матрице все эти числа умножаются (строка 3 / столбец4 содержит 12, например).
  • Наконец, все простые числа должны быть окрашены.

Моя проблема начинается с последнего шага (мой код начинается с "Primzahlen hervorheben"). Для каждой комбинации строки и столбца я использую два цикла for, в которых я сначала предполагаю, что продукт - это простое число, установив primzahl = true и установив k = 2, который равен 1 для всех чисел вплоть до самого продукта. ... НО по какой-то причине k продолжает расти и в конечном итоге достигает пятизначной области, прежде чем он падает. Я думаю, проблема должна быть в этой строке:

Do While (primzahl = True) Or (k <= i * j) Or (i * j <> 1)

Я соединил все условия так, как это было бы в конструкции if. У самого редактора, похоже, нет проблемы с этим, но почему он игнорирует второе условие, которое не позволяет k стать больше, чем i * j? Я что-то упускаю?
Просто, чтобы выразить это словами: цикл будет продолжаться, пока

  • , если это не простое число, это так (p rimzahl = false),ИЛИ
  • k меньше или равно i * j, ИЛИ
  • i * j не равно 1

Этот случай не является чрезвычайным или что-либо, япросто хочу знать, где крючок. Буду признателен за вашу поддержку и надежду на получение полезных советов.

Sub rechnen()
    'Zellen leeren
      Cells.ClearContents
      Cells.ClearFormats

    'Variablen definieren
      Dim i As Integer, j As Integer, k As Integer, iMax As Integer, jMax As Integer, primzahl As Boolean

    'Variablen Werte zuweisen
      iMax = 3 'InputBox("Anzahl Zeilen")
      jMax = 5 'InputBox("Anzahl Spalten")

    'Eigentliche Prozedur
      For i = 1 To iMax
        Cells(1 + i, 1).Value = i
        For j = 1 To jMax
          Cells(1, 1 + j).Value = j
          Cells(1 + i, 1 + j).Value = i * j
        Next j
      Next i

    'Spaltenbreite anpassen
      ActiveSheet.UsedRange.Columns.AutoFit



    'Primzahlen hervorheben
      For i = 1 To iMax
        For j = 1 To jMax
          k = 2
          primzahl = True
          ''''''''
          Do While (primzahl = True) Or (k <= i * j) Or (i * j <> 1)
            If Cells(1 + i, 1 + j).Value Mod k = 0 Then
              primzahl = False
              Exit Do
            End If
              k = k + 1
          Loop
          ''''''''
          If primzahl = True Then
            Cells(1 + i, 1 + j).Interior.Color = vbRed
          End If      
        Next j
      Next i

End Sub
``

1 Ответ

2 голосов
/ 27 октября 2019

Вы, кажется, смешиваете ИЛИ и И:

Цикл должен продолжаться, пока [...] ИЛИ [...] ИЛИ [...]

Вы на самом деле имеете в виду , чтобы сказать, что цикл должен заканчиваться , когда любое из этих трех условий не выполняется. Таким образом, логически цикл должен продолжать , в то время как все условий все еще выполняются. Это выражает логическое И, а не ИЛИ.

То есть вы имели в виду:

Do While (primzahl = True) And (k <= i * j) And (i * j <> 1)

Но это можно упростить.

Выражение primzahl = True всегда будет истиннымпотому что, как только вы установите primzahl = False, вы явно выйдете из цикла с помощью Exit Do, поэтому условие While никогда не будет оценено с помощью primzahl = False.

Во-вторых, если (i * j <> 1) равно true,первая итерация, это также будет верно для любой другой итерации, так как итерации не изменяются ни i, ни j. Но даже если бы это было верно в первый раз, то, конечно, k <= i * j равно , а не true (вы уже установили k = 2, и оно получает только большие значения), так что это условие всегда будет выполнено один разВы проходите условие k.

Итак, принимая это во внимание, вы получите:

k = 2
Do While k <= i * j
    ' etc..
    k = k + 1
Loop

И тогда почему бы не сделать это циклом For, так как вы позволяетеk перейти от 2 к i*j?

For k = 2 To i * j
    ' etc.. (don't do k = k + 1 now)
Next

Относительно задания, которое вы дали себе: числа, следующие из i * j с i и j, оба больше 1, по определению не простых чисел, поэтому нет смысла проверять их. Они имеют по крайней мере i и j в качестве делителей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...