2016-08-10 3 views
1

Введениефильтры сценария Excel VBA заголовок неожиданно

У меня есть некоторые таблицы, как в следующем.

original data after script execution

Вот заголовок на строках 16 и 17. Существует «заголовок» влево (не показан), среди предыдущих строк и столбцов, которые включает в себя картину, некоторые не табличные данные, а легенда и т. д., что здесь неважно. Текст заголовка в строке 16 обфускается, потому что причинам. Данные, выделенные жирным красным цветом, указывают на то, что эта точка выборки претерпела некоторый процесс. Вот фрагмент кода из сценария, который выделяет эти точки данных жирным красным цветом.

' Traverse columns applying redding until hitting the row end, Comment, or SpGr: whichever comes first 
For currIndex = abcDateCol + 1 To lastCol 
    ' Check for exit conditions: 
    If Cells(abcDateRowDesc, currIndex).Value() = "Comments" Then Exit For 

    If Cells(abcDateRowDesc, currIndex).Value() <> "" Then 
    If Cells(abcDateRowDesc, currIndex + 1).Value() = "process" Then 
     ' Looks like we have a column of something Red-able 
     Columns(ColumnLetter(currIndex) & ":" & ColumnLetter(currIndex + 1)).Select 
     Selection.AutoFilter ' Turn on autofiltering (hopefully) 
     Selection.AutoFilter Field:=2, Criteria1:="=1", Operator:=xlOr, Criteria2:="=e" 
     Selection.Font.ColorIndex = 3 
     Selection.Font.Bold = True 
     Selection.AutoFilter ' Turn off autofiltering 
     Columns(ColumnLetter(currIndex + 1) & ":" & ColumnLetter(currIndex + 1)).EntireColumn.Delete Shift:=xlToLeft 
    End If 
    End If 
Next currIndex 

Контекст

Здесь abcDateCol относится к колонку АЕ, lastCol относится к колонку AQ, abcDateRow (не показаны, но доступны) и abcDateRowDesc относятся к строкам заголовка 16 и 17 соответственно, а ColumnLetter Функция - это определяемая пользователем функция, которая возвращает удобочитаемое письмо (-ы) для чтения с учетом номера столбца; это общая функциональность, которую вы, возможно, видели в другом месте или даже сделали сами.

Продолжим

Ничего, что условие в If Cells(abcDateRowDesc, currIndex).Value() = "Comments" никогда не удовлетворяется из-за оплошности (я предполагаю, что) - два разных строках, гарантировано.

Давайте посмотрим, как выглядит таблица, прежде чем этот скрипт будет выполнен.

original data before script execution

Итак, сценарий принимает пары столбцов, и для каждой пары столбцов она отмечает ячейки данных жирного шрифта красных, если правые соседние соты ячейки данных имеют 1 (или «е»?) (как логическое, отвечает на вопрос: «Была ли эта точка примера обработана каким-либо процессом?»), а затем удаляет столбец «процесс».

Проблема

клиент хочет безвозмездный заголовок ушел, так что они могут легко импортировать таблицу в любое решение у них есть. Удалите строки с 1 по 15, и это то, что я получаю.

enter image description here

Что в bleepity-звуковым сигналом случилось с головой? Я не понимаю, как подсвечивается эта первая строка. Это кажется слишком странным. Теперь перейдем к первой таблице.

enter image description here

Я заполнил «заголовок» с некоторым фиктивным текстом после скрипта, который выполняется. Ничего себе, первый ряд снова покраснел, на этот раз ad infinitum! Итак, эта проблема всегда существовала. О, и в первом столбце тоже! И он волшебным образом останавливается прямо над правильным заголовком, поэтому мы никогда его не увидим.

Вопросы,

Почему этот сценарий неожиданно покраснев первую строку и столбец? Можно ли это легко решить, или я смотрю на какую-то переписку? Если да, укажите мне в общем направлении.

Это помогает упомянуть, что эти электронные таблицы создаются из приложения Windows, а их сценарии выполняются до того, как пользователь имеет копию своей электронной таблицы. Кроме того, что касается второго изображения (таблица с показанными столбцами «процесс»), эта таблица не является тем, что обычно существует. Я создал его для этого сообщения, пропустив цикл сценария for. Приложение использует выбранный шаблон электронной таблицы, который выглядит одинаково за вычетом данных, заполняет образцы данных и затем выполняет несколько сценариев над данными.

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

Примечание

Я не являюсь автором этого сценария (или любой из VBA моей компании!). Я рассматриваю это налог на наследство, взимаемый с меня.

