Количество уникальных хостов, связанных с группами, к которым у аккаунтов есть доступ - PullRequest
0 голосов
/ 15 мая 2018

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

Поскольку хосты могут быть в нескольких группах, а учетная запись может быть связана с несколькими группами, можнобыть дубликатами хостов, учитываемых для учетной записи.Я попытался создать макрос, который бы проходил по первому листу, получал значение группы, а затем переходил на второй лист и помещал все имена хостов для этой группы в массив.Он будет делать это для каждой группы и добавлять хосты в конец массива, пока не достигнет конца списка групп для данной учетной записи.Затем мой макрос использует функцию для удаления дубликатов из массива, а затем помещает счетчик массива в ячейку в столбце b на листе 1.

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

Мой код указан ниже:

Sub PopulatingArrayVariable()
'PURPOSE: Dynamically Create Array Variable based on a Given Size

Dim myArray As Variant
Dim arr2() As Variant
Dim myString As String
Dim x As Long
Dim r As Long
Dim d As Variant
Dim row As Integer
Dim Group As String
Dim endRow As Long

For i = 2 To 5
Worksheets("Sheet1").Activate

    For Each c In Worksheets("Sheet1").Range("C2:I2").Cells 'Finds the group the account belongs to and loops through each of them
    'For c = 3 To 8

    Group = c.Value

    Worksheets("Sheet2").Activate

    endRow = 14 ' of course it's best to retrieve the last used row number via a function
        For r = 1 To endRow

            If Cells(r, Columns("B").Column).Value = Group Then 'adds each host in the group into an array

            myString = myString & ";|;" & Cells(r, 1).Value

            End If

        Next r
    Next 'c

'Remove first delimiter from string (;|;)
   myString = Right(myString, Len(myString) - 3)


'Create an array with the Split() function
    myArray = Split(myString, ";|;")

arr2 = RemoveDupesColl(myArray)

Dim lNumElements As Long

    lNumElements = UBound(arr2) - LBound(arr2) + 1

    Worksheets("Sheet1").Cells(i, 2).Value = lNumElements
myString = Empty

Next i

'Print values to Immediate Window (Ctrl + G to view)
     'For x = LBound(myArray) To UBound(myArray)
      '   Debug.Print myArray(x)
       '  Next x

End Sub

, а вот функция удаления дубликатов:

Function RemoveDupesColl(myArray As Variant) As Variant
'DESCRIPTION:  Removes duplicates from your array using the collection method.
'NOTES:  (1)   This function returns unique elements in your array, but
'              it converts your array elements to strings.
'SOURCE: https://wellsr.com
'-----------------------------------------------------------------------
    Dim i As Long
    Dim arrColl As New Collection
    Dim arrDummy() As Variant
    Dim arrDummy1() As Variant
    Dim item As Variant
    ReDim arrDummy1(LBound(myArray) To UBound(myArray))

    For i = LBound(myArray) To UBound(myArray) 'convert to string
        arrDummy1(i) = CStr(myArray(i))
    Next i
    On Error Resume Next
    For Each item In arrDummy1
       arrColl.Add item, item
    Next item
    Err.Clear
    ReDim arrDummy(LBound(myArray) To arrColl.Count - LBound(myArray) - 1)
    i = LBound(myArray)
    For Each item In arrColl
       arrDummy(i) = item
       i = i + 1
    Next item
    RemoveDupesColl = arrDummy
End Function

Может кто-нибудь помочь мне разобраться, как заставить это работать или помочьменя с более эффективным макросом, так как в конечном итоге я буду использовать его для нескольких тысяч учетных записей, более 100 групп и более 10000 хостов.

Спасибо

1 Ответ

0 голосов
/ 16 мая 2018

Здесь хранится количество уникальных хостов на группу от Sheet2 (вложение показано ниже)

Основная операция генерирует набор уникальных хостов для всех групп в одной строке (записи)

Ожидается, что первая строка в качестве заголовка на обоих листах будет начинаться с групп в столбце C на Sheet1


Option Explicit

Public Sub PopulateHosts()
    Dim ws1 As Worksheet:   Set ws1 = Sheet1    'Or ThisWorkbook.Worksheets("Sheet1")
    Dim ws2 As Worksheet:   Set ws2 = Sheet2
    Dim lr1 As Long:        lr1 = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row
    Dim lc1 As Long:        lc1 = ws1.UsedRange.Columns.Count
    Dim lr2 As Long:        lr2 = ws2.Cells(ws2.Rows.Count, "A").End(xlUp).Row

    Dim groups As Object:   Set groups = CreateObject("Scripting.Dictionary")

    Dim r As Long, c As Long, arr As Variant, h As String, g As String, hosts As Object

    arr = ws2.Range(ws2.Cells(1, 1), ws2.Cells(lr2, 2))             'Sheet2 - Hosts
    For r = 2 To lr2                'Exclude Headers
        h = arr(r, 1)               'Convert host to string (number to string)
        g = arr(r, 2)               'Convert group to string (number to string)
        If Not groups.Exists(g) Then
            Set hosts = CreateObject("Scripting.Dictionary")
            hosts(h) = 0
            Set groups(g) = hosts
        Else
            groups(g)(h) = 0
        End If
    Next

    Dim itm As Variant, u As Object

    arr = ws1.Range(ws1.Cells(1, 1), ws1.Cells(lr1, lc1)).Formula   'Sheet1 - Accounts
    For r = 2 To lr1                'Exclude Headers
        Set u = CreateObject("Scripting.Dictionary")
        For c = 3 To lc1
            g = arr(r, c)           'Convert any group (number to string)
            If groups.Exists(g) Then
                For Each itm In groups(g)
                    u(itm) = 0      'Extract unique hosts for all groups in this row
                Next
            End If
        Next
        arr(r, 2) = u.Count
    Next
    ws1.Range(ws1.Cells(1, 1), ws1.Cells(lr1, lc1)).Formula = arr
End Sub

.

Производительность

ws1.Rows (Accounts): 10,001
ws2.Rows (Hosts):   100,002 (Groups: 10,000)
Time:   2.238 sec

.

Вложенные словари - структура (только ключи):

Group: 1 -> Host: H2      (not unique in set: Group 1 + Group 4)
Group: 1 -> Host: H5      (not unique in set: Group 1 + Group 4)
Group: 1 -> Host: H10002
Group: 1 -> Host: H20002
Group: 1 -> Host: H30002
...
Group: 1 -> Host: H90002

Group: 2 -> Host: H3      (not unique in set: Group 2 + Group 3)
Group: 2 -> Host: H4      (not unique in set: Group 2 + Group 3)
Group: 2 -> Host: H10003
Group: 2 -> Host: H20003
Group: 2 -> Host: H30003
...
Group: 2 -> Host: H90003

Group: 3 -> Host: H4      (not unique in set: Group 2 + Group 3)
Group: 3 -> Host: H3      (not unique in set: Group 2 + Group 3)
Group: 3 -> Host: H10004
Group: 3 -> Host: H20004
Group: 3 -> Host: H30004
...
Group: 3 -> Host: H90004

Group: 4 -> Host: H5      (not unique in set: Group 1 + Group 4)
Group: 4 -> Host: H2      (not unique in set: Group 1 + Group 4)
...

Тестовые данные

Sheet1

Sheet1

Sheet2

Sheet2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...