Страницы: 1
RSS
Получить данные из массива по нескольким условиям, сделать формулу счетесли более универсальной без перечисления каждого диапазона
 
Добрый вечер! Есть таблица, в которой необхоимо посчитать количество повтороний фамилии в разрезе одной даты. данные для просчета находятся в диапазоне с H по S. Таблица выглядит фамилия-комментарий-фамилия-комментарий. Я сделала через счетеслимн, но очень неудобно через плюс указывать каждый диапазон. Можно ли упростить формулу и сделать ее более универсальной? формула в ячейке F70. =СЧЁТЕСЛИМН($H$3:$H$64;$B70;$A$3:$A$64;F$69)+СЧЁТЕСЛИМН($J$3:$J$64;$B70;$A$3:$A$64;F$69)+СЧЁТЕСЛИМН($L$3:$L$64;$B70;$A$3:$A$64;F$69)+СЧЁТЕСЛИМН($N$3:$N$64;$B70;$A$3:$A$64;F$69)+СЧЁТЕСЛИМН($P$3:$P$64;$B70;$A$3:$A$64;F$69)+СЧЁТЕСЛИМН($R$3:$R$64;$B70;$A$3:$A$64;F$69)
Изменено: Sanja - 14.01.2026 11:16:24 (Изменил название темы. В следующий раз Тема с нарушением Правил форума (ознакомьтесь) будет закрыта)
 
Здравствуйте.
Попробуйте любую формулу для F70
Код
=СЧЁТЕСЛИ(ИНДЕКС($H$3:$H$64;ПОИСКПОЗ(F$69;$A$3:$A$64;)):ИНДЕКС($S$3:$S$64;ПОИСКПОЗ(F$69;$A$3:$A$64;)+1);$B70)
=СЧЁТЕСЛИ(СМЕЩ($H$2;ПОИСКПОЗ(F$69;$A$3:$A$64;);;2;12);$B70)
=СУММПРОИЗВ(($H$3:$S$64=$B70)*($A$3:$A$64=F$69))
Изменено: gling - 06.01.2026 21:13:36
 
@ gling Спасибо большое! Все получилось!
 
Цитата
написал:
Здравствуйте.Попробуйте любую формулу для F70Код ? 123=СЧЁТЕСЛИ(ИНДЕКС($H$3:$H$64;ПОИСКПОЗ(F$69;$A$3:$A$64;)):ИНДЕКС($S$3:$S$64;ПОИСКПОЗ(F$69;$A$3:$A$64;)+1);$B70)=СЧЁТЕСЛИ(СМЕЩ($H$2;ПОИСКПОЗ(F$69;$A$3:$A$64;);;2;12);$B70)=СУММПРОИЗВ(($H$3:$S$64=$B70)*($A$3:$A$64=F$69))

Изменено: gling  - 06.01.2026 21:13:36
gling, добрый день! Подскажите, пожалуйста, а если еще добавить условие по комментариям? То есть считать только то кол-во, где указан комментарий. Пробовала в 3-й вариант формулы добавить условие <>"", но выдает ошибку (=СУММПРОИЗВ(($H$3:$S$64=$B71)*($A$3:$A$64=F$69)*($H$3:$S$64<>""))). Помогите, пожалуйста. Фомула для ячейки F71
Изменено: Elen2801 - 14.01.2026 11:08:37
 
Код
=СУММПРОИЗВ(($H$3:$S$64=$B71)*($A$3:$A$64=F$69)*($O$3:$O$64<>""))
Согласие есть продукт при полном непротивлении сторон
 
Цитата
написал:
=СУММПРОИЗВ(($H$3:$S$64=$B71)*($A$3:$A$64=F$69)*($O$3:$O$64<>""))
Sanja, спасибо! Это если только один столбец брать для просмотра О, а если нужно нужно пересмотреть все столбцы с комментариями, как сделать формулу универсальной? Сотрудник ФИО1 и на складе 2 попадается. Каждый диапазон указывать неудобно, это маленькая часть таблицы, а таких складов 30...
 
$H$3:$S$64
$I$3:$T$64
 
Цитата
Elen2801 написал: это маленькая часть таблицы, а таких складов 30
Переработайте данные в плоский вид и переходите на Сводную таблицу
Согласие есть продукт при полном непротивлении сторон
 
