Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.11.2021, 22:46   #1
andreysuperman42
Пользователь
 
Регистрация: 31.03.2013
Сообщений: 43
Вопрос Внесение второго значения в элемент словаря

Добрый вечер.
На основании одной таблицы создаю другую таблицу с уникальными значениями. Количество фруктов с одинаковыми значениями суммируется.
Как можно вычислить среднее значение цены фруктов с одинаковыми значениями?
Вложения
Тип файла: xls Тест1.xls (144.5 Кб, 15 просмотров)
andreysuperman42 вне форума Ответить с цитированием
Старый 14.11.2021, 19:33   #2
Aleksandr H.
2 the Nation Glory
Старожил
 
Аватар для Aleksandr H.
 
Регистрация: 27.05.2014
Сообщений: 3,289
По умолчанию

Код:
Option Explicit
Dim dictObject As New Dictionary ' Создаем словарь
Dim varArray, varArray2, Keys
Dim dblКоличество#, dblPrice#
Dim lngRow&, key$
Private Sub CommandButton2_Click()
    Dim val() As String
    '  Application.ScreenUpdating = False    ' Отключаем обновление экрана...
    Range("J2:X65000").ClearContents    '=> Очищаем содержимое на листе
    varArray = Range("A1").CurrentRegion.Value ' Создаем массив varArray
    With dictObject
        .RemoveAll
        For lngRow = 2 To UBound(varArray)
            key = varArray(lngRow, 1) & "|" & varArray(lngRow, 2) & "|" & varArray(lngRow, 3) & "|" & varArray(lngRow, 4)
            dblКоличество = varArray(lngRow, 5)
            dblPrice = varArray(lngRow, 6)                       '=> Цена (как внести в словарь)??????????????????
            If dblКоличество > 0 Then
                If .Exists(key) Then                                         ' Если значение ключа повторяется, тогда...
                '.Item(key) = .Item(key) + dblКоличество ' Суммируем элемент (количество фруктов)
                val = Split(.Item(key), "|")
                val(0) = CInt(val(0)) + 1
                val(1) = CDbl(val(1)) + dblКоличество
                val(2) = Round((CDbl(val(2)) + dblPrice / dblКоличество) / 2, 2)
                .Item(key) = Join(val, "|")
                
                Else                                                                 ' Иначе
                    '.Item(key) = dblКоличество                      ' Вносим количество фруктов в элемент
                    .Item(key) = "1|" & dblКоличество & "|" & dblPrice / dblКоличество
                End If
            End If
        Next lngRow
        
        Keys = .Keys ' Передаем переменной Keys все созданные ключи
        ReDim varArray2(0 To 6, 0 To UBound(Keys)) ' Создаем массив varArray2
        
        For lngRow = 0 To UBound(Keys)
            key = .Keys(lngRow)
            varArray = Split(key, "|")
            varArray2(0, lngRow) = lngRow + 1
            varArray2(1, lngRow) = varArray(1)
            varArray2(2, lngRow) = varArray(2)
            varArray2(3, lngRow) = varArray(3)
            varArray2(4, lngRow) = varArray(0)
            'varArray2(5, lngRow) = Format(.Item(key), "0.00")
            val = Split(.Item(key), "|")
            varArray2(5, lngRow) = CInt(val(1))
            varArray2(6, lngRow) = CDbl(val(2))
            
        Next lngRow
        'Range("J2").Resize(.Count, 6) = Application.Transpose(varArray2) ' Вставка созданного массива varArray2 с транспонированием
        Range("R2").Resize(.Count, 7) = Application.Transpose(varArray2) ' Вставка созданного массива varArray2 с транспонированием
    End With
    'Range("J1") = lngRow
    Range("R1") = lngRow
End Sub
Кто умер, но не забыт, тот бессмертен.
Лао-Цзы.
Aleksandr H. вне форума Ответить с цитированием
Старый 14.11.2021, 21:10   #3
andreysuperman42
Пользователь
 
Регистрация: 31.03.2013
Сообщений: 43
По умолчанию