* Обновление

меня спросили, я проследил по этому коду. Прошу прощения, что я не включил эту информацию в свой первоначальный пост. Вот что я знаю. Selection.Font.ColorIndex = 3 превращает ячейки в выборку, которые удовлетворяют автофильтру плюс первая строка (две ячейки, так как в данный момент выбираются только два столбца), а Selection.Font.Bold = True делает одинаковые ячейки жирным шрифтом тем же способом. Я подозреваю, что это имеет какое-то отношение к автофильтру, поэтому я собираюсь взглянуть на ответы сейчас.

+1

(a) Пробовали ли вы пропустить код по одной строке за раз, чтобы определить, какая строка кода вызывает изменение этих ячеек на красный? (b) Вы проверили, что ячейки, которые стали красными, не стали красными из-за условного форматирования? например если в ячейке AG16 был установлен условный формат, который устанавливает ячейку в красный цвет, если '= 0 = IFERROR (IF (AG15 =« XYZ », 0,1), 0)», тогда он станет красным, когда ячейка переместится с AG16 на AG1. (Я просто делаю этот тест, исключительно для того, чтобы подчеркнуть, что сдвигающие ячейки могут привести к форматированию условного формата.) – YowE3K

+0

Сначала я отвечу ** b **. Ни один из листов шаблонов не имеет условных правил форматирования. Я рад, что вы упомянули об этом, поскольку я не проверял ранее. Что касается ** a **, я пытаюсь сделать свою часть, прежде чем я попрошу сообщество помочь. Да, я проследил, я отредактирую свой пост, чтобы включить эту информацию, чтобы у меня не было смехотворно длинного комментария. Должен бежать, поэтому я буду редактировать дома или завтра утром. Еще раз спасибо. – jefff

+0

Как раз перед выходом из системы, я вижу, что есть ответ. Я буду копаться в нем завтра, но, учитывая мое отслеживание, я подозревал, что это связано с автофильтром. – jefff

ответ

1

вот (комментарий) рефакторинга кода, который должен сделать:

Option Explicit 

Sub main() 
    Dim abcDateCol As Long, lastCol As Long, abcDateRow As Long, abcDateRowDesc As Long, currIndex As Long 

    abcDateCol = 31 
    lastCol = 43 
    abcDateRow = 16 '<--| you can change it to 1 for the last "scenario" 
    abcDateRowDesc = 17 '<--| you can change it to 2 for the last "scenario" 


    For currIndex = abcDateCol + 1 To lastCol '<--| loop through columns 
     With Cells(abcDateRow, currIndex) '<--| refer to cell in current column on row abcDateRow 
      If .Value = "Comments" Then Exit For '<--| Check for exit conditions on row 'abcDateRow' 

      If .Offset(1).Value <> "" And .Offset(1, 1).Value = "process" Then '<--| Check for processing conditions on row 'abcDateRowDesc' 
       With .Resize(.Offset(, 1).End(xlDown).Row - .Row + 1, 2) '<-- consider the range from current referenced cell 1 column to the right and down to last 'process' number/letter 
        .AutoFilter Field:=2, Criteria1:="=1", Operator:=xlOr, Criteria2:="=e" '<--| filter on "process" field with "1" or "e" 
        If Application.WorksheetFunction.Subtotal(103, .Cells.Resize(, 1)) > 1 Then '<--| if any values match... 
         With .Offset(2).Resize(.Rows.Count - 2, 1).SpecialCells(xlCellTypeVisible).Font '<--|... consider only filtered values skipping headers (2 rows), and apply formatting 
          .ColorIndex = 3 
          .Bold = True 
         End With 
        End If 
        .AutoFilter '<-- reset autofilter 
        .Resize(, 1).Offset(, 1).EntireColumn.Delete Shift:=xlToLeft '<-- delete the "2nd" column (i.e. one column offsetted to the right) 
       End With 
      End If 
     End With 
    Next currIndex 
End Sub 

были две ошибки в вашей «унаследованной» код:

  • If Cells(abcDateRowDesc, currIndex).Value() = "Comments" Then Exit For было упоминаться abcDateRow индекс строка вместо

  • форматирование будет применяться ко всем ячейкам, были ли они отфильтрованы (сопоставлены) или нет

+0

