Страницы: 1
RSS
[ Закрыто ] Горизонтальный автофильтр и управляемая раскраска таблицы
 
Здравствуйте ужаваемые специалисты.
Помогите поправить макрос.

Есть макрос, который по определенной схеме формирует таблицу (на листе Лист1), в которой горизонтальная и вертикальная шапки - имеют иерархическую структуру. Также макрос закрашивает поочередно столбцы в обеих шапках, чередуя цвета.

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

Как сделать фильтр таблицы - для горизонтальной шапки (в ячейках К10 и К11) ?
Как изменить макрос, чтобы если рядом с ячейкой иерархии (в исходных данных) стоит "1" - то цвет не повторялся бы в пределах одной иерархии ?
 
а почему таблицы пустые - где примеры данных в исходной и результирующей таблицах?
 
nilske, так там самое главное - это создание шапок, а не заполнение данных.
Сама таблица будет пустой.
Исходной таблицы не существует.
Исходные данные - это две строки с описанием иерархии шапок.
Изменено: Dalm - 25.08.2026 09:14:29
 
Макрос для горизонтального фильтра.
Выделите ячейку в диапазоне L11:N11, запустите макрос.
Код
Option Explicit

Sub Горизонтальный_фильтр()
    Dim clLeft As Range, clRigh As Range, rnHide As Range
    Set clLeft = ActiveCell
    Dim thisFilterValueAlreadySet As Boolean
    thisFilterValueAlreadySet = GetThisFilterValueAlreadySet(clLeft)
    Range("K1").Resize(1, ActiveSheet.UsedRange.Columns.count).EntireColumn.Hidden = False
    If thisFilterValueAlreadySet Then Exit Sub
    Set clRigh = clLeft.EntireRow.Cells(1, Columns.count).End(xlToLeft)
    If clLeft.Column >= clRigh.Column Then Exit Sub
    
    Set rnHide = Range(clLeft.Cells(1, 2), clRigh)
    
    If WorksheetFunction.CountIfs(rnHide, clLeft) = 0 Then Exit Sub
    
    Application.ScreenUpdating = False
    
    If clLeft.Column > Range("K1").Column + 1 Then
        Range(Range("K1").Cells(1, 2), clLeft.Cells(1, 0)).EntireColumn.Hidden = True
    End If
    
    Dim xLeft As Long, xRigh As Long
    For xLeft = 1 To rnHide.Columns.count
        For xRigh = xLeft + 1 To rnHide.Columns.count + 1
            If rnHide.Cells(1, xRigh).Value = clLeft.Value Then Exit For
        Next
        xRigh = xRigh - 1
        If xLeft <= xRigh Then
            Range(rnHide.Cells(1, xLeft), rnHide.Cells(1, xRigh)).EntireColumn.Hidden = True
            xLeft = xRigh + 1
        End If
    Next
    Application.ScreenUpdating = True
End Sub

Private Function GetThisFilterValueAlreadySet(clLeft As Range) As Boolean
    Dim xx As Long
    For xx = 2 To clLeft.Parent.UsedRange.Columns.count
        With clLeft.Cells(1, xx)
            If .EntireColumn.Hidden = False Then
                If Not IsEmpty(.Value) Then
                    If .Value <> clLeft.Value Then
                        GetThisFilterValueAlreadySet = False
                        Exit Function
                    End If
                End If
            End If
        End With
    Next
    GetThisFilterValueAlreadySet = True
End Function

 
Dalm, добрый день!
Я думаю Вам пора брать МатросаНаЗебре хотя бы на пол ставки.  :D
 
любая посильная часть ставки была бы уместна )
 
