Забарвлення клітини однозначно в кожному рядку


1

Я хочу розфарбувати дані в аркушах Excel:

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

Наведений нижче код перебирає всі дані в перших 10 рядках і по-різному позначає кожну клітинку. Я не впевнений, як запам'ятати кольорові клітини та їх кольори на цьому шляху, і застосувати цей колір замість нового кольору, якщо поточну клітинку запам'ятовують у списку вже для цього рядка.

Чи є щось, що можна використовувати як динамічний список у vba, і як?

Sub Test1()

    Dim x As Integer, rowInt As Integer, color As Integer
    Application.ScreenUpdating = False

    For rowInt = 1 To 10
        color = 3

        'numRows = number of cells before the first blank cell in the row ("A" & rowInt)
        numRows = Range("A" & rowInt, Range("A" & rowInt).End(xlToRight)).Columns.Count
        If numRows >= 16384 Then
            numRows = 1
        End If

        Range("A" & rowInt).Select
        For x = 1 To numRows

            With Selection.Interior
                .ColorIndex = color
                .Pattern = xlSolid
            End With

            color = color + 1

            ActiveCell.Offset(0, 1).Select
        Next
    Next

    Application.ScreenUpdating = True

End Sub

Відповіді:


1

Ви можете використовувати словник для захоплення індексу кольору для унікальних значень


Option Explicit

Public Sub ColorUniquesByRows()
    Const START_ROW = 2
    Dim ur As Range, arr As Variant, clrIndex As Long, i As Long, j As Long, ci As Long
    Dim cArr As Variant, r As Long, g As Long, b As Long, a As Double, d As Object

    Set ur = Sheet1.UsedRange   'Or ThisWorkbook.Worksheets("Sheet1").UsedRange
    Set d = CreateObject("Scripting.Dictionary")
    Application.ScreenUpdating = False
    arr = ur
    clrIndex = 3
    For i = START_ROW To UBound(arr)            'Iterate each row
        For j = 1 To UBound(arr, 2)             'Iterate each column (in current row)
            If Len(arr(i, j)) > 0 Then          'Ignore empty cells
                If Not d.Exists(arr(i, j)) Then 'Capture color index for each unique value
                    If clrIndex > 56 Then clrIndex = 3  'More than 56 columns - reset indx
                    ci = ThisWorkbook.Colors(clrIndex)  'Determine font color vs clr index
                    r = ci Mod 256: g = ci \ 256 Mod 256:   b = ci \ 65536 Mod 256
                    a = 1 - ((0.299 * r) + (0.587 * g) + (0.144 * b)) / 255
                    d(arr(i, j)) = clrIndex & " " & IIf(a < 0.5, vbBlack, vbWhite)
                    clrIndex = clrIndex + 1
                End If
                cArr = Split(d(arr(i, j)))
                With ur.Cells(i, j)
                    .Interior.colorIndex = cArr(0)
                    .Font.Color = cArr(1)
                End With
            End If
        Next j
        clrIndex = 3    'moving to next row: reset color index and dictionary object
        Set d = CreateObject("Scripting.Dictionary")
    Next i
    Application.ScreenUpdating = True
End Sub

Примітка: Це також визначає колір шрифту на основі кольору фону


Результат

Sheet1


1
Дякуємо, просто зауважте, що ваш код працює над стовпцями, а не рядками - чи можете ви редагувати свою відповідь, щоб відповідати на запитання, щоб я міг прийняти її.
Vepir

1
Я прийняв вашу відповідь, не запускаючи її самостійно (оскільки я вже впровадив модифіковану версію вашої попередньої версії відповіді), але після того, як побачив ваші результати зараз, я думаю, ви неправильно зробили це питання. Кожен рядок слід обробляти окремо. Наприклад, у вашій таблиці результатів, на основі цих значень, це означає, що col 1 буде червоним, col 2 буде зеленим, і т. Д. Оскільки кожен рядок слід розглядати як власний випадок унікальних значень. - Я не буду неприйнятне відповідь, але ви повинні виправити відповідь, щоб відповідати на запитання. Крім того, я думаю, що сценарій не повинен продовжувати кольору порожніх клітинок у рядку.
Vepir

1
Ваш останній коментар зробив це більш зрозумілим - я оновив відповідь. Як примітка, попередня версія продовжувала пофарбовувати порожні клітинки, тому що UsedRange на вашому аркуші містив порожні клітинки; це означає, що ці клітини містили дані або форматування в певний момент, але тепер не використовуються. Я оновлював сценарій, щоб ігнорувати порожні клітинки на всякий випадок, але ви можете видалити додаткові рядки (або стовпці), якщо вони не потрібні. Щоб визначити, що Excel вважає "UsedRange", натисніть Ctrl + End і він вибере останню Використовувану клітку на аркуші
paul bica

Дякуємо за записку, яка була використана.
Vepir
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.