Страницы: 1
RSS
Формирование массива по критерию с выборкой данных из него по условию
 
Всем, привет

На первый взгляд показалась лёгкая задача но когда принялся делать появились сложности.

Задача в том, что бы из таблицы в которой записаны события вытащить по определённым критериям дату начала этого события (дату отправки на согласование) и дату окончания события (дату согласования).
Вытаскиваем дату согласования только если последние событие будет иметь статус "Согласовано" или "Не требует согласования"  в противном случае вытаскиваем фразу из последнего статус (копируем значение ячейки статус)

В файле есть рядом две таблицы.
Первая таблица А1:С50 содержит не уникальный список событий (Заказы) напротив которого дата этого события (Период) и статус события (статус)

Вторая таблица Е1:G11 содержит уже уникальные события (Заказа) взятые из первой таблице (то есть взят весь список событий и удалены дубли после чего вставлен во вторую таблицу)  напротив каждого события "Дата отправки на согласования" и "Дата согласования"

Пример:
ЗаказПериодСтатус
Заказ   поставщику WB-ЦБ\ЗПС-000009 от 02.01.2018 11:14:3602.01.2018 11:14:37Ожидание   синхронизации
Заказ   поставщику WB-ЦБ\ЗПС-000009 от 02.01.2018 11:14:3602.01.2018 11:21:09На согласовании
Заказ   поставщику WB-ЦБ\ЗПС-000009 от 02.01.2018 11:14:3603.01.2018 12:24:35Согласован
.
.
Результат:
Заказ уникальныйДата отправки на согласования Дата согласования
Заказ поставщику WB-ЦБ\ЗПС-000009 от 02.01.2018 11:14:3602.01.2018 11:21:09

03.01.2018 12:24:35

Дата отправки на согласование - находит по номеру заказа первый статус "На согласование" и вставляет дату
Дата Согласование - находит последний статус "Согласовано" или "Не требует согласование" и вставляет дату, в противном случае вытаскиваем фразу из последнего статус (копируем значение ячейки статус)
Изменено: Mutarix - 17.08.2018 14:36:50
 
Доброе время суток.
Это так модно составлять пример результата, противоречащий постановке задачи?
Цитата
Mutarix написал:
Вторая таблица ... содержит уже уникальные события (Заказа)
Выделено красным дата согласования для Заказа "Заказ поставщику WB-ЦБ\ЗПС-000009 от 02.01.2018 11:14:36", тут всё хорошо, но почему зелёным выделено для совсем другого заказа? Как в детском анекдоте - чтобы не догадался?
Версия на Power Query.
 
Андрей VG, Вы правы ошибочно указал. Изменил в первом сообщении.
Файл который вы прислали содержит верные результат но у меня версия офиса 2010.
Как это можно сделать с помощью формул?
Изменено: Mutarix - 20.08.2018 11:47:59
 
вариант
Код
Sub d()
Dim dic
Set dic = CreateObject("Scripting.Dictionary")
For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
    If Cells(i, 3).Value = "На согласовании" Or Cells(i, 3).Value = "Не требует согласования" Then
        ky = Cells(i, 1).Value
        it = Cells(i, 2).Value & "|" & Cells(i, 3).Value
        If dic.exists(ky) Then dic.Item(ky) = it Else dic.Add ky, it
    End If
Next
For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
    If Cells(i, 3).Value = "Согласован" Then
        ky = Cells(i, 1).Value
        s = Split(dic.Item(ky), "|")
        dic.Item(ky) = s(LBound(s)) & "|" & Cells(i, 2).Value
    End If
Next
i = 2
For Each ky In dic.keys
    s = Split(dic.Item(ky), "|")
    Range("E" & i) = ky
    Range("F" & i) = s(LBound(s))
    Range("G" & i) = s(UBound(s))
    i = i + 1
Next
End Sub
 
yozhik, Макрос работает почти правильно.