Цитата
написал:
если рядом с ячейкой иерархии (в исходных данных) стоит "1" - то цвет не повторялся бы
В этом варианте вероятность повторения цвета 6 в -3 степени (около полпроцента).
Код
Option Explicit
'v3
Public Sub makeTable()
    
    Dim ws As Worksheet, new_ws As Worksheet
    Set ws = Worksheets("3464743")
    Set new_ws = Worksheets("Лист1")
    
    Const vert_rng As String = "L4"
    Const hor_rng As String = "L5"
    Const target_rng As String = "E10"
    Const delim = ","
    
    ' ===== ЛОГ-ФАЙЛ =====
    Dim logFile As String
    Dim fileNum As Integer
    
    logFile = ThisWorkbook.Path & "\debug_log.txt"
    fileNum = FreeFile
    Open logFile For Output As #fileNum
    
    Print #fileNum, "=== DEBUG LOG ===" & " " & Now
    Print #fileNum, ""
    
    Dim v_range As Range, h_range As Range
    
    With ws
        Set v_range = .Range(vert_rng, .Cells(.Range(vert_rng).Row, .Columns.count).End(xlToLeft))
        Set h_range = .Range(hor_rng, .Cells(.Range(hor_rng).Row, .Columns.count).End(xlToLeft))
    End With
    
    Dim v_arr As Variant, h_arr As Variant
    v_arr = v_range.Value
    h_arr = h_range.Value
    
    Dim count As Long
    count = 1
    
    Dim out_arr() As Variant
    Dim i As Long, num_column As Long, num_row As Long
    Dim d As Variant
    Dim rr As Range
    
    If IsArray(v_arr) Then
        num_column = UBound(v_arr, 2)
    Else
        num_column = 1
    End If
    
    Print #fileNum, "num_column (вертикальная шапка): " & num_column
    
    If IsArray(h_arr) Then
        num_row = UBound(h_arr, 2)
        Print #fileNum, "num_row (горизонтальная шапка): " & num_row
        ReDim out_arr(1 To row_count(h_arr), 1 To UBound(h_arr, 2))
        For i = UBound(h_arr, 2) To LBound(h_arr, 2) Step -1
            count = count * (UBound(Split(h_arr(1, i), delim), 1) + 1)
            fill_arr h_arr(1, i), out_arr, i, count
        Next i
        d = Application.Transpose(out_arr)
        new_ws.Range(target_rng).Offset(0, num_column + 1).Resize(UBound(d, 1), UBound(d, 2)).Value = d
        Set rr = new_ws.Range(target_rng).Offset(0, num_column + 1).Resize(UBound(d, 1) - 1, UBound(d, 2))
    Else
        d = Split(h_arr, delim)
        num_row = 1
        new_ws.Range(target_rng).Offset(0, num_column + 1).Resize(1, UBound(d, 1) + 1).Value = Application.Transpose(d)
        Set rr = new_ws.Range(target_rng).Offset(0, num_column + 1).Resize(1, UBound(d, 1) + 1)
    End If
    
    Print #fileNum, "Горизонтальная шапка (rr): " & rr.Address
    Print #fileNum, ""
    
    ' ===== РАСКРАСКА И ГРАНИЦЫ ГОРИЗОНТАЛЬНОЙ ШАПКИ =====
    rr.Interior.Pattern = xlNone
    
    Dim col_idx As Long
    Dim src_col As Long
    Dim color1 As Long, color2 As Long
    Dim cell As Range
    
    Randomize
    For col_idx = 1 To rr.Rows.count
        If col_idx <= h_range.Columns.count Then
            src_col = h_range.Column + col_idx - 1
            If ws.Cells(6, src_col).Value = 1 Then
                color1 = RGB(100 + Int((155 * Rnd) / 20) * 20, 100 + Int((155 * Rnd) / 20) * 20, 100 + Int((155 * Rnd) / 20) * 20)
                color2 = RGB(100 + Int((155 * Rnd) / 20) * 20, 100 + Int((155 * Rnd) / 20) * 20, 100 + Int((155 * Rnd) / 20) * 20)
            Else
                color1 = ws.Cells(6, src_col).Interior.Color
                color2 = ws.Cells(7, src_col).Interior.Color
            End If
            ColorRow rr.Rows(col_idx), color1, color2
            
            ' Границы для каждой ячейки в строке горизонтальной шапки
            For Each cell In rr.Rows(col_idx).Cells
                With cell.Borders
                    .LineStyle = xlContinuous
                    .Weight = xlThin
                    .ColorIndex = 1
                End With
            Next cell
        End If
    Next col_idx
    
    ClearBottomRange rr
    
    count = 1
    
    If IsArray(v_arr) Then
        ReDim out_arr(1 To row_count(v_arr), 1 To UBound(v_arr, 2))
        For i = UBound(v_arr, 2) To LBound(v_arr, 2) Step -1
            count = count * (UBound(Split(v_arr(1, i), delim), 1) + 1)
            fill_arr v_arr(1, i), out_arr, i, count
        Next i
        new_ws.Range(target_rng).Offset(num_row + 1, 0).Resize(UBound(out_arr, 1), UBound(out_arr, 2)).Value = out_arr
        Set rr = new_ws.Range(target_rng).Offset(num_row + 1, 0).Resize(UBound(out_arr, 1), UBound(out_arr, 2))
    Else
        d = Split(v_arr, delim)
        new_ws.Range(target_rng).Offset(num_row + 1, 0).Resize(UBound(d, 1) + 1, 1).Value = d
        Set rr = new_ws.Range(target_rng).Offset(num_row + 1, 0).Resize(UBound(d, 1) + 1, 1)
    End If
    
    Print #fileNum, "Вертикальная шапка (rr): " & rr.Address
    Print #fileNum, ""

    ' ===== РАСКРАСКА И ГРАНИЦЫ ВЕРТИКАЛЬНОЙ ШАПКИ =====
    rr.Interior.Pattern = xlNone
    
    Dim row_idx As Long
    
    For row_idx = 1 To rr.Columns.count
        If row_idx <= v_range.Columns.count Then
            src_col = v_range.Column + row_idx - 1
            If ws.Cells(3, src_col).Value = 1 Then
                color1 = RGB(100 + Int((155 * Rnd) / 20) * 20, 100 + Int((155 * Rnd) / 20) * 20, 100 + Int((155 * Rnd) / 20) * 20)
                color2 = RGB(100 + Int((155 * Rnd) / 20) * 20, 100 + Int((155 * Rnd) / 20) * 20, 100 + Int((155 * Rnd) / 20) * 20)
            Else
                color1 = ws.Cells(2, src_col).Interior.Color
                color2 = ws.Cells(3, src_col).Interior.Color
            End If
            ColorColumn rr.Columns(row_idx), color1, color2
            
            ' Границы для каждой ячейки в столбце вертикальной шапки
            For Each cell In rr.Columns(row_idx).Cells
                With cell.Borders
                    .LineStyle = xlContinuous
                    .Weight = xlThin
                    .ColorIndex = 1
                End With
            Next cell
        End If
    Next row_idx
    
    ClearBottomRange rr

    ' ===== ПОИСК ГРАНИЦ В СТРОКЕ 10 =====
    Dim firstColBorders As Long
    Dim lastColBorders As Long
    Dim c As Long
    Dim hasBorders As Boolean
    
    Print #fileNum, ""
    Print #fileNum, "=== ПОИСК ГРАНИЦ В СТРОКЕ 10 ==="
    
    firstColBorders = 0
    lastColBorders = 0
    
    For c = 1 To new_ws.Columns.count
        On Error Resume Next
        hasBorders = (new_ws.Cells(10, c).Borders.LineStyle <> xlNone)
        On Error GoTo 0
        
        If hasBorders Then
            If firstColBorders = 0 Then firstColBorders = c
            lastColBorders = c
        End If
    Next c
    
    If firstColBorders <> 0 And lastColBorders <> 0 Then
        Print #fileNum, "Первая ячейка с границей: " & new_ws.Cells(10, firstColBorders).Address
        Print #fileNum, "Последняя ячейка с границей: " & new_ws.Cells(10, lastColBorders).Address
        Print #fileNum, "Диапазон в строке 10: " & new_ws.Range(new_ws.Cells(10, firstColBorders), new_ws.Cells(10, lastColBorders)).Address
    Else
        Print #fileNum, "Границы в строке 10 не найдены!"
    End If
    
    ' ===== ПОИСК ГРАНИЦ В СТОЛБЦЕ E =====
    Dim firstRowBorders As Long
    Dim lastRowBorders As Long
    Dim r As Long
    
    Print #fileNum, ""
    Print #fileNum, "=== ПОИСК ГРАНИЦ В СТОЛБЦЕ E ==="
    
    firstRowBorders = 0
    lastRowBorders = 0
    
    For r = 1 To new_ws.Rows.count
        On Error Resume Next
        hasBorders = (new_ws.Cells(r, 5).Borders.LineStyle <> xlNone)
        On Error GoTo 0
        
        If hasBorders Then
            If firstRowBorders = 0 Then firstRowBorders = r
            lastRowBorders = r
        End If
    Next r
    
    If firstRowBorders <> 0 And lastRowBorders <> 0 Then
        Print #fileNum, "Первая ячейка с границей: " & new_ws.Cells(firstRowBorders, 5).Address
        Print #fileNum, "Последняя ячейка с границей: " & new_ws.Cells(lastRowBorders, 5).Address
        Print #fileNum, "Диапазон в столбце E: " & new_ws.Range(new_ws.Cells(firstRowBorders, 5), new_ws.Cells(lastRowBorders, 5)).Address
    Else
        Print #fileNum, "Границы в столбце E не найдены!"
    End If
    
    ' ===== ЗАПОЛНЕНИЕ ПЕРЕСЕЧЕНИЯ ГРАНИЦАМИ =====
    If firstColBorders <> 0 And lastColBorders <> 0 And firstRowBorders <> 0 And lastRowBorders <> 0 Then
        Dim intersectRange As Range
        
        ' Пересечение: строки от firstRowBorders до lastRowBorders, столбцы от firstColBorders до lastColBorders
        Set intersectRange = new_ws.Range(new_ws.Cells(firstRowBorders, firstColBorders), new_ws.Cells(lastRowBorders, lastColBorders))
        
        Print #fileNum, ""
        Print #fileNum, "=== ПЕРЕСЕЧЕНИЕ ==="
        Print #fileNum, "Диапазон пересечения: " & intersectRange.Address
        Print #fileNum, "Строки: " & firstRowBorders & " - " & lastRowBorders
        Print #fileNum, "Столбцы: " & firstColBorders & " - " & lastColBorders
        
        ' Рисуем границы в пересечении
        With intersectRange.Borders
            .LineStyle = xlContinuous
            .Weight = xlThin
            .ColorIndex = 1
        End With
        
        ' Внешняя рамка
        With intersectRange.Borders(xlEdgeLeft)
            .LineStyle = xlContinuous
            .Weight = xlMedium
            .ColorIndex = 1
        End With
        With intersectRange.Borders(xlEdgeTop)
            .LineStyle = xlContinuous
            .Weight = xlMedium
            .ColorIndex = 1
        End With
        With intersectRange.Borders(xlEdgeRight)
            .LineStyle = xlContinuous
            .Weight = xlMedium
            .ColorIndex = 1
        End With
        With intersectRange.Borders(xlEdgeBottom)
            .LineStyle = xlContinuous
            .Weight = xlMedium
            .ColorIndex = 1
        End With
        
        Print #fileNum, "Границы применены к пересечению!"
        
        ' ===== ОЧИСТКА ВСЕХ ГРАНИЦ В ЛЕВОМ СТОЛБЦЕ =====
        If firstColBorders > 1 Then
            Dim leftCol As Long
            Dim clearRange As Range
            
            leftCol = firstColBorders - 1
            
            Set clearRange = new_ws.Range(new_ws.Cells(firstRowBorders, leftCol), new_ws.Cells(lastRowBorders, leftCol))
            
            ' Очищаем ВСЕ границы (полностью)
            clearRange.Borders.LineStyle = xlNone
            
            Print #fileNum, ""
            Print #fileNum, "=== ОЧИСТКА ЛЕВОГО СТОЛБЦА ==="
            Print #fileNum, "Очищены ВСЕ границы в столбце: " & clearRange.Address
        End If
        
    Else
        Print #fileNum, ""
        Print #fileNum, "=== ПЕРЕСЕЧЕНИЕ НЕ НАЙДЕНО ==="
        Print #fileNum, "Не удалось найти границы в строке 10 или столбце E"
    End If
    
    Print #fileNum, ""
    Print #fileNum, "=== ГОТОВО ==="
    
    Close #fileNum

    new_ws.Select
    
    MsgBox "Готово! Лог: " & logFile, vbInformation, "makeTable"
    