Цитата
написал:
Переработайте данные в плоский вид и переходите на Сводную таблицу
Хотелось бы найти вариант через формулы. Сейчас думают переносить это все в гугл-таблицы... мне кажется буде тогда неудобно. Только с помощью PQ можно же перейти в плоский вид?
 
Цитата
написал:
$H$3:$S$64$I$3:$T$64
Спасибо! ПОЛУЧИЛОСЬ!!!!
Изменено: Elen2801 - 14.01.2026 14:16:53 (неправильно ввела)
 
Цитата
Elen2801 написал: Только с помощью PQ можно же перейти в плоский вид?
Можно по-разному. Вручную/PQ/макрос. Один раз заморочиться, но потом в разы облегчить себе жизнь
Согласие есть продукт при полном непротивлении сторон
 
Цитата
написал:
Один раз заморочиться, но потом в разы облегчить ... жизнь
Код
Option Explicit

Sub Получить_данные()
    CloseEmptyWb

    Dim aTarget As Variant
    aTarget = GetTargetArray(ActiveSheet.UsedRange)
    If IsEmpty(aTarget) Then Exit Sub
    
    PrintArray Workbooks.Add(1).Sheets(1).Cells(1, 1), aTarget
End Sub

Private Sub PrintArray(rr As Range, arr As Variant)
    With rr.Cells(1 + UBound(arr(1), 1), 1 + UBound(arr(0), 2)).Resize(UBound(arr(2), 1), UBound(arr(2), 2))
        .Value = arr(2)
        .HorizontalAlignment = xlCenter
        With .Interior
            .Pattern = xlSolid
            .PatternColorIndex = xlAutomatic
            .ThemeColor = xlThemeColorAccent5
            .TintAndShade = 0.599963377788629
            .PatternTintAndShade = 0
        End With
        
        .Cells.FormatConditions.Delete
        .Cells.FormatConditions.Add Type:=xlCellValue, Operator:=xlEqual, Formula1:="=0"
        .Cells.FormatConditions(.Cells.FormatConditions.Count).SetFirstPriority
        With .Cells.FormatConditions(1).Font
            .ThemeColor = xlThemeColorDark1
            .TintAndShade = 0
        End With
        With .Cells.FormatConditions(1).Interior
            .Pattern = xlNone
            .TintAndShade = 0
        End With
        .Cells.FormatConditions(1).StopIfTrue = False
    End With
    With rr.Cells(1 + UBound(arr(1), 1), 1).Resize(UBound(arr(0), 1), UBound(arr(0), 2))
        .Value = arr(0)
    End With
    With rr.Cells(1, 1 + UBound(arr(0), 2)).Resize(UBound(arr(1), 1), UBound(arr(1), 2))
        .Value = arr(1)
        .NumberFormat = "d-mmm"
    End With
    With rr.Cells(1 + UBound(arr(1), 1), 1 + UBound(arr(0), 2) + UBound(arr(2), 2) + 1).Resize(UBound(arr(3), 1), UBound(arr(3), 2))
        .Value = arr(3)
        .Rows(0).Value = Array(1, 2)
    End With
    
    Set rr = rr.Parent.UsedRange
    
    With rr.Parent.Sort
        .SortFields.Clear
        .SortFields.Add Key:=rr.Columns(1), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        .SetRange rr
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With

    
    rr.Parent.Parent.Saved = True
End Sub

