VBA Excel IsError в пределах проблем l oop - PullRequest
0 голосов
/ 06 апреля 2020

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

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

Я начал с определения MyList как диапазона ячеек, с которым я хочу сравнивать данные из другой лист. Затем я устанавливаю другие переменные, которые в конечном итоге меняю, когда масштабирую это. Затем я удаляю существующее условное форматирование из всей книги, так как мне это не понадобится, как только я все это заработаю. Затем я активирую рабочую таблицу, над которой хочу работать. Кажется, что для l oop работает нормально. У меня настроены часы для переменной NB, и я вижу, что это обновление корректно для каждого l oop. Проблема, с которой я сталкиваюсь, заключается в том, что независимо от того, что я делаю с IsError (Match ()), он никогда не обновляется с каждой итерацией для l oop. Таким образом, он либо остается на false все время и окрашивает каждую строку в таблице, либо остается на true все время и ничего не окрашивает (в зависимости от того, какое расположение кода я пробую).

Я сделал кучу Google ищет и читает и не может найти нужную информацию, чтобы выяснить, как это исправить. Пытаюсь ли я использовать то, что мне не следует, или я не правильно что-то определяю? Что еще мне не хватает?

Я новичок в VBA и практически не занимался программированием в течение ряда лет. Таким образом, в дополнение к исправлению этого я действительно заинтересован в причинах этого, поэтому я надеюсь, что не буду повторять эти ошибки.

Set MyList = Worksheets("Sheet1").Range("A1", "A500")
Dim NBcol As Integer, MZcol As Integer, blcol As Integer, NB As String
NBcol = 13
MZcol = 16
blcol = 12

Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
    ws.Cells.FormatConditions.Delete
Next ws

Worksheets("Sheet2").Activate
For i = 7 To 26
    NB = Left(Cells(i, NBcol), 6)
    If Not IsError(Application.Match(NB, MyList, 0)) Then
        If Cells(i, MZcol) >= 3.5 Then
            ActiveSheet.Range(Cells(i, blcol), Cells(i, MZcol)).Interior.Color = RGB(250, 191, 143)
        Else
            ActiveSheet.Range(Cells(i, blcol), Cells(i, MZcol)).Interior.Color = RGB(197, 217, 241)
        End If
    Else
    End If
Next i

1 Ответ

0 голосов
/ 07 апреля 2020

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

  1. Попробуйте избегать"маги c чисел". Создайте константу, используя имя, которое описывает , почему число существует.
  2. Постарайтесь сохранить логику верхнего уровня c "читабельной". Если вы можете создать автономный блок кода, который встречается только один раз или повторяется, он может более четко показать «поток» вашей логики c.
  3. Establi sh «рабочие» переменные которые используют имена, тесно связанные с данными или типом операции, с которой вы работаете. В этом случае я показываю три объекта листа. Вы должны выбрать имена, которые имеют значение для вас и вашего приложения.
  4. Всегда полностью квалифицируйте ваши ссылки на листы .

Вот код:

Option Explicit

Private Const NBcol As Long = 13
Private Const MZcol As Long = 16
Private Const BLcol As Long = 12

Sub CompareMyDataExample()

    ClearAllConditionalFormats

    Dim listWS As Worksheet
    Dim dataWS As Worksheet
    Dim infoWS As Worksheet
    Set listWS = ThisWorkbook.Sheet1
    Set dataWS = ThisWorkbook.Sheets("My Data")
    Set infoWS = ThisWorkbook.Sheet2

    Const START_ROW As Long = 7
    Const END_ROW As Long = 26

    Dim myList As Range
    Dim lastRow As Long
    With listWS
        lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
        Set myList = .Range("A1").Resize(lastRow, 1)
    End With

    Dim i As Long
    For i = START_ROW To END_ROW
        Dim nb As Long
        nb = infoWS.Cells(i, NBcol).Value
        If Not IsError(Application.Match(nb, myList, 0)) Then
            If infoWS.Cells(i, MZcol).Value >= 3.5 Then
                '--- always include ALL worksheet references with every
                '    reference to a part of a worksheet
                infoWS.Range(infoWS.Cells(i, BLcol), infoWS.Cells(i, MZcol)).Interior.Color = RGB(250, 191, 143)
            Else
                '--- as an alternative, you can set up a "with" block
                '    but ALWAYS remember to use the "." to make sure it
                '    links back to the "with" block reference
                With infoWS
                    .Range(.Cells(i, BLcol), .Cells(i, MZcol)).Interior.Color = RGB(197, 217, 241)
                End With
            End If
        End If
    Next i

End Sub

Private Sub ClearAllConditionalFormats()
    Dim ws As Worksheet
    For Each ws In ThisWorkbook.Worksheets
        ws.Cells.FormatConditions.Delete
    Next ws
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...