End Sub

'==================================================================
' ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ (БЕЗ ИЗМЕНЕНИЙ)
'==================================================================

Private Function row_count(arr As Variant, Optional delim As String = ",") As Long
    Dim i As Long, result As Long
    result = 1
    For i = UBound(arr, 2) To LBound(arr, 2) Step -1
        result = result * (UBound(Split(arr(1, i), delim), 1) + 1)
    Next i
    row_count = result
End Function

Private Sub fill_arr(arr As Variant, new_arr() As Variant, ind As Long, count As Long, Optional delim As String = ",")
    Dim i As Long, result As Long, n As Long, k As Long, d As Long
    Dim txt As Variant, el As Variant
    txt = Split(arr, delim)
    d = UBound(txt, 1) + 1
    For i = LBound(new_arr, 1) To UBound(new_arr, 1) Step count
        n = count / d
        For k = 0 To (count - 1) Step n
            new_arr(i + k, ind) = txt(k \ n)
        Next k
    Next i
End Sub

Private Sub ClearBottomRange(rr As Range)
    Set rr = rr.Cells(rr.Rows.count + 1, 1)
    Set rr = rr.Resize(rr.Parent.UsedRange.Rows.count, rr.Parent.UsedRange.Columns.count)
    rr.Clear
End Sub

Private Sub ColorColumn(rr As Range, ByVal color1 As Long, ByVal color2 As Long)
    Dim arrY As Variant
    arrY = GetNodeRows(rr)
     
    If IsEmpty(arrY) Then Exit Sub
    
    rr.Interior.Color = color2
    Dim ya As Long
    For ya = LBound(arrY) To UBound(arrY) Step 2
        If ya + 1 <= UBound(arrY) Then
            rr.Cells(arrY(ya), 1).Resize(arrY(ya + 1) - arrY(ya), 1).Interior.Color = color1
        ElseIf ya = UBound(arrY) Then
            rr.Cells(arrY(ya), 1).Resize(rr.Rows.count - arrY(ya) + 1, 1).Interior.Color = color1
        End If
    Next
End Sub

Private Sub ColorRow(rr As Range, ByVal color1 As Long, ByVal color2 As Long)
    Dim arrY As Variant
    arrY = GetNodeCols(rr)
     
    If IsEmpty(arrY) Then Exit Sub
    
    rr.Interior.Color = color2
    Dim ya As Long
    For ya = LBound(arrY) To UBound(arrY) Step 2
        If ya + 1 <= UBound(arrY) Then
            rr.Cells(1, arrY(ya)).Resize(1, arrY(ya + 1) - arrY(ya)).Interior.Color = color1
        ElseIf ya = UBound(arrY) Then
            rr.Cells(1, arrY(ya)).Resize(1, rr.Columns.count - arrY(ya) + 1).Interior.Color = color1
        End If
    Next
End Sub