Private Function GetTargetArray(rSource As Range) As Variant
    Dim aSource As Variant
    aSource = rSource.Value
    
    Dim ys As Long, rSmen As Range, aSmen As Variant
    For ys = 1 To UBound(aSource, 1)
        If IsDate(aSource(ys, 1)) Then
            On Error Resume Next
            Set rSmen = rSource.Rows(ys).Find("смена 1")
            On Error GoTo 0
            If Not rSmen Is Nothing Then
                Set rSmen = rSmen.EntireColumn
                Set rSmen = Intersect(rSmen, rSource)
                aSmen = rSmen.Value
                Exit For
            End If
        End If
    Next
    If IsEmpty(aSmen) Then Exit Function
    
    
    For ys = UBound(aSource, 1) To 2 Step -1
        If IsEmpty(aSource(ys, 1)) Then
            If IsDate(aSource(ys - 1, 1)) Then
                aSource(ys, 1) = aSource(ys - 1, 1)
            End If
        End If
    Next
    
    Dim xs As Long, dicFIO As Object, dicDat As Object, dicSmen As Object
    
    Set dicDat = CreateObject("Scripting.Dictionary")
    For ys = 1 To UBound(aSource, 1)
        If Not IsEmpty(aSource(ys, 1)) Then
            If IsDate(aSource(ys, 1)) Then
                dicDat(aSource(ys, 1)) = Empty
            End If
        End If
    Next
    If dicDat.Count = 0 Then Exit Function
    
    Dim aDates As Variant
    aDates = dicDat.Keys()
    
    Set dicFIO = CreateObject("Scripting.Dictionary")
    For xs = rSmen.Column + 1 To UBound(aSource, 2)
        If aSource(2, xs) = "Сотрудник" Then
            For ys = 1 To UBound(aSource, 1)
                If Not IsEmpty(aSource(ys, xs)) Then
                    If aSmen(ys, 1) Like "смена #" Then
                        If IsDate(aSource(ys, 1)) Then
                            If dicFIO.Exists(aSource(ys, xs)) Then
                                Set dicDat = dicFIO(aSource(ys, xs))
                            Else
                                Set dicDat = CreateObject("Scripting.Dictionary")
                            End If
                            If dicDat.Exists(aSource(ys, 1)) Then
                                Set dicSmen = dicDat(aSource(ys, 1))
                            Else
                                Set dicSmen = CreateObject("Scripting.Dictionary")
                            End If
                            dicSmen(aSmen(ys, 1)) = Empty
                            Set dicDat(aSource(ys, 1)) = dicSmen
                            Set dicSmen = Nothing
                            Set dicFIO(aSource(ys, xs)) = dicDat
                            Set dicDat = Nothing
                        End If
                    End If
                End If
            Next
        End If
    Next
    If dicFIO.Count = 0 Then Exit Function
    
    Dim targFIO As Variant, targSmen As Variant, targDate As Variant, targSum As Variant
    ReDim targFIO(1 To dicFIO.Count, 1 To 3)
    ReDim targSmen(1 To dicFIO.Count, 1 To UBound(aDates) + 1)
    ReDim targDate(1 To 1, 1 To UBound(targSmen, 2))
    ReDim targSum(1 To dicFIO.Count, 1 To 2)
        
    Dim yt As Long, xt As Long
    For yt = 1 To UBound(targFIO, 1)
        targFIO(yt, 1) = dicFIO.Keys()(yt - 1)
        targFIO(yt, 2) = " (1)/(2)"
        targFIO(yt, 3) = "=COUNTIFS(RC[1]:RC[" & UBound(targSmen, 2) & "],1)+COUNTIFS(RC[1]:RC[" & UBound(targSmen, 2) & "],2)+2*COUNTIFS(RC[1]:RC[" & UBound(targSmen, 2) & "],""1,2"")"
        
        targSum(yt, 1) = "=COUNTIFS(RC[-" & UBound(targSmen, 2) + 1 & "]:RC[-2],1)+COUNTIFS(RC[-" & UBound(targSmen, 2) + 1 & "]:RC[-2],""1,2"")"
        targSum(yt, 2) = "=COUNTIFS(RC[-" & UBound(targSmen, 2) + 2 & "]:RC[-3],2)+COUNTIFS(RC[-" & UBound(targSmen, 2) + 3 & "]:RC[-4],""1,2"")"
    Next
    For xt = 1 To UBound(targDate, 2)
        targDate(1, xt) = aDates(xt - 1)
    Next
    
    For yt = 1 To UBound(targSmen, 1)
        Set dicDat = dicFIO.Items()(yt - 1)
        For xt = 1 To UBound(targSmen, 2)
            If dicDat.Exists(targDate(1, xt)) Then
                Set dicSmen = dicDat(targDate(1, xt))
                targSmen(yt, xt) = Replace(Join(dicSmen.Keys(), ","), "смена ", "")
                Set dicSmen = Nothing
            End If
        Next
        Set dicDat = Nothing
    Next
    GetTargetArray = Array(targFIO, targDate, targSmen, targSum)
End Function

Private Sub CloseEmptyWb()
    Dim wb As Workbook
    For Each wb In Application.Workbooks
        If wb.Path = "" Then wb.Close False
    Next
End Sub
Страницы: 1
Читают тему
Наверх