Нужно что бы в столбце "Дата согласования" выводил дату если последнее событие "согласовано" или "не требует согласование".
Если последнее событие имеет другой статус нужно выводить "статус" последнего события.

Заранее спасибо.
Изменено: Mutarix - 20.08.2018 12:52:40
 
yozhik, Большое спасибо.

Доработал ваш код. Сейчас работает верно.
Ошибка ушла после того как добавил On Error Resume Next

Остался один вопрос - есть ли варианты чтобы ускорить работу кода, так как при 300 000 строк выполняется примерно 1-2 мин.
Скрытый текст
Изменено: Mutarix - 20.08.2018 15:56:10
 
Может так?
Скрытый текст
 
Цитата
Mutarix написал:
Ошибка ушла после того как добавил On Error Resume Next
после этого оно так -то вообще любые ошибки уходят..) вернее, никуда они не уходят, и скорее всего Вы получите не совсем то, мягко говоря, что ожидаете, а и вполне вероятно на больших объемах данных Вы этого и не заметите
 

попробуйте отключить автообновление экрана, возможно и автопересчет формул, чтоб ускорить код. Для того, чтоб выводить даты, можно дописать условие во второй цикл. Не знаю, может ли у Вас быть заказ с пометкой сразу "не требует согласования" и отсутствовать запись по этому же заказу с пометкой "на согласовании", поэтому проверку оставил в двух циклах

Код
Sub d()
Application.ScreenUpdating = False
Dim dic
Set dic = CreateObject("Scripting.Dictionary")
For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
    If Cells(i, 3).Value = "На согласовании" Or Cells(i, 3).Value = "Не требует согласования" Then
        ky = Cells(i, 1).Value
        it = Cells(i, 2).Value & "|" & Cells(i, 3).Value
        If dic.exists(ky) Then dic.Item(ky) = it Else dic.Add ky, it
    End If
Next
For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
    If Cells(i, 3).Value = "Согласован" Or Cells(i, 3).Value = "Не требует согласования" Then
        ky = Cells(i, 1).Value
        s = Split(dic.Item(ky), "|")
        dic.Item(ky) = s(LBound(s)) & "|" & Cells(i, 2).Value
    End If
Next
i = 2
For Each ky In dic.keys
    s = Split(dic.Item(ky), "|")
    Range("E" & i) = ky
    Range("F" & i) = s(LBound(s))
    Range("G" & i) = s(UBound(s))
    i = i + 1
Next
Application.ScreenUpdating = True
End Sub



Изменено: yozhik - 20.08.2018 17:57:03
 
Добрый день, Друзья

Созданный макрос ниже даёт следующий результат:
Входящие данные.

Скрытый текст

Помогите преобразовать код, что бы результатом было первое событие, то есть первая дата отправки на согласование и первая дата согласования.
Входящие данные
Заранее спасибо и надеюсь на конструктивный ответ.

Ещё один небольшой комментарий, при работе с большим объёмом данных больше 300 000 строк макрос подвисает. Возможно есть какой то лучше способ чем использовать On Error Resume Next
Изменено: Mutarix - 31.01.2019 18:20:26
 
Цитата
Mutarix написал: есть какие либо идеи по моему вопросу?
В цикле по массиву формировать словарь, где ключ - "Заказ", а его значение - одномерный массив из 2х элементов:
1) максимальное значение по статусу "На согласовании" поля "Статус";
2) максимальное значение по статусу "Согласован" поля "Статус".
Всё. Вывод в таблицу из словаря, думаю, сможете организовать самостоятельно.

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
JayBhagavan, спасибо за ваш комментарий.
Правильно я понимаю этот комментарий к сообщению:
Цитата
Ещё один небольшой комментарий, при работе с большим объёмом данных больше 300 000 строк макрос подвисает. Возможно есть какой то лучше способ чем использовать On Error Resume Next
Основной вопрос написан в сообщении выше: от 17 Дек 2018 18:22:25
 