Private Function GetNodeRows(rr As Range) As Variant
    Dim arr As Variant
    arr = rr.Value
    
    Dim dic As Object
    Set dic = CreateObject("Scripting.Dictionary")
    
    Dim ya As Long
    For ya = 1 To UBound(arr, 1)
        If Not IsEmpty(arr(ya, 1)) Then
            dic(ya) = Empty
        End If
    Next
    
    GetNodeRows = dic.Keys()
End Function

Private Function GetNodeCols(rr As Range) As Variant
    Dim arr As Variant
    arr = rr.Value
    
    Dim dic As Object
    Set dic = CreateObject("Scripting.Dictionary")
    
    Dim ya As Long
    For ya = 1 To UBound(arr, 2)
        If Not IsEmpty(arr(1, ya)) Then
            dic(ya) = Empty
        End If
    Next
    
    GetNodeCols = dic.Keys()
End Function

 
Цитата
написал:
Я думаю Вам пора брать МатросаНаЗебре хотя бы на пол ставки.  
Давно пора, почему так долго  :D  :D  :D  
 
МатросНаЗебре, "Макрос для горизонтального фильтра. Выделите ячейку в диапазоне L11:N11, запустите макрос."

Спасибо.
Но там же горизонтальная шапка - из нескольких строк состоит. А как на других строках фильтрацию сделать ?


МатросНаЗебре, "В этом варианте вероятность повторения цвета 6 в -3 степени (около полпроцента)."

Тут не работает, то о чем я говорил в первом посте.
Вот даже в этом файле - получилась ситуация, что для позиции "один" у одного стека  - цвет отличается от позиции "один"  в другом стеке.
Такого не должно быть.
Позиция "один" - должна быть везде одинакового цвета. Позиция "два_" тоже везде одинакового цвета. Если стоит "1".

Потом в этом стеке (с единицей "1") - пять позиций, и два цвета. Это значит что должны быть раскрашены только первые две позиции стека (так как цветов два).  А у вас - раскрашиваются также - третья, четвертая и пятая позиция (и раскрашиваются какими-то не теми цветами, что в исходных данных назначены).
Изменено: Dalm - 26.08.2026 07:55:16
 
Dalm, это не у матроса не получается, а у вас
матрос лишь помогает вам эти проблемы решать
поэтому подробнее и повежливее описывайте что именно  у вас работает не так и как должно
если нужно решить за вас - добро пожаловать в ветку работа
 
Цитата
nilske написал:
матрос лишь помогает
Это мы так думаем, а Dalm, решил, что раз уж взялся делать за него работу, то должен довести ее до конца  :D
 
В этом варианте можно последовательно устанавливать горизонтальный фильтр для разных строк.
При смене иерархии для строк, цвет устанавливается первый.

Цитата
написал:
а  Dalm , решил, что раз уж взялся делать за него работу, то должен довести ее до конца  
:D  :D  :D
Скрытый текст
Скрытый текст
 
МатросНаЗебре, "В этом варианте можно последовательно устанавливать горизонтальный фильтр для разных строк.
При смене иерархии для строк, цвет устанавливается первый."

А как его тут устанавливать ?
Горизонтальный фильтр работает только для самой нижней строки шапки.
Когда я щелкаю по другим строкам горизонтальной шапки - кнопка макроса фильтра не действует.

С расположением цветов - ничего не изменилось.
Пример в горизонтальной шапке - каждый из "ТретийВерт2s" - имеет свой уникальный цвет.
Такого быть не должно - "ТретийВерт2s" должен быть одинакового цвета во всех стеках.  А поскольку в исходных данных для этого стека стоит "1" и цвета задано всего два, а "ТретийВерт2s" идет третьим внутри стека - то у него вообще не должно быть цвета (потому что два заданных цвета из исходных данных - уже израсходовались на первые две позиции стека).
С вертикальной шапкой - та же история.

Смысл "1" в исходных данных в том, что цвета не могут идти вразнобой и не могут раскрашивать больше позиций чем заданных цветов (то есть если цветов два - то и позиций в стеке может быть раскрашено всего две... а остальные позиции в таком случае вообще не закрашиваются).
А здесь кроме того - еще какие-то дополнительные цвета добавились, которых не было в исходных данных.
Изменено: Dalm - 26.08.2026 22:48:32
 
Как же это сделать ?
 
Цитата
Dalm написал:
Как же это сделать ?
ну вот началось. Думаю вам нужно в раздел Работа обратиться.
 
Msi2102, вы почему-то все время вместо того чтобы помочь собрату-форумчанину, попавшему в беду ... все время ищите возможность нажиться на чужом несчастье.
Это - неблагородный подход.
 
Цитата
Dalm написал:
Msi2102, вы почему-то все время вместо того чтобы помочь собрату-форумчанину, попавшему в беду ... все время ищите возможность нажиться на чужом несчастье.
Уважаемый Dalm, я не пытаюсь нажиться ни на чьем несчастье. Я больше скажу, я не беру заказы в платном разделе и помогаю всем абсолютно бескорыстно. Но все Ваши хотелки (я имею ввиду не только этот пост) выходят за рамки просто помощи, Вы составляете ТЗ, мало того составляете его так, что очень сложно понять, что Вы хотите, в результате если кто-то и берется Вам оказать ПОСИЛЬНУЮ помощь, то переделывает это по несколько раз. Я например, в этом посту, только после #13 сообщения примерно понял, что Вы хотите и то не факт, что правильно. Сами Вы не желаете развиваться и не пытаетесь, что-то делать своими руками, и если ни кто не помогает начинаете клянчить, типа "Как же это сделать", "Ни ужели никто не поможет", поэтому с таким подходом Вам в Платную ветку.
Цитата
Dalm написал:
Это - неблагородный подход.
По поводу благородства, Вам ли писать, единственный, кто Вам пытается помочь это Матрос (широкой души человек) и у того по-видимому закончилось терпение, да и окончательно пропало желание переписывать бесконечно коды, так вы его хотя бы отблагодарили, это было бы благородно с Вашей стороны.
Изменено: Msi2102 - 28.08.2026 09:53:06
 
Dalm, в разделе Работа никто не возьмёт вашу задачу, кроме матроса на зебре. Либо только после его отказа.
Сумма оплаты очень часто является символической, а взаимодействовать намного удобнее обеим сторонам.
А здесь получается, что нажиться за чужой счёт (за затраченном времени матроса) пытаетесь как раз вы, потому что никаких самостоятельных попыток в решении задачи не демонстрируете.
 
Цитата
написал:
Горизонтальный фильтр работает только для самой нижней строки шапки.
Не предполагался клик в пустоту. Теперь предполагается.
Код
Option Explicit

