Простая до цикла LBA в VBA - PullRequest
       5

Простая до цикла LBA в VBA

0 голосов
/ 05 января 2019

Я новичок в Excel VBA и у меня простой вопрос. Как только я пойму, как выполнить этот цикл, я смогу на нем опираться.

Я хотел бы автоматизировать классификацию. Данные повторяются в одном столбце, то есть sampleA, sampleA, sampleA, sampleB, sampleB, sampleC, sampleC, sampleC и т. Д. Я хотел бы, чтобы мой макрос определял, когда имя образца изменяется между именами образца. Так, например, когда следующая ячейка после sampleA превращается в sampleB, я бы хотел, чтобы макрос понял, что произошло изменение, и напишу рядом с ним фразу (это затем превратится в уравнение с данными в соответствующих строках образца но ребенок шагает :)).

В целом, макрос должен воспринимать изменения между столбцом идентичных имен образцов, пока не будет достигнуто новое имя.

Я исследовал решения, и цикл «до» кажется наиболее близким решением к тому, что мне нужно. Кроме того, чтобы показать, что sampleA не совпадает с sampleB, я использовал <>.

Sub DoUntilStringMacro()

Dim sampleA As String

Dim sampleB As String

Dim sampleC As String

Dim classification As String

    Do Until ActiveCell.Value = ""

        If sampleA <> sampleB Then
            classification = "hello"
        ElseIf sampleB <> sampleC Then
            classification = "goodbye"
        ElseIf sampleC <> sampleA Then
            classification = "see you soon"
        End If

        answer = classification
        Cells(classification, "B").Value = answer

    Loop

End Sub

Фактические результаты: ошибка в ячейках (классификация, "B"). Значение = ответ Что-то здесь не так. Я пытаюсь отобразить результаты в столбце "B".

Ожидаемые результаты на листе Excel в столбцах:

Sample:  Classification
sampleA  --
sampleA  --
sampleA  hello
sampleB  --
sampleB  goodbye
sampleC  --
sampleC  --
sampleC  see you soon

Ответы [ 3 ]

0 голосов
/ 05 января 2019
  1. Вы объявляете свои sampleA,B,C переменные, но никогда не устанавливаете их, поэтому при сравнении этих трех переменных ничего не происходит.

  2. Внутри вашего цикла вы никогда не устанавливаете ActiveCell на что-либо, поэтому ActiveCell остается неизменным. Вы будете зацикливаться из-за этого.

Вот переписывание, которое на самом деле не оптимизировано. Конечно, есть лучшие способы сделать это (например, использовать цикл for для Range("A1:A" & lastFilledRow)), но я хотел бы, чтобы это было довольно близко к вашей попытке увидеть, как решить эту проблему так, как вы планировали, поскольку это, безусловно, жизнеспособно и разумно. способ сделать это.

Я добавил тонну комментариев, чтобы объяснить, что происходит.

Sub DoUntilStringMacro()

    Dim currentValue As String
    Dim previousValue As String
    Dim classification As String

    'set the first cell to search and we will iterate
    '   from there
    Dim searchCell As Range
    Set searchCell = Sheet1.Range("A2")

    'Lets also get a counter variable to see how many
    '   times we've found a change...
    Dim changesFound As Integer

    'Loop until the searchCell is empty
    Do Until searchCell.Value = ""


        'set the currentValue
        currentValue = searchCell.Value

        'If the previousValue variable is empty then
        '   this is the first cell we're analyzing
        '   so don't bother running this bit of code
        '   that does the comparison
        If previousValue <> "" Then

            'Compare to what we stored in previousValue
            If currentValue <> previousValue Then
                'We found a change, increment our counter
                changesFound = changesFound + 1

                'and based on that value lets figure out
                '   what to write out
                Select Case changesFound
                    Case 1
                        'This is the first time we hit a
                        '   a change so write out "hello"
                        'BUT!!! we need to write it the
                        '   cell above the current
                        '   searchCell and one column over
                        '   We'll use .Offset() to do that
                        searchCell.Offset(-1, 1).Value = "Hello"
                    Case 2
                        searchCell.Offset(-1, 1).Value = "goodbye"
                    Case 3
                        searchCell.Offset(-1, 1).Value = "see you soon"
                End Select

            End If
        End If

        'So we are going to iterate again, lets capture
        '   the currentValue into the previousValue
        '   variable so we have it to compare on the
        '   the next loop
        previousValue = currentValue

        'Also... we want to make sure that searchCell
        '   is the next cell otherwise we will just
        '   keep testing the same cell over and over
        '   again until excel crashes.
        'Again we'll use `.Offset()` to move to the
        '   next row
        Set searchCell = searchCell.Offset(1)

    Loop

    'Heres the kicker... we needed one more iteration
    '   since we exited when the searchCell was blank... 
    '   so that Case 3 never hit... 
    '   we'll just go ahead and fill that out now
    searchCell.Offset(-1, 1).Value = "See you soon"

End Sub

Я покончил с ActiveCell, так как это не очень хорошая идея. Select, Activate, ActiveCell это все дерьмовые выстрелы в VBA. Лучше сказать «Явно эта ячейка / диапазон - это то, что я хочу», а не надеяться, что ячейка, которую вы хотите, активна в данный момент.

0 голосов
/ 05 января 2019

Вы можете использовать формулы и избегать циклов:

Sub IdentifySampleNameChanges()
    With Worksheets("Sheet1") ‘ change “Sheet1” to your actual sheet name
          With .Range("A2", .Cells(.Rows.Count, "A").End(xlUp)).Offset(, 1)
             .Formula = "=IF(A2<>A3,""Hello"","""")"
             .Value = .Value
        End With 
    End With 
End Sub
0 голосов
/ 05 января 2019

Вы можете попробовать цикл For:

Option Explicit

Sub Change()

    Dim Lastrow As Long, Row As Long
    Dim PreviousString As String, CurrenctString As String

    'With statement refers to shee 1
    With ThisWorkbook.Worksheets("Sheet1")
        'Find last row in Sheet 1 - Column A
         Lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
        'Loop each row start from 3 to lastrow
        For Row = 3 To Lastrow
            PreviousString = .Range("A" & Row - 1).Value
            CurrenctString = .Range("A" & Row).Value

            'Check if both strings are not the same
            If PreviousString <> CurrenctString Then
                If PreviousString = "sampleA" And CurrenctString = "sampleB" Then
                    .Range("B" & Row - 1).Value = "hello"
                ElseIf PreviousString = "sampleB" And CurrenctString = "sampleC" Then
                    .Range("B" & Row - 1).Value = "goodbye"
                ElseIf PreviousString = "sampleC" And CurrenctString = "sampleD" Then
                    .Range("B" & Row - 1).Value = "see you soon"
                End If

            End If

        Next Row

    End With


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