Спасибо, Александр, за ответ.
К сожалению, среднюю цену не правильно считает и количество округляет до целых чисел.
Но, я думаю, все решаемо. Буду разбираться.
andreysuperman42 вне форума Ответить с цитированием
Старый 15.11.2021, 00:13   #4
andreysuperman42
Пользователь
 
Регистрация: 31.03.2013
Сообщений: 43
По умолчанию

Разобрался.
Код:
Option Explicit
Dim dictObject As New Dictionary ' Создаем словарь
Dim varArray, varArray2, Keys
Dim dblКоличество#, dblPrice#
Dim lngRow&, key$
Private Sub CommandButton2_Click()
    Dim val() As String

    Range("J2:P65000").ClearContents    '=> Очищаем содержимое на листе
    varArray = Range("A1").CurrentRegion.Value ' Создаем массив varArray
    
    With dictObject
        .RemoveAll
        For lngRow = 2 To UBound(varArray)
            key = varArray(lngRow, 1) & "|" & varArray(lngRow, 2) & "|" & varArray(lngRow, 3) & "|" & varArray(lngRow, 4)
            dblКоличество = Format(varArray(lngRow, 5), "0.00")
            dblPrice = varArray(lngRow, 6)                       '=> Цена (разобрался, как внести в словарь)
            If dblКоличество > 0 Then
                If .Exists(key) Then                                         ' Если значение ключа повторяется, тогда...
                    val = Split(.item(key), "|")
                    val(0) = CInt(val(0)) + 1
                    val(1) = Format(CDbl(val(1)) + dblКоличество, "0.00")
                    val(2) = Format(CDbl(val(2)) + dblPrice, "0.00")
                    .item(key) = Join(val, "|")
                Else                                                                 ' Иначе
                    .item(key) = "1|" & dblКоличество & "|" & dblPrice
                End If
            End If
        Next lngRow

        Keys = .Keys ' Передаем переменной Keys все созданные ключи
        ReDim varArray2(0 To 6, 0 To UBound(Keys)) ' Создаем массив varArray2

        For lngRow = 0 To UBound(Keys)
            key = .Keys(lngRow)
            varArray = Split(key, "|")
            varArray2(0, lngRow) = lngRow + 1
            varArray2(1, lngRow) = varArray(1)
            varArray2(2, lngRow) = varArray(2)
            varArray2(3, lngRow) = varArray(3)
            varArray2(4, lngRow) = varArray(0)
            val = Split(.item(key), "|")
            varArray2(5, lngRow) = CDbl(val(1))
            varArray2(6, lngRow) = Format(CDbl(val(2)) / val(0), "0.00")

        Next lngRow
        Range("J2").Resize(.Count, 7) = Application.Transpose(varArray2) ' Вставка созданного массива varArray2 с транспонированием
    End With
    Range("J1") = lngRow
End Sub
andreysuperman42 вне форума Ответить с цитированием
Старый 26.11.2021, 21:24   #5
andreysuperman42
Пользователь
 
Регистрация: 31.03.2013
Сообщений: 43
По умолчанию

Задача усложнилась.
Теперь надо, чтобы фрукты располагались не вертикально, а горизонтально (в одну строку).
Буду благодарен за помощь.
Вложения
Тип файла: xls Тест2.xls (147.0 Кб, 4 просмотров)
andreysuperman42 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
найти одинаковые значения во второй таблице сравнив с первой, чтобы одинаковые значения со второго столбца распределились по строк Мариэн Microsoft Office Excel 1 27.07.2016 16:27
Найти наибольший элемент второго столбца в двумерном массиве Виталя01 Visual C++ 2 08.03.2015 18:54
Замена второго элемента односвязного списка на предпоследний элемент s24g Паскаль, Turbo Pascal, PascalABC.NET 6 17.11.2014 18:17
хранения второго значения в listbox alman12 Общие вопросы Delphi 8 15.04.2014 01:07
Firebird. Автоматическое внесение значения в поле при добовлении SNUPY БД в Delphi 11 11.12.2010 14:34