Sub Горизонтальный_фильтр()
    If ActiveCell.Row < 10 Or ActiveCell.Column < Range("M1").Column Then
        Range("M1").Resize(1, ActiveSheet.UsedRange.Columns.count).EntireColumn.Hidden = False
    End If
    
    Dim clLeft As Range, clRigh As Range, rnHide As Range
    Set clLeft = GetLeftCell(ActiveCell)
    Dim thisFilterValueAlreadySet As Boolean
    thisFilterValueAlreadySet = GetThisFilterValueAlreadySet(clLeft)
    
    If thisFilterValueAlreadySet Then Exit Sub
    Set clRigh = clLeft.EntireRow.Cells(1, ActiveSheet.UsedRange.Column + ActiveSheet.UsedRange.Columns.count - 1) 'Columns.count).End(xlToLeft)
    If clLeft.Column >= clRigh.Column Then Exit Sub
    
    Set rnHide = Range(clLeft, clRigh)
    
    Application.ScreenUpdating = False
    
'    If clLeft.Column > Range("K1").Column + 1 Then
'        Range(Range("K1").Cells(1, 2), clLeft.Cells(1, 0)).EntireColumn.Hidden = True
'    End If
    
    Dim xLeft As Long, xRigh As Long, prveVal As Variant
    For xLeft = 1 To rnHide.Columns.count
        If Not IsEmpty(rnHide.Cells(1, xLeft).Value) Then
            prveVal = rnHide.Cells(1, xLeft).Value
        End If
        If prveVal <> clLeft.Value Then
            For xRigh = xLeft + 1 To rnHide.Columns.count + 1
                If rnHide.Cells(1, xRigh).Value = clLeft.Value Then Exit For
            Next
            xRigh = xRigh - 1
            If xLeft <= xRigh Then
                Range(rnHide.Cells(1, xLeft), rnHide.Cells(1, xRigh)).Select
                Range(rnHide.Cells(1, xLeft), rnHide.Cells(1, xRigh)).EntireColumn.Hidden = True
                xLeft = xRigh + 1
            End If
        End If
    Next
    Application.ScreenUpdating = True
End Sub


Private Function GetLeftCell(cl As Range) As Range
    Do
        If Not IsEmpty(cl.Value) Then Exit Do
        If cl.Column <= Range("M1").Column Then Exit Do
        Set cl = cl.Cells(1, 0)
        DoEvents
    Loop
    Set GetLeftCell = cl
End Function

Private Function GetThisFilterValueAlreadySet(clLeft As Range) As Boolean
    Dim xx As Long
    For xx = 2 To clLeft.Parent.UsedRange.Columns.count
        With clLeft.Cells(1, xx)
            If .EntireColumn.Hidden = False Then
                If Not IsEmpty(.Value) Then
                    If .Value <> clLeft.Value Then
                        GetThisFilterValueAlreadySet = False
                        Exit Function
                    End If
                End If
            End If
        End With
    Next
    GetThisFilterValueAlreadySet = True
End Function

 
Цитата
написал:
А как его тут устанавливать ?
Цвет устанавливается на листе "цвет".
Код
Option Explicit
'v5
Public Sub makeTable()
    
    Dim ws As Worksheet, new_ws As Worksheet
    Set ws = Worksheets("3464743")
    Set new_ws = Worksheets("Лист1")
    
    Const vert_rng As String = "L4"
    Const hor_rng As String = "L5"
    Const target_rng As String = "E10"
    Const delim = ","
    
    ' ===== ЛОГ-ФАЙЛ =====
    Dim logFile As String
    Dim fileNum As Integer
    
    logFile = ThisWorkbook.Path & "\debug_log.txt"
    fileNum = FreeFile
    Open logFile For Output As #fileNum
    
    Print #fileNum, "=== DEBUG LOG ===" & " " & Now
    Print #fileNum, ""
    
    Dim v_range As Range, h_range As Range
    
    With ws
        Set v_range = .Range(vert_rng, .Cells(.Range(vert_rng).Row, .Columns.count).End(xlToLeft))
        Set h_range = .Range(hor_rng, .Cells(.Range(hor_rng).Row, .Columns.count).End(xlToLeft))
    End With
    
    Dim v_arr As Variant, h_arr As Variant
    v_arr = v_range.Value
    h_arr = h_range.Value
    
    Dim count As Long
    count = 1
    
    Dim out_arr() As Variant
    Dim i As Long, num_column As Long, num_row As Long
    Dim d As Variant
    Dim rr As Range
    
    If IsArray(v_arr) Then
        num_column = UBound(v_arr, 2)
    Else
        num_column = 1
    End If
    
    Print #fileNum, "num_column (вертикальная шапка): " & num_column
    
    If IsArray(h_arr) Then
        num_row = UBound(h_arr, 2)
        Print #fileNum, "num_row (горизонтальная шапка): " & num_row
        ReDim out_arr(1 To row_count(h_arr), 1 To UBound(h_arr, 2))
        For i = UBound(h_arr, 2) To LBound(h_arr, 2) Step -1
            count = count * (UBound(Split(h_arr(1, i), delim), 1) + 1)
            fill_arr h_arr(1, i), out_arr, i, count
        Next i
        d = Application.Transpose(out_arr)
        new_ws.Range(target_rng).Offset(0, num_column + 1).Resize(UBound(d, 1), UBound(d, 2)).Value = d
        Set rr = new_ws.Range(target_rng).Offset(0, num_column + 1).Resize(UBound(d, 1) - 1, UBound(d, 2))
    Else
        d = Split(h_arr, delim)
        num_row = 1
        new_ws.Range(target_rng).Offset(0, num_column + 1).Resize(1, UBound(d, 1) + 1).Value = Application.Transpose(d)
        Set rr = new_ws.Range(target_rng).Offset(0, num_column + 1).Resize(1, UBound(d, 1) + 1)
    End If
    
    Print #fileNum, "Горизонтальная шапка (rr): " & rr.Address
    Print #fileNum, ""
    
    ' ===== РАСКРАСКА И ГРАНИЦЫ ГОРИЗОНТАЛЬНОЙ ШАПКИ =====
    rr.Interior.Pattern = xlNone
    
    Dim col_idx As Long
    Dim src_col As Long, aColor As Variant
    Dim cell As Range
    
    Randomize
    For col_idx = 1 To rr.Rows.count
        If col_idx <= h_range.Columns.count Then
            src_col = h_range.Column + col_idx - 1