Победитель, курица ужин. Это решение сработало для моего случая, и я испытал его на всех моих других электронных таблицах с успехом. Я все еще мысленно пережевываю некоторые детали вашего решения. Ваш первый пункт, о котором я знал (я упомянул об этом в разделе ** Let's Continue **). Это свойство автофильтра кажется слишком странным для моих вкусов. – jefff

+0

Да, странно, но весьма полезно. Рад видеть, что это помогло. Хорошая кодировка! – user3598756

3

Это изменение должны исправить ваши проблемы, мы надеюсь (они сделали для моего ремейка таблицы, но мы не будем знать, пока вы примерить реальную вещь)

' Traverse columns applying redding until hitting the row end, Comment, or SpGr: whichever comes first 
For currIndex = abcDateCol + 1 To lastCol 
    ' Check for exit conditions: 
    If Cells(abcDateRowDesc, currIndex).Value() = "Comments" Then Exit For 

    If Cells(abcDateRowDesc, currIndex).Value() <> "" Then 
     If Cells(abcDateRowDesc, currIndex + 1).Value() = "process" Then 
      ' Looks like we have a column of something Red-able 
      'Columns(ColumnLetter(currIndex) & ":" & ColumnLetter(currIndex + 1)).Select 
      With Range(Cells(abcDateRowDesc, currIndex), Cells(abcDateRowDesc, currIndex + 1).End(xlDown)) 
       .AutoFilter 2, "=1", xlOr, "=e" 
       ' Don't format header 
       With .Offset(1, 0).Resize(.Rows.Count - 1, .Columns.Count)       .Font.ColorIndex = 3 
        .Font.Bold = True 
        .AutoFilter ' Turn off autofiltering 
       End With 
      End With 
      Columns(currIndex + 1).Delete xlShiftLeft 
     End If 
    End If 
Next currIndex 

Это все начинается с причудой как код выбирает свой диапазон для автофильтра. Выбранная область - это полный столбец, а не область, которую вы действительно хотите отформатировать (строка 18 до последней записи). Кажется, что автофильтр в полном столбце с пустыми верхними строками автоматически устанавливает первую непустую строку в качестве строки заголовка. Таким образом, заголовок остается нефильтрованным/не скрытым инструкцией, и он окрашивается как часть полного выбора столбца. Вот почему ваши заголовки становятся цветными.

Теперь, если вы попытались протестировать это, поместив данные в указанные выше пустые строки, такие как «a», эти значения станут первыми в столбце и будут выбраны в качестве заголовков, то есть те значения получают цветные , Независимо от того, что находится в первой непустой строке ваших столбцов, будет заголовок автофильтра и будет окрашен.

Но это должно влиять только на столбцы, которые вы явно окрашивали, а не на всю первую строку, не так ли? Проблема здесь в том, что Excel любит делать предположения о данных, чтобы сэкономить время. Поэтому, если у вас есть целая строка, полная красного, жирного «a» и рядом с ними вы помещаете еще один «а», чтобы проверить, отформатирована ли эта ячейка или нет ...ну, он автоматически дает вам красный, полужирный «a», несмотря на то, что ранее неформатированная ячейка! И если вы продолжаете идти по строке таким образом, это будет выглядеть так, как вся ваша строка была отформатирована. Но, если вам нужно перепрыгнуть через несколько столбцов (например, 5-иш) и войти в другую «а», вуалу, она неформатирована, и любые «а», которые вы ставите рядом с ней, тоже будут. Вы также можете проверить, что Excel, удалив неформатированный «a» в удаленном столбце, а затем продолжайте вводить «a» до конца, пока не дойдете до той же самой ячейки - на этот раз, «a» будет красным и жирным, потому что все остальные в строке тоже были, хотя мы только что проверили, что это неформатированная ячейка!

В принципе, неправильный диапазон для вашего автофильтра делался очень неожиданно, а затем попытался протестировать проблему форматирования, введя значения, которые сделали все менее ясным. Код, который я предоставил, просто автофильтрует соответствующую область (строка 17 до последней смежной строки), фиксируя основную проблему.

+0

++ для подробного ответа. Большие усилия. – cyboashu

+1

Это решение не работает в моем случае. Как ни странно, он красновато украсил второй ряд, ряд знаков «mille_». Я не мог даже выработать решение, изменив некоторые из них. Однако мне понравился более аккуратный код и удаление ненужного использования 'ColumnLetter'. Это также помогло мне лучше понять мою проблему. SO указывает на вас. – jefff

+1

@jefff Это потому, что вторая строка была частью объекта «С» - я ожидал, что она будет окрашена. Код теперь редактируется, чтобы учесть это и удалить его из форматирования. – Mikegrann

Смежные вопросы