Страницы: 1
RSS
Оставить из дубликатов файл с самым поздним индексом
 
Здравствуйте. Пытаюсь получить определенные файлы из папок и столкнулся с проблемой: в некоторых папках есть несколько файлов, среди которые правильным считается тот, у которого в конце через знак тире добавлена наибольшая цифра. Как пример, на скриншоте есть дублирующийся файл "RFQ107005-Response.xml" под названием "RFQ107005-3-Response.xml". Как из списка полученных файлов оставлять только самые свежие на основе данного индекса? У меня пока что есть только идея разбивать как-нибудь название на части, заводить отдельное поле для индексов и по ним потом фильтровать, но тогда проблема с файлами, у которых нет индексов - надо будет ещё что-то придумывать... Может, я перемудрил и есть куда более простой способ?
 
Цитата
Сергей Кузьмин написал:
Пытаюсь получить определенные файлы из папок
из каких папок?
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Не совсем понял вопрос. Если интересует структура, то она следующая: папка, в которой много папок, в каждой из которых несколько файлов. То есть Папка->Папки->Файлы.
 
скопируйте этот
Код
Sub Test()
  Dim a, d, k, ks
  Set d = GetLastFiles
  If d.Count Then
    ks = d.keys
    For Each k In ks: a = d(k): Debug.Print a(2): Next
  End If
End Sub

Function GetLastFiles()
  Dim a, b(), d, f, fs0, fn$, fs, fso, i&, k$, sfs
  fn = GetDataFolder("Выберите папку, содержащую папки с файлами")
  If fn = "" Then Exit Function
  Set fso = CreateObject("Scripting.FileSystemObject")
  Set d = CreateObject("Scripting.Dictionary")
  Set fs0 = fso.getfolder(fn)
  For Each fs In fs0.subfolders
    For Each f In fs.Files
      a = Split(f.Name, "-")
      If UBound(a) > 0 And UBound(a) < 3 Then
        If UBound(a) = 1 Then k = a(0) & a(1): i = 0
        If UBound(a) = 2 Then k = a(0) & a(2): i = Val(a(1))
        If d.exists(k) Then b = d(k) Else ReDim b(1 To 2)
        If i > b(1) Then b(1) = i: b(2) = f.Path: d(k) = b
      End If
    Next
  Next
  Set GetLastFiles = d
End Function

Function GetDataFolder$(tit$, Optional Pth$ = "")
  With Application.FileDialog(msoFileDialogFolderPicker)
    If Pth = "" Then Pth = ThisWorkbook.Path
    .ButtonName = "Выбрать": .Title = tit: .InitialFileName = Pth
    If .Show <> -1 Then Exit Function
    GetDataFolder = .SelectedItems(1)
  End With
End Function
выполните Test
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Честно говоря, я даже не понимаю, что это и что с этим делать(. Я спрашивал, есть ли более простой способ, чем тот, что предложил я. Мне жаль, но в предложенном Вами варианте я не могу ничего понять.
 
Сергей Кузьмин, нам Вам по картинке код писать? Пример очень долго делать?
Приложите файл пример: таблица, где будет один столбец с наименованиями файлов, аналогичных реальным наименованиям (можете просто выгрузить на лист столбец наименований из Вашего запроса).
 
Файл приложил, но я повторюсь - мне не нужен код. Я хочу найти простой алгоритм. Возможно в Power Query есть какая-то встроенная функция, которая удаляет дубликаты, оставляя те, у кого наибольший индекс или еще что.
 
Цитата
Сергей Кузьмин написал:
мне не нужен код. Я хочу найти простой алгоритм
Вы считаете, что компьютер сам должен понять, что дубликат, а что нет? :)
1. Выделяете наименование (текст до "-") из имени файла в отдельный столбец.
2. Выделяете число после наименования.
3. Группируете по наименованию, оставляя строку с максимальным числом после наименования.
Сделали?
Если нет:
Скрытый текст
Изменено: surkenny - 09.07.2022 19:26:37
 
Да, сделал. Вы предлагаете джоинить группировку с исходными данными и получить таким образом нужный результат?
 
Цитата
Сергей Кузьмин написал:
Честно говоря, я даже не понимаю, что это и что с этим делать(.
в сообщении написано скопировать в модуль, выполнить Test
какой из этих 2-х пунктов вам не понятен, где случилась осечка?
ладно
отвечать не нужно
надеюсь у вас достаточно квалификации чтобы скачать файл, открыть его, нажать кнопку BANZAY!!! ?
Изменено: Ігор Гончаренко - 09.07.2022 22:14:41
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Квалификации достаточно, только ответ он выдает неправильный - всего 4 значения вместо 18. Я никогда не имел дел с макросами, поэтому и не знал, что делать с этим кодом. Вариант, предложенный surkenny сработал. Но все равно спасибо за трату времени на мой вопрос.
 
Цитата
Сергей Кузьмин написал:
только ответ он выдает неправильный
1. проблемы неоднозначной постановки задачи
(мой макрос выбирает файлы с последними индексами не в рамках одной папки, а анализируя имена всех файлов всех подпапок
если в папке1 есть файл А-1-В, а в папке2 А-2-В - файл А-1-В не попадет в отчет, потому что где-то в папках нашелся с таким же именем, только с большим индексом внутри имени)
2. я не создавал систему подпапок у себя на компьютере, не наполнял их разными файлами с выдуманными именами для того чтобы проверить как работает иакрос. т.е. макрос не тестировался( и мог у вас вообще не сработать((
и там-таки есть ошибка(((
строи 23 и 24 в предыдущем коде следует заменить на
Код
        If d.Exists(k) Then b = d(k) _
        Else ReDim b(1 To 2): b(1) = -1: b(2) = f.Path
        If i > b(1) Then b(1) = i: d(k) = b

а вот этот
Код
Sub ClearLowIndex()
  Dim a, b, d, i&, k, ks, r&, s
  Set d = CreateObject("Scripting.Dictionary"): a = [a1].CurrentRegion
  For r = 2 To UBound(a)
    s = Split(a(r, 1), "-")
    If UBound(s) > 0 And UBound(s) < 3 Then
      If UBound(s) = 1 Then k = s(0) & s(1): i = 0
      If UBound(s) = 2 Then k = s(0) & s(2): i = Val(s(1))
      If d.Exists(k) Then b = d(k) _
      Else ReDim b(1 To 2): b(1) = -1: b(2) = a(r, 1)
      If i > b(1) Then b(1) = i: d(k) = b
    End If
  Next
  If d.Count Then
    ks = d.keys: [c:c].ClearContents: r = 1
    For Each k In ks: a = d(k): r = r + 1: Cells(r, 3) = a(2): Next
  End If
End Sub
оставит из выше предложенного списка файлов 18 шт.
Изменено: Ігор Гончаренко - 10.07.2022 05:19:21
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
Сергей Кузьмин написал:
Вы предлагаете джоинить группировку с исходными данными и получить таким образом нужный результат?
Нет. Группируйте сразу свою таблицу с данными файлов в папке. Из каждой группы у Вас в столбце группировки после Table.Max(table,{“ind”}) останется запись Вашей таблицы с максимальным числом после наименования. Создаёте из записей таблицу. Все. Получили прежнюю таблицу с нужным Вам отбором последних файлов.
Страницы: 1
Наверх