'            color1 = ws.Cells(6, src_col).Interior.Color
'            color2 = ws.Cells(7, src_col).Interior.Color
                        
            aColor = GetCollorArray(ws.Cells(7, src_col))
            ColorRow rr.Rows(col_idx), aColor, ws.Cells(6, src_col).Value = 1
            
            ' Границы для каждой ячейки в строке горизонтальной шапки
            For Each cell In rr.Rows(col_idx).Cells
                With cell.Borders
                    .LineStyle = xlContinuous
                    .Weight = xlThin
                    .ColorIndex = 1
                End With
            Next cell
        End If
    Next col_idx
    
    ClearBottomRange rr
    
    count = 1
    
    If IsArray(v_arr) Then
        ReDim out_arr(1 To row_count(v_arr), 1 To UBound(v_arr, 2))
        For i = UBound(v_arr, 2) To LBound(v_arr, 2) Step -1
            count = count * (UBound(Split(v_arr(1, i), delim), 1) + 1)
            fill_arr v_arr(1, i), out_arr, i, count
        Next i
        new_ws.Range(target_rng).Offset(num_row + 1, 0).Resize(UBound(out_arr, 1), UBound(out_arr, 2)).Value = out_arr
        Set rr = new_ws.Range(target_rng).Offset(num_row + 1, 0).Resize(UBound(out_arr, 1), UBound(out_arr, 2))
    Else
        d = Split(v_arr, delim)
        new_ws.Range(target_rng).Offset(num_row + 1, 0).Resize(UBound(d, 1) + 1, 1).Value = d
        Set rr = new_ws.Range(target_rng).Offset(num_row + 1, 0).Resize(UBound(d, 1) + 1, 1)
    End If
    
    Print #fileNum, "Вертикальная шапка (rr): " & rr.Address
    Print #fileNum, ""

    ' ===== РАСКРАСКА И ГРАНИЦЫ ВЕРТИКАЛЬНОЙ ШАПКИ =====
    rr.Interior.Pattern = xlNone
    
    Dim row_idx As Long
    
    For row_idx = 1 To rr.Columns.count
        If row_idx <= v_range.Columns.count Then
            src_col = v_range.Column + row_idx - 1
'            color1 = ws.Cells(2, src_col).Interior.Color
'            If ws.Cells(3, src_col).Value = 1 Then
'                color2 = RGB(100 + Int((155 * Rnd) / 20) * 20, 100 + Int((155 * Rnd) / 20) * 20, 100 + Int((155 * Rnd) / 20) * 20)
'            Else
'                color2 = ws.Cells(3, src_col).Interior.Color
'            End If
            aColor = GetCollorArray(ws.Cells(2, src_col))
            ColorColumn rr.Columns(row_idx), aColor
            
            ' Границы для каждой ячейки в столбце вертикальной шапки
            For Each cell In rr.Columns(row_idx).Cells
                With cell.Borders
                    .LineStyle = xlContinuous
                    .Weight = xlThin
                    .ColorIndex = 1
                End With
            Next cell
        End If
    Next row_idx
    
    ClearBottomRange rr

    ' ===== ПОИСК ГРАНИЦ В СТРОКЕ 10 =====
    Dim firstColBorders As Long
    Dim lastColBorders As Long
    Dim c As Long
    Dim hasBorders As Boolean
    
    Print #fileNum, ""
    Print #fileNum, "=== ПОИСК ГРАНИЦ В СТРОКЕ 10 ==="
    
    firstColBorders = 0
    lastColBorders = 0
    
    For c = 1 To new_ws.Columns.count
        On Error Resume Next
        hasBorders = (new_ws.Cells(10, c).Borders.LineStyle <> xlNone)
        On Error GoTo 0
        
        If hasBorders Then
            If firstColBorders = 0 Then firstColBorders = c
            lastColBorders = c
        End If
    Next c
    
    If firstColBorders <> 0 And lastColBorders <> 0 Then
        Print #fileNum, "Первая ячейка с границей: " & new_ws.Cells(10, firstColBorders).Address
        Print #fileNum, "Последняя ячейка с границей: " & new_ws.Cells(10, lastColBorders).Address
        Print #fileNum, "Диапазон в строке 10: " & new_ws.Range(new_ws.Cells(10, firstColBorders), new_ws.Cells(10, lastColBorders)).Address
    Else
        Print #fileNum, "Границы в строке 10 не найдены!"
    End If
    
    ' ===== ПОИСК ГРАНИЦ В СТОЛБЦЕ E =====
    Dim firstRowBorders As Long
    Dim lastRowBorders As Long
    Dim r As Long
    
    Print #fileNum, ""
    Print #fileNum, "=== ПОИСК ГРАНИЦ В СТОЛБЦЕ E ==="
    
    firstRowBorders = 0
    lastRowBorders = 0
    
    For r = 1 To new_ws.Rows.count
        On Error Resume Next
        hasBorders = (new_ws.Cells(r, 5).Borders.LineStyle <> xlNone)
        On Error GoTo 0
        
        If hasBorders Then
            If firstRowBorders = 0 Then firstRowBorders = r
            lastRowBorders = r
        End If
    Next r
    
    If firstRowBorders <> 0 And lastRowBorders <> 0 Then
        Print #fileNum, "Первая ячейка с границей: " & new_ws.Cells(firstRowBorders, 5).Address
        Print #fileNum, "Последняя ячейка с границей: " & new_ws.Cells(lastRowBorders, 5).Address
        Print #fileNum, "Диапазон в столбце E: " & new_ws.Range(new_ws.Cells(firstRowBorders, 5), new_ws.Cells(lastRowBorders, 5)).Address
    Else
        Print #fileNum, "Границы в столбце E не найдены!"
    End If
    
    ' ===== ЗАПОЛНЕНИЕ ПЕРЕСЕЧЕНИЯ ГРАНИЦАМИ =====
    If firstColBorders <> 0 And lastColBorders <> 0 And firstRowBorders <> 0 And lastRowBorders <> 0 Then
        Dim intersectRange As Range
        
        ' Пересечение: строки от firstRowBorders до lastRowBorders, столбцы от firstColBorders до lastColBorders
        Set intersectRange = new_ws.Range(new_ws.Cells(firstRowBorders, firstColBorders), new_ws.Cells(lastRowBorders, lastColBorders))
        
        Print #fileNum, ""
        Print #fileNum, "=== ПЕРЕСЕЧЕНИЕ ==="
        Print #fileNum, "Диапазон пересечения: " & intersectRange.Address
        Print #fileNum, "Строки: " & firstRowBorders & " - " & lastRowBorders
        Print #fileNum, "Столбцы: " & firstColBorders & " - " & lastColBorders
        
        ' Рисуем границы в пересечении
        With intersectRange.Borders
            .LineStyle = xlContinuous
            .Weight = xlThin
            .ColorIndex = 1
        End With
        
        ' Внешняя рамка
        With intersectRange.Borders(xlEdgeLeft)
            .LineStyle = xlContinuous
            .Weight = xlMedium
            .ColorIndex = 1
        End With
        With intersectRange.Borders(xlEdgeTop)
            .LineStyle = xlContinuous
            .Weight = xlMedium
            .ColorIndex = 1
        End With
        With intersectRange.Borders(xlEdgeRight)
            .LineStyle = xlContinuous
            .Weight = xlMedium
            .ColorIndex = 1
        End With
        With intersectRange.Borders(xlEdgeBottom)
            .LineStyle = xlContinuous
            .Weight = xlMedium
            .ColorIndex = 1
        End With
        
        Print #fileNum, "Границы применены к пересечению!"
        
        ' ===== ОЧИСТКА ВСЕХ ГРАНИЦ В ЛЕВОМ СТОЛБЦЕ =====
        If firstColBorders > 1 Then
            Dim leftCol As Long
            Dim clearRange As Range
            
            leftCol = firstColBorders - 1
            
            Set clearRange = new_ws.Range(new_ws.Cells(firstRowBorders, leftCol), new_ws.Cells(lastRowBorders, leftCol))
            
            ' Очищаем ВСЕ границы (полностью)
            clearRange.Borders.LineStyle = xlNone
            
            Print #fileNum, ""
            Print #fileNum, "=== ОЧИСТКА ЛЕВОГО СТОЛБЦА ==="
            Print #fileNum, "Очищены ВСЕ границы в столбце: " & clearRange.Address
        End If
        
    Else
        Print #fileNum, ""
        Print #fileNum, "=== ПЕРЕСЕЧЕНИЕ НЕ НАЙДЕНО ==="
        Print #fileNum, "Не удалось найти границы в строке 10 или столбце E"
    End If
    
    Print #fileNum, ""
    Print #fileNum, "=== ГОТОВО ==="
    
    Close #fileNum

    new_ws.Select
    
    MsgBox "Готово! Лог: " & logFile, vbInformation, "makeTable"
    