Цитата
Mutarix написал: Помогите преобразовать код, что бы результатом было первое событие, то есть первая дата отправки на согласование и первая дата согласования.
Согласно этому уточнению, нужна корректировка алгоритма. Вместо:
Цитата
1) максимальное значение по статусу "На согласовании" поля "Статус";
2) максимальное значение по статусу "Согласован" поля "Статус".
надо:
Цитата
1) МИНимальное значение по статусу "На согласовании" поля "Статус";
2) МИНимальное значение по статусу "Согласован" поля "Статус".

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
JayBhagavan, вот здесь то и проблема, мои знания к сожалению не позволяют реализовать эту задачу, напишите пожалуйста пример реализации. Я постираю его прикрутить к своей задаче.
 
Mutarix, я словари освоил читая этот форум и справочную информацию. Не вижу в чём у Вас проблема освоить их работу самостоятельно. Конструктивный вопрос стоит конструктивного ответа. А "я не умею" подразумевает ответ "научИтесь".
В помощь освоения словарей "Исчерпывающее описание объекта Dictionary".

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
JayBhagavan, спасибо

Андрей VG, начал разбираться в вашем варианте решения задачи и столкнулся с проблемой.
Как обратиться к последней (максимальной) строке столбца дата согласования и проверить определённые статусы ("Согласован" или "Не требует согласования") если они отсутствуют возвращаем статус если есть возвращаем дату первого согласования (минимального)?
Скрытый текст
Изменено: Mutarix - 31.01.2019 18:23:08
 
Друзья, помогите решить задачу. Вернее доработать.

У меня есть два варианта реализации:
- Power Query
- макрос
Оба варианта некорректно делают выборку данных в некоторых случаях.

Логика выборки должна быть следующая:
Скрытый текст

Посмотрите во вложенных вариантах, что получается и, что должно получиться.

 
Макрос
Скрытый текст
Изменено: Sanja - 08.02.2019 15:22:43
Согласие есть продукт при полном непротивлении сторон
 
Sanja, большое спасибо.
Макрос работает правильно.

400000 строк обрабатывает за 6-10 мин. Есть варианты ускорить процесс?

Очень профессионально вы получили данные "СА-ЦБ\ЗПС-000002" для первого столбца "Е2",   из "Заказ поставщику СА-ЦБ\ЗПС-000002 от 01.01.2018 0:00:01"
Попытался также вытащить 01.01.2018 из строки "Заказ поставщику СА-ЦБ\ЗПС-000002 от 01.01.2018 0:00:01" и вставить в пятый столбец,
Не получилось.

Можете подсказать как вытащить ещё и дату из "Заказ поставщику СА-ЦБ\ЗПС-000002 от 01.01.2018 0:00:01" и вставить в столбец "I2" (5-й столбец)
 
Цитата
Mutarix написал: вытащить 01.01.2018 из строки "Заказ поставщику СА-ЦБ\ЗПС-000002 от 01.01.2018 0:00:01"
Добавил. Проверьте в файле

Цитата
Mutarix написал: Есть варианты ускорить процесс?
Есть. Посмотрю чуть позже
Согласие есть продукт при полном непротивлении сторон
 
Sanja,

У меня всё таки получилось вытащить дату и вставить 5-й столбец, но ваш вариант думаю лучше (код короче)
Я пошёл другим путём, в коде можно проследить, что я изменил во вложенном файле (все строки с '+++++++++++++Поменял код,)

Цитата
Sanja, Есть. Посмотрю чуть позже
Спасибо, буду ждать вариант более шустрый
 
Попробуйте такой вариант. Коллекция на больших объемах работает быстрее
Скрытый текст
Согласие есть продукт при полном непротивлении сторон
 
Sanja, Спасибо, немного быстрее работает ( на 27 % быстрее)
Страницы: 1
Наверх