2015-02-27 5 views
0

Я работаю в объекте таблицы, и мне нужно значение -измерять или удалять строки данных на основе уникального ссылочного столбца. Проблема состоит в том, что эти данные разбиваются на не-непрерывные столбцы. Я, вероятно, следует показать именно то, что я пытаюсь сделать:VBA Excel - Непрерывные ячейки в той же строке, по строкам

For Each i In Range("Table1[#Headers]") 
    If i = "REF" Then 
     For Each j In Range("Table1[" & i & "]") 
      If j <> j.Offset(-1, 0) Then 
       Range("Table1[[#All],[COL01]]").Cells(j.Row, 1) = val(Range("Table1[[#All],[COL01]]").Cells(j.Row, 1)) 
       Range("Table1[[#All],[COL05]]").Cells(j.Row, 1) = val(Range("Table1[[#All],[COL05]]").Cells(j.Row, 1)) 
'etc.... 
      Else: 
       Range("Table1[[#All],[COL01]]").Cells(j.Row, 1).ClearContents 
       Range("Table1[[#All],[COL05]]").Cells(j.Row, 1).ClearContents 
'etc.... 
      End If 
     Next j 
     Exit For 
    End If 
Next i 

Это находит столбец «REF», который сортируется и имеет кратные одного и того же значения, определяет начало каждого набора одинаковых значений {j <> j.Offset(-1, 0)} , и если j действительно является началом набора, он смотрит на другой столбец в той же строке и делает на нем val(), эффективно превращая пробелы в нули. В противном случае он очистит содержимое этой ячейки ...

Проблема. У меня есть много столбцов типа «COL», с которыми вы работаете, и они не всегда непрерывны, а строки в этих данных таблица составляет 10 000+; весь процесс берет навсегда. Есть ли способ сделать диапазон Union(), который не является кошмаром для записи? Может быть, используя массивы/словарь/что-то? Любая помощь могла бы быть полезна.

+1

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

+0

Не могли бы вы привести пример того, что вы имеете в виду? Массивы для меня новы ... –

+1

Вы можете начать с обсуждения Chip Pearson [VBA Arrays and Worksheet Ranges] (http://www.cpearson.com/Excel/ArraysAndRanges.aspx) –

ответ

0

Хорошо мне удалось найти ответ, используя собственные диапазоны и Intersect()

Вот код, который я придумал:

Dim Rng As Range 

For Each i_1 In Range("Table1[#Headers]") 
    If i_1 = "REF" Then 
     For Each j_1 In Range("Table1[#Headers]") 
      If InStr(1, "COL01|COL05|...|...|...", j_1) <> 0 Then 
       If Rng Is Nothing Then 
        Set Rng = Range("Table1[[#All],[" & j_1 & "]]") 
       Else: 
        Set Rng = Union(Rng, Range("Table1[[#All],[" & j_1 & "]]")) 
       End If 
      End If 
     Next j_1 
     For Each j_2 In Range("Table1[" & i_1 & "]") 
      If j_2 <> j_2.Offset(-1, 0) Then 
       Intersect(Rng, Rows(j_2.Row)).SpecialCells(xlCellTypeBlanks).Value = 0 
      Else: 
       Intersect(Rng, Rows(j_2.Row)).ClearContents 
      End If 
     Next j_2 
    Exit For 
    End If 
Next i_1 

Смотрите, как только он находит "REF" колонку, он устанавливает все необходимые столбцов в диапазон Union(). Затем он пересекает эти столбцы с каждой строкой в ​​Table1 через другой цикл с собственными условиями. Если вы можете найти лучший способ создать это, дайте мне знать, но я обнаружил, что это значительно сокращает время обработки.

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