End Sub

'==================================================================
' ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ (БЕЗ ИЗМЕНЕНИЙ)
'==================================================================

Private Function row_count(arr As Variant, Optional delim As String = ",") As Long
    Dim i As Long, result As Long
    result = 1
    For i = UBound(arr, 2) To LBound(arr, 2) Step -1
        result = result * (UBound(Split(arr(1, i), delim), 1) + 1)
    Next i
    row_count = result
End Function

Private Sub fill_arr(arr As Variant, new_arr() As Variant, ind As Long, count As Long, Optional delim As String = ",")
    Dim i As Long, result As Long, n As Long, k As Long, d As Long
    Dim txt As Variant, el As Variant
    txt = Split(arr, delim)
    d = UBound(txt, 1) + 1
    For i = LBound(new_arr, 1) To UBound(new_arr, 1) Step count
        n = count / d
        For k = 0 To (count - 1) Step n
            new_arr(i + k, ind) = txt(k \ n)
        Next k
    Next i
End Sub

Private Sub ClearBottomRange(rr As Range)
    Set rr = rr.Cells(rr.Rows.count + 1, 1)
    Set rr = rr.Resize(rr.Parent.UsedRange.Rows.count, rr.Parent.UsedRange.Columns.count)
    rr.Clear
End Sub

Private Sub ColorColumn(rr As Range, aColor As Variant)
    If IsEmpty(aColor) Then Exit Sub
    
    Dim arrY As Variant
    arrY = GetNodeRows(rr)
     
    If IsEmpty(arrY) Then Exit Sub
    
    Dim iColor As Long
    iColor = LBound(aColor)
    
    Dim ya As Long
    For ya = LBound(arrY) To UBound(arrY) Step 1
        If ya + 1 <= UBound(arrY) Then
            rr.Cells(arrY(ya), 1).Resize(arrY(ya + 1) - arrY(ya), 1).Interior.Color = aColor(iColor)
        ElseIf ya = UBound(arrY) Then
            rr.Cells(arrY(ya), 1).Resize(rr.Rows.count - arrY(ya) + 1, 1).Interior.Color = aColor(iColor)
        End If
        iColor = iColor + 1
        If iColor > UBound(aColor) Then
            iColor = LBound(aColor)
        End If
    Next
End Sub

Private Sub ColorRow(rr As Range, aColor As Variant, flag As Boolean)
    If IsEmpty(aColor) Then Exit Sub
    
    Dim arrY As Variant
    arrY = GetNodeCols(rr)
     
    If IsEmpty(arrY) Then Exit Sub
    
    Dim iColor As Long
    iColor = LBound(aColor)
    
    Dim ya As Long
    For ya = LBound(arrY) To UBound(arrY) Step 1
        If flag Then
            If rr.Cells(0, arrY(ya)) <> "" Then
                iColor = LBound(aColor)
            End If
        End If
        If ya + 1 <= UBound(arrY) Then
            rr.Cells(1, arrY(ya)).Resize(1, arrY(ya + 1) - arrY(ya)).Interior.Color = aColor(iColor)
        ElseIf ya = UBound(arrY) Then
            rr.Cells(1, arrY(ya)).Resize(1, rr.Columns.count - arrY(ya) + 1).Interior.Color = aColor(iColor)
        End If
        iColor = iColor + 1
        If iColor > UBound(aColor) Then
            iColor = LBound(aColor)
        End If
    Next
End Sub

Private Function GetNodeRows(rr As Range) As Variant
    Dim arr As Variant
    arr = rr.Value
    
    Dim dic As Object
    Set dic = CreateObject("Scripting.Dictionary")
    
    Dim ya As Long
    For ya = 1 To UBound(arr, 1)
        If Not IsEmpty(arr(ya, 1)) Then
            dic(ya) = Empty
        End If
    Next
    
    GetNodeRows = dic.Keys()
End Function

Private Function GetNodeCols(rr As Range) As Variant
    Dim arr As Variant
    arr = rr.Value
    
    Dim dic As Object
    Set dic = CreateObject("Scripting.Dictionary")
    
    Dim ya As Long
    For ya = 1 To UBound(arr, 2)
        If Not IsEmpty(arr(1, ya)) Then
            dic(ya) = Empty
        End If
    Next
    
    GetNodeCols = dic.Keys()
