Макрос Excel VBA дает неожиданные результаты?

#excel #vba

#excel #vba

Вопрос:

У меня есть макрос, который перебирает лист (Лист4) для размещения данных на другом листе (Ark7). Переменная ‘rKvartal’ представляет собой текстовую строку, полученную с третьего листа (Ark4). Только если выполнены два критерия во внешнем цикле, он перейдет во внутренний цикл. Эта часть работает. Моя проблема в том, что макрос перечисляет данные из внутреннего цикла, которые не меньше или равны переменной ‘rKvartal’. (Это должно быть сделано в макросе) Макросы выглядят так:

 Dim C, C2 As Range
Dim rKvartal As String


Application.ScreenUpdating = False

    Ark7.Columns("B:F").ClearContents
    
    cValOffset = 101
    cVal = 2 'row# where data in rLog (ark7) goes to
    rKvartal = Sheet3.Range("AP24") 'Criteria to filter data
    
    'Create headers for use in the list being created
    Ark7.Cells(1, 2).Value = "ID"
    Ark7.Cells(1, 3).Value = "Sansynlighed"
    Ark7.Cells(1, 4).Value = "Konsekvens"
    Ark7.Cells(1, 5).Value = "Sum"
    Ark7.Cells(1, 6).Value = "Kvartal"
    
    For Each C In Sheet4.Range("W15:W114")
        If C = "Risk" Or C = "Occured" Then
            For Each C2 In Sheet4.Range("K15:K114")
                    If C2 <= rKvartal Then
                        'All cells that are either a risk or occured and that is less than or equal to e.g Q4 2021
                        Ark7.Cells(cVal, 2).Value = C.Offset(0, -21).Value
                        Ark7.Cells(cVal, 3).Value = C.Offset(0, -15).Value
                        Ark7.Cells(cVal, 4).Value = C.Offset(0, -14).Value
                        Ark7.Cells(cVal, 5).Value = C.Offset(0, -13).Value
                        Ark7.Cells(cVal, 6).Value = C.Offset(0, -12).Value
                        cVal = cVal   1
                        Exit For
                    End If
            Next C2
        End If
    Next C
    
    ActiveWorkbook.Worksheets("rLog").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("rLog").Sort.SortFields.Add2 key:=Range("E2"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
        With ActiveWorkbook.Worksheets("rLog").Sort
            .SetRange Range("B2:F100")
            .Header = xlNo
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With
        
    Ark7.Activate
    Ark7.Range(Cells(1, 2), Cells(8, 6)).Select 
    Application.CutCopyMode = False
    ActiveSheet.ListObjects.Add(xlSrcRange, Ark7.Range(Cells(1, 2), Cells(8, 6)), , xlYes).Name = "RisikoSorteret" 'Laver en tabel eller liste
    ActiveSheet.ListObjects("RisikoSorteret").TableStyle = "Tabeltypografi 3" 'Giver listen en typografi
End Sub
 

Данные . неожиданный результат

Источник данных

Ответ №1:

rKvartal является строковой переменной, поэтому числовые сравнения («меньше» или «больше») не будут работать, поскольку они работают только с числами и датами.
Если текстовая строка rKvartal означает числовое значение или значение даты, рассмотрите возможность использования CDec() или CDate() для получения этого значения. В качестве альтернативы, если Sheet3.Range("AP24") будет содержать число или дату, а не текст, просто измените тип переменной;

 'Change
Dim rKvartal As String

'To any one of the below:
Dim rKvartal as Long     'Integer
Dim rKvartal as Date     'Date
Dim rKvartal as Double   'Decimal
 

Комментарии:

1. Да, я попытался уменьшить значение ‘rKvartal’ до даты, а представление ‘Sheet3.Range («AP24»)’ действительно является датой, но результат, к сожалению, все тот же…

2. что вы имеете в виду под «представлением»? Имеет ли ячейка значение даты в Excel или просто текст, который означает дату? (чтобы узнать, попробуйте изменить формат номера ячейки; если это позволит вам перейти в другие форматы, такие как короткая дата, длинная дата или числовое значение, это значение даты; если нет, это текст).

3. Если значение ячейки является текстом, а не значением даты, вам нужно будет изменить rKvartal = Sheet3.Range("AP24") на rKvartal = CDate(Sheet3.Range("AP24"))

4. Ячейка в sheet3.range («AP23») является неформатированной датой, поэтому она представлена числом, например, 44105 на 1 октября 2020 года. Переменная C2 в таблице источника данных также представляет собой неформатированную дату, представленную в виде числа — поэтому в моей книге я сравниваю яблоки-яблоки, поскольку пошаговое выполнение кода показывает мне 44105 <= 44105 —> несмотря на это, я все равно получаю тот же результат.

5. Хорошо — единственное, что я могу предложить, это продолжить пошаговое выполнение кода, пока он не начнет выполнять неправильные действия, и в этот момент проверьте переменные, чтобы увидеть, что не так. Вероятно, вы захотите прокомментировать ‘application.screenupdating = false’, чтобы вы могли видеть, что происходит на листе. Я изо всех сил пытаюсь определить что-нибудь еще, что должно заставить этот код дать неожиданный результат.

Ответ №2:

Я сам это понял. Внутренний цикл был избыточным. Ему просто нужны были критерии, а не другой цикл:

     For Each C In Sheet4.Range("W15:W114")
        If C = "Risiko" Or C = "Indtraf" Then
            If C.Offset(0, 1).Value <= rKvartal Then
                'Alle risici der opfylder kriterierne
                Ark7.Cells(cVal, 2).Value = C.Offset(0, -21).Value
                Ark7.Cells(cVal, 3).Value = C.Offset(0, -15).Value
                Ark7.Cells(cVal, 4).Value = C.Offset(0, -14).Value
                Ark7.Cells(cVal, 5).Value = C.Offset(0, -13).Value
                Ark7.Cells(cVal, 6).Value = C.Offset(0, 1).Value
                cVal = cVal   1
            End If
        End If
    Next C