Excel vba - сравнение трех диапазонов - PullRequest
1 голос
/ 21 октября 2011

Мне нужна помощь в прохождении трех диапазонов (листов) и проверке данных взад-вперед. Но эти циклы For убивают меня. Три цикла - это слишком много для меня, и я даже не уверен, как логически распределить код, что и куда идет.

Хорошо, поэтому я собираю эти три диапазона в свои собственные массивы Variants:

  • Основная информация
  • Пользователи
  • Статья

У меня есть лист здесь, для просмотра онлайн. Не нужно загружать его или что-нибудь. У меня есть код макроса, который собирает данные, если сводный лист пуст. И это работает так, как должно. https://skydrive.live.com/view.aspx?cid=5D018DB0458F03ED&resid=5D018DB0458F03ED%21164

В таблице есть несколько норвежских слов, но это не должно иметь большого значения :) В основном это Oppsummering (Summary), Brukere (Users) и Artikler (Articles).

В любом случае, я хочу убедиться, что сводная таблица содержит каждого пользователя столько раз, сколько статей. В основном это должно быть отражено. Если я удаляю строку (имя) из листа «Пользователи», эти строки также должны быть удалены из листа «Сводка». Но в то же время я хочу сохранить данные из столбца D в сводной таблице. Поэтому мне нужно сохранить эти данные вместе с идентификатором пользователя и идентификатором статьи, чтобы убедиться, что данные в столбце D находятся на своем месте.

Это мой (плохой) код, как сейчас ..

    With shtSummary
    ReDim tempArr(1 To UBound(arrUsers) * UBound(arrarticles), 1 To 6)
    If Not .Range("A2") = "" Then
        arrsummary = .Range("A2", .Cells(Rows.Count, "A").End(xlUp)).Resize(, 6)

        ' Start collecting data, make sure summary sheet contains refreshed data while keeping the amount of each item for that particular user
        For u = 1 To UBound(arrsummary)
            For i = 1 To UBound(arrUsers)
                For p = 1 To UBound(arrarticles)
                    j = j + 1
                    ' Check ID
                    If arrsummary(u, 1) = arrUsers(i, 1) And arrsummary(u, 3) = arrarticles(p, 1) Then
                        ' ID
                        tempArr(j, 1) = arrUsers(u, 1)
                        ' Name
                        tempArr(j, 2) = arrUsers(u, 2)
                        ' Article Number
                        tempArr(j, 3) = arrarticles(i, 1)
                        ' Article Name
                        tempArr(j, 4) = arrarticles(i, 2)
                        ' Amount of that item
                        tempArr(j, 5) = arrsumary(u, 5)
                        ' Price of that article
                        tempArr(j, 6) = arrarticles(i, 3)
                    End If
                Next
            Next
        Next

    Else
        ' If summary sheet is empty, add all data from the two other sheets
        For u = 1 To UBound(arrUsers)
            For i = 1 To UBound(arrarticles)
                j = j + 1
                ' ID
                tempArr(j, 1) = arrUsers(u, 1)
                ' Name
                tempArr(j, 2) = arrUsers(u, 2)
                ' Article number
                tempArr(j, 3) = arrarticles(i, 1)
                ' Article name
                tempArr(j, 4) = arrarticles(i, 2)
                ' Article price
                tempArr(j, 6) = arrarticles(i, 3)
            Next
        Next
        ' Finally add data to spreadsheet Summary
        .Range("A2").Resize(j, 6).Value = tempArr
    End If
End With

Обратите внимание, что есть три цикла For, и это для меня слишком много, я думаю ... У меня была похожая тема до этого, здесь, в Stackoverflow, и кто-то порекомендовал мне добавить другой лист, чтобы в основном копировать данные из листа Summary. Таким образом, я мог бы просто стереть данные из сводной таблицы в конце. Но я не понимаю, зачем это нужно делать, я имею в виду, я все равно храню все данные из сводной таблицы в shtSummary, она просто в массиве. Но это все те же данные?

Редактировать: Так что упростите эту вещь. Повторите каждое имя пользователя для каждого элемента в листе статей. То есть, если есть 10 статей, повторите имя пользователя 10 раз. Статьи находятся на странице «Статьи», а пользователи - на странице «Пользователи». НО, данные в столбце D на сводном листе не собираются с другого листа, они вводятся непосредственно в сводный лист. И вот проблема в том, что данные будут потеряны, если я просто опустошу сводный лист и повторно импортирую данные из листа пользователей и статей. Потому что это легко (сделано в макросе выше). Это просто запоминание количества данных для каждого элемента для каждого пользователя, это проблема. Если userID "2", articleNumber "452" имеет значение 2 в столбце D, то я хочу сохранить это и убедиться, что значение "2" в ColumnD "приклеено" к строке userID "2", articleNumber "452 ».

1 Ответ

1 голос
/ 29 октября 2011

Одно быстрое примечание: в вашем вопросе говорится, что сумма была в столбце D, а в файле примера - в столбце E, поэтому я буду использовать столбец E при обращении к этому столбцу.

Я согласен с комментариями, что, вероятно, это проще сделать в Access, но, учитывая, как большинство пользователей любят использовать Excel, вот алгоритм, который я бы использовал для решения этой проблемы:

  • Копировать столбцы A(Идентификатор пользователя), C (идентификатор статьи) и E (сумма) на временном листе, чтобы сохранить суммы, чтобы мы могли добавить их позже
  • Очистить содержимое сводного листа (это проще, чем ручная проверкакакие пользователи и / или статьи должны быть удалены)
  • Использование двух вложенных циклов for для перебора содержимого листов пользователей и статей и ввода всех комбинаций идентификаторов пользователей (с соответствующим именем) и идентификаторов статей (с соответствующим именем и ценой) в столбцы A, B, C и F сводного листа
  • Переберите сводный лист и найдите первоначальную сумму во временномлист с использованием идентификатора пользователя и идентификатора статьи в качестве ключей поиска для заполнения столбца E

Надеюсь, это поможет, хотя я и не определил точный код VBA.Если в коде есть конкретные части, с которыми вам нужна помощь, дайте мне знать.

...