End Function

Private Function GetCollorArray(cl As Range) As Variant
    Dim col As Variant
    col = cl.Value
    
    Dim res As Variant
    Dim rr As Range, rCol As Range
    Set rCol = ThisWorkbook.Names("цвета").RefersToRange
    If IsNumeric(col) Then
        If col > 0 Then
            Set rr = rCol.Columns(col)
        End If
    Else
        On Error Resume Next
        Set rr = rCol.Range(col & 1)
        On Error GoTo 0
    End If
    If rr Is Nothing Then
        ReDim res(0 To 1)
        If cl.Interior.Color <> RGB(255, 255, 255) Then
            res(0) = cl.Interior.Color
            res(1) = RGB(255, 255, 255)
        Else
            res(0) = RGB(255, 255, 255)
            res(1) = cl.Interior.Color
        End If
        GetCollorArray = res
        Exit Function
    End If
    
    ReDim res(0 To 0)
    Dim yr As Long
    yr = LBound(res)
    Do
        res(yr) = rr.Cells(1 + yr, 1).Interior.Color
        yr = yr + 1
        If rr.Cells(1 + yr, 1).Interior.Color = RGB(255, 255, 255) Then Exit Do
        If yr > 2 ^ 7 Then Exit Do
        If yr > UBound(res) Then
            ReDim Preserve res(LBound(res) To 2 * (UBound(res) + 1))
        End If
            
        DoEvents
    Loop
    yr = yr - 1
    If yr >= LBound(res) And yr < UBound(res) Then
        ReDim Preserve res(LBound(res) To yr)
    End If
    GetCollorArray = res
End Function

OFF: Прелесть задачек из бесплатной ветки заключается в свободе. Нравится задача - делаешь, не нравится - не делаешь. Плюс ты свободен как в выборе методов решения, так и в виде окончательного результата. Упоминания благородства и выручки попавшего это уже про ответственность, то есть они накладывают некие ограничения на эту свободу, а следовательно лишают задачу прелести. Другими словами, подобные отсылки скорее отпугнут, чем привлекут.)
 
Цитата
МатросНаЗебре написал:
Прелесть задачек из бесплатной ветки заключается в свободе.
Свобода это хорошо, но ещё лучше если есть люди которые везут, когда на них едут. Сугубо моё личное мнение, что господин Dalm, уже сел на шею и начинает погонять  :D
Мне, например, какая бы не была интересная задача, код в 400+ строк было бы лень лопатить туда сюда, потому как создатель темы не может толком объяснить, что ему нужно. Да и в любом случае, я считаю что это полноценное ТЗ для Платной ветки, тем более что сам ТС палец о палец не ударил, для решения этой задачи.
 
МатросНаЗебре, спасибо.
Не очень понятно - что обозначают цвета ячеек на листе "цвета" (никаких подписей к ним нет) ?
И что обозначают числа - в ячейках исходных данных (с цветами) ?
 
Цитата
Msi2102 написал:
Dalm , уже сел на шею и начинает погонять
это ещё не конец "хотелки", далее ещё веселее будет.
 
Msi2102, "....создатель темы не может толком объяснить, что ему нужно...."
Да все я объяснил.
Если стоит "1" - то раскраска не должна - ни повторятся ни чередоваться, а отобразится в стеке лишь один раз. Если же стоит "1" - то раскраска чередуется, как обычно.
Вот и все.

"....Сугубо моё личное мнение, что господин Dalm, уже сел на шею и начинает погонять..."
Ваше сугубо личное мнение - неправильное и попросил бы - его ко мне не применять.

"...сам ТС палец о палец не ударил, для решения этой задачи...."
Было-было, ударял я пальцем о палец для решения этой задачи. Даже искуственный интелект привлекал (только этот искуственный интелект оказался не интелектуальным, а тупым).

"...это полноценное ТЗ для Платной ветки..."
Хватит пытаться совратить благородных программистов - темной стороной капиталистического мира наживы и чистогана.
Я напомню, что христианство и многие другие религии считают жадность - смертным грехом.
Лучше покайтесь в грехах, и предложите какое-либо решение. Может быть именно ваш свежий взгляд поможет решить проблему.
 
Вот - на рисунке нарисовал, чтобы было понятнее.
Изменено: Dalm - 29.08.2026 10:23:49
 
Dalm, добрый день.
Цитата
написал:
Хватит пытаться совратить благородных программистов - темной стороной капиталистического мира наживы и чистогана.Я напомню, что христианство и многие другие религии считают жадность - смертным грехом.
Исходя из комментария выше я правильно понимаю, что вы со своего работодателя деньги за свою работу не берете, и все эта задача основана на сугубо альтруистических целях? Если так то это очень похвально!
Цитата
написал:
Может быть именно ваш свежий взгляд поможет решить проблему.
А может нужно просто заполнить иерархию целиком, чтоб не было пустых ячеек по уровням, тогда и автофильтр будет работать правильно и все ваши раскраски можно легко будет сделать с помощью условного форматирования, и сводную построить, если нужно в дальнейшем.

Цитата
написал:
Лучше покайтесь в грехах, и предложите какое-либо решение.
Вот это поворот. Я думаю, ваш комментарий абсолютно не уместен, потому что Msi2102, один из активных участников форума, который за много лет предоставил столько бескорыстной помощи!!!
 
Dalm, Что-то яснее не стало исходя из вашего скриншота из поста#25, всё ещё сложнее стало. Может вы всё таки ручками будете решать и далее свой вопрос, по старинке? Все ваши предыдущие темы крутятся вокруг одних и тех же таблиц.
 
Цитата
Dalm написал:
Если стоит "1" - то раскраска не должна...
Если же стоит "1" - то раскраска чередуется...
а что если стоит "1"?
Пришелец-прораб.
 
Цитата
Dalm написал:
Хватит пытаться совратить благородных программистов
Этим программистам семьи надо обеспечивать, в магазинах же продукты и всё остальное необходимого для существования не дадут за красивые глаза.
Цитата
Dalm написал:
предложите какое-либо решение
Решений уже много вам дал Уважаемый МатросНаЗебре, но вы же как обычно в прошлых ваших темах, всё не то - всё не так. Вашу задачу понимаете только вы сами. Решение есть - "ручками", по старинке.
Страницы: 1
Читают тему
Наверх